Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(14)

Side by Side Diff: Modules/_tkinter.c

Issue 16840: Tkinter doesn't support large integers
Patch Set: Created 4 years, 12 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
« Lib/test/test_tcl.py ('K') | « Lib/test/test_tcl.py ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 /*********************************************************** 1 /***********************************************************
2 Copyright (C) 1994 Steen Lumholt. 2 Copyright (C) 1994 Steen Lumholt.
3 3
4 All Rights Reserved 4 All Rights Reserved
5 5
6 ******************************************************************/ 6 ******************************************************************/
7 7
8 /* _tkinter.c -- Interface to libtk.a and libtcl.a. */ 8 /* _tkinter.c -- Interface to libtk.a and libtcl.a. */
9 9
10 /* TCL/TK VERSION INFO: 10 /* TCL/TK VERSION INFO:
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
47 #include <Tk/tk.h> 47 #include <Tk/tk.h>
48 #else 48 #else
49 #include <tcl.h> 49 #include <tcl.h>
50 #include <tk.h> 50 #include <tk.h>
51 #endif 51 #endif
52 52
53 #include "tkinter.h" 53 #include "tkinter.h"
54 54
55 #if TK_VERSION_HEX < 0x08040002 55 #if TK_VERSION_HEX < 0x08040002
56 #error "Tk older than 8.4 not supported" 56 #error "Tk older than 8.4 not supported"
57 #endif
58
59 #if TK_VERSION_HEX >= 0x08050000
60 #define HAVE_LIBTOMMAMTH
61 #include <tclTomMath.h>
57 #endif 62 #endif
58 63
59 #if !(defined(MS_WINDOWS) || defined(__CYGWIN__)) 64 #if !(defined(MS_WINDOWS) || defined(__CYGWIN__))
60 #define HAVE_CREATEFILEHANDLER 65 #define HAVE_CREATEFILEHANDLER
61 #endif 66 #endif
62 67
63 #ifdef HAVE_CREATEFILEHANDLER 68 #ifdef HAVE_CREATEFILEHANDLER
64 69
65 /* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere 70 /* This bit is to ensure that TCL_UNIX_FD is defined and doesn't interfere
66 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */ 71 with the proper calculation of FHANDLETYPE == TCL_UNIX_FD below. */
(...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after
226 int wantobjects; 231 int wantobjects;
227 int threaded; /* True if tcl_platform[threaded] */ 232 int threaded; /* True if tcl_platform[threaded] */
228 Tcl_ThreadId thread_id; 233 Tcl_ThreadId thread_id;
229 int dispatching; 234 int dispatching;
230 /* We cannot include tclInt.h, as this is internal. 235 /* We cannot include tclInt.h, as this is internal.
231 So we cache interesting types here. */ 236 So we cache interesting types here. */
232 const Tcl_ObjType *BooleanType; 237 const Tcl_ObjType *BooleanType;
233 const Tcl_ObjType *ByteArrayType; 238 const Tcl_ObjType *ByteArrayType;
234 const Tcl_ObjType *DoubleType; 239 const Tcl_ObjType *DoubleType;
235 const Tcl_ObjType *IntType; 240 const Tcl_ObjType *IntType;
241 const Tcl_ObjType *WideIntType;
242 const Tcl_ObjType *BignumType;
236 const Tcl_ObjType *ListType; 243 const Tcl_ObjType *ListType;
237 const Tcl_ObjType *ProcBodyType; 244 const Tcl_ObjType *ProcBodyType;
238 const Tcl_ObjType *StringType; 245 const Tcl_ObjType *StringType;
239 } TkappObject; 246 } TkappObject;
240 247
241 #define Tkapp_Interp(v) (((TkappObject *) (v))->interp) 248 #define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
242 #define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v)) 249 #define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
243 250
244 #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \ 251 #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
245 (void *) v, Py_REFCNT(v))) 252 (void *) v, Py_REFCNT(v)))
(...skipping 336 matching lines...) Expand 10 before | Expand all | Expand 10 after
582 /* If Tcl is threaded, we don't need the lock. */ 589 /* If Tcl is threaded, we don't need the lock. */
583 PyThread_free_lock(tcl_lock); 590 PyThread_free_lock(tcl_lock);
584 tcl_lock = NULL; 591 tcl_lock = NULL;
585 } 592 }
586 #endif 593 #endif
587 594
588 v->BooleanType = Tcl_GetObjType("boolean"); 595 v->BooleanType = Tcl_GetObjType("boolean");
589 v->ByteArrayType = Tcl_GetObjType("bytearray"); 596 v->ByteArrayType = Tcl_GetObjType("bytearray");
590 v->DoubleType = Tcl_GetObjType("double"); 597 v->DoubleType = Tcl_GetObjType("double");
591 v->IntType = Tcl_GetObjType("int"); 598 v->IntType = Tcl_GetObjType("int");
599 v->WideIntType = Tcl_GetObjType("wideInt");
600 v->BignumType = Tcl_GetObjType("bignum");
592 v->ListType = Tcl_GetObjType("list"); 601 v->ListType = Tcl_GetObjType("list");
593 v->ProcBodyType = Tcl_GetObjType("procbody"); 602 v->ProcBodyType = Tcl_GetObjType("procbody");
594 v->StringType = Tcl_GetObjType("string"); 603 v->StringType = Tcl_GetObjType("string");
595 604
596 /* Delete the 'exit' command, which can screw things up */ 605 /* Delete the 'exit' command, which can screw things up */
597 Tcl_DeleteCommand(v->interp, "exit"); 606 Tcl_DeleteCommand(v->interp, "exit");
598 607
599 if (screenName != NULL) 608 if (screenName != NULL)
600 Tcl_SetVar2(v->interp, "env", "DISPLAY", 609 Tcl_SetVar2(v->interp, "env", "DISPLAY",
601 screenName, TCL_GLOBAL_ONLY); 610 screenName, TCL_GLOBAL_ONLY);
(...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after
872 881
873 882
874 #if PY_SIZE_MAX > INT_MAX 883 #if PY_SIZE_MAX > INT_MAX
875 #define CHECK_STRING_LENGTH(s) do { \ 884 #define CHECK_STRING_LENGTH(s) do { \
876 if (s != NULL && strlen(s) >= INT_MAX) { \ 885 if (s != NULL && strlen(s) >= INT_MAX) { \
877 PyErr_SetString(PyExc_OverflowError, "string is too long"); \ 886 PyErr_SetString(PyExc_OverflowError, "string is too long"); \
878 return NULL; \ 887 return NULL; \
879 } } while(0) 888 } } while(0)
880 #else 889 #else
881 #define CHECK_STRING_LENGTH(s) 890 #define CHECK_STRING_LENGTH(s)
891 #endif
892
893 #ifdef HAVE_LIBTOMMAMTH
894 static Tcl_Obj*
895 asBignumObj(PyObject *value)
896 {
897 Tcl_Obj *result;
898 int neg;
899 PyObject *hexstr;
900 char *hexchars;
901 mp_int bigValue;
902
903 neg = Py_SIZE(value) < 0;
904 hexstr = _PyLong_Format(value, 16);
905 if (hexstr == NULL)
906 return NULL;
907 hexchars = PyUnicode_AsUTF8(hexstr);
908 if (hexchars == NULL) {
909 Py_DECREF(hexstr);
910 return NULL;
911 }
912 hexchars += neg + 2; /* skip sign and "0x" */
913 mp_init(&bigValue);
914 if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) {
915 mp_clear(&bigValue);
916 Py_DECREF(hexstr);
917 PyErr_NoMemory();
918 return NULL;
919 }
920 Py_DECREF(hexstr);
921 bigValue.sign = neg ? MP_NEG : MP_ZPOS;
922 result = Tcl_NewBignumObj(&bigValue);
923 mp_clear(&bigValue);
924 if (result == NULL) {
925 PyErr_NoMemory();
926 return NULL;
927 }
928 return result;
929 }
882 #endif 930 #endif
883 931
884 static Tcl_Obj* 932 static Tcl_Obj*
885 AsObj(PyObject *value) 933 AsObj(PyObject *value)
886 { 934 {
887 Tcl_Obj *result; 935 Tcl_Obj *result;
888 long longVal;
889 int overflow;
890 936
891 if (PyBytes_Check(value)) { 937 if (PyBytes_Check(value)) {
892 if (PyBytes_GET_SIZE(value) >= INT_MAX) { 938 if (PyBytes_GET_SIZE(value) >= INT_MAX) {
893 PyErr_SetString(PyExc_OverflowError, "bytes object is too long"); 939 PyErr_SetString(PyExc_OverflowError, "bytes object is too long");
894 return NULL; 940 return NULL;
895 } 941 }
896 return Tcl_NewByteArrayObj((unsigned char *)PyBytes_AS_STRING(value), 942 return Tcl_NewByteArrayObj((unsigned char *)PyBytes_AS_STRING(value),
897 (int)PyBytes_GET_SIZE(value)); 943 (int)PyBytes_GET_SIZE(value));
898 } 944 }
899 else if (PyBool_Check(value)) 945 if (PyBool_Check(value))
900 return Tcl_NewBooleanObj(PyObject_IsTrue(value)); 946 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
901 else if (PyLong_CheckExact(value) && 947
902 ((longVal = PyLong_AsLongAndOverflow(value, &overflow)), 948 if (PyLong_CheckExact(value)) {
903 !overflow)) { 949 int overflow;
950 long longValue;
951 Tcl_WideInt wideValue;
952
953 longValue = PyLong_AsLongAndOverflow(value, &overflow);
954 if (!overflow) {
955 return Tcl_NewLongObj(longValue);
956 }
904 /* If there is an overflow in the long conversion, 957 /* If there is an overflow in the long conversion,
905 fall through to default object handling. */ 958 fall through to wideInt handling. */
906 return Tcl_NewLongObj(longVal); 959
960 if (_PyLong_AsByteArray((PyLongObject *)value,
961 (unsigned char *)(void *)&wideValue,
962 sizeof(wideValue),
963 PY_LITTLE_ENDIAN,
964 /* signed */ 1) == 0) {
965 return Tcl_NewWideIntObj(wideValue);
966 }
967 PyErr_Clear();
968 /* If there is an overflow in the wideInt conversion,
969 fall through to bignum handling. */
970 #ifdef HAVE_LIBTOMMAMTH
971 return asBignumObj(value);
972 #endif
907 } 973 }
908 else if (PyFloat_Check(value)) 974
975 if (PyFloat_Check(value))
909 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); 976 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
910 else if (PyTuple_Check(value) || PyList_Check(value)) { 977 if (PyTuple_Check(value) || PyList_Check(value)) {
911 Tcl_Obj **argv; 978 Tcl_Obj **argv;
912 Py_ssize_t size, i; 979 Py_ssize_t size, i;
913 980
914 size = PySequence_Fast_GET_SIZE(value); 981 size = PySequence_Fast_GET_SIZE(value);
915 if (size == 0) 982 if (size == 0)
916 return Tcl_NewListObj(0, NULL); 983 return Tcl_NewListObj(0, NULL);
917 if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) { 984 if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) {
918 PyErr_SetString(PyExc_OverflowError, 985 PyErr_SetString(PyExc_OverflowError,
919 PyTuple_Check(value) ? "tuple is too long" : 986 PyTuple_Check(value) ? "tuple is too long" :
920 "list is too long"); 987 "list is too long");
921 return NULL; 988 return NULL;
922 } 989 }
923 argv = (Tcl_Obj **) PyMem_Malloc(((size_t)size) * sizeof(Tcl_Obj *)); 990 argv = (Tcl_Obj **) PyMem_Malloc(((size_t)size) * sizeof(Tcl_Obj *));
924 if (!argv) { 991 if (!argv) {
925 PyErr_NoMemory(); 992 PyErr_NoMemory();
926 return NULL; 993 return NULL;
927 } 994 }
928 for (i = 0; i < size; i++) 995 for (i = 0; i < size; i++)
929 argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i)); 996 argv[i] = AsObj(PySequence_Fast_GET_ITEM(value,i));
930 result = Tcl_NewListObj((int)size, argv); 997 result = Tcl_NewListObj((int)size, argv);
931 PyMem_Free(argv); 998 PyMem_Free(argv);
932 return result; 999 return result;
933 } 1000 }
934 else if (PyUnicode_Check(value)) { 1001 if (PyUnicode_Check(value)) {
935 void *inbuf; 1002 void *inbuf;
936 Py_ssize_t size; 1003 Py_ssize_t size;
937 int kind; 1004 int kind;
938 Tcl_UniChar *outbuf = NULL; 1005 Tcl_UniChar *outbuf = NULL;
939 Py_ssize_t i; 1006 Py_ssize_t i;
940 size_t allocsize; 1007 size_t allocsize;
941 1008
942 if (PyUnicode_READY(value) == -1) 1009 if (PyUnicode_READY(value) == -1)
943 return NULL; 1010 return NULL;
944 1011
(...skipping 29 matching lines...) Expand all
974 PyMem_Free(outbuf); 1041 PyMem_Free(outbuf);
975 return NULL; 1042 return NULL;
976 } 1043 }
977 #endif 1044 #endif
978 outbuf[i] = ch; 1045 outbuf[i] = ch;
979 } 1046 }
980 result = Tcl_NewUnicodeObj(outbuf, (int)size); 1047 result = Tcl_NewUnicodeObj(outbuf, (int)size);
981 PyMem_Free(outbuf); 1048 PyMem_Free(outbuf);
982 return result; 1049 return result;
983 } 1050 }
984 else if(PyTclObject_Check(value)) { 1051 if(PyTclObject_Check(value)) {
985 Tcl_Obj *v = ((PyTclObject*)value)->value; 1052 Tcl_Obj *v = ((PyTclObject*)value)->value;
986 Tcl_IncrRefCount(v); 1053 Tcl_IncrRefCount(v);
987 return v; 1054 return v;
988 } 1055 }
989 else { 1056 {
990 PyObject *v = PyObject_Str(value); 1057 PyObject *v = PyObject_Str(value);
991 if (!v) 1058 if (!v)
992 return 0; 1059 return 0;
993 result = AsObj(v); 1060 result = AsObj(v);
994 Py_DECREF(v); 1061 Py_DECREF(v);
995 return result; 1062 return result;
996 } 1063 }
997 } 1064 }
1065
1066 static PyObject*
1067 fromWideIntObj(PyObject* tkapp, Tcl_Obj *value)
1068 {
1069 Tcl_WideInt wideValue;
1070 if (Tcl_GetWideIntFromObj(Tkapp_Interp(tkapp), value, &wideValue) == TCL _OK) {
1071 #ifdef HAVE_LONG_LONG
1072 if (sizeof(wideValue) <= SIZEOF_LONG_LONG)
1073 return PyLong_FromLongLong(wideValue);
1074 #endif
1075 return _PyLong_FromByteArray((unsigned char *)(void *)&wideValue,
1076 sizeof(wideValue),
1077 PY_LITTLE_ENDIAN,
1078 /* signed */ 1);
1079 }
1080 return NULL;
1081 }
1082
1083 #ifdef HAVE_LIBTOMMAMTH
1084 static PyObject*
1085 fromBignumObj(PyObject* tkapp, Tcl_Obj *value)
1086 {
1087 mp_int bigValue;
1088 unsigned long numBytes;
1089 unsigned char *bytes;
1090 PyObject *res;
1091
1092 if (Tcl_GetBignumFromObj(Tkapp_Interp(tkapp), value, &bigValue) != TCL_OK)
1093 return Tkinter_Error(tkapp);
1094 numBytes = mp_unsigned_bin_size(&bigValue);
1095 bytes = PyMem_Malloc(numBytes);
1096 if (bytes == NULL) {
1097 mp_clear(&bigValue);
1098 return NULL;
haypo 2015/03/27 11:16:37 Hum, you should call PyErr_NoMemory() here, no?
storchaka 2015/03/27 12:01:44 Good catch.
1099 }
1100 if (mp_to_unsigned_bin_n(&bigValue, bytes,
1101 &numBytes) != MP_OKAY) {
1102 mp_clear(&bigValue);
1103 PyMem_Free(bytes);
1104 return PyErr_NoMemory();
1105 }
1106 res = _PyLong_FromByteArray(bytes, numBytes,
1107 /* big-endian */ 0,
1108 /* unsigned */ 0);
1109 PyMem_Free(bytes);
1110 if (res != NULL && bigValue.sign == MP_NEG) {
1111 PyObject *res2 = PyNumber_Negative(res);
haypo 2015/03/27 11:16:37 We should maybe expose _PyLong_Negate() in longobj
storchaka 2015/03/27 12:01:44 Large negative numbers are pretty rare (they never
1112 Py_DECREF(res);
1113 res = res2;
1114 }
1115 mp_clear(&bigValue);
1116 return res;
1117 }
1118 #endif
998 1119
999 static PyObject* 1120 static PyObject*
1000 FromObj(PyObject* tkapp, Tcl_Obj *value) 1121 FromObj(PyObject* tkapp, Tcl_Obj *value)
1001 { 1122 {
1002 PyObject *result = NULL; 1123 PyObject *result = NULL;
1003 TkappObject *app = (TkappObject*)tkapp; 1124 TkappObject *app = (TkappObject*)tkapp;
1125 Tcl_Interp *interp = Tkapp_Interp(tkapp);
1004 1126
1005 if (value->typePtr == NULL) { 1127 if (value->typePtr == NULL) {
1006 return unicodeFromTclStringAndSize(value->bytes, value->length); 1128 return unicodeFromTclStringAndSize(value->bytes, value->length);
1007 } 1129 }
1008 1130
1009 if (value->typePtr == app->BooleanType) { 1131 if (value->typePtr == app->BooleanType) {
1010 result = value->internalRep.longValue ? Py_True : Py_False; 1132 result = value->internalRep.longValue ? Py_True : Py_False;
1011 Py_INCREF(result); 1133 Py_INCREF(result);
1012 return result; 1134 return result;
1013 } 1135 }
1014 1136
1015 if (value->typePtr == app->ByteArrayType) { 1137 if (value->typePtr == app->ByteArrayType) {
1016 int size; 1138 int size;
1017 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); 1139 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
1018 return PyBytes_FromStringAndSize(data, size); 1140 return PyBytes_FromStringAndSize(data, size);
1019 } 1141 }
1020 1142
1021 if (value->typePtr == app->DoubleType) { 1143 if (value->typePtr == app->DoubleType) {
1022 return PyFloat_FromDouble(value->internalRep.doubleValue); 1144 return PyFloat_FromDouble(value->internalRep.doubleValue);
1023 } 1145 }
1024 1146
1025 if (value->typePtr == app->IntType) { 1147 if (value->typePtr == app->IntType) {
1026 return PyLong_FromLong(value->internalRep.longValue); 1148 long longValue;
1149 if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK)
1150 return PyLong_FromLong(longValue);
1151 /* If there is an error in the long conversion,
1152 fall through to wideInt handling. */
1153 }
1154
1155 if (value->typePtr == app->IntType ||
1156 value->typePtr == app->WideIntType) {
1157 result = fromWideIntObj(tkapp, value);
1158 if (result != NULL || PyErr_Occurred())
1159 return result;
1160 Tcl_ResetResult(interp);
1161 /* If there is an error in the wideInt conversion,
1162 fall through to bignum handling. */
1027 } 1163 }
1028 1164
1029 if (value->typePtr == app->ListType) { 1165 if (value->typePtr == app->ListType) {
1030 int size; 1166 int size;
1031 int i, status; 1167 int i, status;
1032 PyObject *elem; 1168 PyObject *elem;
1033 Tcl_Obj *tcl_elem; 1169 Tcl_Obj *tcl_elem;
1034 1170
1035 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size); 1171 status = Tcl_ListObjLength(interp, value, &size);
1036 if (status == TCL_ERROR) 1172 if (status == TCL_ERROR)
1037 return Tkinter_Error(tkapp); 1173 return Tkinter_Error(tkapp);
1038 result = PyTuple_New(size); 1174 result = PyTuple_New(size);
1039 if (!result) 1175 if (!result)
1040 return NULL; 1176 return NULL;
1041 for (i = 0; i < size; i++) { 1177 for (i = 0; i < size; i++) {
1042 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp), 1178 status = Tcl_ListObjIndex(interp, value, i, &tcl_elem);
1043 value, i, &tcl_elem);
1044 if (status == TCL_ERROR) { 1179 if (status == TCL_ERROR) {
1045 Py_DECREF(result); 1180 Py_DECREF(result);
1046 return Tkinter_Error(tkapp); 1181 return Tkinter_Error(tkapp);
1047 } 1182 }
1048 elem = FromObj(tkapp, tcl_elem); 1183 elem = FromObj(tkapp, tcl_elem);
1049 if (!elem) { 1184 if (!elem) {
1050 Py_DECREF(result); 1185 Py_DECREF(result);
1051 return NULL; 1186 return NULL;
1052 } 1187 }
1053 PyTuple_SetItem(result, i, elem); 1188 PyTuple_SetItem(result, i, elem);
1054 } 1189 }
1055 return result; 1190 return result;
1056 } 1191 }
1057 1192
1058 if (value->typePtr == app->ProcBodyType) { 1193 if (value->typePtr == app->ProcBodyType) {
1059 /* fall through: return tcl object. */ 1194 /* fall through: return tcl object. */
1060 } 1195 }
1061 1196
1062 if (value->typePtr == app->StringType) { 1197 if (value->typePtr == app->StringType) {
1063 return PyUnicode_FromKindAndData( 1198 return PyUnicode_FromKindAndData(
1064 sizeof(Tcl_UniChar), Tcl_GetUnicode(value), 1199 sizeof(Tcl_UniChar), Tcl_GetUnicode(value),
1065 Tcl_GetCharLength(value)); 1200 Tcl_GetCharLength(value));
1066 } 1201 }
1202
1203 #ifdef HAVE_LIBTOMMAMTH
haypo 2015/03/27 11:16:37 Why not moving this block closer to the fromWideIn
storchaka 2015/03/27 12:01:44 Initially it was close to the fromWideIntObj() blo
1204 if (value->typePtr == app->IntType ||
1205 value->typePtr == app->WideIntType ||
1206 value->typePtr == app->BignumType) {
1207 return fromBignumObj(tkapp, value);
1208 }
1209 if (app->BignumType == NULL &&
haypo 2015/03/27 11:16:37 Maybe keep this unlikely case at the end.
storchaka 2015/03/27 12:01:44 Done.
1210 strcmp(value->typePtr->name, "bignum") == 0) {
1211 /* bignum type is not registered in Tcl */
1212 app->BignumType = value->typePtr;
1213 return fromBignumObj(tkapp, value);
1214 }
1215 #endif
1067 1216
1068 return newPyTclObject(value); 1217 return newPyTclObject(value);
1069 } 1218 }
1070 1219
1071 #ifdef WITH_THREAD 1220 #ifdef WITH_THREAD
1072 /* This mutex synchronizes inter-thread command calls. */ 1221 /* This mutex synchronizes inter-thread command calls. */
1073 TCL_DECLARE_MUTEX(call_mutex) 1222 TCL_DECLARE_MUTEX(call_mutex)
1074 1223
1075 typedef struct Tkapp_CallEvent { 1224 typedef struct Tkapp_CallEvent {
1076 Tcl_Event ev; /* Must be first */ 1225 Tcl_Event ev; /* Must be first */
(...skipping 615 matching lines...) Expand 10 before | Expand all | Expand 10 after
1692 } 1841 }
1693 1842
1694 1843
1695 1844
1696 /** Tcl to Python **/ 1845 /** Tcl to Python **/
1697 1846
1698 static PyObject * 1847 static PyObject *
1699 Tkapp_GetInt(PyObject *self, PyObject *args) 1848 Tkapp_GetInt(PyObject *self, PyObject *args)
1700 { 1849 {
1701 char *s; 1850 char *s;
1702 int v; 1851 Tcl_Obj *value;
1852 PyObject *result;
1703 1853
1704 if (PyTuple_Size(args) == 1) { 1854 if (PyTuple_Size(args) == 1) {
1705 PyObject* o = PyTuple_GetItem(args, 0); 1855 PyObject* o = PyTuple_GetItem(args, 0);
1706 if (PyLong_Check(o)) { 1856 if (PyLong_Check(o)) {
1707 Py_INCREF(o); 1857 Py_INCREF(o);
1708 return o; 1858 return o;
1709 } 1859 }
1710 } 1860 }
1711 if (!PyArg_ParseTuple(args, "s:getint", &s)) 1861 if (!PyArg_ParseTuple(args, "s:getint", &s))
1712 return NULL; 1862 return NULL;
1713 CHECK_STRING_LENGTH(s); 1863 CHECK_STRING_LENGTH(s);
1714 if (Tcl_GetInt(Tkapp_Interp(self), s, &v) == TCL_ERROR) 1864 value = Tcl_NewStringObj(s, -1);
1865 if (value == NULL)
1715 return Tkinter_Error(self); 1866 return Tkinter_Error(self);
1716 return Py_BuildValue("i", v); 1867 /* Don't use Tcl_GetInt() because it returns ambiguous result for value
1868 in ranges -2**32..-2**31-1 and 2**31..2**32-1 (on 32-bit platform).
1869
1870 Prefer bignum because Tcl_GetWideIntFromObj returns ambiguous result for
1871 value in ranges -2**64..-2**63-1 and 2**63..2**64-1 (on 32-bit platform).
1872 */
1873 #ifdef HAVE_LIBTOMMAMTH
1874 result = fromBignumObj(self, value);
1875 #else
1876 result = fromWideIntObj(self, value);
1877 #endif
1878 Tcl_DecrRefCount(value);
1879 if (result != NULL || PyErr_Occurred())
1880 return result;
1881 return Tkinter_Error(self);
1717 } 1882 }
1718 1883
1719 static PyObject * 1884 static PyObject *
1720 Tkapp_GetDouble(PyObject *self, PyObject *args) 1885 Tkapp_GetDouble(PyObject *self, PyObject *args)
1721 { 1886 {
1722 char *s; 1887 char *s;
1723 double v; 1888 double v;
1724 1889
1725 if (PyTuple_Size(args) == 1) { 1890 if (PyTuple_Size(args) == 1) {
1726 PyObject *o = PyTuple_GetItem(args, 0); 1891 PyObject *o = PyTuple_GetItem(args, 0);
(...skipping 1416 matching lines...) Expand 10 before | Expand all | Expand 10 after
3143 } 3308 }
3144 3309
3145 #if 0 3310 #if 0
3146 /* This was not a good idea; through <Destroy> bindings, 3311 /* This was not a good idea; through <Destroy> bindings,
3147 Tcl_Finalize() may invoke Python code but at that point the 3312 Tcl_Finalize() may invoke Python code but at that point the
3148 interpreter and thread state have already been destroyed! */ 3313 interpreter and thread state have already been destroyed! */
3149 Py_AtExit(Tcl_Finalize); 3314 Py_AtExit(Tcl_Finalize);
3150 #endif 3315 #endif
3151 return m; 3316 return m;
3152 } 3317 }
OLDNEW
« Lib/test/test_tcl.py ('K') | « Lib/test/test_tcl.py ('k') | no next file » | no next file with comments »

RSS Feeds Recent Issues | This issue
This is Rietveld 894c83f36cb7+