jlec        14/10/27 14:22:43

  Added:                tclpython-4.1-python-3.patch
  Log:
  dev-tcltk/tclpython: Add missing patch, #509738; thanks Alexander Turenko for 
the backport
  
  (Portage version: 2.2.14/cvs/Linux x86_64, signed Manifest commit with key 
B9D4F231BD1558AB!)

Revision  Changes    Path
1.1                  dev-tcltk/tclpython/files/tclpython-4.1-python-3.patch

file : 
http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-tcltk/tclpython/files/tclpython-4.1-python-3.patch?rev=1.1&view=markup
plain: 
http://sources.gentoo.org/viewvc.cgi/gentoo-x86/dev-tcltk/tclpython/files/tclpython-4.1-python-3.patch?rev=1.1&content-type=text/plain

Index: tclpython-4.1-python-3.patch
===================================================================
--- a/tclpython.c       2006-03-07 16:28:03.000000000 +0300
+++ b/tclpython.c       2014-05-06 23:33:41.713623943 +0400
@@ -19,13 +19,83 @@
 $ cc -fpic -I/usr/local/include/tcltk/tcl8.3 -c tclthread.c
 $ ld -o tclpython.so -Bshareable -L/usr/X11R6/lib -L/usr/local/lib 
-L/usr/local/share/python/config tclpython.o tclthread.o -lpython -lutil 
-lreadline -ltermcap -lcrypt -lgmp -lgdbm -lpq -lz -ltcl83 -ltk83 -lX11
 
+Patched for Python 3 with respect to 
https://github.com/facebook/fbthrift/blob/master/thrift/lib/py/protocol/fastbinary.c
+
 */
 
 #include <Python.h>
 #include <tcl.h>
-#include <cStringIO.h>
+
+#if PY_MAJOR_VERSION >= 3
+    #define PyInt_FromLong PyLong_FromLong
+    #define PyInt_AsLong PyLong_AsLong
+    #define PyString_FromStringAndSize PyBytes_FromStringAndSize
+#else
+    #include <cStringIO.h>
+#endif
+
 #include "tclpython.h"
 
+// Mostly copied from cStringIO.c
+#if PY_MAJOR_VERSION >= 3
+
+/** io module in python3. */
+static PyObject* Python3IO;
+
+typedef struct {
+  PyObject_HEAD
+  char *buf;
+  Py_ssize_t pos, string_size;
+} IOobject;
+
+#define IOOOBJECT(O) ((IOobject*)(O))
+
+static int
+IO__opencheck(IOobject *self) {
+    if (!self->buf) {
+        PyErr_SetString(PyExc_ValueError,
+                        "I/O operation on closed file");
+        return 0;
+    }
+    return 1;
+}
+
+static PyObject *
+IO_cgetval(PyObject *self) {
+    if (!IO__opencheck(IOOOBJECT(self))) return NULL;
+    assert(IOOOBJECT(self)->pos >= 0);
+    return PyBytes_FromStringAndSize(((IOobject*)self)->buf,
+                                     ((IOobject*)self)->pos);
+}
+#endif
+
+/* -- PYTHON MODULE SETUP STUFF --- */
+
+static PyObject *pythonTclEvaluate(PyObject *self, PyObject *args);
+
+static PyMethodDef tclMethods[] = {
+    {"eval", pythonTclEvaluate, METH_VARARGS, "Evaluate a Tcl script."},
+    {0, 0, 0, 0}                                                               
                                       /* sentinel */
+};
+
+#if PY_MAJOR_VERSION >= 3
+struct module_state {
+  PyObject *error;
+};
+
+static struct PyModuleDef TclModuleDef = {
+  PyModuleDef_HEAD_INIT,
+  "tcl",
+  NULL,
+  sizeof(struct module_state),
+  tclMethods,
+  NULL,
+  NULL,
+  NULL,
+  NULL
+};
+#endif
+
 #ifndef WIN32
 /* George Petasis, 21 Feb 2006:
  * The following check cannot be handled correctly
@@ -66,13 +136,13 @@
 
 static int pythonInterpreter(ClientData clientData, Tcl_Interp *interpreter, 
int numberOfArguments, Tcl_Obj * CONST arguments[])
 {
-    int identifier;
+    intptr_t identifier;
     PyObject *output;
     PyObject *message;
     PyObject *result;
     PyObject *globals;
     char *string = 0;
-    int length;
+    Py_ssize_t length;
     Tcl_Obj *object;
     struct Tcl_HashEntry *entry;
     unsigned evaluate;
@@ -111,12 +181,22 @@
     /* choose start token depending on whether this is an evaluation or an 
execution: */
     result = PyRun_String(Tcl_GetString(arguments[2]), (evaluate? 
Py_eval_input: Py_file_input), globals, globals);
     if (result == 0) {                                                         
                               /* an error occured */
+#if PY_MAJOR_VERSION >= 3
+        output = PyObject_CallMethod(Python3IO, "BytesIO", "()");
+#else
         output = PycStringIO->NewOutput(1024);               /* use a 
reasonable initial size but big enough to handle most cases */
-        PySys_SetObject("stderr", output);                                     
           /* capture all interpreter error output */
+#endif
+        PySys_SetObject("sys.stderr", output);                                 
               /* capture all interpreter error output */
         PyErr_Print();                                            /* so that 
error is printed on standard error, redirected above */
+#if PY_MAJOR_VERSION >= 3
+        message = IO_cgetval(output);
+        string = PyBytes_AsString(message);
+        length = (string == NULL) ? 0 : strlen(string);
+#else
         message = PycStringIO->cgetvalue(output);
         string = PyString_AsString(message);
         length = PyString_Size(message);
+#endif
         if ((length > 0) && (string[length - 1] == '\n')) length--;            
  /* eventually remove trailing new line character */
         object = Tcl_NewObj();
         Tcl_AppendStringsToObj(object, Tcl_GetString(arguments[0]), ": ", 0);  
                  /* identify interpreter in error */
@@ -124,7 +204,11 @@
         Py_DECREF(output);
     } else {
         if (evaluate) {
+#if PY_MAJOR_VERSION >= 3
+            string = PyUnicode_AsUTF8(PyObject_Str(result));
+#else
             string = PyString_AsString(PyObject_Str(result));
+#endif
             object = Tcl_NewStringObj(string, -1);                             
                       /* return evaluation result */
         } else                                                                 
                                        /* execute */
             object = Tcl_NewObj();                                             
      /* always return an empty result or an error */
@@ -139,9 +223,9 @@
 
 Tcl_Interp *tclInterpreter(CONST char *name)                           /* 
public function for use in extensions to this extension */
 {
-    int identifier;
+    intptr_t identifier;
 
-    if ((sscanf(name, "tcl%u", &identifier) == 0) || (identifier != 0)) {
+    if ((sscanf(name, "tcl%lu", &identifier) == 0) || (identifier != 0)) {
         return 0;                                                              
                                   /* invalid name */
     } else {
         return mainInterpreter;                                                
                     /* sole available interpreter */
@@ -188,14 +272,9 @@
     return Py_BuildValue("s", result);
 }
 
-static PyMethodDef tclMethods[] = {
-    {"eval", pythonTclEvaluate, METH_VARARGS, "Evaluate a Tcl script."},
-    {0, 0, 0, 0}                                                               
                                       /* sentinel */
-};
-
 static int newInterpreter(Tcl_Interp *interpreter)
 {
-    int identifier;
+    intptr_t identifier;
     Tcl_Obj *object;
     int created;
 #ifdef WITH_THREAD
@@ -214,19 +293,31 @@
         return TCL_ERROR;
     } else {
         Py_Initialize();                                                       
                    /* initialize main interpreter */
+#if PY_MAJOR_VERSION >= 3 
+        Python3IO = PyImport_ImportModule("io");
+#else
         PycString_IMPORT;
+#endif
     }
     Tcl_SetHashValue(Tcl_CreateHashEntry(&threadStates, 
(ClientData)identifier, &created), 0);
 #else
     if (existingInterpreters == 0) {
         Py_Initialize();                                                       
                    /* initialize main interpreter */
         PyEval_InitThreads();                                               /* 
initialize and acquire the global interpreter lock */
+#if PY_MAJOR_VERSION >= 3 
+        Python3IO = PyImport_ImportModule("io");
+#else
         PycString_IMPORT;
+#endif
         globalState = PyThreadState_Swap(0);                                   
                         /* save the global thread */
     } else {
         PyEval_AcquireLock();                                           /* 
needed in order to be able to create a new interpreter */
     }
+#if PY_MAJOR_VERSION >= 3
+    if (Python3IO == 0) {                                              /* make 
sure string input/output is properly initialized */
+#else
     if (PycStringIO == 0) {                                              /* 
make sure string input/output is properly initialized */
+#endif
         Tcl_SetResult(interpreter, "fatal error: could not initialize Python 
string input/output module", TCL_STATIC);
         return TCL_ERROR;
     }
@@ -250,7 +341,11 @@
     newIdentifier++;
 #endif
     existingInterpreters++;
+#if PY_MAJOR_VERSION >= 3
+    tcl = PyModule_Create(&TclModuleDef);
+#else
     tcl = Py_InitModule("tcl", tclMethods);                                   
/* add a new 'tcl' module to the python interpreter */
+#endif
     Py_INCREF(tcl);
     PyModule_AddObject(PyImport_AddModule("__builtin__"), "tcl", tcl);
     return TCL_OK;
@@ -260,7 +355,7 @@
 {
     int index;
     char *name;
-    int identifier;
+    intptr_t identifier;
     struct Tcl_HashEntry *entry;
     Tcl_Obj *object;
 #ifdef WITH_THREAD
@@ -270,7 +365,7 @@
     for (index = 0; index < numberOfArguments; index++) {
         name = Tcl_GetString(arguments[index]);                                
                  /* interpreter name is "pythonN" */
         entry = 0;
-        if (sscanf(name, "python%u", &identifier) == 1) {
+        if (sscanf(name, "python%lu", &identifier) == 1) {
             identifier = atoi(name + 6);
             entry = Tcl_FindHashEntry(&threadStates, (ClientData)identifier);
         }




Reply via email to