comparison Tools/gdb/libpython.py @ 64570:a2aeddc19b66

Issue #9188: The gdb extension now handles correctly narrow (UCS2) as well as wide (UCS4) unicode builds for both the host interpreter (embedded inside gdb) and the interpreter under test.
author Antoine Pitrou <solipsis@pitrou.net>
date Wed, 08 Sep 2010 20:57:48 +0000
parents fc794add559d
children b1cf3f7f304c
comparison
equal deleted inserted replaced
64569:8627c3ec9711 64570:a2aeddc19b66
1063 def _unichr_is_printable(char): 1063 def _unichr_is_printable(char):
1064 # Logic adapted from Python 3's Tools/unicode/makeunicodedata.py 1064 # Logic adapted from Python 3's Tools/unicode/makeunicodedata.py
1065 if char == u" ": 1065 if char == u" ":
1066 return True 1066 return True
1067 import unicodedata 1067 import unicodedata
1068 return unicodedata.category(char)[0] not in ("C", "Z") 1068 return unicodedata.category(char) not in ("C", "Z")
1069
1070 if sys.maxunicode >= 0x10000:
1071 _unichr = unichr
1072 else:
1073 # Needed for proper surrogate support if sizeof(Py_UNICODE) is 2 in gdb
1074 def _unichr(x):
1075 if x < 0x10000:
1076 return unichr(x)
1077 x -= 0x10000
1078 ch1 = 0xD800 | (x >> 10)
1079 ch2 = 0xDC00 | (x & 0x3FF)
1080 return unichr(ch1) + unichr(ch2)
1069 1081
1070 1082
1071 class PyUnicodeObjectPtr(PyObjectPtr): 1083 class PyUnicodeObjectPtr(PyObjectPtr):
1072 _typename = 'PyUnicodeObject' 1084 _typename = 'PyUnicodeObject'
1073 1085
1082 field_length = long(self.field('length')) 1094 field_length = long(self.field('length'))
1083 field_str = self.field('str') 1095 field_str = self.field('str')
1084 1096
1085 # Gather a list of ints from the Py_UNICODE array; these are either 1097 # Gather a list of ints from the Py_UNICODE array; these are either
1086 # UCS-2 or UCS-4 code points: 1098 # UCS-2 or UCS-4 code points:
1087 Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)] 1099 if self.char_width() > 2:
1100 Py_UNICODEs = [int(field_str[i]) for i in safe_range(field_length)]
1101 else:
1102 # A more elaborate routine if sizeof(Py_UNICODE) is 2 in the
1103 # inferior process: we must join surrogate pairs.
1104 Py_UNICODEs = []
1105 i = 0
1106 while i < field_length:
1107 ucs = int(field_str[i])
1108 i += 1
1109 if ucs < 0xD800 or ucs >= 0xDC00 or i == field_length:
1110 Py_UNICODEs.append(ucs)
1111 continue
1112 # This could be a surrogate pair.
1113 ucs2 = int(field_str[i])
1114 if ucs2 < 0xDC00 or ucs2 > 0xDFFF:
1115 continue
1116 code = (ucs & 0x03FF) << 10
1117 code |= ucs2 & 0x03FF
1118 code += 0x00010000
1119 Py_UNICODEs.append(code)
1120 i += 1
1088 1121
1089 # Convert the int code points to unicode characters, and generate a 1122 # Convert the int code points to unicode characters, and generate a
1090 # local unicode instance: 1123 # local unicode instance.
1091 result = u''.join([unichr(ucs) for ucs in Py_UNICODEs]) 1124 # This splits surrogate pairs if sizeof(Py_UNICODE) is 2 here (in gdb).
1125 result = u''.join([_unichr(ucs) for ucs in Py_UNICODEs])
1092 return result 1126 return result
1093 1127
1094 def write_repr(self, out, visited): 1128 def write_repr(self, out, visited):
1095 # Write this out as a Python 3 str literal, i.e. without a "u" prefix 1129 # Write this out as a Python 3 str literal, i.e. without a "u" prefix
1096 1130
1135 1169
1136 # Non-ASCII characters 1170 # Non-ASCII characters
1137 else: 1171 else:
1138 ucs = ch 1172 ucs = ch
1139 orig_ucs = None 1173 orig_ucs = None
1174 ch2 = None
1140 if self.char_width() == 2: 1175 if self.char_width() == 2:
1141 # Get code point from surrogate pair 1176 # If sizeof(Py_UNICODE) is 2 here (in gdb), join
1177 # surrogate pairs before calling _unichr_is_printable.
1142 if (i < len(proxy) 1178 if (i < len(proxy)
1143 and 0xD800 <= ord(ch) < 0xDC00 \ 1179 and 0xD800 <= ord(ch) < 0xDC00 \
1144 and 0xDC00 <= ord(proxy[i]) <= 0xDFFF): 1180 and 0xDC00 <= ord(proxy[i]) <= 0xDFFF):
1145 ch2 = proxy[i] 1181 ch2 = proxy[i]
1146 code = (ord(ch) & 0x03FF) << 10 1182 ucs = ch + ch2
1147 code |= ord(ch2) & 0x03FF
1148 code += 0x00010000
1149 orig_ucs = ucs
1150 ucs = unichr(code)
1151 i += 1 1183 i += 1
1152 else:
1153 ch2 = None
1154 1184
1155 printable = _unichr_is_printable(ucs) 1185 printable = _unichr_is_printable(ucs)
1156 if printable: 1186 if printable:
1157 try: 1187 try:
1158 ucs.encode(ENCODING) 1188 ucs.encode(ENCODING)
1193 out.write(hexdigits[(code >> 4) & 0x000F]) 1223 out.write(hexdigits[(code >> 4) & 0x000F])
1194 out.write(hexdigits[code & 0x000F]) 1224 out.write(hexdigits[code & 0x000F])
1195 else: 1225 else:
1196 # Copy characters as-is 1226 # Copy characters as-is
1197 out.write(ch) 1227 out.write(ch)
1198 if self.char_width() == 2 and (ch2 is not None): 1228 if ch2 is not None:
1199 out.write(ch2) 1229 out.write(ch2)
1200 1230
1201 out.write(quote) 1231 out.write(quote)
1202 1232
1203 1233