Mercurial > cpython-lru_cache-weakref
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 |
