source: neercs/trunk/src/interpreter.c @ 4035

Last change on this file since 4035 was 4035, checked in by Jean-Yves Lamoureux, 11 years ago
  • Added 'neercs' python module, with dummy 'version' method
File size: 8.0 KB
Line 
1/*
2 *  neercs        console-based window manager
3 *  Copyright (c) 2009 Jean-Yves Lamoureux <jylam@lnxscene.org>
4 *                All Rights Reserved
5 *
6 *  $Id: interpreter.c 3996 2009-11-22 12:41:45Z jylam $
7 *
8 *  This program is free software. It comes without any warranty, to
9 *  the extent permitted by applicable law. You can redistribute it
10 *  and/or modify it under the terms of the Do What The Fuck You Want
11 *  To Public License, Version 2, as published by Sam Hocevar. See
12 *  http://sam.zoy.org/wtfpl/COPYING for more details.
13 */
14
15#include "config.h"
16
17#ifdef USE_PYTHON
18
19#include <Python.h>
20
21#include <stdio.h>
22#include <stdlib.h>
23#include <string.h>
24#include <unistd.h>
25
26#include <fcntl.h>
27#include <signal.h>
28#include <sys/ioctl.h>
29#include <sys/socket.h>
30#include <sys/time.h>
31#include <time.h>
32#include <sys/wait.h>
33#include <sys/types.h>
34
35#include <caca.h>
36
37#include "neercs.h"
38#include "py_module.h"
39
40static void add_char(struct screen_list *sl, unsigned int c);
41static void del_char(struct screen_list *sl);
42static int python_execute(struct screen_list *sl);
43static char *getStringFromPyObject(PyObject * p);
44static char *getPythonError(void);
45
46static void add_char(struct screen_list *sl, unsigned int c)
47{
48    /* FIXME handle return values */
49    if (!sl->interpreter_props.command)
50    {
51        sl->interpreter_props.size = 1;
52        sl->interpreter_props.x = 0;
53        sl->interpreter_props.command = (char *)malloc(2);
54        sl->interpreter_props.command[0] = 0;
55    }
56    else
57    {
58        sl->interpreter_props.command =
59            (char *)realloc(sl->interpreter_props.command,
60                            sl->interpreter_props.size + 1);
61    }
62    memmove(&sl->interpreter_props.command[sl->interpreter_props.x + 1],
63            &sl->interpreter_props.command[sl->interpreter_props.x],
64            (sl->interpreter_props.size - sl->interpreter_props.x));
65
66    sl->interpreter_props.command[sl->interpreter_props.x] = c;
67    sl->interpreter_props.x++;
68    sl->interpreter_props.size++;
69}
70
71static void del_char(struct screen_list *sl)
72{
73    if (sl->interpreter_props.x < 1)
74        return;
75    if (sl->interpreter_props.size > 1)
76        sl->interpreter_props.size--;
77    else
78        return;
79
80    memcpy(&sl->interpreter_props.command[sl->interpreter_props.x - 1],
81           &sl->interpreter_props.command[sl->interpreter_props.x],
82           sl->interpreter_props.size - sl->interpreter_props.x);
83
84    sl->interpreter_props.command =
85        (char *)realloc(sl->interpreter_props.command,
86                        sl->interpreter_props.size);
87
88    if (sl->interpreter_props.x)
89        sl->interpreter_props.x--;
90    sl->interpreter_props.command[sl->interpreter_props.size - 1] = 0;
91}
92
93
94int python_command_handle_key(struct screen_list *screen_list, unsigned int c)
95{
96    if (c == CACA_KEY_ESCAPE)
97    {
98        if (screen_list->interpreter_props.command)
99        {
100            free(screen_list->interpreter_props.command);
101            screen_list->interpreter_props.command = NULL;
102        }
103        screen_list->python_command = 0;
104        screen_list->changed = 1;
105        return 1;
106    }
107    else if (c == CACA_KEY_LEFT)
108    {
109        if (screen_list->interpreter_props.x)
110            screen_list->interpreter_props.x--;
111    }
112    else if (c == CACA_KEY_RIGHT)
113    {
114        if (screen_list->interpreter_props.x <
115            screen_list->interpreter_props.size - 1)
116            screen_list->interpreter_props.x++;
117    }
118    else if (c == CACA_KEY_RETURN)
119    {
120        python_execute(screen_list);
121    }
122    else
123    {
124        if (c >= ' ' && c < 127)
125            add_char(screen_list, c);
126        else if (c == 8)
127        {
128            del_char(screen_list);
129        }
130        screen_list->changed = 1;
131        return 0;
132    }
133    return 0;
134}
135
136void draw_python_command(struct screen_list *screen_list)
137{
138    int w = 65, h = 6;
139    int x = (caca_get_canvas_width(screen_list->cv) - w) / 2;
140    int y = (caca_get_canvas_height(screen_list->cv) - h) / 2;
141
142    caca_set_color_ansi(screen_list->cv, CACA_BLUE, CACA_BLUE);
143    caca_fill_box(screen_list->cv, x, y, w, h, '#');
144    caca_set_color_ansi(screen_list->cv, CACA_DEFAULT, CACA_BLUE);
145    caca_draw_cp437_box(screen_list->cv, x, y, w, h);
146    caca_printf(screen_list->cv, x, y, "Execute command");
147
148    caca_printf(screen_list->cv, x + 2, y + 2,
149                "[___________________________________________________________]");
150
151    if (screen_list->interpreter_props.command)
152    {
153        caca_printf(screen_list->cv, x + 3, y + 2,
154                    "%s", screen_list->interpreter_props.command);
155        caca_gotoxy(screen_list->cv,
156                    x + 3 + screen_list->interpreter_props.x, y + 2);
157    }
158    else
159    {
160        caca_gotoxy(screen_list->cv, x + 3, y + 2);
161    }
162
163    if (screen_list->interpreter_props.output)
164    {
165        caca_set_color_ansi(screen_list->cv, CACA_RED, CACA_BLUE);
166        caca_printf(screen_list->cv, x + 2, y + 4,
167                    screen_list->interpreter_props.output);
168    }
169
170}
171
172/* Actual Python interpreter stuff */
173int python_init(struct screen_list *sl)
174{
175    sl->interpreter_props.output = NULL;
176    Py_Initialize();
177   
178    PyInit_neercs();
179   
180    return 0;
181}
182
183int python_close(struct screen_list *sl)
184{
185    if (sl->interpreter_props.output)
186        free(sl->interpreter_props.output);
187    sl->interpreter_props.output = NULL;
188    Py_Finalize();
189    return 0;
190}
191
192
193static int python_execute(struct screen_list *sl)
194{
195    if (!sl->interpreter_props.command || sl->interpreter_props.size < 1)
196        return -1;
197    int err = 0;
198
199    debug("py Executing '%s'\n", sl->interpreter_props.command);
200
201    if (sl->interpreter_props.output)
202    {
203        // FIXME free(sl->interpreter_props.output);
204        sl->interpreter_props.output = NULL;
205    }
206
207    PyObject *pModule, *pName, *pFunc, *pValue;
208
209    /* Module from which to call the function */
210    pName = PyUnicode_FromString("neercs");
211    if (!pName)
212    {
213        sl->interpreter_props.output = getPythonError();
214        err = 1;
215        debug("py Error 1\n");
216        goto end;
217    }
218
219
220    pModule = PyImport_Import(pName);
221    Py_DECREF(pName);
222    if (pModule != NULL)
223    {
224        pFunc = PyObject_GetAttrString(pModule, sl->interpreter_props.command);
225        if (pFunc && PyCallable_Check(pFunc))
226        {
227            pValue = PyObject_CallObject(pFunc, NULL);
228            if (pValue != NULL) {
229                char *res = getStringFromPyObject(pValue);
230                sl->interpreter_props.output = res;
231                debug("py Result of call: %s\n", res);
232                Py_DECREF(pValue);
233            }
234            else {
235                Py_DECREF(pFunc);
236                Py_DECREF(pModule);
237                sl->interpreter_props.output = getPythonError();
238                err = 1;
239                debug("py Call failed\n");
240                goto end;
241                return 1;
242            }
243        }
244        else
245        {
246            sl->interpreter_props.output = getPythonError();
247            err = 1;
248            debug("py Error 2\n");
249            goto end;
250        }
251    }
252    else
253    {
254        sl->interpreter_props.output = getPythonError();
255        err = 1;
256        debug("py: %s\n", sl->interpreter_props.output);
257        goto end;
258    }
259
260  end:
261   
262    Py_XDECREF(pFunc);
263    Py_DECREF(pModule);
264   
265    if (!err)
266    {
267        free(sl->interpreter_props.command);
268        sl->interpreter_props.command = NULL;
269        sl->interpreter_props.size = 0;
270        sl->interpreter_props.x = 0;
271        sl->python_command = 0;
272    }
273    sl->changed = 1;
274
275    return 0;
276}
277
278
279
280static char *getPythonError(void)
281{
282    char *err;
283    PyObject *type, *value, *traceback;
284    PyErr_Fetch(&type, &value, &traceback);
285
286    char *etype = getStringFromPyObject(type);
287    char *evalue = getStringFromPyObject(value);
288
289    int r = asprintf(&err, "Error in %s : %s", etype, evalue);
290        (void)r;
291    return err;
292}
293
294static char *getStringFromPyObject(PyObject * p)
295{
296    PyObject *str = PyObject_Repr(p);
297    char *err = PyBytes_AS_STRING(PyUnicode_AsEncodedString(str, "utf-8",
298                                                            "Error ~"));
299    return err;
300}
301
302
303#endif
Note: See TracBrowser for help on using the repository browser.