]> gerrit.simantics Code Review - simantics/python.git/blobdiff - org.simantics.pythonlink.win32.x86_64/src/sclpy.c
Merge branch 'change/300/2'
[simantics/python.git] / org.simantics.pythonlink.win32.x86_64 / src / sclpy.c
index 8e41834ee1d2c505bc0a8e4764782e4c08323503..4881cc7d7c26d4a20979542530230724dc1df5f2 100644 (file)
@@ -14,7 +14,7 @@
 
 #include <windows.h>
 
-jint throwException( JNIEnv *env, char *className, char *message )
+jint throwException( JNIEnv *env, char *className, const char *message )
 {
     jclass exClass = (*env)->FindClass( env, className);
     if (exClass == NULL) {
@@ -24,24 +24,71 @@ jint throwException( JNIEnv *env, char *className, char *message )
     return (*env)->ThrowNew( env, exClass, message );
 }
 
-jint throwPythonException( JNIEnv *env, char *message ) {
+jint throwPythonException( JNIEnv *env, const char *message ) {
        return throwException( env, PYTHON_EXCEPTION, message );
 }
 
-jint throwIllegalArgumentException( JNIEnv *env, char *message ) {
+jint throwIllegalArgumentException( JNIEnv *env, const char *message ) {
        return throwException( env, ILLEGAL_ARGUMENT_EXCEPTION, message );
 }
 
+PyObject* getModule(jlong contextID) {
+       return PyState_FindModule((PyModuleDef*) contextID);
+//     return PyImport_AddModule("__main__");
+}
+
 int moduleCount = 0;
 int hasNumpy = 0;
 PyThreadState *main_ts = 0;
 
+static JNIEnv *currentEnv = NULL;
+jobject sclWriter = NULL;
+
+static PyObject *
+writeToSCL(PyObject *self, PyObject *args)
+{
+    if (currentEnv != NULL && sclWriter != NULL) {
+       JNIEnv *env = currentEnv;
+
+               Py_UNICODE *what;
+               Py_ssize_t length;
+               if (!PyArg_ParseTuple(args, "u#", &what, &length))
+                       return Py_BuildValue("");
+
+               {
+               jclass writerClass = (*env)->FindClass(env, WRITER_CLASS);
+               jmethodID writeMethod = (*env)->GetMethodID(env, writerClass, "write", "([CII)V");
+               jcharArray chars = (*env)->NewCharArray(env, (jsize)length);
+
+               (*env)->SetCharArrayRegion(env, chars, 0, length, what);
+               (*env)->CallVoidMethod(env, sclWriter, writeMethod, chars, 0, length);
+               }
+    }
+
+    return Py_BuildValue("");
+}
+
+static PyMethodDef sclWriterMethods[] = {
+    {"write", writeToSCL, METH_VARARGS, "Write something."},
+    {NULL, NULL, 0, NULL}
+};
+
+
 JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_createContextImpl(JNIEnv *env, jobject thisObj) {
        char name[16];
 
        if (!main_ts) {
         Py_Initialize();
 
+        {
+               static struct PyModuleDef moduledef = { PyModuleDef_HEAD_INIT, "sclwriter", NULL, -1, sclWriterMethods, };
+                       PyObject *m = PyModule_Create(&moduledef);
+
+               if (m == NULL) throwException(env, PYTHON_EXCEPTION, "Failed to create SCL writer module");
+                       PySys_SetObject("stdout", m);
+                       PySys_SetObject("stderr", m);
+        }
+
        hasNumpy = _import_array();
        hasNumpy = hasNumpy != -1;
        main_ts = PyEval_SaveThread();
@@ -51,19 +98,37 @@ JNIEXPORT jlong JNICALL Java_org_simantics_pythonlink_PythonContext_createContex
 
        PyEval_RestoreThread(main_ts);
        {
-               PyObject *module = PyModule_New(name);
-               PyObject *main = PyImport_AddModule("__main__");
+               PyObject *module;
+               PyModuleDef *modDef = malloc(sizeof(PyModuleDef));
+               memset(modDef, 0, sizeof(PyModuleDef));
+               modDef->m_name = strdup(name);
+               modDef->m_doc = NULL;
+               modDef->m_size = -1;
+
+               module = PyModule_Create(modDef);
+               Py_INCREF(module);
+               PyState_AddModule(module, modDef);
 
-               PyDict_Merge(PyModule_GetDict(module), PyModule_GetDict(main), 0);
-               PyEval_SaveThread();
-               return (jlong)module;
+               {
+                       PyObject *builtin = PyImport_AddModule("builtins");
+                       PyObject *dict = PyModule_GetDict(module);
+                       PyDict_SetItemString(dict, "__builtin__", builtin);
+                       PyDict_SetItemString(dict, "__builtins__", builtin);
+
+                       return (jlong)modDef;
+               }
        }
 }
 
 JNIEXPORT void JNICALL Java_org_simantics_pythonlink_PythonContext_deleteContextImpl(JNIEnv *env, jobject thisObj, jlong contextID) {
-       PyObject *module = (PyObject*)contextID;
+       PyModuleDef *modDef = (PyModuleDef*)contextID;
+       PyObject *module;
        PyEval_RestoreThread(main_ts);
+       module = PyState_FindModule(modDef);
        Py_XDECREF(module);
+       PyState_RemoveModule(modDef);
+       free((char*)modDef->m_name);
+       free(modDef);
        PyEval_SaveThread();
 }
 
@@ -791,7 +856,7 @@ jobject pythonDictionaryAsMap(JNIEnv *env, PyObject *dict) {
     ##VariableImpl(                                                     \
         JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName, \
         jtype value) {                                                  \
-            PyObject *module = (PyObject*)contextID;                    \
+            PyObject *module = getModule(contextID);                    \
                                                                         \
             PyEval_RestoreThread(main_ts);                              \
             setPythonVariable(module, getPythonString(env, variableName), \
@@ -818,7 +883,7 @@ JNIEXPORT void JNICALL
 Java_org_simantics_pythonlink_PythonContext_setPythonNDArrayVariableImpl(
                JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName,
                jobject value) {
-       PyObject *module = (PyObject*)contextID;
+       PyObject *module = getModule(contextID);
 
        if (!hasNumpy) {
                throwPythonException(env, "Importing numpy failed");
@@ -839,7 +904,7 @@ JNIEXPORT void JNICALL
 Java_org_simantics_pythonlink_PythonContext_setPythonVariantVariableImpl(
                JNIEnv *env, jobject thisObj, jlong contextID, jstring variableName,
                jobject value, jobject binding) {
-       PyObject *module = (PyObject*)contextID;
+       PyObject *module = getModule(contextID);
 
        PyEval_RestoreThread(main_ts);
        setPythonVariable(module, getPythonString(env, variableName),
@@ -850,17 +915,27 @@ Java_org_simantics_pythonlink_PythonContext_setPythonVariantVariableImpl(
 JNIEXPORT jint JNICALL
 Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl(
                JNIEnv *env, jobject thisObj, jlong contextID, jstring statement) {
-       PyObject *module = (PyObject*)contextID;
+       PyObject *module = getModule(contextID);
 
        const char *utfchars = (*env)->GetStringUTFChars(env, statement, NULL);
 
        PyEval_RestoreThread(main_ts);
        PyErr_Clear();
        {
+               jclass sclReportingWriterClass = (*env)->FindClass(env, SCL_REPORTING_WRITER_CLASS);
+               jmethodID constructor = (*env)->GetMethodID(env, sclReportingWriterClass, "<init>", "()V");
+               jmethodID flushMethod = (*env)->GetMethodID(env, sclReportingWriterClass, "flush", "()V");
+
                PyObject *globals;
 
                globals = PyModule_GetDict(module);
 
+               currentEnv = env;
+               if (sclReportingWriterClass && constructor)
+                       sclWriter = (*env)->NewObject(env, sclReportingWriterClass, constructor);
+               else
+                       sclWriter = NULL;
+
                {
                        PyObject *result = PyRun_String(utfchars, Py_file_input, globals, globals);
 
@@ -912,16 +987,22 @@ Java_org_simantics_pythonlink_PythonContext_executePythonStatementImpl(
                        PyEval_SaveThread();
                        (*env)->ReleaseStringUTFChars(env, statement, utfchars);
 
+                       if (sclWriter != NULL) {
+                               (*env)->CallVoidMethod(env, sclWriter, flushMethod);
+                       }
+
+                       currentEnv = NULL;
+                       sclWriter = NULL;
+
                        return result != NULL ? 0 : 1;
                }
        }
 }
 
-
 // Returns a borrowed reference.
 static PyObject *getPythonValue(
                JNIEnv *env, jlong contextID, jstring variableName) {
-    PyObject *module = (PyObject*)contextID;
+       PyObject *module = getModule(contextID);
     PyObject *pythonName = getPythonString(env, variableName);
     PyObject *value = PyDict_GetItem(PyModule_GetDict(module), pythonName);
 
@@ -1041,7 +1122,7 @@ Java_org_simantics_pythonlink_PythonContext_getPythonVariableNamesImpl(
        jobjectArray result = NULL;
        PyEval_RestoreThread(main_ts);
        {
-               PyObject *module = (PyObject*)contextID;
+               PyObject *module = getModule(contextID);
                PyObject *dict = PyModule_GetDict(module);
 
                PyObject *keys = PyDict_Keys(dict);