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

Side by Side Diff: Modules/_tkinter.c

Issue 16840: Tkinter doesn't support large integers
Patch Set: Created 6 years, 7 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
« no previous file with comments | « 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 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
62 Tcl are empty. */ 62 Tcl are empty. */
63 #define TCL_THREADS 63 #define TCL_THREADS
64 64
65 #ifdef TK_FRAMEWORK 65 #ifdef TK_FRAMEWORK
66 #include <Tcl/tcl.h> 66 #include <Tcl/tcl.h>
67 #include <Tk/tk.h> 67 #include <Tk/tk.h>
68 #else 68 #else
69 #include <tcl.h> 69 #include <tcl.h>
70 #include <tk.h> 70 #include <tk.h>
71 #endif 71 #endif
72 #include <tclTomMath.h>
72 73
73 #include "tkinter.h" 74 #include "tkinter.h"
74 75
75 /* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */ 76 /* For Tcl 8.2 and 8.3, CONST* is not defined (except on Cygwin). */
76 #ifndef CONST84_RETURN 77 #ifndef CONST84_RETURN
77 #define CONST84_RETURN 78 #define CONST84_RETURN
78 #undef CONST 79 #undef CONST
79 #define CONST 80 #define CONST
80 #endif 81 #endif
81 82
(...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after
253 int wantobjects; 254 int wantobjects;
254 int threaded; /* True if tcl_platform[threaded] */ 255 int threaded; /* True if tcl_platform[threaded] */
255 Tcl_ThreadId thread_id; 256 Tcl_ThreadId thread_id;
256 int dispatching; 257 int dispatching;
257 /* We cannot include tclInt.h, as this is internal. 258 /* We cannot include tclInt.h, as this is internal.
258 So we cache interesting types here. */ 259 So we cache interesting types here. */
259 Tcl_ObjType *BooleanType; 260 Tcl_ObjType *BooleanType;
260 Tcl_ObjType *ByteArrayType; 261 Tcl_ObjType *ByteArrayType;
261 Tcl_ObjType *DoubleType; 262 Tcl_ObjType *DoubleType;
262 Tcl_ObjType *IntType; 263 Tcl_ObjType *IntType;
264 Tcl_ObjType *WideIntType;
265 Tcl_ObjType *BignumType;
263 Tcl_ObjType *ListType; 266 Tcl_ObjType *ListType;
264 Tcl_ObjType *ProcBodyType; 267 Tcl_ObjType *ProcBodyType;
265 Tcl_ObjType *StringType; 268 Tcl_ObjType *StringType;
266 } TkappObject; 269 } TkappObject;
267 270
268 #define Tkapp_Interp(v) (((TkappObject *) (v))->interp) 271 #define Tkapp_Interp(v) (((TkappObject *) (v))->interp)
269 #define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v)) 272 #define Tkapp_Result(v) Tcl_GetStringResult(Tkapp_Interp(v))
270 273
271 #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \ 274 #define DEBUG_REFCNT(v) (printf("DEBUG: id=%p, refcnt=%i\n", \
272 (void *) v, Py_REFCNT(v))) 275 (void *) v, Py_REFCNT(v)))
(...skipping 268 matching lines...) Expand 10 before | Expand all | Expand 10 after
541 /* If Tcl is threaded, we don't need the lock. */ 544 /* If Tcl is threaded, we don't need the lock. */
542 PyThread_free_lock(tcl_lock); 545 PyThread_free_lock(tcl_lock);
543 tcl_lock = NULL; 546 tcl_lock = NULL;
544 } 547 }
545 #endif 548 #endif
546 549
547 v->BooleanType = Tcl_GetObjType("boolean"); 550 v->BooleanType = Tcl_GetObjType("boolean");
548 v->ByteArrayType = Tcl_GetObjType("bytearray"); 551 v->ByteArrayType = Tcl_GetObjType("bytearray");
549 v->DoubleType = Tcl_GetObjType("double"); 552 v->DoubleType = Tcl_GetObjType("double");
550 v->IntType = Tcl_GetObjType("int"); 553 v->IntType = Tcl_GetObjType("int");
554 v->WideIntType = Tcl_GetObjType("wideInt");
555 v->BignumType = Tcl_GetObjType("bignum");
551 v->ListType = Tcl_GetObjType("list"); 556 v->ListType = Tcl_GetObjType("list");
552 v->ProcBodyType = Tcl_GetObjType("procbody"); 557 v->ProcBodyType = Tcl_GetObjType("procbody");
553 v->StringType = Tcl_GetObjType("string"); 558 v->StringType = Tcl_GetObjType("string");
554 559
555 /* Delete the 'exit' command, which can screw things up */ 560 /* Delete the 'exit' command, which can screw things up */
556 Tcl_DeleteCommand(v->interp, "exit"); 561 Tcl_DeleteCommand(v->interp, "exit");
557 562
558 if (screenName != NULL) 563 if (screenName != NULL)
559 Tcl_SetVar2(v->interp, "env", "DISPLAY", 564 Tcl_SetVar2(v->interp, "env", "DISPLAY",
560 screenName, TCL_GLOBAL_ONLY); 565 screenName, TCL_GLOBAL_ONLY);
(...skipping 267 matching lines...) Expand 10 before | Expand all | Expand 10 after
828 0, 833 0,
829 Py_TPFLAGS_DEFAULT, 834 Py_TPFLAGS_DEFAULT,
830 PyTclObject_Type_slots, 835 PyTclObject_Type_slots,
831 }; 836 };
832 837
833 838
834 static Tcl_Obj* 839 static Tcl_Obj*
835 AsObj(PyObject *value) 840 AsObj(PyObject *value)
836 { 841 {
837 Tcl_Obj *result; 842 Tcl_Obj *result;
838 long longVal;
839 int overflow;
840 843
841 if (PyBytes_Check(value)) 844 if (PyBytes_Check(value))
842 return Tcl_NewStringObj(PyBytes_AS_STRING(value), 845 return Tcl_NewStringObj(PyBytes_AS_STRING(value),
843 PyBytes_GET_SIZE(value)); 846 PyBytes_GET_SIZE(value));
844 else if (PyBool_Check(value)) 847 if (PyBool_Check(value))
845 return Tcl_NewBooleanObj(PyObject_IsTrue(value)); 848 return Tcl_NewBooleanObj(PyObject_IsTrue(value));
846 else if (PyLong_CheckExact(value) && 849
847 ((longVal = PyLong_AsLongAndOverflow(value, &overflow)), 850 if (PyLong_CheckExact(value)) {
848 !overflow)) { 851 int overflow;
849 /* If there is an overflow in the long conversion, 852 long longValue;
850 fall through to default object handling. */ 853 #ifdef HAVE_LONG_LONG
851 return Tcl_NewLongObj(longVal); 854 PY_LONG_LONG wideValue;
855 #endif
856 int neg;
857 PyObject *hexstr;
858 char *hexchars;
859 mp_int bigValue;
860
861 longValue = PyLong_AsLongAndOverflow(value, &overflow);
862 if (!overflow) {
863 /* If there is an overflow in the long conversion,
864 fall through to wideInt handling. */
865 return Tcl_NewLongObj(longValue);
866 }
867
868 #ifdef HAVE_LONG_LONG
869 wideValue = PyLong_AsLongLongAndOverflow(value, &overflow);
870 if (!overflow) {
871 /* If there is an overflow in the wideInt conversion,
872 fall through to bignum handling. */
873 return Tcl_NewWideIntObj(wideValue);
874 }
875 #endif
876
877 neg = Py_SIZE(value) < 0;
878 hexstr = _PyLong_Format(value, 16);
879 if (hexstr == NULL)
880 return NULL;
881 hexchars = PyUnicode_AsUTF8(hexstr);
882 if (hexchars == NULL) {
883 Py_DECREF(hexstr);
884 return NULL;
885 }
886 hexchars += neg + 2; /* skip sign and "0x" */
887 mp_init(&bigValue);
888 if (mp_read_radix(&bigValue, hexchars, 16) != MP_OKAY) {
889 mp_clear(&bigValue);
890 Py_DECREF(hexstr);
891 PyErr_NoMemory();
892 return NULL;
893 }
894 Py_DECREF(hexstr);
895 bigValue.sign = neg ? MP_NEG : MP_ZPOS;
896 result = Tcl_NewBignumObj(&bigValue);
897 mp_clear(&bigValue);
898 if (result == NULL) {
899 PyErr_NoMemory();
900 return NULL;
901 }
902 return result;
852 } 903 }
853 else if (PyFloat_Check(value)) 904
905 if (PyFloat_Check(value))
854 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value)); 906 return Tcl_NewDoubleObj(PyFloat_AS_DOUBLE(value));
855 else if (PyTuple_Check(value)) { 907 if (PyTuple_Check(value)) {
856 Tcl_Obj **argv; 908 Tcl_Obj **argv;
857 Py_ssize_t size, i; 909 Py_ssize_t size, i;
858 910
859 size = PyTuple_Size(value); 911 size = PyTuple_Size(value);
860 if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) { 912 if (!CHECK_SIZE(size, sizeof(Tcl_Obj *))) {
861 PyErr_SetString(PyExc_OverflowError, "tuple is too long"); 913 PyErr_SetString(PyExc_OverflowError, "tuple is too long");
862 return NULL; 914 return NULL;
863 } 915 }
864 argv = (Tcl_Obj **) ckalloc(((size_t)size) * sizeof(Tcl_Obj *)); 916 argv = (Tcl_Obj **) ckalloc(((size_t)size) * sizeof(Tcl_Obj *));
865 if(!argv) 917 if(!argv)
866 return 0; 918 return 0;
867 for (i = 0; i < size; i++) 919 for (i = 0; i < size; i++)
868 argv[i] = AsObj(PyTuple_GetItem(value,i)); 920 argv[i] = AsObj(PyTuple_GetItem(value,i));
869 result = Tcl_NewListObj(PyTuple_Size(value), argv); 921 result = Tcl_NewListObj(PyTuple_Size(value), argv);
870 ckfree(FREECAST argv); 922 ckfree(FREECAST argv);
871 return result; 923 return result;
872 } 924 }
873 else if (PyUnicode_Check(value)) { 925 if (PyUnicode_Check(value)) {
874 void *inbuf; 926 void *inbuf;
875 Py_ssize_t size; 927 Py_ssize_t size;
876 int kind; 928 int kind;
877 Tcl_UniChar *outbuf = NULL; 929 Tcl_UniChar *outbuf = NULL;
878 Py_ssize_t i; 930 Py_ssize_t i;
879 size_t allocsize; 931 size_t allocsize;
880 932
881 if (PyUnicode_READY(value) == -1) 933 if (PyUnicode_READY(value) == -1)
882 return NULL; 934 return NULL;
883 935
(...skipping 25 matching lines...) Expand all
909 ckfree(FREECAST outbuf); 961 ckfree(FREECAST outbuf);
910 return NULL; 962 return NULL;
911 } 963 }
912 #endif 964 #endif
913 outbuf[i] = ch; 965 outbuf[i] = ch;
914 } 966 }
915 result = Tcl_NewUnicodeObj(outbuf, size); 967 result = Tcl_NewUnicodeObj(outbuf, size);
916 ckfree(FREECAST outbuf); 968 ckfree(FREECAST outbuf);
917 return result; 969 return result;
918 } 970 }
919 else if(PyTclObject_Check(value)) { 971 if(PyTclObject_Check(value)) {
920 Tcl_Obj *v = ((PyTclObject*)value)->value; 972 Tcl_Obj *v = ((PyTclObject*)value)->value;
921 Tcl_IncrRefCount(v); 973 Tcl_IncrRefCount(v);
922 return v; 974 return v;
923 } 975 }
924 else { 976 {
925 PyObject *v = PyObject_Str(value); 977 PyObject *v = PyObject_Str(value);
926 if (!v) 978 if (!v)
927 return 0; 979 return 0;
928 result = AsObj(v); 980 result = AsObj(v);
929 Py_DECREF(v); 981 Py_DECREF(v);
930 return result; 982 return result;
931 } 983 }
932 } 984 }
933 985
934 static PyObject* 986 static PyObject*
935 FromObj(PyObject* tkapp, Tcl_Obj *value) 987 FromObj(PyObject* tkapp, Tcl_Obj *value)
936 { 988 {
937 PyObject *result = NULL; 989 PyObject *result = NULL;
938 TkappObject *app = (TkappObject*)tkapp; 990 TkappObject *app = (TkappObject*)tkapp;
991 Tcl_Interp *interp = Tkapp_Interp(tkapp);
939 992
940 if (value->typePtr == NULL) { 993 if (value->typePtr == NULL) {
941 return PyUnicode_FromStringAndSize(value->bytes, 994 return PyUnicode_FromStringAndSize(value->bytes,
942 value->length); 995 value->length);
943 } 996 }
944 997
945 if (value->typePtr == app->BooleanType) { 998 if (value->typePtr == app->BooleanType) {
946 result = value->internalRep.longValue ? Py_True : Py_False; 999 result = value->internalRep.longValue ? Py_True : Py_False;
947 Py_INCREF(result); 1000 Py_INCREF(result);
948 return result; 1001 return result;
949 } 1002 }
950 1003
951 if (value->typePtr == app->ByteArrayType) { 1004 if (value->typePtr == app->ByteArrayType) {
952 int size; 1005 int size;
953 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size); 1006 char *data = (char*)Tcl_GetByteArrayFromObj(value, &size);
954 return PyBytes_FromStringAndSize(data, size); 1007 return PyBytes_FromStringAndSize(data, size);
955 } 1008 }
956 1009
957 if (value->typePtr == app->DoubleType) { 1010 if (value->typePtr == app->DoubleType) {
958 return PyFloat_FromDouble(value->internalRep.doubleValue); 1011 return PyFloat_FromDouble(value->internalRep.doubleValue);
959 } 1012 }
960 1013
961 if (value->typePtr == app->IntType) { 1014 if (value->typePtr == app->IntType) {
962 return PyLong_FromLong(value->internalRep.longValue); 1015 long longValue;
1016 if (Tcl_GetLongFromObj(interp, value, &longValue) == TCL_OK)
1017 return PyLong_FromLong(longValue);
1018 /* If there is an error in the long conversion,
1019 fall through to wideInt handling. */
1020 }
1021
1022 #ifdef HAVE_LONG_LONG
1023 if (value->typePtr == app->IntType ||
1024 value->typePtr == app->WideIntType) {
1025 Tcl_WideInt wideValue;
1026 if (Tcl_GetWideIntFromObj(interp, value, &wideValue) == TCL_OK)
1027 return PyLong_FromLongLong(wideValue);
1028 /* If there is an error in the wideInt conversion,
1029 fall through to bignum handling. */
1030 }
1031 #endif
1032
1033 if (value->typePtr == app->IntType ||
1034 value->typePtr == app->WideIntType ||
1035 value->typePtr == app->BignumType ||
1036 (app->BignumType == NULL &&
1037 strcmp(value->typePtr->name, "bignum") == 0)) {
1038 mp_int bigValue;
1039 /* bignum type is not registered in Tcl */
1040 if (app->BignumType == NULL &&
1041 strcmp(value->typePtr->name, "bignum") == 0) {
1042 app->BignumType = value->typePtr;
1043 }
1044 if (Tcl_GetBignumFromObj(interp, value, &bigValue) == TCL_OK) {
1045 unsigned long numBytes = mp_unsigned_bin_size(&bigValue);
1046 unsigned char *bytes = PyMem_Malloc(numBytes);
1047 PyObject *res;
1048 if (bytes == NULL) {
1049 mp_clear(&bigValue);
1050 return NULL;
1051 }
1052 if (mp_to_unsigned_bin_n(&bigValue, bytes,
1053 &numBytes) != MP_OKAY) {
1054 mp_clear(&bigValue);
1055 PyMem_Free(bytes);
1056 return PyErr_NoMemory();
1057 }
1058 res = _PyLong_FromByteArray(bytes, numBytes,
1059 /* big-endian */ 0,
1060 /* unsigned */ 0);
1061 PyMem_Free(bytes);
1062 if (res != NULL && bigValue.sign == MP_NEG) {
1063 PyObject *res2 = PyNumber_Negative(res);
1064 Py_DECREF(res);
1065 res = res2;
1066 }
1067 mp_clear(&bigValue);
1068 return res;
1069 }
1070 return Tkinter_Error(tkapp);
963 } 1071 }
964 1072
965 if (value->typePtr == app->ListType) { 1073 if (value->typePtr == app->ListType) {
966 int size; 1074 int size;
967 int i, status; 1075 int i, status;
968 PyObject *elem; 1076 PyObject *elem;
969 Tcl_Obj *tcl_elem; 1077 Tcl_Obj *tcl_elem;
970 1078
971 status = Tcl_ListObjLength(Tkapp_Interp(tkapp), value, &size); 1079 status = Tcl_ListObjLength(interp, value, &size);
972 if (status == TCL_ERROR) 1080 if (status == TCL_ERROR)
973 return Tkinter_Error(tkapp); 1081 return Tkinter_Error(tkapp);
974 result = PyTuple_New(size); 1082 result = PyTuple_New(size);
975 if (!result) 1083 if (!result)
976 return NULL; 1084 return NULL;
977 for (i = 0; i < size; i++) { 1085 for (i = 0; i < size; i++) {
978 status = Tcl_ListObjIndex(Tkapp_Interp(tkapp), 1086 status = Tcl_ListObjIndex(interp, value, i, &tcl_elem);
979 value, i, &tcl_elem);
980 if (status == TCL_ERROR) { 1087 if (status == TCL_ERROR) {
981 Py_DECREF(result); 1088 Py_DECREF(result);
982 return Tkinter_Error(tkapp); 1089 return Tkinter_Error(tkapp);
983 } 1090 }
984 elem = FromObj(tkapp, tcl_elem); 1091 elem = FromObj(tkapp, tcl_elem);
985 if (!elem) { 1092 if (!elem) {
986 Py_DECREF(result); 1093 Py_DECREF(result);
987 return NULL; 1094 return NULL;
988 } 1095 }
989 PyTuple_SetItem(result, i, elem); 1096 PyTuple_SetItem(result, i, elem);
(...skipping 2059 matching lines...) Expand 10 before | Expand all | Expand 10 after
3049 } 3156 }
3050 3157
3051 #if 0 3158 #if 0
3052 /* This was not a good idea; through <Destroy> bindings, 3159 /* This was not a good idea; through <Destroy> bindings,
3053 Tcl_Finalize() may invoke Python code but at that point the 3160 Tcl_Finalize() may invoke Python code but at that point the
3054 interpreter and thread state have already been destroyed! */ 3161 interpreter and thread state have already been destroyed! */
3055 Py_AtExit(Tcl_Finalize); 3162 Py_AtExit(Tcl_Finalize);
3056 #endif 3163 #endif
3057 return m; 3164 return m;
3058 } 3165 }
OLDNEW
« no previous file with comments | « Lib/test/test_tcl.py ('k') | no next file » | no next file with comments »

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