153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*
253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    string_format.h -- implementation of string.format().
353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    It uses the Objects/stringlib conventions, so that it can be
553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    compiled for both unicode and string objects.
653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* Defines for Python 2.6 compatibility */
1053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#if PY_VERSION_HEX < 0x03000000
1153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#define PyLong_FromSsize_t _PyLong_FromSsize_t
1253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#endif
1353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
1453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* Defines for more efficiently reallocating the string buffer */
1553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#define INITIAL_SIZE_INCREMENT 100
1653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#define SIZE_MULTIPLIER 2
1753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#define MAX_SIZE_INCREMENT  3200
1853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
1953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
2053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
2153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/***********   Global data structures and forward declarations  *********/
2253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
2353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
2453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*
2553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   A SubString consists of the characters between two string or
2653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   unicode pointers.
2753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
2853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieltypedef struct {
2953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR *ptr;
3053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR *end;
3153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel} SubString;
3253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
3353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
3453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieltypedef enum {
3553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    ANS_INIT,
3653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    ANS_AUTO,
3753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    ANS_MANUAL
3853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel} AutoNumberState;   /* Keep track if we're auto-numbering fields */
3953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
4053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* Keeps track of our auto-numbering state, and which number field we're on */
4153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieltypedef struct {
4253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    AutoNumberState an_state;
4353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int an_field_number;
4453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel} AutoNumber;
4553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
4653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
4753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* forward declaration for recursion */
4853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
4953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielbuild_string(SubString *input, PyObject *args, PyObject *kwargs,
5053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel             int recursion_depth, AutoNumber *auto_number);
5153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
5253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
5353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
5453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
5553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/**************************  Utility  functions  ************************/
5653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
5753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
5853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic void
5953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielAutoNumber_Init(AutoNumber *auto_number)
6053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
6153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    auto_number->an_state = ANS_INIT;
6253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    auto_number->an_field_number = 0;
6353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
6453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
6553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* fill in a SubString from a pointer and length */
6653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPy_LOCAL_INLINE(void)
6753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielSubString_init(SubString *str, STRINGLIB_CHAR *p, Py_ssize_t len)
6853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
6953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    str->ptr = p;
7053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (p == NULL)
7153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        str->end = NULL;
7253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else
7353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        str->end = str->ptr + len;
7453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
7553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
7653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* return a new string.  if str->ptr is NULL, return None */
7753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPy_LOCAL_INLINE(PyObject *)
7853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielSubString_new_object(SubString *str)
7953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
8053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (str->ptr == NULL) {
8153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_INCREF(Py_None);
8253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return Py_None;
8353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
8453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return STRINGLIB_NEW(str->ptr, str->end - str->ptr);
8553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
8653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
8753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* return a new string.  if str->ptr is NULL, return None */
8853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielPy_LOCAL_INLINE(PyObject *)
8953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielSubString_new_object_or_empty(SubString *str)
9053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
9153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (str->ptr == NULL) {
9253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return STRINGLIB_NEW(NULL, 0);
9353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
9453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return STRINGLIB_NEW(str->ptr, str->end - str->ptr);
9553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
9653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
9753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* Return 1 if an error has been detected switching between automatic
9853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   field numbering and manual field specification, else return 0. Set
9953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   ValueError on error. */
10053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
10153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielautonumber_state_error(AutoNumberState state, int field_name_is_empty)
10253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
10353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (state == ANS_MANUAL) {
10453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (field_name_is_empty) {
10553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            PyErr_SetString(PyExc_ValueError, "cannot switch from "
10653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                            "manual field specification to "
10753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                            "automatic field numbering");
10853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            return 1;
10953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
11053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
11153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else {
11253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (!field_name_is_empty) {
11353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            PyErr_SetString(PyExc_ValueError, "cannot switch from "
11453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                            "automatic field numbering to "
11553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                            "manual field specification");
11653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            return 1;
11753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
11853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
11953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 0;
12053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
12153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
12253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
12353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
12453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/***********    Output string management functions       ****************/
12553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
12653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
12753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieltypedef struct {
12853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR *ptr;
12953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR *end;
13053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *obj;
13153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t size_increment;
13253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel} OutputString;
13353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
13453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* initialize an OutputString object, reserving size characters */
13553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
13653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieloutput_initialize(OutputString *output, Py_ssize_t size)
13753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
13853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output->obj = STRINGLIB_NEW(NULL, size);
13953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (output->obj == NULL)
14053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 0;
14153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
14253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output->ptr = STRINGLIB_STR(output->obj);
14353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output->end = STRINGLIB_LEN(output->obj) + output->ptr;
14453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output->size_increment = INITIAL_SIZE_INCREMENT;
14553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
14653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 1;
14753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
14853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
14953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*
15053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output_extend reallocates the output string buffer.
15153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    It returns a status:  0 for a failed reallocation,
15253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    1 for success.
15353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
15453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
15553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
15653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieloutput_extend(OutputString *output, Py_ssize_t count)
15753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
15853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR *startptr = STRINGLIB_STR(output->obj);
15953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t curlen = output->ptr - startptr;
16053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t maxlen = curlen + count + output->size_increment;
16153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
16253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (STRINGLIB_RESIZE(&output->obj, maxlen) < 0)
16353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 0;
16453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    startptr = STRINGLIB_STR(output->obj);
16553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output->ptr = startptr + curlen;
16653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output->end = startptr + maxlen;
16753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (output->size_increment < MAX_SIZE_INCREMENT)
16853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        output->size_increment *= SIZE_MULTIPLIER;
16953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 1;
17053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
17153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
17253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*
17353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output_data dumps characters into our output string
17453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    buffer.
17553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
17653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    In some cases, it has to reallocate the string.
17753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
17853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    It returns a status:  0 for a failed reallocation,
17953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    1 for success.
18053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
18153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
18253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieloutput_data(OutputString *output, const STRINGLIB_CHAR *s, Py_ssize_t count)
18353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
18453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if ((count > output->end - output->ptr) && !output_extend(output, count))
18553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 0;
18653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    memcpy(output->ptr, s, count * sizeof(STRINGLIB_CHAR));
18753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output->ptr += count;
18853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 1;
18953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
19053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
19153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
19253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/***********  Format string parsing -- integers and identifiers *********/
19353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
19453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
19553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic Py_ssize_t
19653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielget_integer(const SubString *str)
19753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
19853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t accumulator = 0;
19953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t digitval;
20053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR *p;
20153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
20253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* empty string is an error */
20353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (str->ptr >= str->end)
20453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return -1;
20553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
20653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    for (p = str->ptr; p < str->end; p++) {
20753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        digitval = STRINGLIB_TODECIMAL(*p);
20853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (digitval < 0)
20953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            return -1;
21053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /*
21153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           Detect possible overflow before it happens:
21253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
21353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel              accumulator * 10 + digitval > PY_SSIZE_T_MAX if and only if
21453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel              accumulator > (PY_SSIZE_T_MAX - digitval) / 10.
21553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        */
21653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (accumulator > (PY_SSIZE_T_MAX - digitval) / 10) {
21753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            PyErr_Format(PyExc_ValueError,
21853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                         "Too many decimal digits in format string");
21953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            return -1;
22053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
22153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        accumulator = accumulator * 10 + digitval;
22253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
22353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return accumulator;
22453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
22553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
22653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
22753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/******** Functions to get field objects and specification strings ******/
22853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
22953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
23053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* do the equivalent of obj.name */
23153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
23253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielgetattr(PyObject *obj, SubString *name)
23353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
23453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *newobj;
23553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *str = SubString_new_object(name);
23653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (str == NULL)
23753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
23853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    newobj = PyObject_GetAttr(obj, str);
23953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_DECREF(str);
24053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return newobj;
24153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
24253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
24353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* do the equivalent of obj[idx], where obj is a sequence */
24453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
24553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielgetitem_sequence(PyObject *obj, Py_ssize_t idx)
24653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
24753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return PySequence_GetItem(obj, idx);
24853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
24953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
25053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* do the equivalent of obj[idx], where obj is not a sequence */
25153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
25253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielgetitem_idx(PyObject *obj, Py_ssize_t idx)
25353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
25453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *newobj;
25553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *idx_obj = PyLong_FromSsize_t(idx);
25653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (idx_obj == NULL)
25753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
25853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    newobj = PyObject_GetItem(obj, idx_obj);
25953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_DECREF(idx_obj);
26053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return newobj;
26153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
26253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
26353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* do the equivalent of obj[name] */
26453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
26553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielgetitem_str(PyObject *obj, SubString *name)
26653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
26753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *newobj;
26853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *str = SubString_new_object(name);
26953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (str == NULL)
27053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
27153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    newobj = PyObject_GetItem(obj, str);
27253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_DECREF(str);
27353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return newobj;
27453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
27553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
27653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieltypedef struct {
27753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* the entire string we're parsing.  we assume that someone else
27853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       is managing its lifetime, and that it will exist for the
27953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       lifetime of the iterator.  can be empty */
28053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString str;
28153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
28253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* pointer to where we are inside field_name */
28353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR *ptr;
28453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel} FieldNameIterator;
28553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
28653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
28753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
28853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielFieldNameIterator_init(FieldNameIterator *self, STRINGLIB_CHAR *ptr,
28953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                       Py_ssize_t len)
29053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
29153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString_init(&self->str, ptr, len);
29253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    self->ptr = self->str.ptr;
29353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 1;
29453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
29553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
29653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
29753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel_FieldNameIterator_attr(FieldNameIterator *self, SubString *name)
29853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
29953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR c;
30053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
30153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    name->ptr = self->ptr;
30253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
30353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* return everything until '.' or '[' */
30453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    while (self->ptr < self->str.end) {
30553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        switch (c = *self->ptr++) {
30653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case '[':
30753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case '.':
30853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            /* backup so that we this character will be seen next time */
30953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            self->ptr--;
31053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            break;
31153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        default:
31253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            continue;
31353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
31453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        break;
31553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
31653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* end of string is okay */
31753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    name->end = self->ptr;
31853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 1;
31953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
32053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
32153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
32253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel_FieldNameIterator_item(FieldNameIterator *self, SubString *name)
32353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
32453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int bracket_seen = 0;
32553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR c;
32653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
32753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    name->ptr = self->ptr;
32853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
32953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* return everything until ']' */
33053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    while (self->ptr < self->str.end) {
33153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        switch (c = *self->ptr++) {
33253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case ']':
33353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            bracket_seen = 1;
33453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            break;
33553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        default:
33653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            continue;
33753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
33853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        break;
33953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
34053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* make sure we ended with a ']' */
34153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!bracket_seen) {
34253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_SetString(PyExc_ValueError, "Missing ']' in format string");
34353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 0;
34453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
34553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
34653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* end of string is okay */
34753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* don't include the ']' */
34853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    name->end = self->ptr-1;
34953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 1;
35053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
35153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
35253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* returns 0 on error, 1 on non-error termination, and 2 if it returns a value */
35353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
35453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielFieldNameIterator_next(FieldNameIterator *self, int *is_attribute,
35553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                       Py_ssize_t *name_idx, SubString *name)
35653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
35753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* check at end of input */
35853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (self->ptr >= self->str.end)
35953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 1;
36053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
36153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    switch (*self->ptr++) {
36253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    case '.':
36353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        *is_attribute = 1;
36453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (_FieldNameIterator_attr(self, name) == 0)
36553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            return 0;
36653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        *name_idx = -1;
36753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        break;
36853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    case '[':
36953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        *is_attribute = 0;
37053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (_FieldNameIterator_item(self, name) == 0)
37153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            return 0;
37253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        *name_idx = get_integer(name);
37353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (*name_idx == -1 && PyErr_Occurred())
37453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            return 0;
37553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        break;
37653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    default:
37753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* Invalid character follows ']' */
37853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_SetString(PyExc_ValueError, "Only '.' or '[' may "
37953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                        "follow ']' in format field specifier");
38053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 0;
38153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
38253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
38353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* empty string is an error */
38453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (name->ptr == name->end) {
38553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_SetString(PyExc_ValueError, "Empty attribute in format string");
38653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 0;
38753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
38853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
38953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 2;
39053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
39153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
39253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
39353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* input: field_name
39453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   output: 'first' points to the part before the first '[' or '.'
39553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           'first_idx' is -1 if 'first' is not an integer, otherwise
39653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                       it's the value of first converted to an integer
39753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           'rest' is an iterator to return the rest
39853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
39953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
40053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielfield_name_split(STRINGLIB_CHAR *ptr, Py_ssize_t len, SubString *first,
40153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                 Py_ssize_t *first_idx, FieldNameIterator *rest,
40253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                 AutoNumber *auto_number)
40353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
40453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR c;
40553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR *p = ptr;
40653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR *end = ptr + len;
40753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int field_name_is_empty;
40853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int using_numeric_index;
40953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
41053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* find the part up until the first '.' or '[' */
41153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    while (p < end) {
41253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        switch (c = *p++) {
41353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case '[':
41453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case '.':
41553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            /* backup so that we this character is available to the
41653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel               "rest" iterator */
41753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            p--;
41853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            break;
41953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        default:
42053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            continue;
42153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
42253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        break;
42353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
42453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
42553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* set up the return values */
42653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString_init(first, ptr, p - ptr);
42753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    FieldNameIterator_init(rest, p, end - p);
42853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
42953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* see if "first" is an integer, in which case it's used as an index */
43053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    *first_idx = get_integer(first);
43153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (*first_idx == -1 && PyErr_Occurred())
43253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 0;
43353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
43453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    field_name_is_empty = first->ptr >= first->end;
43553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
43653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* If the field name is omitted or if we have a numeric index
43753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       specified, then we're doing numeric indexing into args. */
43853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    using_numeric_index = field_name_is_empty || *first_idx != -1;
43953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
44053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* We always get here exactly one time for each field we're
44153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       processing. And we get here in field order (counting by left
44253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       braces). So this is the perfect place to handle automatic field
44353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       numbering if the field name is omitted. */
44453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
44553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* Check if we need to do the auto-numbering. It's not needed if
44653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       we're called from string.Format routines, because it's handled
44753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       in that class by itself. */
44853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (auto_number) {
44953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* Initialize our auto numbering state if this is the first
45053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           time we're either auto-numbering or manually numbering. */
45153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (auto_number->an_state == ANS_INIT && using_numeric_index)
45253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            auto_number->an_state = field_name_is_empty ?
45353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                ANS_AUTO : ANS_MANUAL;
45453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
45553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* Make sure our state is consistent with what we're doing
45653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           this time through. Only check if we're using a numeric
45753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           index. */
45853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (using_numeric_index)
45953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            if (autonumber_state_error(auto_number->an_state,
46053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                       field_name_is_empty))
46153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                return 0;
46253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* Zero length field means we want to do auto-numbering of the
46353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           fields. */
46453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (field_name_is_empty)
46553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            *first_idx = (auto_number->an_field_number)++;
46653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
46753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
46853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 1;
46953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
47053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
47153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
47253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*
47353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    get_field_object returns the object inside {}, before the
47453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    format_spec.  It handles getindex and getattr lookups and consumes
47553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    the entire input string.
47653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
47753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
47853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielget_field_object(SubString *input, PyObject *args, PyObject *kwargs,
47953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                 AutoNumber *auto_number)
48053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
48153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *obj = NULL;
48253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int ok;
48353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int is_attribute;
48453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString name;
48553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString first;
48653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t index;
48753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    FieldNameIterator rest;
48853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
48953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!field_name_split(input->ptr, input->end - input->ptr, &first,
49053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                          &index, &rest, auto_number)) {
49153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto error;
49253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
49353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
49453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (index == -1) {
49553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* look up in kwargs */
49653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject *key = SubString_new_object(&first);
49753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (key == NULL)
49853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto error;
49953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if ((kwargs == NULL) || (obj = PyDict_GetItem(kwargs, key)) == NULL) {
50053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            PyErr_SetObject(PyExc_KeyError, key);
50153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            Py_DECREF(key);
50253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto error;
50353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
50453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_DECREF(key);
50553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_INCREF(obj);
50653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
50753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else {
50853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* look up in args */
50953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        obj = PySequence_GetItem(args, index);
51053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (obj == NULL)
51153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto error;
51253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
51353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
51453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* iterate over the rest of the field_name */
51553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    while ((ok = FieldNameIterator_next(&rest, &is_attribute, &index,
51653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                        &name)) == 2) {
51753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject *tmp;
51853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
51953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (is_attribute)
52053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            /* getattr lookup "." */
52153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            tmp = getattr(obj, &name);
52253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        else
52353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            /* getitem lookup "[]" */
52453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            if (index == -1)
52553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                tmp = getitem_str(obj, &name);
52653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            else
52753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                if (PySequence_Check(obj))
52853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    tmp = getitem_sequence(obj, index);
52953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                else
53053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    /* not a sequence */
53153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    tmp = getitem_idx(obj, index);
53253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (tmp == NULL)
53353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto error;
53453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
53553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* assign to obj */
53653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_DECREF(obj);
53753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        obj = tmp;
53853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
53953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* end of iterator, this is the non-error case */
54053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (ok == 1)
54153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return obj;
54253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielerror:
54353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(obj);
54453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return NULL;
54553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
54653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
54753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
54853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*****************  Field rendering functions  **************************/
54953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
55053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
55153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*
55253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    render_field() is the main function in this section.  It takes the
55353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    field object and field specification string generated by
55453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    get_field_and_spec, and renders the field into the output string.
55553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
55653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    render_field calls fieldobj.__format__(format_spec) method, and
55753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    appends to the output.
55853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
55953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
56053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielrender_field(PyObject *fieldobj, SubString *format_spec, OutputString *output)
56153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
56253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int ok = 0;
56353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *result = NULL;
56453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *format_spec_object = NULL;
56553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *(*formatter)(PyObject *, STRINGLIB_CHAR *, Py_ssize_t) = NULL;
56653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR* format_spec_start = format_spec->ptr ?
56753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            format_spec->ptr : NULL;
56853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t format_spec_len = format_spec->ptr ?
56953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            format_spec->end - format_spec->ptr : 0;
57053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
57153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* If we know the type exactly, skip the lookup of __format__ and just
57253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       call the formatter directly. */
57353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#if STRINGLIB_IS_UNICODE
57453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (PyUnicode_CheckExact(fieldobj))
57553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        formatter = _PyUnicode_FormatAdvanced;
57653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* Unfortunately, there's a problem with checking for int, long,
57753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       and float here.  If we're being included as unicode, their
57853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       formatters expect string format_spec args.  For now, just skip
57953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       this optimization for unicode.  This could be fixed, but it's a
58053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       hassle. */
58153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#else
58253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (PyString_CheckExact(fieldobj))
58353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        formatter = _PyBytes_FormatAdvanced;
58453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else if (PyInt_CheckExact(fieldobj))
58553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        formatter =_PyInt_FormatAdvanced;
58653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else if (PyLong_CheckExact(fieldobj))
58753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        formatter =_PyLong_FormatAdvanced;
58853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else if (PyFloat_CheckExact(fieldobj))
58953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        formatter = _PyFloat_FormatAdvanced;
59053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#endif
59153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
59253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (formatter) {
59353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* we know exactly which formatter will be called when __format__ is
59453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           looked up, so call it directly, instead. */
59553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        result = formatter(fieldobj, format_spec_start, format_spec_len);
59653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
59753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else {
59853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* We need to create an object out of the pointers we have, because
59953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           __format__ takes a string/unicode object for format_spec. */
60053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        format_spec_object = STRINGLIB_NEW(format_spec_start,
60153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                           format_spec_len);
60253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (format_spec_object == NULL)
60353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto done;
60453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
60553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        result = PyObject_Format(fieldobj, format_spec_object);
60653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
60753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (result == NULL)
60853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto done;
60953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
61053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#if PY_VERSION_HEX >= 0x03000000
61153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    assert(PyUnicode_Check(result));
61253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#else
61353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    assert(PyString_Check(result) || PyUnicode_Check(result));
61453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
61553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* Convert result to our type.  We could be str, and result could
61653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       be unicode */
61753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    {
61853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject *tmp = STRINGLIB_TOSTR(result);
61953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (tmp == NULL)
62053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto done;
62153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_DECREF(result);
62253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        result = tmp;
62353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
62453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel#endif
62553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
62653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    ok = output_data(output,
62753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                     STRINGLIB_STR(result), STRINGLIB_LEN(result));
62853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieldone:
62953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(format_spec_object);
63053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(result);
63153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return ok;
63253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
63353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
63453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
63553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielparse_field(SubString *str, SubString *field_name, SubString *format_spec,
63653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            STRINGLIB_CHAR *conversion)
63753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
63853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* Note this function works if the field name is zero length,
63953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       which is good.  Zero length field names are handled later, in
64053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       field_name_split. */
64153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
64253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR c = 0;
64353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
64453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* initialize these, as they may be empty */
64553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    *conversion = '\0';
64653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString_init(format_spec, NULL, 0);
64753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
64853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* Search for the field name.  it's terminated by the end of
64953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       the string, or a ':' or '!' */
65053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    field_name->ptr = str->ptr;
65153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    while (str->ptr < str->end) {
65253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        switch (c = *(str->ptr++)) {
65353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case ':':
65453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case '!':
65553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            break;
65653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        default:
65753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            continue;
65853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
65953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        break;
66053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
66153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
66253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (c == '!' || c == ':') {
66353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* we have a format specifier and/or a conversion */
66453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* don't include the last character */
66553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        field_name->end = str->ptr-1;
66653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
66753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* the format specifier is the rest of the string */
66853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        format_spec->ptr = str->ptr;
66953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        format_spec->end = str->end;
67053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
67153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* see if there's a conversion specifier */
67253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (c == '!') {
67353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            /* there must be another character present */
67453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            if (format_spec->ptr >= format_spec->end) {
67553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                PyErr_SetString(PyExc_ValueError,
67653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                "end of format while looking for conversion "
67753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                "specifier");
67853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                return 0;
67953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            }
68053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            *conversion = *(format_spec->ptr++);
68153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
68253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            /* if there is another character, it must be a colon */
68353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            if (format_spec->ptr < format_spec->end) {
68453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                c = *(format_spec->ptr++);
68553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                if (c != ':') {
68653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    PyErr_SetString(PyExc_ValueError,
68753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                    "expected ':' after format specifier");
68853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    return 0;
68953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                }
69053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            }
69153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
69253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
69353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else
69453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* end of string, there's no format_spec or conversion */
69553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        field_name->end = str->ptr;
69653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
69753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 1;
69853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
69953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
70053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
70153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/******* Output string allocation and escape-to-markup processing  ******/
70253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
70353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
70453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* MarkupIterator breaks the string into pieces of either literal
70553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   text, or things inside {} that need to be marked up.  it is
70653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   designed to make it easy to wrap a Python iterator around it, for
70753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   use with the Formatter class */
70853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
70953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieltypedef struct {
71053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString str;
71153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel} MarkupIterator;
71253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
71353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
71453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielMarkupIterator_init(MarkupIterator *self, STRINGLIB_CHAR *ptr, Py_ssize_t len)
71553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
71653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString_init(&self->str, ptr, len);
71753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 1;
71853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
71953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
72053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* returns 0 on error, 1 on non-error termination, and 2 if it got a
72153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   string (or something to be expanded) */
72253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
72353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielMarkupIterator_next(MarkupIterator *self, SubString *literal,
72453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    int *field_present, SubString *field_name,
72553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    SubString *format_spec, STRINGLIB_CHAR *conversion,
72653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    int *format_spec_needs_expanding)
72753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
72853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int at_end;
72953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR c = 0;
73053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR *start;
73153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int count;
73253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t len;
73353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int markup_follows = 0;
73453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
73553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* initialize all of the output variables */
73653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString_init(literal, NULL, 0);
73753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString_init(field_name, NULL, 0);
73853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString_init(format_spec, NULL, 0);
73953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    *conversion = '\0';
74053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    *format_spec_needs_expanding = 0;
74153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    *field_present = 0;
74253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
74353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* No more input, end of iterator.  This is the normal exit
74453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       path. */
74553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (self->str.ptr >= self->str.end)
74653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 1;
74753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
74853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    start = self->str.ptr;
74953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
75053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* First read any literal text. Read until the end of string, an
75153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       escaped '{' or '}', or an unescaped '{'.  In order to never
75253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       allocate memory and so I can just pass pointers around, if
75353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       there's an escaped '{' or '}' then we'll return the literal
75453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       including the brace, but no format object.  The next time
75553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       through, we'll return the rest of the literal, skipping past
75653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       the second consecutive brace. */
75753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    while (self->str.ptr < self->str.end) {
75853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        switch (c = *(self->str.ptr++)) {
75953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case '{':
76053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case '}':
76153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            markup_follows = 1;
76253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            break;
76353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        default:
76453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            continue;
76553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
76653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        break;
76753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
76853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
76953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    at_end = self->str.ptr >= self->str.end;
77053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    len = self->str.ptr - start;
77153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
77253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if ((c == '}') && (at_end || (c != *self->str.ptr))) {
77353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_SetString(PyExc_ValueError, "Single '}' encountered "
77453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                        "in format string");
77553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 0;
77653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
77753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (at_end && c == '{') {
77853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_SetString(PyExc_ValueError, "Single '{' encountered "
77953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                        "in format string");
78053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 0;
78153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
78253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!at_end) {
78353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (c == *self->str.ptr) {
78453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            /* escaped } or {, skip it in the input.  there is no
78553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel               markup object following us, just this literal text */
78653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            self->str.ptr++;
78753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            markup_follows = 0;
78853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
78953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        else
79053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            len--;
79153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
79253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
79353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* record the literal text */
79453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    literal->ptr = start;
79553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    literal->end = start + len;
79653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
79753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!markup_follows)
79853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return 2;
79953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
80053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* this is markup, find the end of the string by counting nested
80153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       braces.  note that this prohibits escaped braces, so that
80253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       format_specs cannot have braces in them. */
80353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    *field_present = 1;
80453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    count = 1;
80553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
80653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    start = self->str.ptr;
80753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
80853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* we know we can't have a zero length string, so don't worry
80953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       about that case */
81053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    while (self->str.ptr < self->str.end) {
81153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        switch (c = *(self->str.ptr++)) {
81253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case '{':
81353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            /* the format spec needs to be recursively expanded.
81453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel               this is an optimization, and not strictly needed */
81553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            *format_spec_needs_expanding = 1;
81653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            count++;
81753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            break;
81853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        case '}':
81953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            count--;
82053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            if (count <= 0) {
82153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                /* we're done.  parse and get out */
82253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                SubString s;
82353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
82453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                SubString_init(&s, start, self->str.ptr - 1 - start);
82553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                if (parse_field(&s, field_name, format_spec, conversion) == 0)
82653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                    return 0;
82753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
82853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                /* success */
82953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                return 2;
83053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            }
83153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            break;
83253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
83353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
83453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
83553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* end of string while searching for matching '}' */
83653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyErr_SetString(PyExc_ValueError, "unmatched '{' in format");
83753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return 0;
83853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
83953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
84053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
84153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* do the !r or !s conversion on obj */
84253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
84353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieldo_conversion(PyObject *obj, STRINGLIB_CHAR conversion)
84453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
84553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* XXX in pre-3.0, do we need to convert this to unicode, since it
84653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       might have returned a string? */
84753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    switch (conversion) {
84853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    case 'r':
84953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return PyObject_Repr(obj);
85053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    case 's':
85153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return STRINGLIB_TOSTR(obj);
85253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    default:
85353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (conversion > 32 && conversion < 127) {
85453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                /* It's the ASCII subrange; casting to char is safe
85553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                   (assuming the execution character set is an ASCII
85653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                   superset). */
85753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                PyErr_Format(PyExc_ValueError,
85853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                     "Unknown conversion specifier %c",
85953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                     (char)conversion);
86053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        } else
86153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                PyErr_Format(PyExc_ValueError,
86253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                     "Unknown conversion specifier \\x%x",
86353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                     (unsigned int)conversion);
86453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
86553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
86653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
86753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
86853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* given:
86953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
87053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   {field_name!conversion:format_spec}
87153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
87253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   compute the result and write it to output.
87353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   format_spec_needs_expanding is an optimization.  if it's false,
87453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   just output the string directly, otherwise recursively expand the
87553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   format_spec string.
87653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
87753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   field_name is allowed to be zero length, in which case we
87853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   are doing auto field numbering.
87953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
88053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
88153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
88253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieloutput_markup(SubString *field_name, SubString *format_spec,
88353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel              int format_spec_needs_expanding, STRINGLIB_CHAR conversion,
88453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel              OutputString *output, PyObject *args, PyObject *kwargs,
88553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel              int recursion_depth, AutoNumber *auto_number)
88653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
88753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *tmp = NULL;
88853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *fieldobj = NULL;
88953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString expanded_format_spec;
89053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString *actual_format_spec;
89153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int result = 0;
89253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
89353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* convert field_name to an object */
89453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    fieldobj = get_field_object(field_name, args, kwargs, auto_number);
89553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (fieldobj == NULL)
89653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto done;
89753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
89853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (conversion != '\0') {
89953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        tmp = do_conversion(fieldobj, conversion);
90053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (tmp == NULL)
90153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto done;
90253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
90353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* do the assignment, transferring ownership: fieldobj = tmp */
90453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_DECREF(fieldobj);
90553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        fieldobj = tmp;
90653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        tmp = NULL;
90753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
90853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
90953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* if needed, recurively compute the format_spec */
91053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (format_spec_needs_expanding) {
91153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        tmp = build_string(format_spec, args, kwargs, recursion_depth-1,
91253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                           auto_number);
91353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (tmp == NULL)
91453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto done;
91553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
91653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* note that in the case we're expanding the format string,
91753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           tmp must be kept around until after the call to
91853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           render_field. */
91953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        SubString_init(&expanded_format_spec,
92053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                       STRINGLIB_STR(tmp), STRINGLIB_LEN(tmp));
92153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        actual_format_spec = &expanded_format_spec;
92253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
92353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else
92453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        actual_format_spec = format_spec;
92553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
92653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (render_field(fieldobj, actual_format_spec, output) == 0)
92753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto done;
92853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
92953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    result = 1;
93053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
93153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieldone:
93253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(fieldobj);
93353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(tmp);
93453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
93553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return result;
93653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
93753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
93853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*
93953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    do_markup is the top-level loop for the format() method.  It
94053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    searches through the format string for escapes to markup codes, and
94153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    calls other functions to move non-markup text to the output,
94253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    and to perform the markup to the output.
94353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
94453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic int
94553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieldo_markup(SubString *input, PyObject *args, PyObject *kwargs,
94653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel          OutputString *output, int recursion_depth, AutoNumber *auto_number)
94753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
94853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    MarkupIterator iter;
94953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int format_spec_needs_expanding;
95053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int result;
95153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int field_present;
95253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString literal;
95353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString field_name;
95453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString format_spec;
95553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR conversion;
95653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
95753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    MarkupIterator_init(&iter, input->ptr, input->end - input->ptr);
95853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    while ((result = MarkupIterator_next(&iter, &literal, &field_present,
95953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                         &field_name, &format_spec,
96053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                         &conversion,
96153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                         &format_spec_needs_expanding)) == 2) {
96253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (!output_data(output, literal.ptr, literal.end - literal.ptr))
96353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            return 0;
96453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (field_present)
96553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            if (!output_markup(&field_name, &format_spec,
96653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                               format_spec_needs_expanding, conversion, output,
96753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                               args, kwargs, recursion_depth, auto_number))
96853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                return 0;
96953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
97053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return result;
97153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
97253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
97353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
97453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*
97553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    build_string allocates the output string and then
97653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    calls do_markup to do the heavy lifting.
97753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
97853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
97953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielbuild_string(SubString *input, PyObject *args, PyObject *kwargs,
98053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel             int recursion_depth, AutoNumber *auto_number)
98153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
98253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    OutputString output;
98353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *result = NULL;
98453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t count;
98553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
98653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output.obj = NULL; /* needed so cleanup code always works */
98753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
98853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* check the recursion level */
98953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (recursion_depth <= 0) {
99053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyErr_SetString(PyExc_ValueError,
99153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                        "Max string recursion exceeded");
99253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto done;
99353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
99453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
99553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* initial size is the length of the format string, plus the size
99653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       increment.  seems like a reasonable default */
99753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!output_initialize(&output,
99853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                           input->end - input->ptr +
99953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                           INITIAL_SIZE_INCREMENT))
100053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto done;
100153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
100253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!do_markup(input, args, kwargs, &output, recursion_depth,
100353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                   auto_number)) {
100453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto done;
100553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
100653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
100753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    count = output.ptr - STRINGLIB_STR(output.obj);
100853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (STRINGLIB_RESIZE(&output.obj, count) < 0) {
100953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto done;
101053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
101153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
101253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* transfer ownership to result */
101353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    result = output.obj;
101453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    output.obj = NULL;
101553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
101653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieldone:
101753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(output.obj);
101853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return result;
101953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
102053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
102153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
102253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*********** main routine ***********************************************/
102353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
102453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
102553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* this is the main entry point */
102653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
102753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieldo_string_format(PyObject *self, PyObject *args, PyObject *kwargs)
102853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
102953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString input;
103053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
103153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* PEP 3101 says only 2 levels, so that
103253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       "{0:{1}}".format('abc', 's')            # works
103353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       "{0:{1:{2}}}".format('abc', 's', '')    # fails
103453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    */
103553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int recursion_depth = 2;
103653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
103753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    AutoNumber auto_number;
103853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
103953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    AutoNumber_Init(&auto_number);
104053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString_init(&input, STRINGLIB_STR(self), STRINGLIB_LEN(self));
104153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return build_string(&input, args, kwargs, recursion_depth, &auto_number);
104253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
104353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
104453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
104553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
104653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
104753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*********** formatteriterator ******************************************/
104853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
104953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
105053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* This is used to implement string.Formatter.vparse().  It exists so
105153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   Formatter can share code with the built in unicode.format() method.
105253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   It's really just a wrapper around MarkupIterator that is callable
105353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   from Python. */
105453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
105553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieltypedef struct {
105653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_HEAD
105753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
105853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_OBJECT *str;
105953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
106053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    MarkupIterator it_markup;
106153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel} formatteriterobject;
106253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
106353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic void
106453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielformatteriter_dealloc(formatteriterobject *it)
106553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
106653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(it->str);
106753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_FREE(it);
106853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
106953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
107053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* returns a tuple:
107153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   (literal, field_name, format_spec, conversion)
107253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
107353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   literal is any literal text to output.  might be zero length
107453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   field_name is the string before the ':'.  might be None
107553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   format_spec is the string after the ':'.  mibht be None
107653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   conversion is either None, or the string after the '!'
107753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
107853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
107953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielformatteriter_next(formatteriterobject *it)
108053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
108153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString literal;
108253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString field_name;
108353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString format_spec;
108453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_CHAR conversion;
108553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int format_spec_needs_expanding;
108653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int field_present;
108753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int result = MarkupIterator_next(&it->it_markup, &literal, &field_present,
108853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                     &field_name, &format_spec, &conversion,
108953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                     &format_spec_needs_expanding);
109053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
109153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* all of the SubString objects point into it->str, so no
109253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       memory management needs to be done on them */
109353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    assert(0 <= result && result <= 2);
109453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (result == 0 || result == 1)
109553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* if 0, error has already been set, if 1, iterator is empty */
109653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
109753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else {
109853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject *literal_str = NULL;
109953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject *field_name_str = NULL;
110053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject *format_spec_str = NULL;
110153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject *conversion_str = NULL;
110253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject *tuple = NULL;
110353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
110453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        literal_str = SubString_new_object(&literal);
110553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (literal_str == NULL)
110653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto done;
110753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
110853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        field_name_str = SubString_new_object(&field_name);
110953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (field_name_str == NULL)
111053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto done;
111153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
111253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* if field_name is non-zero length, return a string for
111353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           format_spec (even if zero length), else return None */
111453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        format_spec_str = (field_present ?
111553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                           SubString_new_object_or_empty :
111653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                           SubString_new_object)(&format_spec);
111753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (format_spec_str == NULL)
111853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto done;
111953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
112053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* if the conversion is not specified, return a None,
112153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           otherwise create a one length string with the conversion
112253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel           character */
112353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (conversion == '\0') {
112453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            conversion_str = Py_None;
112553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            Py_INCREF(conversion_str);
112653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        }
112753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        else
112853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            conversion_str = STRINGLIB_NEW(&conversion, 1);
112953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (conversion_str == NULL)
113053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto done;
113153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
113253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        tuple = PyTuple_Pack(4, literal_str, field_name_str, format_spec_str,
113353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                             conversion_str);
113453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    done:
113553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_XDECREF(literal_str);
113653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_XDECREF(field_name_str);
113753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_XDECREF(format_spec_str);
113853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_XDECREF(conversion_str);
113953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return tuple;
114053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
114153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
114253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
114353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyMethodDef formatteriter_methods[] = {
114453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    {NULL,              NULL}           /* sentinel */
114553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel};
114653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
114753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyTypeObject PyFormatterIter_Type = {
114853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyVarObject_HEAD_INIT(&PyType_Type, 0)
114953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    "formatteriterator",                /* tp_name */
115053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    sizeof(formatteriterobject),        /* tp_basicsize */
115153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_itemsize */
115253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* methods */
115353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    (destructor)formatteriter_dealloc,  /* tp_dealloc */
115453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_print */
115553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_getattr */
115653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_setattr */
115753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_compare */
115853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_repr */
115953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_as_number */
116053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_as_sequence */
116153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_as_mapping */
116253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_hash */
116353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_call */
116453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_str */
116553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_GenericGetAttr,            /* tp_getattro */
116653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_setattro */
116753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_as_buffer */
116853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
116953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_doc */
117053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_traverse */
117153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_clear */
117253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_richcompare */
117353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_weaklistoffset */
117453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_SelfIter,                  /* tp_iter */
117553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    (iternextfunc)formatteriter_next,   /* tp_iternext */
117653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    formatteriter_methods,              /* tp_methods */
117753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,
117853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel};
117953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
118053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* unicode_formatter_parser is used to implement
118153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   string.Formatter.vformat.  it parses a string and returns tuples
118253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   describing the parsed elements.  It's a wrapper around
118353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   stringlib/string_format.h's MarkupIterator */
118453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
118553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielformatter_parser(STRINGLIB_OBJECT *self)
118653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
118753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    formatteriterobject *it;
118853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
118953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    it = PyObject_New(formatteriterobject, &PyFormatterIter_Type);
119053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (it == NULL)
119153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
119253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
119353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* take ownership, give the object to the iterator */
119453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_INCREF(self);
119553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    it->str = self;
119653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
119753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* initialize the contained MarkupIterator */
119853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    MarkupIterator_init(&it->it_markup,
119953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                        STRINGLIB_STR(self),
120053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                        STRINGLIB_LEN(self));
120153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
120253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return (PyObject *)it;
120353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
120453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
120553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
120653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
120753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/*********** fieldnameiterator ******************************************/
120853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/************************************************************************/
120953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
121053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
121153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* This is used to implement string.Formatter.vparse().  It parses the
121253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   field name into attribute and item values.  It's a Python-callable
121353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   wrapper around FieldNameIterator */
121453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
121553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieltypedef struct {
121653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_HEAD
121753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
121853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    STRINGLIB_OBJECT *str;
121953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
122053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    FieldNameIterator it_field;
122153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel} fieldnameiterobject;
122253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
122353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic void
122453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielfieldnameiter_dealloc(fieldnameiterobject *it)
122553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
122653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(it->str);
122753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_FREE(it);
122853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
122953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
123053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* returns a tuple:
123153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   (is_attr, value)
123253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   is_attr is true if we used attribute syntax (e.g., '.foo')
123353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel              false if we used index syntax (e.g., '[foo]')
123453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   value is an integer or string
123553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel*/
123653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
123753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielfieldnameiter_next(fieldnameiterobject *it)
123853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
123953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int result;
124053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    int is_attr;
124153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t idx;
124253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString name;
124353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
124453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    result = FieldNameIterator_next(&it->it_field, &is_attr,
124553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                                    &idx, &name);
124653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (result == 0 || result == 1)
124753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* if 0, error has already been set, if 1, iterator is empty */
124853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
124953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else {
125053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject* result = NULL;
125153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject* is_attr_obj = NULL;
125253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        PyObject* obj = NULL;
125353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
125453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        is_attr_obj = PyBool_FromLong(is_attr);
125553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (is_attr_obj == NULL)
125653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto done;
125753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
125853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* either an integer or a string */
125953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (idx != -1)
126053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            obj = PyLong_FromSsize_t(idx);
126153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        else
126253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            obj = SubString_new_object(&name);
126353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        if (obj == NULL)
126453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel            goto done;
126553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
126653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* return a tuple of values */
126753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        result = PyTuple_Pack(2, is_attr_obj, obj);
126853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
126953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    done:
127053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_XDECREF(is_attr_obj);
127153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        Py_XDECREF(obj);
127253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return result;
127353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    }
127453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
127553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
127653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyMethodDef fieldnameiter_methods[] = {
127753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    {NULL,              NULL}           /* sentinel */
127853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel};
127953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
128053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyTypeObject PyFieldNameIter_Type = {
128153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyVarObject_HEAD_INIT(&PyType_Type, 0)
128253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    "fieldnameiterator",                /* tp_name */
128353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    sizeof(fieldnameiterobject),        /* tp_basicsize */
128453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_itemsize */
128553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* methods */
128653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    (destructor)fieldnameiter_dealloc,  /* tp_dealloc */
128753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_print */
128853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_getattr */
128953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_setattr */
129053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_compare */
129153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_repr */
129253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_as_number */
129353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_as_sequence */
129453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_as_mapping */
129553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_hash */
129653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_call */
129753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_str */
129853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_GenericGetAttr,            /* tp_getattro */
129953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_setattro */
130053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_as_buffer */
130153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_TPFLAGS_DEFAULT,                 /* tp_flags */
130253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_doc */
130353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_traverse */
130453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_clear */
130553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_richcompare */
130653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0,                                  /* tp_weaklistoffset */
130753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject_SelfIter,                  /* tp_iter */
130853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    (iternextfunc)fieldnameiter_next,   /* tp_iternext */
130953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    fieldnameiter_methods,              /* tp_methods */
131053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    0};
131153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
131253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel/* unicode_formatter_field_name_split is used to implement
131353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   string.Formatter.vformat.  it takes an PEP 3101 "field name", and
131453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   returns a tuple of (first, rest): "first", the part before the
131553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   first '.' or '['; and "rest", an iterator for the rest of the field
131653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   name.  it's a wrapper around stringlib/string_format.h's
131753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   field_name_split.  The iterator it returns is a
131853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel   FieldNameIterator */
131953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielstatic PyObject *
132053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanielformatter_field_name_split(STRINGLIB_OBJECT *self)
132153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel{
132253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    SubString first;
132353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_ssize_t first_idx;
132453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    fieldnameiterobject *it;
132553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
132653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *first_obj = NULL;
132753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    PyObject *result = NULL;
132853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
132953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    it = PyObject_New(fieldnameiterobject, &PyFieldNameIter_Type);
133053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (it == NULL)
133153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        return NULL;
133253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
133353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* take ownership, give the object to the iterator.  this is
133453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       just to keep the field_name alive */
133553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_INCREF(self);
133653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    it->str = self;
133753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
133853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* Pass in auto_number = NULL. We'll return an empty string for
133953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel       first_obj in that case. */
134053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (!field_name_split(STRINGLIB_STR(self),
134153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                          STRINGLIB_LEN(self),
134253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel                          &first, &first_idx, &it->it_field, NULL))
134353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto done;
134453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
134553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* first becomes an integer, if possible; else a string */
134653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (first_idx != -1)
134753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        first_obj = PyLong_FromSsize_t(first_idx);
134853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    else
134953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        /* convert "first" into a string object */
135053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        first_obj = SubString_new_object(&first);
135153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    if (first_obj == NULL)
135253b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel        goto done;
135353b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
135453b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    /* return a tuple of values */
135553b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    result = PyTuple_Pack(2, first_obj, it);
135653b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel
135753b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDanieldone:
135853b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(it);
135953b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    Py_XDECREF(first_obj);
136053b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel    return result;
136153b2ba5790b57b3dcdfbb9fa5835a979d94908faDaryl McDaniel}
1362