[Python-checkins] r54218 - sandbox/trunk/pep3101/unicodeformat.c
patrick.maupin
python-checkins at python.org
Thu Mar 8 06:03:49 CET 2007
Author: patrick.maupin
Date: Thu Mar 8 06:03:44 2007
New Revision: 54218
Modified:
sandbox/trunk/pep3101/unicodeformat.c
Log:
Better exception handling will require the fmtstr object, so
I merged the SubString and SubstrObj structures. (I guess that
was a premature optimization :)
Also added comment headers to functions that didn't have them.
Modified: sandbox/trunk/pep3101/unicodeformat.c
==============================================================================
--- sandbox/trunk/pep3101/unicodeformat.c (original)
+++ sandbox/trunk/pep3101/unicodeformat.c Thu Mar 8 06:03:44 2007
@@ -89,22 +89,15 @@
#include "pep3101.h"
/*
- A SubString is a string between two unicode pointers.
-*/
-typedef struct {
- CH_TYPE *ptr;
- CH_TYPE *end;
-} SubString;
-
-/*
- A SubStringObj is like a SubString, but also has an associated
- object (which may be null).
+ A SubString consists of the characters between two string or
+ unicode pointers. It may also have an associated object,
+ or the object may be null.
*/
typedef struct {
CH_TYPE *ptr;
CH_TYPE *end;
PyObject *obj;
-} SubStringObj;
+} SubString;
/*
A MarkupEscapeHandler allows us to handle different escape
@@ -127,8 +120,9 @@
PyObject *args;
/* keywords passed to PyString_FormatMethod or PyUnicode_FormatMethod */
PyObject *keywords;
- /* arg_param_offset is 1 if not called as a method */
+ /* Total number of positional arguments */
int num_args;
+ /* arg_param_offset is 1 if not called as a method */
int arg_param_offset;
/* Function to call to perform markup */
MarkupEscapeHandler do_markup;
@@ -137,12 +131,12 @@
/* Used for error reporting */
CH_TYPE *fmtstart, *fieldstart;
/* Output string we are constructing, including current and end pointers*/
- SubStringObj outstr;
+ SubString outstr;
/* Field Specifier, after the colon in {1:{2}}
This may or may not have a valid object (the field specifier might
just be a substring of the fmtstr. If it does not have its own
object, the .obj struct member will be NULL */
- SubStringObj fieldspec;
+ SubString fieldspec;
/* size_increment is used for optimizing string growth */
int size_increment;
/* max_recursion is used to limit the ability of a malicious string
@@ -166,6 +160,9 @@
int syntaxmode;
/* Support for hooking render calls */
PyObject *hookfunc;
+ /* hookalways is true if we should call the hook function
+ on every single field, false to just call it on fields
+ with a specifier ending in 'p' */
int hookalways;
} FmtState;
@@ -277,6 +274,12 @@
return 1;
}
+/*
+ get_locals_globals builds a tuple out of our locals()
+ and globals() dictionaries. It only does this if we
+ have no positional arguments. (It will not be called
+ unless we have no keyword arguments.)
+*/
static int
get_locals_globals(FmtState *fs)
{
@@ -352,6 +355,11 @@
return SetError(fs, "name lookup failed");
}
+/*
+ read_parameter reads a single parameter out of our "namespace".
+
+ Returns object, or NULL on error.
+*/
static PyObject *
read_parameter(FmtState *fs, const char *keyword)
{
@@ -364,6 +372,11 @@
return result;
}
+/*
+ read_bool_parameter uses read_parameter to retrieve
+ a parameter and check it for "truth" Returns
+ 0 for false, 1 for true, -1 for error.
+*/
static int
read_bool_parameter(FmtState *fs, const char *keyword)
{
@@ -377,6 +390,11 @@
return result;
}
+/*
+ read_allow_under_parameter determines if leading underscores
+ are allowed, and saves the value so it doesn't need to
+ be called again later.
+*/
static int
read_allow_under_parameter(FmtState *fs)
{
@@ -385,6 +403,10 @@
return result;
}
+/*
+ read_hook_parameter retrieves the hook function, and saves the
+ object so it doesn't need to be called again later.
+*/
static int
read_hook_parameter(FmtState *fs)
{
@@ -398,11 +420,11 @@
/*********** Output string management functions ****************/
/************************************************************************/
-/* Fill in a SubStringObj from a Python string */
-Py_LOCAL_INLINE(SubStringObj)
-make_substrobj(PyObject *obj)
+/* Fill in a SubString from a Python string */
+Py_LOCAL_INLINE(SubString)
+make_substr(PyObject *obj)
{
- SubStringObj s;
+ SubString s;
s.obj = obj;
s.ptr = STROBJ_AS_PTR(obj);
s.end = STROBJ_GET_SIZE(obj) + s.ptr;
@@ -657,7 +679,7 @@
myobject = recurse_format(fs);
if (myobject == NULL)
return 0;
- fs->fieldspec = make_substrobj(myobject);
+ fs->fieldspec = make_substr(myobject);
fs->fmtstr = savefmt;
}
return 1;
@@ -1786,6 +1808,12 @@
return format_function(fieldobj, &format)(fieldobj, fs, &format);
}
+/*
+ get_field_spec_obj creates a string object for the fieldspec,
+ if necessary. (The field spec might already be an object,
+ or it might just be a substring of the format string, in
+ which case we need to copy it into a real string object.)
+*/
static PyObject *
get_field_spec_obj(FmtState *fs)
{
@@ -1799,8 +1827,8 @@
}
/*
- object_self_render is invoked to format an object with a defined __format__
- attribute.
+ object_self_render is invoked to format an object with a defined
+ __format__ attribute.
*/
static int
object_self_render(FmtState *fs, PyObject *__format__)
@@ -1899,6 +1927,11 @@
return result;
}
+/*
+ check_keyword compares a string against an expected
+ string, a character at a time, so that it works on
+ unicode vs. regular strings.
+*/
static int
check_keyword(const CH_TYPE *ptr, const char *expected, int count)
{
@@ -1908,6 +1941,9 @@
return 1;
}
+/*
+ process_metadata handles string metadata, e.g. "{!keyword}"
+*/
static int
process_metadata(FmtState *fs)
{
@@ -1983,8 +2019,8 @@
/************************************************************************/
/*
- do_markup is the main program loop. It rummages through
- the format string, looking for escapes to markup, and
+ do_markup is the top-level loop for the format() function. It
+ searches through the format string for escapes to markup codes, and
calls other functions to move non-markup text to the output,
and to perform the markup to the output.
*/
@@ -2095,7 +2131,7 @@
fs->fmtstr.end - fs->fmtstr.ptr + INITIAL_SIZE_INCREMENT);
if (myobj == NULL)
return NULL;
- fs->outstr = make_substrobj(myobj);
+ fs->outstr = make_substr(myobj);
fs->size_increment = INITIAL_SIZE_INCREMENT;
ok = fs->do_markup(fs);
@@ -2119,7 +2155,7 @@
recurse_format(FmtState *fs)
{
PyObject *result;
- SubStringObj saveoutstr = fs->outstr;
+ SubString saveoutstr = fs->outstr;
int saveincrement = fs->size_increment;
if (--(fs->max_recursion) < 0)
return SetError(fs, "Max string recursion exceeded");
@@ -2155,11 +2191,14 @@
fs->arg_param_offset = 1;
fs->num_args -= 1;
}
- fs->fmtstr.ptr = fs->fmtstart = STROBJ_AS_PTR(self);
- fs->fmtstr.end = fs->fmtstr.ptr + STROBJ_GET_SIZE(self);
+ fs->fmtstr = make_substr(self);
return 1;
}
+/*
+ if {!useall} is set, check_args_consumed will be called to verify
+ that all arguments have been used during string processing.
+*/
static PyObject *
check_args_consumed(FmtState *fs, PyObject *result)
{
More information about the Python-checkins
mailing list