~siretart/lcd4linux/debian

0.1.1 by Reinhard Tartler
Import upstream version 0.11.0~svn1143
1
/* $Id: plugin_python.c 1086 2010-01-19 14:26:33Z mzuther $
2
 * $URL: https://ssl.bulix.org/svn/lcd4linux/trunk/plugin_python.c $
535 by reinelt
[lcd4linux @ 2005-05-02 10:29:20 by reinelt]
3
 *
4
 * Python plugin
5
 *
536 by reinelt
[lcd4linux @ 2005-05-03 11:13:23 by reinelt]
6
 * Copyright 2005 Dan Fritz  
535 by reinelt
[lcd4linux @ 2005-05-02 10:29:20 by reinelt]
7
 * Copyright 2005 The LCD4Linux Team <lcd4linux-devel@users.sourceforge.net>
8
 *
9
 * This file is part of LCD4Linux.
10
 *
11
 * LCD4Linux is free software; you can redistribute it and/or modify
12
 * it under the terms of the GNU General Public License as published by
13
 * the Free Software Foundation; either version 2, or (at your option)
14
 * any later version.
15
 *
16
 * LCD4Linux is distributed in the hope that it will be useful,
17
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19
 * GNU General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License
22
 * along with this program; if not, write to the Free Software
23
 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
24
 *
25
 */
26
27
/* 
28
 * exported functions:
29
 *
30
 * int plugin_init_python (void)
31
 *  adds a python interpreter
537 by reinelt
[lcd4linux @ 2005-05-04 05:22:12 by reinelt]
32
 * 
535 by reinelt
[lcd4linux @ 2005-05-02 10:29:20 by reinelt]
33
 */
34
0.1.1 by Reinhard Tartler
Import upstream version 0.11.0~svn1143
35
#include "config.h"
536 by reinelt
[lcd4linux @ 2005-05-03 11:13:23 by reinelt]
36
#include <Python.h>
535 by reinelt
[lcd4linux @ 2005-05-02 10:29:20 by reinelt]
37
#include "debug.h"
38
#include "plugin.h"
39
536 by reinelt
[lcd4linux @ 2005-05-03 11:13:23 by reinelt]
40
/* 
41
 * Executes a python function specified by function name and module.
42
 *
43
 * This method is more or less a copy of an example found in the python 
44
 * documentation. Kudos goes to Guido van Rossum and Fred L. Drake.
45
 * 
537 by reinelt
[lcd4linux @ 2005-05-04 05:22:12 by reinelt]
46
 * Fixme: this function should be able to accept and receive any types 
47
 * of arguments supported by the evaluator. Right now only strings are accepted.
536 by reinelt
[lcd4linux @ 2005-05-03 11:13:23 by reinelt]
48
 */
546 by reinelt
[lcd4linux @ 2005-05-08 04:32:43 by reinelt]
49
50
static void pyt_exec_str(RESULT * result, const char *module, const char *function, int argc, const char *argv[])
51
{
52
53
    PyObject *pName, *pModule, *pDict, *pFunc;
54
    PyObject *pArgs, *pValue;
55
    const char *rv = NULL;
56
    int i;
57
58
    pName = PyString_FromString(module);
59
    /* Error checking of pName left out */
60
61
    pModule = PyImport_Import(pName);
62
    Py_DECREF(pName);
63
64
    if (pModule != NULL) {
65
	pDict = PyModule_GetDict(pModule);
66
	/* pDict is a borrowed reference */
67
68
	pFunc = PyDict_GetItemString(pDict, function);
69
	/* pFun: Borrowed reference */
70
71
	if (pFunc && PyCallable_Check(pFunc)) {
72
	    pArgs = PyTuple_New(argc);
73
	    for (i = 0; i < argc; ++i) {
74
		pValue = PyString_FromString(argv[i]);
75
		if (!pValue) {
76
		    Py_DECREF(pArgs);
77
		    Py_DECREF(pModule);
78
		    error("Cannot convert argument \"%s\" to python format", argv[i]);
79
		    SetResult(&result, R_STRING, "");
80
		    return;
81
		}
82
		/* pValue reference stolen here: */
83
		PyTuple_SetItem(pArgs, i, pValue);
84
	    }
85
	    pValue = PyObject_CallObject(pFunc, pArgs);
86
	    Py_DECREF(pArgs);
87
	    if (pValue != NULL) {
88
		rv = PyString_AsString(pValue);
89
		SetResult(&result, R_STRING, rv);
90
		Py_DECREF(pValue);
91
		/* rv is now a 'dangling reference' */
92
		return;
93
	    } else {
94
		Py_DECREF(pModule);
95
		error("Python call failed (\"%s.%s\")", module, function);
0.1.1 by Reinhard Tartler
Import upstream version 0.11.0~svn1143
96
		/* print traceback on stderr */
97
		PyErr_PrintEx(0);
546 by reinelt
[lcd4linux @ 2005-05-08 04:32:43 by reinelt]
98
		SetResult(&result, R_STRING, "");
99
		return;
100
	    }
101
	    /* pDict and pFunc are borrowed and must not be Py_DECREF-ed */
102
	} else {
103
	    error("Can not find python function \"%s.%s\"", module, function);
104
	}
105
	Py_DECREF(pModule);
106
    } else {
107
	error("Failed to load python module \"%s\"", module);
0.1.1 by Reinhard Tartler
Import upstream version 0.11.0~svn1143
108
	/* print traceback on stderr */
109
	PyErr_PrintEx(0);
546 by reinelt
[lcd4linux @ 2005-05-08 04:32:43 by reinelt]
110
    }
111
    SetResult(&result, R_STRING, "");
112
    return;
536 by reinelt
[lcd4linux @ 2005-05-03 11:13:23 by reinelt]
113
}
114
115
static int python_cleanup_responsibility = 0;
546 by reinelt
[lcd4linux @ 2005-05-08 04:32:43 by reinelt]
116
117
static void my_exec(RESULT * result, RESULT * module, RESULT * function, RESULT * arg)
118
{
119
    /* Fixme: a plugin should be able to accept any number of arguments, don't know how
120
       to code that (yet) */
121
    const char *args[] = { R2S(arg) };
122
    pyt_exec_str(result, R2S(module), R2S(function), 1, args);
123
}
124
125
int plugin_init_python(void)
126
{
127
    if (!Py_IsInitialized()) {
128
	Py_Initialize();
129
	python_cleanup_responsibility = 1;
130
    }
131
    AddFunction("python::exec", 3, my_exec);
132
    return 0;
133
}
134
135
void plugin_exit_python(void)
136
{
137
    /* Make sure NOT to call Py_Finalize() When (and if) the entire lcd4linux process 
138
     * is started from inside python
139
     */
140
    if (python_cleanup_responsibility) {
141
	python_cleanup_responsibility = 0;
142
	Py_Finalize();
143
    }
535 by reinelt
[lcd4linux @ 2005-05-02 10:29:20 by reinelt]
144
}