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