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

Last change on this file since 4165 was 4165, checked in by sam, 4 years ago

Start porting the Python interpreter to Python 2.4/2.5.

File size: 4.5 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_PYTHON2
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_PYTHON3
191    tmp = PyBytes_AS_STRING(PyUnicode_AsEncodedString(str, "utf-8", "Error ~"));
192#elif defined HAVE_PYTHON2
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.