LCOV - code coverage report
Current view: | top level - Objects/stringlib - unicode_format.h (source / functions) |  |  | Hit | Total | Coverage
Test: | CPython 3.12 LCOV report [commit 5e6661bce9] |  | Lines: | 197 | 494 | 39.9 %
Date: | 2023-03-20 08:15:36 |  | Functions: | 18 | 32 | 56.2 %
|  |  | Branches: | 105 | 266 | 39.5 %

               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                 :            : }

Generated by: LCOV version 1.14