source: neercs/trunk/src/python/interpreter.c @ 4336

Last change on this file since 4336 was 4336, checked in by Pascal Terjan, 11 years ago

Support python 2.6, and ask for 2.4 as it is accepted

File size: 4.4 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 int python_execute(struct screen_list *sl);
41char *getStringFromPyObject(PyObject * p);
42static char *getPythonError(void);
43
44#if ! defined HAVE_PYTHON26
45static PyObject *PyUnicode_FromString(char const *str)
46{
47    PyObject *tmp, *ret;
48    tmp = PyString_FromString(str);
49    if (!tmp)
50        return NULL;
51    ret = PyString_AsDecodedObject(tmp, "utf-8", "replace");
52    Py_DECREF(tmp);
53    return ret;
54}
55#endif
56
57int python_command_handle_key(struct screen_list *screen_list, unsigned int c)
58{
59    int ret = widget_ibox_handle_key(screen_list->interpreter_props.box, c);
60
61    if (ret == INPUT_BOX_ESC)
62    {
63        widget_ibox_destroy(screen_list->interpreter_props.box);
64        screen_list->interpreter_props.box = NULL;
65        screen_list->modals.python_command = 0;
66    }
67    else if (ret == INPUT_BOX_RET)
68    {
69        python_execute(screen_list);
70    }
71    screen_list->changed = 1;
72
73    return 1;
74}
75
76void draw_python_command(struct screen_list *screen_list)
77{
78    if (!screen_list->interpreter_props.box)
79    {
80        screen_list->interpreter_props.box =
81            widget_ibox_init(screen_list->cv, 65, 6);
82        debug("py Init %p\n", screen_list->interpreter_props.box);
83    }
84    widget_ibox_draw(screen_list->interpreter_props.box);
85}
86
87/* Actual Python interpreter stuff */
88int python_init(struct screen_list *sl)
89{
90    initNeercsModule(sl);
91
92    return 0;
93}
94
95int python_close(struct screen_list *sl)
96{
97    widget_ibox_destroy(sl->interpreter_props.box);
98    sl->interpreter_props.box = NULL;
99
100    Py_Finalize();
101    return 0;
102}
103
104
105static int python_execute(struct screen_list *sl)
106{
107    char *command = widget_ibox_get_text(sl->interpreter_props.box);
108    if (!command || strlen(command) < 1)
109        return -1;
110    int err = 0;
111
112    debug("py Executing '%s'\n", command);
113
114
115    PyObject *pModule, *pName;
116
117    /* Module from which to call the function */
118    pName = PyUnicode_FromString("neercs");
119    if (!pName)
120    {
121        widget_ibox_set_error(sl->interpreter_props.box, getPythonError());
122        err = 1;
123        debug("py Error 1\n");
124        goto end;
125    }
126
127    pModule = PyImport_Import(pName);
128    Py_DECREF(pName);
129
130    if (pModule != NULL)
131    {
132        PyObject *dictionary = PyModule_GetDict(pModule);
133
134        getExportedValues(dictionary);
135
136        PyObject *o =
137            PyRun_String(command, Py_single_input,
138                         dictionary, NULL);
139        if (!o)
140        {
141            widget_ibox_set_error(sl->interpreter_props.box, getPythonError());
142            err = 1;
143        }
144        else
145        {
146            setExportedValues(dictionary);
147
148            widget_ibox_set_msg(sl->interpreter_props.box, getStringFromPyObject(o));
149            err = 1;
150        }
151
152        Py_DECREF(pModule);
153    }
154    else
155    {
156        widget_ibox_set_error(sl->interpreter_props.box, getPythonError());
157        err = 1;
158    }
159
160  end:
161
162    if (!err)
163    {
164        widget_ibox_destroy(sl->interpreter_props.box);
165        sl->interpreter_props.box = NULL;
166        sl->modals.python_command = 0;
167    }
168    sl->changed = 1;
169
170    return 0;
171}
172
173static char *getPythonError(void)
174{
175    char *err;
176    PyObject *type, *value, *traceback;
177    PyErr_Fetch(&type, &value, &traceback);
178
179    char *evalue = getStringFromPyObject(value);
180
181    int r = asprintf(&err, "%s", evalue);
182    (void)r;
183    return err;
184}
185
186char *getStringFromPyObject(PyObject * p)
187{
188    PyObject *str = PyObject_Repr(p);
189    char *tmp;
190#if defined HAVE_PYTHON26
191    tmp = PyBytes_AS_STRING(PyUnicode_AsEncodedString(str, "utf-8", "Error ~"));
192#else
193    tmp = PyString_AsString(str);
194#endif
195    return strdup(tmp);
196}
197
198
199#endif
Note: See TracBrowser for help on using the repository browser.