[Python-checkins] r54067 - sandbox/trunk/pep3101/unicodeformat.c
patrick.maupin
python-checkins at python.org
Thu Mar 1 21:54:13 CET 2007
Author: patrick.maupin
Date: Thu Mar 1 21:54:10 2007
New Revision: 54067
Modified:
sandbox/trunk/pep3101/unicodeformat.c
Log:
Added method option parsing code to format func
Modified: sandbox/trunk/pep3101/unicodeformat.c
==============================================================================
--- sandbox/trunk/pep3101/unicodeformat.c (original)
+++ sandbox/trunk/pep3101/unicodeformat.c Thu Mar 1 21:54:10 2007
@@ -102,6 +102,7 @@
/* keywords passed to PyString_FormatMethod or PyUnicode_FormatMethod */
PyObject *keywords;
/* arg_param_offset is 1 if not called as a method */
+ int num_args;
int arg_param_offset;
/* Function to call to perform markup */
MarkupEscapeHandler do_markup;
@@ -224,11 +225,9 @@
}
#if PYTHON_API_VERSION < 1013
-static void
-PySet_Discard(PyObject *myset, PyObject *mykey)
-{
- Py_XDECREF(PyObject_CallMethod(myset, "discard", "(O)", mykey));
-}
+#define PySet_Discard PyDict_DelItem
+#define PySet_New PyDict_Copy
+#define PySet_GET_SIZE PyDict_Size
#endif
/* XXX -- similar function elsewhere ???? */
@@ -1084,6 +1083,94 @@
return result;
}
+static int
+get_options(PyObject *keywords, FmtState *fs)
+{
+ static char* keys[3] = {
+ "useall", "allow_leading_under", NULL
+ };
+ int values[2];
+ int index;
+
+ PyObject *flags, *myobj;
+
+ fs->max_recursion = 4;
+ fs->allow_leading_under = 1; /* XXX- SHould set to 0, but breaks */
+ fs->positional_arg_set = 0;
+ fs->keyword_arg_set = NULL;
+ fs->keywords_is_tuple = 0;
+ fs->do_markup = do_markup;
+ fs->keywords = keywords;
+
+ flags = PyDict_GetItemString(keywords, "_dict");
+ if (flags == NULL)
+ return 1;
+
+ for (index=0; keys[index] != NULL; index++) {
+ myobj = PyDict_GetItemString(flags, keys[index]);
+ if (myobj == NULL)
+ values[index] = 0;
+ else if (PyInt_Check(myobj))
+ values[index] = PyInt_AS_LONG(myobj);
+ else {
+ PyErr_SetString(PyExc_TypeError,
+ "All flags values must be integers");
+ return 0;
+ }
+ }
+ if (values[0]) {
+ fs->positional_arg_set = (1 << fs->num_args) - 1;
+ fs->keyword_arg_set = PySet_New(keywords);
+ if (!fs->keyword_arg_set)
+ return 0;
+ }
+ fs->allow_leading_under = values[1];
+ return 1;
+}
+
+static int
+get_self_args(PyObject *self, PyObject *args, FmtState *fs)
+{
+ fs->num_args = PyTuple_GET_SIZE(args);
+ if (self == NULL) {
+ if (!fs->num_args) {
+ PyErr_SetString(PyExc_TypeError,
+ "Function expects at least one argument");
+ return 0;
+ }
+ self = PyTuple_GET_ITEM(args, 0);
+ if (!STROBJ_CHECK(self)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Not valid format string");
+ return 0;
+ }
+ fs->arg_param_offset = 1;
+ fs->num_args -= 1;
+ }
+ else
+ fs->arg_param_offset = 0;
+ fs->args = args;
+ fs->fmtstr.ptr = STROBJ_AS_PTR(self);
+ fs->fmtstr.end = fs->fmtstr.ptr + STROBJ_GET_SIZE(self);
+ return 1;
+}
+
+static PyObject *
+fs_cleanup(PyObject *result, FmtState *fs)
+{
+ PyObject *used;
+ int ok = result != NULL;
+ used = fs->keyword_arg_set;
+ if (ok && used) {
+ ok = (PySet_GET_SIZE(used) <= 1) && !fs->positional_arg_set;
+ if (!ok) {
+ Py_DECREF(result);
+ result = SetError("Not all arguments consumed");
+ }
+ }
+ Py_XDECREF(used);
+ return result;
+}
/*
STROBJ_FORMAT (actually PyUnicode_FormatMethod or PyString_FormatMethod)
@@ -1098,30 +1185,11 @@
FmtState fs;
/* This function can be called as a python function or as a method */
- if (self == NULL) {
- if (!PyTuple_GET_SIZE(args)) {
- PyErr_SetString(PyExc_TypeError,
- "function expects at least one argument");
- return NULL;
- }
- self = PyTuple_GET_ITEM(args, 0);
- fs.arg_param_offset = 1;
- }
- else
- fs.arg_param_offset = 0;
-
- fs.max_recursion = 4;
- fs.allow_leading_under = 1;
- fs.positional_arg_set = 0;
- fs.keyword_arg_set = NULL;
- fs.keywords_is_tuple = 0;
- fs.do_markup = do_markup;
- fs.fmtstr.ptr = STROBJ_AS_PTR(self);
- fs.fmtstr.end = fs.fmtstr.ptr + STROBJ_GET_SIZE(self);
- fs.args = args;
- fs.keywords = keywords;
+ if (!get_self_args(self, args, &fs) ||
+ !get_options(keywords, &fs))
+ return NULL;
- return do_format(&fs);
+ return fs_cleanup(do_format(&fs), &fs);
}
#ifdef __cplusplus
More information about the Python-checkins
mailing list