annotate Objects/stringlib/string_format.h @ 43244:79080c4889bc

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