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