@@ -318,6 +318,7 @@ typedef struct {
318318 const Tcl_ObjType * BignumType ;
319319 const Tcl_ObjType * ListType ;
320320 const Tcl_ObjType * StringType ;
321+ const Tcl_ObjType * UTF32StringType ;
321322} TkappObject ;
322323
323324#define Tkapp_Interp (v ) (((TkappObject *) (v))->interp)
@@ -588,14 +589,40 @@ Tkapp_New(const char *screenName, const char *className,
588589 }
589590
590591 v -> OldBooleanType = Tcl_GetObjType ("boolean" );
591- v -> BooleanType = Tcl_GetObjType ("booleanString" );
592- v -> ByteArrayType = Tcl_GetObjType ("bytearray" );
592+ {
593+ Tcl_Obj * value ;
594+ int boolValue ;
595+
596+ /* Tcl 8.5 "booleanString" type is not registered
597+ and is renamed to "boolean" in Tcl 9.0.
598+ Based on approach suggested at
599+ https://core.tcl-lang.org/tcl/info/3bb3bcf2da5b */
600+ value = Tcl_NewStringObj ("true" , -1 );
601+ Tcl_GetBooleanFromObj (NULL , value , & boolValue );
602+ v -> BooleanType = value -> typePtr ;
603+ Tcl_DecrRefCount (value );
604+
605+ // "bytearray" type is not registered in Tcl 9.0
606+ value = Tcl_NewByteArrayObj (NULL , 0 );
607+ v -> ByteArrayType = value -> typePtr ;
608+ Tcl_DecrRefCount (value );
609+ }
593610 v -> DoubleType = Tcl_GetObjType ("double" );
611+ /* TIP 484 suggests retrieving the "int" type without Tcl_GetObjType("int")
612+ since it is no longer registered in Tcl 9.0. But even though Tcl 8.7
613+ only uses the "wideInt" type on platforms with 32-bit long, it still has
614+ a registered "int" type, which FromObj() should recognize just in case. */
594615 v -> IntType = Tcl_GetObjType ("int" );
616+ if (v -> IntType == NULL ) {
617+ Tcl_Obj * value = Tcl_NewIntObj (0 );
618+ v -> IntType = value -> typePtr ;
619+ Tcl_DecrRefCount (value );
620+ }
595621 v -> WideIntType = Tcl_GetObjType ("wideInt" );
596622 v -> BignumType = Tcl_GetObjType ("bignum" );
597623 v -> ListType = Tcl_GetObjType ("list" );
598624 v -> StringType = Tcl_GetObjType ("string" );
625+ v -> UTF32StringType = Tcl_GetObjType ("utf32string" );
599626
600627 /* Delete the 'exit' command, which can screw things up */
601628 Tcl_DeleteCommand (v -> interp , "exit" );
@@ -1124,14 +1151,6 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value)
11241151 return PyFloat_FromDouble (value -> internalRep .doubleValue );
11251152 }
11261153
1127- if (value -> typePtr == tkapp -> IntType ) {
1128- long longValue ;
1129- if (Tcl_GetLongFromObj (interp , value , & longValue ) == TCL_OK )
1130- return PyLong_FromLong (longValue );
1131- /* If there is an error in the long conversion,
1132- fall through to wideInt handling. */
1133- }
1134-
11351154 if (value -> typePtr == tkapp -> IntType ||
11361155 value -> typePtr == tkapp -> WideIntType ) {
11371156 result = fromWideIntObj (tkapp , value );
@@ -1176,17 +1195,12 @@ FromObj(TkappObject *tkapp, Tcl_Obj *value)
11761195 return result ;
11771196 }
11781197
1179- if (value -> typePtr == tkapp -> StringType ) {
1198+ if (value -> typePtr == tkapp -> StringType ||
1199+ value -> typePtr == tkapp -> UTF32StringType )
1200+ {
11801201 return unicodeFromTclObj (value );
11811202 }
11821203
1183- if (tkapp -> BooleanType == NULL &&
1184- strcmp (value -> typePtr -> name , "booleanString" ) == 0 ) {
1185- /* booleanString type is not registered in Tcl */
1186- tkapp -> BooleanType = value -> typePtr ;
1187- return fromBoolean (tkapp , value );
1188- }
1189-
11901204 if (tkapp -> BignumType == NULL &&
11911205 strcmp (value -> typePtr -> name , "bignum" ) == 0 ) {
11921206 /* bignum type is not registered in Tcl */
0 commit comments