[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