summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDetlev Casanova <detlev.casanova@gmail.com>2010-07-06 11:37:00 +0200
committerDetlev Casanova <detlev.casanova@gmail.com>2010-07-06 11:37:00 +0200
commitcee0d8244d6b3223c296def49678076edb239445 (patch)
tree152c338a056939395246fb10abb8a0abca726354
parent1fa0da3323562b7bfc74501d4b20a12bdfe5d094 (diff)
downloadlayman-cee0d8244d6b3223c296def49678076edb239445.tar.gz
layman-cee0d8244d6b3223c296def49678076edb239445.tar.bz2
layman-cee0d8244d6b3223c296def49678076edb239445.zip
Now working execute function (only for functions)
-rw-r--r--src/interpreter.c237
1 files changed, 204 insertions, 33 deletions
diff --git a/src/interpreter.c b/src/interpreter.c
index 6ab2843..2e2f7b9 100644
--- a/src/interpreter.c
+++ b/src/interpreter.c
@@ -2,57 +2,228 @@
#include <stdio.h>
#include <string.h>
-int main(int argc, char *argv[])
+/*
+ * PyObjectList
+ */
+typedef struct PyObjectListElem
+{
+ PyObject *object;
+ struct PyObjectListElem *next;
+} PyObjectListElem;
+
+typedef struct PyObjectList
+{
+ PyObjectListElem *root;
+ int count;
+} PyObjectList;
+
+PyObjectList *createObjectList()
+{
+ PyObjectList *ret = malloc(sizeof(PyObjectList));
+ ret->count = 0;
+ ret->root = 0;
+ return ret;
+}
+
+void insert(PyObjectList* list, PyObject *object)
+{
+ if (!list || !object)
+ return;
+ PyObjectListElem *node = malloc(sizeof(PyObjectListElem));
+ node->object = object;
+ node->next = list->root;
+ list->root = node;
+ list->count++;
+}
+
+PyObject *elementAt(PyObjectList* list, int pos)
+{
+ if (!list || list->count < pos)
+ return NULL;
+
+ PyObjectListElem *node = list->root;
+ for (int i = 0; i < pos; i++)
+ {
+ node = node->next;
+ }
+ if (!node)
+ return 0;
+
+ return node->object;
+}
+
+PyObject *moduleNamed(const char *name, PyObjectList *list)
+{
+ PyObjectListElem *node = list->root;
+ while (node)
+ {
+ if (strcmp(PyModule_GetName(node->object), name))
+ return node->object;
+ node = node->next;
+ }
+
+ return NULL;
+}
+
+PyObject *toTuple(PyObjectList *list)
{
- PyObject *pP1, *pP2, *pArgs, *pName, *pModule, *pDict, *pFunc, *pValue;
+ if (!list)
+ return NULL;
- Py_Initialize();
+ PyObject *ret = PyTuple_New(list->count);
+ PyObjectListElem *node = list->root;
+ int i = 0;
+ while (node)
+ {
+ if (node->object)
+ PyTuple_SetItem(ret, i++, node->object);
+ node = node->next;
+ }
- //printf("%s\n", Py_GetVersion());
+ return ret;
+}
- //pName = PyByteArray_FromStringAndSize("portage", strlen("portage"));
- pModule = PyModule_New("portage");
+int listCount(PyObjectList *list)
+{
+ return (list ? list->count : 0);
+}
- pDict = PyModule_GetDict(pModule);
- pFunc = PyDict_GetItemString(pDict, "pkgcmp");
+void freeList(PyObjectList *list, int deref)
+{
+ if (!list)
+ return;
- if (PyCallable_Check(pFunc))
+ PyObjectListElem *node = list->root;
+ while (node)
{
- pP1 = PyByteArray_FromStringAndSize("app-portage/kuroo4-4.2", strlen("app-portage/kuroo4-4.2"));
- pP2 = PyByteArray_FromStringAndSize("app-portage/kuroo4-4.3", strlen("app-portage/kuroo4-4.3"));
+ PyObjectListElem *tmp = node;
+ node = node->next;
+ if (deref)
+ Py_DECREF(tmp->object);
+ free(tmp);
+ }
- pArgs = PyTuple_New(2);
+ free(list);
+}
- PyTuple_SetItem(pArgs, 0, pP1);
- PyTuple_SetItem(pArgs, 0, pP2);
+/*
+ * Interpreter
+ */
- pValue = PyObject_CallObject(pFunc, pArgs);
+/*
+ * A Python interpreter object keeps the context like the loaded modules.
+ */
- if (pArgs != NULL)
+typedef struct Interpreter
+{
+ PyObjectList *modules;
+} Interpreter;
+
+Interpreter *createInterpreter()
+{
+ Interpreter *ret = malloc(sizeof(Interpreter));
+ ret->modules = createObjectList();
+ return ret;
+}
+
+void freeInterpreter(Interpreter *inter)
+{
+ if (!inter)
+ return;
+ freeList(inter->modules, 1);
+ free(inter);
+
+ Py_Finalize();
+}
+
+/*
+ * printf() like function that executes a python function
+ * @param interpreter Python interpreter object on which the function should be ran
+ * @param module name of the python module in which the function is
+ * @param funcName the function name to call
+ * @param arg_types printf() like list of arguments TODO:explain more --> See Python documentation
+ * @param ... arguments for the function
+ */
+
+PyObject *executeFunction(Interpreter *interpreter, const char *module, const char *funcName, const char* format, ...)
+{
+ if (!Py_IsInitialized())
+ Py_Initialize();
+
+ // Make arguments
+ // FIXME: use Py_BuildValue.
+ // FIXME: is it possible to pass this function's arguments to another function ?
+ PyObjectList *argList = createObjectList();
+ int i = 0;
+ while (format[i] != '\0')
+ {
+ while(format[i] != '%' && format[i] != '\0')
+ i++;
+
+ if (format[i] == '\0')
+ break;
+
+ PyObject *arg = NULL;
+ switch(format[++i])
{
- Py_DECREF(pArgs);
+ case 'd': //number
+ break;
+ case 's': //string
+ break;
+ case 'P': //PyObject
+ break;
+ default: //skip or abort ?
+ break;
}
+
+ insert(argList, arg);
+ i++;
}
- else
- PyErr_Print();
- int ret = PyLong_AsLong(pValue);
- switch(ret)
+ PyObject *args = toTuple(argList);
+ freeList(argList, 1);
+
+ // Look for the module.
+ PyObject *mod = 0;
+ if (interpreter->modules)
{
- case -1:
- printf("less");
- break;
- case 0:
- printf("same");
- break;
- case 1:
- printf("more");
- break;
+ mod = moduleNamed(module, interpreter->modules);
+ }
+ if (!mod)
+ {
+ mod = PyImport_ImportModule(module);
+ insert(interpreter->modules, mod);
}
- printf("\n");
+ // Look for the function
+ PyObject *dict = PyModule_GetDict(mod);
+ PyObject *func = PyDict_GetItemString(dict, funcName);
- Py_DECREF(pModule);
+ if (!PyCallable_Check(func))
+ return NULL;
- Py_Finalize();
+ // Call the function
+ PyObject *val = PyObject_CallObject(func, args);
+
+ // Add return value object in a local list so it can be DECREF'ed when the interpreter is deleted.
+ // TODO
+
+ Py_DECREF(args);
+
+ return val;
+}
+
+
+int main(int argc, char *argv[])
+{
+ Interpreter *in = createInterpreter();
+
+ PyObject *ret = executeFunction(in, "portage.data", "portage_group_warning", "");
+
+ if (!ret)
+ printf("failed :-( \n");
+
+ freeInterpreter(in);
+
+ return 0;
}