Mercurial > cpython-lru_cache-weakref
annotate Objects/stringlib/unicode_format.h @ 73323:dad02a080bbc
Improve byte-compilation in packaging to be independent of -O or -B.
The code I fixed to comply with PEP 3147 still had one bug: When run
under python -O, some paths for pyc files would be pyo, because I called
imp.cache_from_source without explicit debug_override argument in some
places, and under -O that would return .pyo (this is well explained in
the imp docs). Now all code (util.byte_compile, build_py, install_lib)
can create .pyo files according to options given by users,
without interference from the calling Python’s own optimize mode.
On a related topic, I also removed the code that prevented byte
compilation under python -B. The rationale is that packaging gives
control over the creation of pyc files to the user with its own explicit
option, and the behavior should not be changed if the calling Python
happens to run with -B for whatever reason. I will argue that this is a
bug fix and ask to be allowed to backport this change to distutils.
Finally, I moved one nugget of information about the --compile and
--optimize options from the source into the doc. It clears up a
misunderstanding that I (and maybe other people) had.
| author | Éric Araujo <merwok@netwok.org> |
|---|---|
| date | Thu, 03 Nov 2011 05:08:28 +0100 |
| parents | d49be9b017a2 |
| children | 783b4b9dfa5e |
| rev | line source |
|---|---|
| 72475 | 1 /* |
| 2 unicode_format.h -- implementation of str.format(). | |
| 3 */ | |
| 4 | |
| 5 | |
| 6 /* Defines for more efficiently reallocating the string buffer */ | |
| 7 #define INITIAL_SIZE_INCREMENT 100 | |
| 8 #define SIZE_MULTIPLIER 2 | |
| 9 #define MAX_SIZE_INCREMENT 3200 | |
| 10 | |
| 11 | |
| 12 /************************************************************************/ | |
| 13 /*********** Global data structures and forward declarations *********/ | |
| 14 /************************************************************************/ | |
| 15 | |
| 16 /* | |
| 17 A SubString consists of the characters between two string or | |
| 18 unicode pointers. | |
| 19 */ | |
| 20 typedef struct { | |
| 21 PyObject *str; /* borrowed reference */ | |
| 22 Py_ssize_t start, end; | |
| 23 } SubString; | |
| 24 | |
| 25 | |
| 26 typedef enum { | |
| 27 ANS_INIT, | |
| 28 ANS_AUTO, | |
| 29 ANS_MANUAL | |
| 30 } AutoNumberState; /* Keep track if we're auto-numbering fields */ | |
| 31 | |
| 32 /* Keeps track of our auto-numbering state, and which number field we're on */ | |
| 33 typedef struct { | |
| 34 AutoNumberState an_state; | |
| 35 int an_field_number; | |
| 36 } AutoNumber; | |
| 37 | |
| 38 | |
| 39 /* forward declaration for recursion */ | |
| 40 static PyObject * | |
| 41 build_string(SubString *input, PyObject *args, PyObject *kwargs, | |
| 42 int recursion_depth, AutoNumber *auto_number); | |
| 43 | |
| 44 | |
| 45 | |
| 46 /************************************************************************/ | |
| 47 /************************** Utility functions ************************/ | |
| 48 /************************************************************************/ | |
| 49 | |
| 50 static void | |
| 51 AutoNumber_Init(AutoNumber *auto_number) | |
| 52 { | |
| 53 auto_number->an_state = ANS_INIT; | |
| 54 auto_number->an_field_number = 0; | |
| 55 } | |
| 56 | |
| 57 /* fill in a SubString from a pointer and length */ | |
| 58 Py_LOCAL_INLINE(void) | |
|
72750
1a0715386d27
Fix compilation warnings under 64-bit Windows
Antoine Pitrou <solipsis@pitrou.net>
parents:
72475
diff
changeset
|
59 SubString_init(SubString *str, PyObject *s, Py_ssize_t start, Py_ssize_t end) |
| 72475 | 60 { |
| 61 str->str = s; | |
| 62 str->start = start; | |
| 63 str->end = end; | |
| 64 } | |
| 65 | |
| 66 /* return a new string. if str->str is NULL, return None */ | |
| 67 Py_LOCAL_INLINE(PyObject *) | |
| 68 SubString_new_object(SubString *str) | |
| 69 { | |
| 70 if (str->str == NULL) { | |
| 71 Py_INCREF(Py_None); | |
| 72 return Py_None; | |
| 73 } | |
| 74 return PyUnicode_Substring(str->str, str->start, str->end); | |
| 75 } | |
| 76 | |
| 77 /* return a new string. if str->str is NULL, return None */ | |
| 78 Py_LOCAL_INLINE(PyObject *) | |
| 79 SubString_new_object_or_empty(SubString *str) | |
| 80 { | |
| 81 if (str->str == NULL) { | |
| 82 return PyUnicode_FromUnicode(NULL, 0); | |
| 83 } | |
| 84 return SubString_new_object(str); | |
| 85 } | |
| 86 | |
| 87 /* Return 1 if an error has been detected switching between automatic | |
| 88 field numbering and manual field specification, else return 0. Set | |
| 89 ValueError on error. */ | |
| 90 static int | |
| 91 autonumber_state_error(AutoNumberState state, int field_name_is_empty) | |
| 92 { | |
| 93 if (state == ANS_MANUAL) { | |
| 94 if (field_name_is_empty) { | |
| 95 PyErr_SetString(PyExc_ValueError, "cannot switch from " | |
| 96 "manual field specification to " | |
| 97 "automatic field numbering"); | |
| 98 return 1; | |
| 99 } | |
| 100 } | |
| 101 else { | |
| 102 if (!field_name_is_empty) { | |
| 103 PyErr_SetString(PyExc_ValueError, "cannot switch from " | |
| 104 "automatic field numbering to " | |
| 105 "manual field specification"); | |
| 106 return 1; | |
| 107 } | |
| 108 } | |
| 109 return 0; | |
| 110 } | |
| 111 | |
| 112 | |
| 113 /************************************************************************/ | |
| 114 /*********** Output string management functions ****************/ | |
| 115 /************************************************************************/ | |
| 116 | |
| 117 /* | |
| 118 output_data dumps characters into our output string | |
| 119 buffer. | |
| 120 | |
| 121 In some cases, it has to reallocate the string. | |
| 122 | |
| 123 It returns a status: 0 for a failed reallocation, | |
| 124 1 for success. | |
| 125 */ | |
| 126 static int | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
127 output_data(_PyAccu *acc, PyObject *s, Py_ssize_t start, Py_ssize_t end) |
| 72475 | 128 { |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
129 PyObject *substring; |
|
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
130 int r; |
|
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
131 |
|
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
132 substring = PyUnicode_Substring(s, start, end); |
|
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
133 if (substring == NULL) |
| 72475 | 134 return 0; |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
135 r = _PyAccu_Accumulate(acc, substring); |
|
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
136 Py_DECREF(substring); |
|
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
137 return r == 0; |
| 72475 | 138 } |
| 139 | |
| 140 /************************************************************************/ | |
| 141 /*********** Format string parsing -- integers and identifiers *********/ | |
| 142 /************************************************************************/ | |
| 143 | |
| 144 static Py_ssize_t | |
| 145 get_integer(const SubString *str) | |
| 146 { | |
| 147 Py_ssize_t accumulator = 0; | |
| 148 Py_ssize_t digitval; | |
| 149 Py_ssize_t i; | |
| 150 | |
| 151 /* empty string is an error */ | |
| 152 if (str->start >= str->end) | |
| 153 return -1; | |
| 154 | |
| 155 for (i = str->start; i < str->end; i++) { | |
| 156 digitval = Py_UNICODE_TODECIMAL(PyUnicode_READ_CHAR(str->str, i)); | |
| 157 if (digitval < 0) | |
| 158 return -1; | |
| 159 /* | |
| 160 Detect possible overflow before it happens: | |
| 161 | |
| 162 accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if | |
| 163 accumulator > (PY_SSIZE_T_MAX - digitval) / 10. | |
| 164 */ | |
| 165 if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) { | |
| 166 PyErr_Format(PyExc_ValueError, | |
| 167 "Too many decimal digits in format string"); | |
| 168 return -1; | |
| 169 } | |
| 170 accumulator = accumulator * 10 + digitval; | |
| 171 } | |
| 172 return accumulator; | |
| 173 } | |
| 174 | |
| 175 /************************************************************************/ | |
| 176 /******** Functions to get field objects and specification strings ******/ | |
| 177 /************************************************************************/ | |
| 178 | |
| 179 /* do the equivalent of obj.name */ | |
| 180 static PyObject * | |
| 181 getattr(PyObject *obj, SubString *name) | |
| 182 { | |
| 183 PyObject *newobj; | |
| 184 PyObject *str = SubString_new_object(name); | |
| 185 if (str == NULL) | |
| 186 return NULL; | |
| 187 newobj = PyObject_GetAttr(obj, str); | |
| 188 Py_DECREF(str); | |
| 189 return newobj; | |
| 190 } | |
| 191 | |
| 192 /* do the equivalent of obj[idx], where obj is a sequence */ | |
| 193 static PyObject * | |
| 194 getitem_sequence(PyObject *obj, Py_ssize_t idx) | |
| 195 { | |
| 196 return PySequence_GetItem(obj, idx); | |
| 197 } | |
| 198 | |
| 199 /* do the equivalent of obj[idx], where obj is not a sequence */ | |
| 200 static PyObject * | |
| 201 getitem_idx(PyObject *obj, Py_ssize_t idx) | |
| 202 { | |
| 203 PyObject *newobj; | |
| 204 PyObject *idx_obj = PyLong_FromSsize_t(idx); | |
| 205 if (idx_obj == NULL) | |
| 206 return NULL; | |
| 207 newobj = PyObject_GetItem(obj, idx_obj); | |
| 208 Py_DECREF(idx_obj); | |
| 209 return newobj; | |
| 210 } | |
| 211 | |
| 212 /* do the equivalent of obj[name] */ | |
| 213 static PyObject * | |
| 214 getitem_str(PyObject *obj, SubString *name) | |
| 215 { | |
| 216 PyObject *newobj; | |
| 217 PyObject *str = SubString_new_object(name); | |
| 218 if (str == NULL) | |
| 219 return NULL; | |
| 220 newobj = PyObject_GetItem(obj, str); | |
| 221 Py_DECREF(str); | |
| 222 return newobj; | |
| 223 } | |
| 224 | |
| 225 typedef struct { | |
| 226 /* the entire string we're parsing. we assume that someone else | |
| 227 is managing its lifetime, and that it will exist for the | |
| 228 lifetime of the iterator. can be empty */ | |
| 229 SubString str; | |
| 230 | |
| 231 /* index to where we are inside field_name */ | |
| 232 Py_ssize_t index; | |
| 233 } FieldNameIterator; | |
| 234 | |
| 235 | |
| 236 static int | |
| 237 FieldNameIterator_init(FieldNameIterator *self, PyObject *s, | |
| 238 Py_ssize_t start, Py_ssize_t end) | |
| 239 { | |
| 240 SubString_init(&self->str, s, start, end); | |
| 241 self->index = start; | |
| 242 return 1; | |
| 243 } | |
| 244 | |
| 245 static int | |
| 246 _FieldNameIterator_attr(FieldNameIterator *self, SubString *name) | |
| 247 { | |
| 248 Py_UCS4 c; | |
| 249 | |
| 250 name->str = self->str.str; | |
| 251 name->start = self->index; | |
| 252 | |
| 253 /* return everything until '.' or '[' */ | |
| 254 while (self->index < self->str.end) { | |
| 255 c = PyUnicode_READ_CHAR(self->str.str, self->index++); | |
| 256 switch (c) { | |
| 257 case '[': | |
| 258 case '.': | |
| 259 /* backup so that we this character will be seen next time */ | |
| 260 self->index--; | |
| 261 break; | |
| 262 default: | |
| 263 continue; | |
| 264 } | |
| 265 break; | |
| 266 } | |
| 267 /* end of string is okay */ | |
| 268 name->end = self->index; | |
| 269 return 1; | |
| 270 } | |
| 271 | |
| 272 static int | |
| 273 _FieldNameIterator_item(FieldNameIterator *self, SubString *name) | |
| 274 { | |
| 275 int bracket_seen = 0; | |
| 276 Py_UCS4 c; | |
| 277 | |
| 278 name->str = self->str.str; | |
| 279 name->start = self->index; | |
| 280 | |
| 281 /* return everything until ']' */ | |
| 282 while (self->index < self->str.end) { | |
| 283 c = PyUnicode_READ_CHAR(self->str.str, self->index++); | |
| 284 switch (c) { | |
| 285 case ']': | |
| 286 bracket_seen = 1; | |
| 287 break; | |
| 288 default: | |
| 289 continue; | |
| 290 } | |
| 291 break; | |
| 292 } | |
| 293 /* make sure we ended with a ']' */ | |
| 294 if (!bracket_seen) { | |
| 295 PyErr_SetString(PyExc_ValueError, "Missing ']' in format string"); | |
| 296 return 0; | |
| 297 } | |
| 298 | |
| 299 /* end of string is okay */ | |
| 300 /* don't include the ']' */ | |
| 301 name->end = self->index-1; | |
| 302 return 1; | |
| 303 } | |
| 304 | |
| 305 /* returns 0 on error, 1 on non-error termination, and 2 if it returns a value */ | |
| 306 static int | |
| 307 FieldNameIterator_next(FieldNameIterator *self, int *is_attribute, | |
| 308 Py_ssize_t *name_idx, SubString *name) | |
| 309 { | |
| 310 /* check at end of input */ | |
| 311 if (self->index >= self->str.end) | |
| 312 return 1; | |
| 313 | |
| 314 switch (PyUnicode_READ_CHAR(self->str.str, self->index++)) { | |
| 315 case '.': | |
| 316 *is_attribute = 1; | |
| 317 if (_FieldNameIterator_attr(self, name) == 0) | |
| 318 return 0; | |
| 319 *name_idx = -1; | |
| 320 break; | |
| 321 case '[': | |
| 322 *is_attribute = 0; | |
| 323 if (_FieldNameIterator_item(self, name) == 0) | |
| 324 return 0; | |
| 325 *name_idx = get_integer(name); | |
| 326 if (*name_idx == -1 && PyErr_Occurred()) | |
| 327 return 0; | |
| 328 break; | |
| 329 default: | |
| 330 /* Invalid character follows ']' */ | |
| 331 PyErr_SetString(PyExc_ValueError, "Only '.' or '[' may " | |
| 332 "follow ']' in format field specifier"); | |
| 333 return 0; | |
| 334 } | |
| 335 | |
| 336 /* empty string is an error */ | |
| 337 if (name->start == name->end) { | |
| 338 PyErr_SetString(PyExc_ValueError, "Empty attribute in format string"); | |
| 339 return 0; | |
| 340 } | |
| 341 | |
| 342 return 2; | |
| 343 } | |
| 344 | |
| 345 | |
| 346 /* input: field_name | |
| 347 output: 'first' points to the part before the first '[' or '.' | |
| 348 'first_idx' is -1 if 'first' is not an integer, otherwise | |
| 349 it's the value of first converted to an integer | |
| 350 'rest' is an iterator to return the rest | |
| 351 */ | |
| 352 static int | |
| 353 field_name_split(PyObject *str, Py_ssize_t start, Py_ssize_t end, SubString *first, | |
| 354 Py_ssize_t *first_idx, FieldNameIterator *rest, | |
| 355 AutoNumber *auto_number) | |
| 356 { | |
| 357 Py_UCS4 c; | |
| 358 Py_ssize_t i = start; | |
| 359 int field_name_is_empty; | |
| 360 int using_numeric_index; | |
| 361 | |
| 362 /* find the part up until the first '.' or '[' */ | |
| 363 while (i < end) { | |
| 364 switch (c = PyUnicode_READ_CHAR(str, i++)) { | |
| 365 case '[': | |
| 366 case '.': | |
| 367 /* backup so that we this character is available to the | |
| 368 "rest" iterator */ | |
| 369 i--; | |
| 370 break; | |
| 371 default: | |
| 372 continue; | |
| 373 } | |
| 374 break; | |
| 375 } | |
| 376 | |
| 377 /* set up the return values */ | |
| 378 SubString_init(first, str, start, i); | |
| 379 FieldNameIterator_init(rest, str, i, end); | |
| 380 | |
| 381 /* see if "first" is an integer, in which case it's used as an index */ | |
| 382 *first_idx = get_integer(first); | |
| 383 if (*first_idx == -1 && PyErr_Occurred()) | |
| 384 return 0; | |
| 385 | |
| 386 field_name_is_empty = first->start >= first->end; | |
| 387 | |
| 388 /* If the field name is omitted or if we have a numeric index | |
| 389 specified, then we're doing numeric indexing into args. */ | |
| 390 using_numeric_index = field_name_is_empty || *first_idx != -1; | |
| 391 | |
| 392 /* We always get here exactly one time for each field we're | |
| 393 processing. And we get here in field order (counting by left | |
| 394 braces). So this is the perfect place to handle automatic field | |
| 395 numbering if the field name is omitted. */ | |
| 396 | |
| 397 /* Check if we need to do the auto-numbering. It's not needed if | |
| 398 we're called from string.Format routines, because it's handled | |
| 399 in that class by itself. */ | |
| 400 if (auto_number) { | |
| 401 /* Initialize our auto numbering state if this is the first | |
| 402 time we're either auto-numbering or manually numbering. */ | |
| 403 if (auto_number->an_state == ANS_INIT && using_numeric_index) | |
| 404 auto_number->an_state = field_name_is_empty ? | |
| 405 ANS_AUTO : ANS_MANUAL; | |
| 406 | |
| 407 /* Make sure our state is consistent with what we're doing | |
| 408 this time through. Only check if we're using a numeric | |
| 409 index. */ | |
| 410 if (using_numeric_index) | |
| 411 if (autonumber_state_error(auto_number->an_state, | |
| 412 field_name_is_empty)) | |
| 413 return 0; | |
| 414 /* Zero length field means we want to do auto-numbering of the | |
| 415 fields. */ | |
| 416 if (field_name_is_empty) | |
| 417 *first_idx = (auto_number->an_field_number)++; | |
| 418 } | |
| 419 | |
| 420 return 1; | |
| 421 } | |
| 422 | |
| 423 | |
| 424 /* | |
| 425 get_field_object returns the object inside {}, before the | |
| 426 format_spec. It handles getindex and getattr lookups and consumes | |
| 427 the entire input string. | |
| 428 */ | |
| 429 static PyObject * | |
| 430 get_field_object(SubString *input, PyObject *args, PyObject *kwargs, | |
| 431 AutoNumber *auto_number) | |
| 432 { | |
| 433 PyObject *obj = NULL; | |
| 434 int ok; | |
| 435 int is_attribute; | |
| 436 SubString name; | |
| 437 SubString first; | |
| 438 Py_ssize_t index; | |
| 439 FieldNameIterator rest; | |
| 440 | |
| 441 if (!field_name_split(input->str, input->start, input->end, &first, | |
| 442 &index, &rest, auto_number)) { | |
| 443 goto error; | |
| 444 } | |
| 445 | |
| 446 if (index == -1) { | |
| 447 /* look up in kwargs */ | |
| 448 PyObject *key = SubString_new_object(&first); | |
| 449 if (key == NULL) | |
| 450 goto error; | |
| 451 | |
| 452 /* Use PyObject_GetItem instead of PyDict_GetItem because this | |
| 453 code is no longer just used with kwargs. It might be passed | |
| 454 a non-dict when called through format_map. */ | |
| 455 if ((kwargs == NULL) || (obj = PyObject_GetItem(kwargs, key)) == NULL) { | |
| 456 PyErr_SetObject(PyExc_KeyError, key); | |
| 457 Py_DECREF(key); | |
| 458 goto error; | |
| 459 } | |
| 460 Py_DECREF(key); | |
| 461 } | |
| 462 else { | |
| 463 /* If args is NULL, we have a format string with a positional field | |
| 464 with only kwargs to retrieve it from. This can only happen when | |
| 465 used with format_map(), where positional arguments are not | |
| 466 allowed. */ | |
| 467 if (args == NULL) { | |
| 468 PyErr_SetString(PyExc_ValueError, "Format string contains " | |
| 469 "positional fields"); | |
| 470 goto error; | |
| 471 } | |
| 472 | |
| 473 /* look up in args */ | |
| 474 obj = PySequence_GetItem(args, index); | |
| 475 if (obj == NULL) | |
| 476 goto error; | |
| 477 } | |
| 478 | |
| 479 /* iterate over the rest of the field_name */ | |
| 480 while ((ok = FieldNameIterator_next(&rest, &is_attribute, &index, | |
| 481 &name)) == 2) { | |
| 482 PyObject *tmp; | |
| 483 | |
| 484 if (is_attribute) | |
| 485 /* getattr lookup "." */ | |
| 486 tmp = getattr(obj, &name); | |
| 487 else | |
| 488 /* getitem lookup "[]" */ | |
| 489 if (index == -1) | |
| 490 tmp = getitem_str(obj, &name); | |
| 491 else | |
| 492 if (PySequence_Check(obj)) | |
| 493 tmp = getitem_sequence(obj, index); | |
| 494 else | |
| 495 /* not a sequence */ | |
| 496 tmp = getitem_idx(obj, index); | |
| 497 if (tmp == NULL) | |
| 498 goto error; | |
| 499 | |
| 500 /* assign to obj */ | |
| 501 Py_DECREF(obj); | |
| 502 obj = tmp; | |
| 503 } | |
| 504 /* end of iterator, this is the non-error case */ | |
| 505 if (ok == 1) | |
| 506 return obj; | |
| 507 error: | |
| 508 Py_XDECREF(obj); | |
| 509 return NULL; | |
| 510 } | |
| 511 | |
| 512 /************************************************************************/ | |
| 513 /***************** Field rendering functions **************************/ | |
| 514 /************************************************************************/ | |
| 515 | |
| 516 /* | |
| 517 render_field() is the main function in this section. It takes the | |
| 518 field object and field specification string generated by | |
| 519 get_field_and_spec, and renders the field into the output string. | |
| 520 | |
| 521 render_field calls fieldobj.__format__(format_spec) method, and | |
| 522 appends to the output. | |
| 523 */ | |
| 524 static int | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
525 render_field(PyObject *fieldobj, SubString *format_spec, _PyAccu *acc) |
| 72475 | 526 { |
| 527 int ok = 0; | |
| 528 PyObject *result = NULL; | |
| 529 PyObject *format_spec_object = NULL; | |
| 530 PyObject *(*formatter)(PyObject *, PyObject *, Py_ssize_t, Py_ssize_t) = NULL; | |
| 531 | |
| 532 /* If we know the type exactly, skip the lookup of __format__ and just | |
| 533 call the formatter directly. */ | |
| 534 if (PyUnicode_CheckExact(fieldobj)) | |
| 535 formatter = _PyUnicode_FormatAdvanced; | |
| 536 else if (PyLong_CheckExact(fieldobj)) | |
| 537 formatter =_PyLong_FormatAdvanced; | |
| 538 else if (PyFloat_CheckExact(fieldobj)) | |
| 539 formatter = _PyFloat_FormatAdvanced; | |
| 540 | |
| 541 /* XXX: for 2.6, convert format_spec to the appropriate type | |
| 542 (unicode, str) */ | |
| 543 | |
| 544 if (formatter) { | |
| 545 /* we know exactly which formatter will be called when __format__ is | |
| 546 looked up, so call it directly, instead. */ | |
| 547 result = formatter(fieldobj, format_spec->str, | |
| 548 format_spec->start, format_spec->end); | |
| 549 } | |
| 550 else { | |
| 551 /* We need to create an object out of the pointers we have, because | |
| 552 __format__ takes a string/unicode object for format_spec. */ | |
| 553 if (format_spec->str) | |
| 554 format_spec_object = PyUnicode_Substring(format_spec->str, | |
| 555 format_spec->start, | |
| 556 format_spec->end); | |
| 557 else | |
| 558 format_spec_object = PyUnicode_New(0, 0); | |
| 559 if (format_spec_object == NULL) | |
| 560 goto done; | |
| 561 | |
| 562 result = PyObject_Format(fieldobj, format_spec_object); | |
| 563 } | |
| 564 if (result == NULL || PyUnicode_READY(result) == -1) | |
| 565 goto done; | |
| 566 | |
| 567 assert(PyUnicode_Check(result)); | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
568 ok = output_data(acc, result, 0, PyUnicode_GET_LENGTH(result)); |
| 72475 | 569 done: |
| 570 Py_XDECREF(format_spec_object); | |
| 571 Py_XDECREF(result); | |
| 572 return ok; | |
| 573 } | |
| 574 | |
| 575 static int | |
| 576 parse_field(SubString *str, SubString *field_name, SubString *format_spec, | |
| 577 Py_UCS4 *conversion) | |
| 578 { | |
| 579 /* Note this function works if the field name is zero length, | |
| 580 which is good. Zero length field names are handled later, in | |
| 581 field_name_split. */ | |
| 582 | |
| 583 Py_UCS4 c = 0; | |
| 584 | |
| 585 /* initialize these, as they may be empty */ | |
| 586 *conversion = '\0'; | |
| 587 SubString_init(format_spec, NULL, 0, 0); | |
| 588 | |
| 589 /* Search for the field name. it's terminated by the end of | |
| 590 the string, or a ':' or '!' */ | |
| 591 field_name->str = str->str; | |
| 592 field_name->start = str->start; | |
| 593 while (str->start < str->end) { | |
| 594 switch ((c = PyUnicode_READ_CHAR(str->str, str->start++))) { | |
| 595 case ':': | |
| 596 case '!': | |
| 597 break; | |
| 598 default: | |
| 599 continue; | |
| 600 } | |
| 601 break; | |
| 602 } | |
| 603 | |
| 604 if (c == '!' || c == ':') { | |
| 605 /* we have a format specifier and/or a conversion */ | |
| 606 /* don't include the last character */ | |
| 607 field_name->end = str->start-1; | |
| 608 | |
| 609 /* the format specifier is the rest of the string */ | |
| 610 format_spec->str = str->str; | |
| 611 format_spec->start = str->start; | |
| 612 format_spec->end = str->end; | |
| 613 | |
| 614 /* see if there's a conversion specifier */ | |
| 615 if (c == '!') { | |
| 616 /* there must be another character present */ | |
| 617 if (format_spec->start >= format_spec->end) { | |
| 618 PyErr_SetString(PyExc_ValueError, | |
| 619 "end of format while looking for conversion " | |
| 620 "specifier"); | |
| 621 return 0; | |
| 622 } | |
| 623 *conversion = PyUnicode_READ_CHAR(format_spec->str, format_spec->start++); | |
| 624 | |
| 625 /* if there is another character, it must be a colon */ | |
| 626 if (format_spec->start < format_spec->end) { | |
| 627 c = PyUnicode_READ_CHAR(format_spec->str, format_spec->start++); | |
| 628 if (c != ':') { | |
| 629 PyErr_SetString(PyExc_ValueError, | |
| 630 "expected ':' after format specifier"); | |
| 631 return 0; | |
| 632 } | |
| 633 } | |
| 634 } | |
| 635 } | |
| 636 else | |
| 637 /* end of string, there's no format_spec or conversion */ | |
| 638 field_name->end = str->start; | |
| 639 | |
| 640 return 1; | |
| 641 } | |
| 642 | |
| 643 /************************************************************************/ | |
| 644 /******* Output string allocation and escape-to-markup processing ******/ | |
| 645 /************************************************************************/ | |
| 646 | |
| 647 /* MarkupIterator breaks the string into pieces of either literal | |
| 648 text, or things inside {} that need to be marked up. it is | |
| 649 designed to make it easy to wrap a Python iterator around it, for | |
| 650 use with the Formatter class */ | |
| 651 | |
| 652 typedef struct { | |
| 653 SubString str; | |
| 654 } MarkupIterator; | |
| 655 | |
| 656 static int | |
| 657 MarkupIterator_init(MarkupIterator *self, PyObject *str, | |
| 658 Py_ssize_t start, Py_ssize_t end) | |
| 659 { | |
| 660 SubString_init(&self->str, str, start, end); | |
| 661 return 1; | |
| 662 } | |
| 663 | |
| 664 /* returns 0 on error, 1 on non-error termination, and 2 if it got a | |
| 665 string (or something to be expanded) */ | |
| 666 static int | |
| 667 MarkupIterator_next(MarkupIterator *self, SubString *literal, | |
| 668 int *field_present, SubString *field_name, | |
| 669 SubString *format_spec, Py_UCS4 *conversion, | |
| 670 int *format_spec_needs_expanding) | |
| 671 { | |
| 672 int at_end; | |
| 673 Py_UCS4 c = 0; | |
| 674 Py_ssize_t start; | |
| 675 int count; | |
| 676 Py_ssize_t len; | |
| 677 int markup_follows = 0; | |
| 678 | |
| 679 /* initialize all of the output variables */ | |
| 680 SubString_init(literal, NULL, 0, 0); | |
| 681 SubString_init(field_name, NULL, 0, 0); | |
| 682 SubString_init(format_spec, NULL, 0, 0); | |
| 683 *conversion = '\0'; | |
| 684 *format_spec_needs_expanding = 0; | |
| 685 *field_present = 0; | |
| 686 | |
| 687 /* No more input, end of iterator. This is the normal exit | |
| 688 path. */ | |
| 689 if (self->str.start >= self->str.end) | |
| 690 return 1; | |
| 691 | |
| 692 start = self->str.start; | |
| 693 | |
| 694 /* First read any literal text. Read until the end of string, an | |
| 695 escaped '{' or '}', or an unescaped '{'. In order to never | |
| 696 allocate memory and so I can just pass pointers around, if | |
| 697 there's an escaped '{' or '}' then we'll return the literal | |
| 698 including the brace, but no format object. The next time | |
| 699 through, we'll return the rest of the literal, skipping past | |
| 700 the second consecutive brace. */ | |
| 701 while (self->str.start < self->str.end) { | |
| 702 switch (c = PyUnicode_READ_CHAR(self->str.str, self->str.start++)) { | |
| 703 case '{': | |
| 704 case '}': | |
| 705 markup_follows = 1; | |
| 706 break; | |
| 707 default: | |
| 708 continue; | |
| 709 } | |
| 710 break; | |
| 711 } | |
| 712 | |
| 713 at_end = self->str.start >= self->str.end; | |
| 714 len = self->str.start - start; | |
| 715 | |
| 716 if ((c == '}') && (at_end || | |
| 717 (c != PyUnicode_READ_CHAR(self->str.str, | |
| 718 self->str.start)))) { | |
| 719 PyErr_SetString(PyExc_ValueError, "Single '}' encountered " | |
| 720 "in format string"); | |
| 721 return 0; | |
| 722 } | |
| 723 if (at_end && c == '{') { | |
| 724 PyErr_SetString(PyExc_ValueError, "Single '{' encountered " | |
| 725 "in format string"); | |
| 726 return 0; | |
| 727 } | |
| 728 if (!at_end) { | |
| 729 if (c == PyUnicode_READ_CHAR(self->str.str, self->str.start)) { | |
| 730 /* escaped } or {, skip it in the input. there is no | |
| 731 markup object following us, just this literal text */ | |
| 732 self->str.start++; | |
| 733 markup_follows = 0; | |
| 734 } | |
| 735 else | |
| 736 len--; | |
| 737 } | |
| 738 | |
| 739 /* record the literal text */ | |
| 740 literal->str = self->str.str; | |
| 741 literal->start = start; | |
| 742 literal->end = start + len; | |
| 743 | |
| 744 if (!markup_follows) | |
| 745 return 2; | |
| 746 | |
| 747 /* this is markup, find the end of the string by counting nested | |
| 748 braces. note that this prohibits escaped braces, so that | |
| 749 format_specs cannot have braces in them. */ | |
| 750 *field_present = 1; | |
| 751 count = 1; | |
| 752 | |
| 753 start = self->str.start; | |
| 754 | |
| 755 /* we know we can't have a zero length string, so don't worry | |
| 756 about that case */ | |
| 757 while (self->str.start < self->str.end) { | |
| 758 switch (c = PyUnicode_READ_CHAR(self->str.str, self->str.start++)) { | |
| 759 case '{': | |
| 760 /* the format spec needs to be recursively expanded. | |
| 761 this is an optimization, and not strictly needed */ | |
| 762 *format_spec_needs_expanding = 1; | |
| 763 count++; | |
| 764 break; | |
| 765 case '}': | |
| 766 count--; | |
| 767 if (count <= 0) { | |
| 768 /* we're done. parse and get out */ | |
| 769 SubString s; | |
| 770 | |
| 771 SubString_init(&s, self->str.str, start, self->str.start - 1); | |
| 772 if (parse_field(&s, field_name, format_spec, conversion) == 0) | |
| 773 return 0; | |
| 774 | |
| 775 /* success */ | |
| 776 return 2; | |
| 777 } | |
| 778 break; | |
| 779 } | |
| 780 } | |
| 781 | |
| 782 /* end of string while searching for matching '}' */ | |
| 783 PyErr_SetString(PyExc_ValueError, "unmatched '{' in format"); | |
| 784 return 0; | |
| 785 } | |
| 786 | |
| 787 | |
| 788 /* do the !r or !s conversion on obj */ | |
| 789 static PyObject * | |
| 790 do_conversion(PyObject *obj, Py_UCS4 conversion) | |
| 791 { | |
| 792 /* XXX in pre-3.0, do we need to convert this to unicode, since it | |
| 793 might have returned a string? */ | |
| 794 switch (conversion) { | |
| 795 case 'r': | |
| 796 return PyObject_Repr(obj); | |
| 797 case 's': | |
| 798 return PyObject_Str(obj); | |
| 799 case 'a': | |
| 800 return PyObject_ASCII(obj); | |
| 801 default: | |
| 802 if (conversion > 32 && conversion < 127) { | |
| 803 /* It's the ASCII subrange; casting to char is safe | |
| 804 (assuming the execution character set is an ASCII | |
| 805 superset). */ | |
| 806 PyErr_Format(PyExc_ValueError, | |
| 807 "Unknown conversion specifier %c", | |
| 808 (char)conversion); | |
| 809 } else | |
| 810 PyErr_Format(PyExc_ValueError, | |
| 811 "Unknown conversion specifier \\x%x", | |
| 812 (unsigned int)conversion); | |
| 813 return NULL; | |
| 814 } | |
| 815 } | |
| 816 | |
| 817 /* given: | |
| 818 | |
| 819 {field_name!conversion:format_spec} | |
| 820 | |
| 821 compute the result and write it to output. | |
| 822 format_spec_needs_expanding is an optimization. if it's false, | |
| 823 just output the string directly, otherwise recursively expand the | |
| 824 format_spec string. | |
| 825 | |
| 826 field_name is allowed to be zero length, in which case we | |
| 827 are doing auto field numbering. | |
| 828 */ | |
| 829 | |
| 830 static int | |
| 831 output_markup(SubString *field_name, SubString *format_spec, | |
| 832 int format_spec_needs_expanding, Py_UCS4 conversion, | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
833 _PyAccu *acc, PyObject *args, PyObject *kwargs, |
| 72475 | 834 int recursion_depth, AutoNumber *auto_number) |
| 835 { | |
| 836 PyObject *tmp = NULL; | |
| 837 PyObject *fieldobj = NULL; | |
| 838 SubString expanded_format_spec; | |
| 839 SubString *actual_format_spec; | |
| 840 int result = 0; | |
| 841 | |
| 842 /* convert field_name to an object */ | |
| 843 fieldobj = get_field_object(field_name, args, kwargs, auto_number); | |
| 844 if (fieldobj == NULL) | |
| 845 goto done; | |
| 846 | |
| 847 if (conversion != '\0') { | |
| 848 tmp = do_conversion(fieldobj, conversion); | |
| 849 if (tmp == NULL || PyUnicode_READY(tmp) == -1) | |
| 850 goto done; | |
| 851 | |
| 852 /* do the assignment, transferring ownership: fieldobj = tmp */ | |
| 853 Py_DECREF(fieldobj); | |
| 854 fieldobj = tmp; | |
| 855 tmp = NULL; | |
| 856 } | |
| 857 | |
| 858 /* if needed, recurively compute the format_spec */ | |
| 859 if (format_spec_needs_expanding) { | |
| 860 tmp = build_string(format_spec, args, kwargs, recursion_depth-1, | |
| 861 auto_number); | |
| 862 if (tmp == NULL || PyUnicode_READY(tmp) == -1) | |
| 863 goto done; | |
| 864 | |
| 865 /* note that in the case we're expanding the format string, | |
| 866 tmp must be kept around until after the call to | |
| 867 render_field. */ | |
| 868 SubString_init(&expanded_format_spec, tmp, 0, PyUnicode_GET_LENGTH(tmp)); | |
| 869 actual_format_spec = &expanded_format_spec; | |
| 870 } | |
| 871 else | |
| 872 actual_format_spec = format_spec; | |
| 873 | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
874 if (render_field(fieldobj, actual_format_spec, acc) == 0) |
| 72475 | 875 goto done; |
| 876 | |
| 877 result = 1; | |
| 878 | |
| 879 done: | |
| 880 Py_XDECREF(fieldobj); | |
| 881 Py_XDECREF(tmp); | |
| 882 | |
| 883 return result; | |
| 884 } | |
| 885 | |
| 886 /* | |
| 887 do_markup is the top-level loop for the format() method. It | |
| 888 searches through the format string for escapes to markup codes, and | |
| 889 calls other functions to move non-markup text to the output, | |
| 890 and to perform the markup to the output. | |
| 891 */ | |
| 892 static int | |
| 893 do_markup(SubString *input, PyObject *args, PyObject *kwargs, | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
894 _PyAccu *acc, int recursion_depth, AutoNumber *auto_number) |
| 72475 | 895 { |
| 896 MarkupIterator iter; | |
| 897 int format_spec_needs_expanding; | |
| 898 int result; | |
| 899 int field_present; | |
| 900 SubString literal; | |
| 901 SubString field_name; | |
| 902 SubString format_spec; | |
| 903 Py_UCS4 conversion; | |
| 904 | |
| 905 MarkupIterator_init(&iter, input->str, input->start, input->end); | |
| 906 while ((result = MarkupIterator_next(&iter, &literal, &field_present, | |
| 907 &field_name, &format_spec, | |
| 908 &conversion, | |
| 909 &format_spec_needs_expanding)) == 2) { | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
910 if (!output_data(acc, literal.str, literal.start, literal.end)) |
| 72475 | 911 return 0; |
| 912 if (field_present) | |
| 913 if (!output_markup(&field_name, &format_spec, | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
914 format_spec_needs_expanding, conversion, acc, |
| 72475 | 915 args, kwargs, recursion_depth, auto_number)) |
| 916 return 0; | |
| 917 } | |
| 918 return result; | |
| 919 } | |
| 920 | |
| 921 | |
| 922 /* | |
| 923 build_string allocates the output string and then | |
| 924 calls do_markup to do the heavy lifting. | |
| 925 */ | |
| 926 static PyObject * | |
| 927 build_string(SubString *input, PyObject *args, PyObject *kwargs, | |
| 928 int recursion_depth, AutoNumber *auto_number) | |
| 929 { | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
930 _PyAccu acc; |
| 72475 | 931 |
| 932 /* check the recursion level */ | |
| 933 if (recursion_depth <= 0) { | |
| 934 PyErr_SetString(PyExc_ValueError, | |
| 935 "Max string recursion exceeded"); | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
936 return NULL; |
| 72475 | 937 } |
| 938 | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
939 if (_PyAccu_Init(&acc)) |
|
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
940 return NULL; |
| 72475 | 941 |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
942 if (!do_markup(input, args, kwargs, &acc, recursion_depth, |
| 72475 | 943 auto_number)) { |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
944 _PyAccu_Destroy(&acc); |
|
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
945 return NULL; |
| 72475 | 946 } |
| 947 | |
|
72780
d49be9b017a2
Fix massive slowdown in string formatting with str.format.
Antoine Pitrou <solipsis@pitrou.net>
parents:
72750
diff
changeset
|
948 return _PyAccu_Finish(&acc); |
| 72475 | 949 } |
| 950 | |
| 951 /************************************************************************/ | |
| 952 /*********** main routine ***********************************************/ | |
| 953 /************************************************************************/ | |
| 954 | |
| 955 /* this is the main entry point */ | |
| 956 static PyObject * | |
| 957 do_string_format(PyObject *self, PyObject *args, PyObject *kwargs) | |
| 958 { | |
| 959 SubString input; | |
| 960 | |
| 961 /* PEP 3101 says only 2 levels, so that | |
| 962 "{0:{1}}".format('abc', 's') # works | |
| 963 "{0:{1:{2}}}".format('abc', 's', '') # fails | |
| 964 */ | |
| 965 int recursion_depth = 2; | |
| 966 | |
| 967 AutoNumber auto_number; | |
| 968 | |
| 969 if (PyUnicode_READY(self) == -1) | |
| 970 return NULL; | |
| 971 | |
| 972 AutoNumber_Init(&auto_number); | |
| 973 SubString_init(&input, self, 0, PyUnicode_GET_LENGTH(self)); | |
| 974 return build_string(&input, args, kwargs, recursion_depth, &auto_number); | |
| 975 } | |
| 976 | |
| 977 static PyObject * | |
| 978 do_string_format_map(PyObject *self, PyObject *obj) | |
| 979 { | |
| 980 return do_string_format(self, NULL, obj); | |
| 981 } | |
| 982 | |
| 983 | |
| 984 /************************************************************************/ | |
| 985 /*********** formatteriterator ******************************************/ | |
| 986 /************************************************************************/ | |
| 987 | |
| 988 /* This is used to implement string.Formatter.vparse(). It exists so | |
| 989 Formatter can share code with the built in unicode.format() method. | |
| 990 It's really just a wrapper around MarkupIterator that is callable | |
| 991 from Python. */ | |
| 992 | |
| 993 typedef struct { | |
| 994 PyObject_HEAD | |
| 995 | |
| 996 PyUnicodeObject *str; | |
| 997 | |
| 998 MarkupIterator it_markup; | |
| 999 } formatteriterobject; | |
| 1000 | |
| 1001 static void | |
| 1002 formatteriter_dealloc(formatteriterobject *it) | |
| 1003 { | |
| 1004 Py_XDECREF(it->str); | |
| 1005 PyObject_FREE(it); | |
| 1006 } | |
| 1007 | |
| 1008 /* returns a tuple: | |
| 1009 (literal, field_name, format_spec, conversion) | |
| 1010 | |
| 1011 literal is any literal text to output. might be zero length | |
| 1012 field_name is the string before the ':'. might be None | |
| 1013 format_spec is the string after the ':'. mibht be None | |
| 1014 conversion is either None, or the string after the '!' | |
| 1015 */ | |
| 1016 static PyObject * | |
| 1017 formatteriter_next(formatteriterobject *it) | |
| 1018 { | |
| 1019 SubString literal; | |
| 1020 SubString field_name; | |
| 1021 SubString format_spec; | |
| 1022 Py_UCS4 conversion; | |
| 1023 int format_spec_needs_expanding; | |
| 1024 int field_present; | |
| 1025 int result = MarkupIterator_next(&it->it_markup, &literal, &field_present, | |
| 1026 &field_name, &format_spec, &conversion, | |
| 1027 &format_spec_needs_expanding); | |
| 1028 | |
| 1029 /* all of the SubString objects point into it->str, so no | |
| 1030 memory management needs to be done on them */ | |
| 1031 assert(0 <= result && result <= 2); | |
| 1032 if (result == 0 || result == 1) | |
| 1033 /* if 0, error has already been set, if 1, iterator is empty */ | |
| 1034 return NULL; | |
| 1035 else { | |
| 1036 PyObject *literal_str = NULL; | |
| 1037 PyObject *field_name_str = NULL; | |
| 1038 PyObject *format_spec_str = NULL; | |
| 1039 PyObject *conversion_str = NULL; | |
| 1040 PyObject *tuple = NULL; | |
| 1041 | |
| 1042 literal_str = SubString_new_object(&literal); | |
| 1043 if (literal_str == NULL) | |
| 1044 goto done; | |
| 1045 | |
| 1046 field_name_str = SubString_new_object(&field_name); | |
| 1047 if (field_name_str == NULL) | |
| 1048 goto done; | |
| 1049 | |
| 1050 /* if field_name is non-zero length, return a string for | |
| 1051 format_spec (even if zero length), else return None */ | |
| 1052 format_spec_str = (field_present ? | |
| 1053 SubString_new_object_or_empty : | |
| 1054 SubString_new_object)(&format_spec); | |
| 1055 if (format_spec_str == NULL) | |
| 1056 goto done; | |
| 1057 | |
| 1058 /* if the conversion is not specified, return a None, | |
| 1059 otherwise create a one length string with the conversion | |
| 1060 character */ | |
| 1061 if (conversion == '\0') { | |
| 1062 conversion_str = Py_None; | |
| 1063 Py_INCREF(conversion_str); | |
| 1064 } | |
| 1065 else | |
| 1066 conversion_str = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND, | |
| 1067 &conversion, 1); | |
| 1068 if (conversion_str == NULL) | |
| 1069 goto done; | |
| 1070 | |
| 1071 tuple = PyTuple_Pack(4, literal_str, field_name_str, format_spec_str, | |
| 1072 conversion_str); | |
| 1073 done: | |
| 1074 Py_XDECREF(literal_str); | |
| 1075 Py_XDECREF(field_name_str); | |
| 1076 Py_XDECREF(format_spec_str); | |
| 1077 Py_XDECREF(conversion_str); | |
| 1078 return tuple; | |
| 1079 } | |
| 1080 } | |
| 1081 | |
| 1082 static PyMethodDef formatteriter_methods[] = { | |
| 1083 {NULL, NULL} /* sentinel */ | |
| 1084 }; | |
| 1085 | |
| 1086 static PyTypeObject PyFormatterIter_Type = { | |
| 1087 PyVarObject_HEAD_INIT(&PyType_Type, 0) | |
| 1088 "formatteriterator", /* tp_name */ | |
| 1089 sizeof(formatteriterobject), /* tp_basicsize */ | |
| 1090 0, /* tp_itemsize */ | |
| 1091 /* methods */ | |
| 1092 (destructor)formatteriter_dealloc, /* tp_dealloc */ | |
| 1093 0, /* tp_print */ | |
| 1094 0, /* tp_getattr */ | |
| 1095 0, /* tp_setattr */ | |
| 1096 0, /* tp_reserved */ | |
| 1097 0, /* tp_repr */ | |
| 1098 0, /* tp_as_number */ | |
| 1099 0, /* tp_as_sequence */ | |
| 1100 0, /* tp_as_mapping */ | |
| 1101 0, /* tp_hash */ | |
| 1102 0, /* tp_call */ | |
| 1103 0, /* tp_str */ | |
| 1104 PyObject_GenericGetAttr, /* tp_getattro */ | |
| 1105 0, /* tp_setattro */ | |
| 1106 0, /* tp_as_buffer */ | |
| 1107 Py_TPFLAGS_DEFAULT, /* tp_flags */ | |
| 1108 0, /* tp_doc */ | |
| 1109 0, /* tp_traverse */ | |
| 1110 0, /* tp_clear */ | |
| 1111 0, /* tp_richcompare */ | |
| 1112 0, /* tp_weaklistoffset */ | |
| 1113 PyObject_SelfIter, /* tp_iter */ | |
| 1114 (iternextfunc)formatteriter_next, /* tp_iternext */ | |
| 1115 formatteriter_methods, /* tp_methods */ | |
| 1116 0, | |
| 1117 }; | |
| 1118 | |
| 1119 /* unicode_formatter_parser is used to implement | |
| 1120 string.Formatter.vformat. it parses a string and returns tuples | |
| 1121 describing the parsed elements. It's a wrapper around | |
| 1122 stringlib/string_format.h's MarkupIterator */ | |
| 1123 static PyObject * | |
| 1124 formatter_parser(PyObject *ignored, PyUnicodeObject *self) | |
| 1125 { | |
| 1126 formatteriterobject *it; | |
| 1127 | |
| 1128 if (!PyUnicode_Check(self)) { | |
| 1129 PyErr_Format(PyExc_TypeError, "expected str, got %s", Py_TYPE(self)->tp_name); | |
| 1130 return NULL; | |
| 1131 } | |
| 1132 | |
| 1133 if (PyUnicode_READY(self) == -1) | |
| 1134 return NULL; | |
| 1135 | |
| 1136 it = PyObject_New(formatteriterobject, &PyFormatterIter_Type); | |
| 1137 if (it == NULL) | |
| 1138 return NULL; | |
| 1139 | |
| 1140 /* take ownership, give the object to the iterator */ | |
| 1141 Py_INCREF(self); | |
| 1142 it->str = self; | |
| 1143 | |
| 1144 /* initialize the contained MarkupIterator */ | |
| 1145 MarkupIterator_init(&it->it_markup, (PyObject*)self, 0, PyUnicode_GET_LENGTH(self)); | |
| 1146 return (PyObject *)it; | |
| 1147 } | |
| 1148 | |
| 1149 | |
| 1150 /************************************************************************/ | |
| 1151 /*********** fieldnameiterator ******************************************/ | |
| 1152 /************************************************************************/ | |
| 1153 | |
| 1154 | |
| 1155 /* This is used to implement string.Formatter.vparse(). It parses the | |
| 1156 field name into attribute and item values. It's a Python-callable | |
| 1157 wrapper around FieldNameIterator */ | |
| 1158 | |
| 1159 typedef struct { | |
| 1160 PyObject_HEAD | |
| 1161 | |
| 1162 PyUnicodeObject *str; | |
| 1163 | |
| 1164 FieldNameIterator it_field; | |
| 1165 } fieldnameiterobject; | |
| 1166 | |
| 1167 static void | |
| 1168 fieldnameiter_dealloc(fieldnameiterobject *it) | |
| 1169 { | |
| 1170 Py_XDECREF(it->str); | |
| 1171 PyObject_FREE(it); | |
| 1172 } | |
| 1173 | |
| 1174 /* returns a tuple: | |
| 1175 (is_attr, value) | |
| 1176 is_attr is true if we used attribute syntax (e.g., '.foo') | |
| 1177 false if we used index syntax (e.g., '[foo]') | |
| 1178 value is an integer or string | |
| 1179 */ | |
| 1180 static PyObject * | |
| 1181 fieldnameiter_next(fieldnameiterobject *it) | |
| 1182 { | |
| 1183 int result; | |
| 1184 int is_attr; | |
| 1185 Py_ssize_t idx; | |
| 1186 SubString name; | |
| 1187 | |
| 1188 result = FieldNameIterator_next(&it->it_field, &is_attr, | |
| 1189 &idx, &name); | |
| 1190 if (result == 0 || result == 1) | |
| 1191 /* if 0, error has already been set, if 1, iterator is empty */ | |
| 1192 return NULL; | |
| 1193 else { | |
| 1194 PyObject* result = NULL; | |
| 1195 PyObject* is_attr_obj = NULL; | |
| 1196 PyObject* obj = NULL; | |
| 1197 | |
| 1198 is_attr_obj = PyBool_FromLong(is_attr); | |
| 1199 if (is_attr_obj == NULL) | |
| 1200 goto done; | |
| 1201 | |
| 1202 /* either an integer or a string */ | |
| 1203 if (idx != -1) | |
| 1204 obj = PyLong_FromSsize_t(idx); | |
| 1205 else | |
| 1206 obj = SubString_new_object(&name); | |
| 1207 if (obj == NULL) | |
| 1208 goto done; | |
| 1209 | |
| 1210 /* return a tuple of values */ | |
| 1211 result = PyTuple_Pack(2, is_attr_obj, obj); | |
| 1212 | |
| 1213 done: | |
| 1214 Py_XDECREF(is_attr_obj); | |
| 1215 Py_XDECREF(obj); | |
| 1216 return result; | |
| 1217 } | |
| 1218 } | |
| 1219 | |
| 1220 static PyMethodDef fieldnameiter_methods[] = { | |
| 1221 {NULL, NULL} /* sentinel */ | |
| 1222 }; | |
| 1223 | |
| 1224 static PyTypeObject PyFieldNameIter_Type = { | |
| 1225 PyVarObject_HEAD_INIT(&PyType_Type, 0) | |
| 1226 "fieldnameiterator", /* tp_name */ | |
| 1227 sizeof(fieldnameiterobject), /* tp_basicsize */ | |
| 1228 0, /* tp_itemsize */ | |
| 1229 /* methods */ | |
| 1230 (destructor)fieldnameiter_dealloc, /* tp_dealloc */ | |
| 1231 0, /* tp_print */ | |
| 1232 0, /* tp_getattr */ | |
| 1233 0, /* tp_setattr */ | |
| 1234 0, /* tp_reserved */ | |
| 1235 0, /* tp_repr */ | |
| 1236 0, /* tp_as_number */ | |
| 1237 0, /* tp_as_sequence */ | |
| 1238 0, /* tp_as_mapping */ | |
| 1239 0, /* tp_hash */ | |
| 1240 0, /* tp_call */ | |
| 1241 0, /* tp_str */ | |
| 1242 PyObject_GenericGetAttr, /* tp_getattro */ | |
| 1243 0, /* tp_setattro */ | |
| 1244 0, /* tp_as_buffer */ | |
| 1245 Py_TPFLAGS_DEFAULT, /* tp_flags */ | |
| 1246 0, /* tp_doc */ | |
| 1247 0, /* tp_traverse */ | |
| 1248 0, /* tp_clear */ | |
| 1249 0, /* tp_richcompare */ | |
| 1250 0, /* tp_weaklistoffset */ | |
| 1251 PyObject_SelfIter, /* tp_iter */ | |
| 1252 (iternextfunc)fieldnameiter_next, /* tp_iternext */ | |
| 1253 fieldnameiter_methods, /* tp_methods */ | |
| 1254 0}; | |
| 1255 | |
| 1256 /* unicode_formatter_field_name_split is used to implement | |
| 1257 string.Formatter.vformat. it takes an PEP 3101 "field name", and | |
| 1258 returns a tuple of (first, rest): "first", the part before the | |
| 1259 first '.' or '['; and "rest", an iterator for the rest of the field | |
| 1260 name. it's a wrapper around stringlib/string_format.h's | |
| 1261 field_name_split. The iterator it returns is a | |
| 1262 FieldNameIterator */ | |
| 1263 static PyObject * | |
| 1264 formatter_field_name_split(PyObject *ignored, PyUnicodeObject *self) | |
| 1265 { | |
| 1266 SubString first; | |
| 1267 Py_ssize_t first_idx; | |
| 1268 fieldnameiterobject *it; | |
| 1269 | |
| 1270 PyObject *first_obj = NULL; | |
| 1271 PyObject *result = NULL; | |
| 1272 | |
| 1273 if (!PyUnicode_Check(self)) { | |
| 1274 PyErr_Format(PyExc_TypeError, "expected str, got %s", Py_TYPE(self)->tp_name); | |
| 1275 return NULL; | |
| 1276 } | |
| 1277 | |
| 1278 if (PyUnicode_READY(self) == -1) | |
| 1279 return NULL; | |
| 1280 | |
| 1281 it = PyObject_New(fieldnameiterobject, &PyFieldNameIter_Type); | |
| 1282 if (it == NULL) | |
| 1283 return NULL; | |
| 1284 | |
| 1285 /* take ownership, give the object to the iterator. this is | |
| 1286 just to keep the field_name alive */ | |
| 1287 Py_INCREF(self); | |
| 1288 it->str = self; | |
| 1289 | |
| 1290 /* Pass in auto_number = NULL. We'll return an empty string for | |
| 1291 first_obj in that case. */ | |
| 1292 if (!field_name_split((PyObject*)self, 0, PyUnicode_GET_LENGTH(self), | |
| 1293 &first, &first_idx, &it->it_field, NULL)) | |
| 1294 goto done; | |
| 1295 | |
| 1296 /* first becomes an integer, if possible; else a string */ | |
| 1297 if (first_idx != -1) | |
| 1298 first_obj = PyLong_FromSsize_t(first_idx); | |
| 1299 else | |
| 1300 /* convert "first" into a string object */ | |
| 1301 first_obj = SubString_new_object(&first); | |
| 1302 if (first_obj == NULL) | |
| 1303 goto done; | |
| 1304 | |
| 1305 /* return a tuple of values */ | |
| 1306 result = PyTuple_Pack(2, first_obj, it); | |
| 1307 | |
| 1308 done: | |
| 1309 Py_XDECREF(it); | |
| 1310 Py_XDECREF(first_obj); | |
| 1311 return result; | |
| 1312 } |
