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

Last change on this file since 4033 was 4033, checked in by jylam, 4 years ago
  • Added basic and non-working python interpreter
File size: 7.3 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: help.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
32#include <caca.h>
33#include <caca.h>
34#include <time.h>
35#include <sys/wait.h>
36#include <sys/types.h>
37
38#include "neercs.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    return 0;
178}
179
180int python_close(struct screen_list *sl)
181{
182    if (sl->interpreter_props.output)
183        free(sl->interpreter_props.output);
184    sl->interpreter_props.output = NULL;
185    Py_Finalize();
186    return 0;
187}
188
189
190static int python_execute(struct screen_list *sl)
191{
192    if (!sl->interpreter_props.command || sl->interpreter_props.size < 1)
193        return -1;
194    int err = 0;
195
196    debug("py Executing '%s'\n", sl->interpreter_props.command);
197
198    if (sl->interpreter_props.output)
199    {
200        free(sl->interpreter_props.output);
201        sl->interpreter_props.output = NULL;
202    }
203
204    PyObject *pModule, *pName, *pFunc;
205
206    /* Module from which to call the function */
207    pName = PyUnicode_FromString("neercs");
208    if (!pName)
209    {
210        sl->interpreter_props.output = getPythonError();
211        err = 1;
212        debug("py Error 1\n");
213        goto end;
214    }
215
216
217    pModule = PyImport_Import(pName);
218    Py_DECREF(pName);
219    if (pModule != NULL)
220    {
221        pFunc = PyObject_GetAttrString(pModule, sl->interpreter_props.command);
222        if (pFunc && PyCallable_Check(pFunc))
223        {
224            debug("py Can call !\n");
225        }
226        else
227        {
228            sl->interpreter_props.output = getPythonError();
229            err = 1;
230            debug("py Error 2\n");
231            goto end;
232        }
233    }
234    else
235    {
236        sl->interpreter_props.output = getPythonError();
237        err = 1;
238        debug("py: %s\n", sl->interpreter_props.output);
239        goto end;
240    }
241
242  end:
243    if (!err)
244    {
245        free(sl->interpreter_props.command);
246        sl->interpreter_props.command = NULL;
247        sl->interpreter_props.size = 0;
248        sl->interpreter_props.x = 0;
249        sl->python_command = 0;
250    }
251    sl->changed = 1;
252
253    return 0;
254}
255
256
257
258static char *getPythonError(void)
259{
260    char *err;
261    PyObject *type, *value, *traceback;
262    PyErr_Fetch(&type, &value, &traceback);
263
264    char *etype = getStringFromPyObject(type);
265    char *evalue = getStringFromPyObject(value);
266
267    asprintf(&err, "Error in %s : %s", etype, evalue);
268
269    return err;
270}
271
272static char *getStringFromPyObject(PyObject * p)
273{
274    PyObject *str = PyObject_Repr(p);
275    char *err = PyBytes_AS_STRING(PyUnicode_AsEncodedString(str, "utf-8",
276                                                            "Error ~"));
277    return err;
278}
279
280
281#endif
Note: See TracBrowser for help on using the repository browser.