[Python-checkins] r54063 - sandbox/trunk/pep3101/loadpep.py sandbox/trunk/pep3101/makefile sandbox/trunk/pep3101/pep3101.c sandbox/trunk/pep3101/unicodeformat.c

patrick.maupin python-checkins at python.org
Thu Mar 1 18:53:29 CET 2007


Author: patrick.maupin
Date: Thu Mar 1 18:53:24 2007
New Revision: 54063
Added:
 sandbox/trunk/pep3101/loadpep.py
 sandbox/trunk/pep3101/makefile
Modified:
 sandbox/trunk/pep3101/pep3101.c
 sandbox/trunk/pep3101/unicodeformat.c
Log:
Generalized the dispatch mechanism, added test/build infrastructure
Added: sandbox/trunk/pep3101/loadpep.py
==============================================================================
--- (empty file)
+++ sandbox/trunk/pep3101/loadpep.py	Thu Mar 1 18:53:24 2007
@@ -0,0 +1,16 @@
+
+import sys
+
+platdict = dict(
+ linux2='build/lib.linux-i686-%s.%s',
+)
+
+platstr = platdict.get(sys.platform)
+
+if platstr is None:
+ raise ValueError("Unknown platform")
+
+sys.path.append(platstr % sys.version_info[:2])
+
+import test_simpleformat
+test_simpleformat.test_main()
Added: sandbox/trunk/pep3101/makefile
==============================================================================
--- (empty file)
+++ sandbox/trunk/pep3101/makefile	Thu Mar 1 18:53:24 2007
@@ -0,0 +1,29 @@
+
+SRCS = pep3101.c stringformat.c unicodeformat.c pep3101.h setup.py
+
+PY30 = ../bin/python
+PY24 = python2.4
+
+test: test24 test30
+
+all: 24 30
+
+24: build/lib.linux-i686-2.4/pep3101.so
+
+30: build/lib.linux-i686-3.0/pep3101.so
+
+build/lib.linux-i686-3.0/pep3101.so: $(SRCS)
+	$(PY30) setup.py build
+
+build/lib.linux-i686-2.4/pep3101.so: $(SRCS)
+	$(PY24) setup.py build
+
+test24: 24
+	$(PY24) loadpep.py
+
+test30: 30
+	$(PY24) loadpep.py
+
+clean:
+	rm -Rf build *.pyc
+
Modified: sandbox/trunk/pep3101/pep3101.c
==============================================================================
--- sandbox/trunk/pep3101/pep3101.c	(original)
+++ sandbox/trunk/pep3101/pep3101.c	Thu Mar 1 18:53:24 2007
@@ -11,26 +11,35 @@
 ;
 
 static PyObject *
-pep3101_format(PyObject *self, PyObject *args, PyObject *keywords)
+StringDispatch(ternaryfunc *table, PyObject *self, PyObject *args, PyObject *keywords)
 {
- PyObject *newargs, *newself, *result;
- newself = PyTuple_GetItem(args, 0); /* borrowed reference */
- if (newself == NULL)
- return NULL;
- newargs = PyTuple_GetSlice(args, 1, PyTuple_Size(args) + 1);
- if (newargs == NULL)
- return NULL;
- if (PyUnicode_Check(newself))
- result = PyUnicode_FormatMethod(newself, newargs, keywords);
- else if (PyString_Check(newself))
- result = PyString_FormatMethod(newself, newargs, keywords);
+ PyObject *myobj = self;
+
+ if (self == NULL) {
+ if (!PyTuple_GET_SIZE(args)) {
+ PyErr_SetString(PyExc_TypeError,
+ "Function expects at least one argument");
+ return NULL;
+ }
+ myobj = PyTuple_GET_ITEM(args, 0);
+ }
+ if (PyUnicode_Check(myobj))
+ return table[0](self, args, keywords);
+ else if (PyString_Check(self))
+ return table[1](self, args, keywords);
 else {
- result = NULL;
 PyErr_SetString(PyExc_TypeError,
- "First parameter to format must be string or unicode object");
+ "First parameter must be string or unicode object");
+ return NULL;
 }
- Py_DECREF(newargs);
- return result;
+}
+
+static PyObject *
+pep3101_format(PyObject *self, PyObject *args, PyObject *keywords)
+{
+ static ternaryfunc table[2] = 
+ {PyUnicode_FormatMethod, PyString_FormatMethod};
+ return StringDispatch(table, self, args, keywords);
 }
 
 /* List of methods defined in the module */
Modified: sandbox/trunk/pep3101/unicodeformat.c
==============================================================================
--- sandbox/trunk/pep3101/unicodeformat.c	(original)
+++ sandbox/trunk/pep3101/unicodeformat.c	Thu Mar 1 18:53:24 2007
@@ -81,15 +81,30 @@
 } SubStringObj;
 
 /*
+ A MarkupEscapeHandler allows us to handle different escape
+ mechanisms between regular text and markup. This is useful
+ both for providing alternate markup syntax, and for
+ providing an eval() type function where there is no regular
+ text.
+*/
+typedef struct FmtState *FSPTR;
+typedef int
+(*MarkupEscapeHandler)(FSPTR fs);
+
+/*
 If this were written in C++, FmtState would be the class,
 and most of the functions inside this file would be members
 of this class.
 */
-typedef struct {
+typedef struct FmtState {
 /* args passed to PyString_FormatMethod or PyUnicode_FormatMethod */
 PyObject *args;
 /* keywords passed to PyString_FormatMethod or PyUnicode_FormatMethod */
 PyObject *keywords;
+ /* arg_param_offset is 1 if not called as a method */
+ int arg_param_offset;
+ /* Function to call to perform markup */
+ MarkupEscapeHandler do_markup;
 /* current position and end of the 'self' string passed to FormatMethod */
 SubString fmtstr;
 /* Output string we are constructing, including current and end pointers*/
@@ -212,7 +227,7 @@
 static void
 PySet_Discard(PyObject *myset, PyObject *mykey)
 {
- /* XXX --- Need to add the right code here */
+ Py_XDECREF(PyObject_CallMethod(myset, "discard", "(O)", mykey));
 }
 #endif
 
@@ -430,6 +445,7 @@
 Py_ssize_t index;
 int isindex, expectclose, isnumeric, isargument;
 
+ index = 0; /* Just to shut up the compiler warning */
 if (!check_fmtstr(fs))
 return NULL;
 isnumeric = (CH_TYPE_ISDECIMAL(*fs->fmtstr.ptr));
@@ -454,6 +470,7 @@
 if (isargument)
 fs->positional_arg_set &= ~(1 << index);
 }
+
 if (isnumeric && PySequence_Check(myobj))
 newobj = PySequence_GetItem(myobj, index);
 else {
@@ -961,13 +978,13 @@
 }
 
 /*
- do_format is the main program loop. It rummages through
+ do_markup is the main program loop. It rummages through
 the format string, looking for escapes to markup, and
 calls other functions to move non-markup text to the output,
 and to perform the markup to the output.
 */
-static PyObject *
-do_format(FmtState *fs)
+static int
+do_markup(FmtState *fs)
 {
 PyObject *myobj;
 CH_TYPE c, *start;
@@ -976,13 +993,6 @@
 int doubled, ok;
 
 fmtstr = fs->fmtstr;
- count = fmtstr.end - fmtstr.ptr;
- myobj = STROBJ_NEW(NULL, count + INITIAL_SIZE_INCREMENT);
- if (myobj == NULL)
- return NULL;
- fs->outstr = make_substrobj(myobj);
- fs->size_increment = INITIAL_SIZE_INCREMENT;
-
 ok = 1;
 c = '0円'; /* Avoid compiler warning */
 while (fmtstr.ptr < fmtstr.end) {
@@ -1020,9 +1030,31 @@
 break;
 fmtstr.ptr = fs->fmtstr.ptr;
 }
- myobj = fs->outstr.obj;
+ return ok;
+}
+
+/*
+ do_format allocates the output string and then
+ calls a markup handler to do the dirty work.
+*/
+static PyObject *
+do_format(FmtState *fs)
+{
+ PyObject *myobj;
+ int ok;
+
+ myobj = STROBJ_NEW(NULL,
+ fs->fmtstr.end - fs->fmtstr.ptr + INITIAL_SIZE_INCREMENT);
+ if (myobj == NULL)
+ return NULL;
+ fs->outstr = make_substrobj(myobj);
+ fs->size_increment = INITIAL_SIZE_INCREMENT;
+
+ ok = fs->do_markup(fs);
+
+ myobj = fs->outstr.obj; /* Might have been reallocated */
 if (ok) {
- count = fs->outstr.ptr - STROBJ_AS_PTR(myobj);
+ int count = fs->outstr.ptr - STROBJ_AS_PTR(myobj);
 if (STROBJ_RESIZE(&myobj, count) >= 0)
 return myobj;
 }
@@ -1050,6 +1082,7 @@
 return result;
 }
 
+
 /*
 STROBJ_FORMAT (actually PyUnicode_FormatMethod or PyString_FormatMethod)
 is the public interface to the module.
@@ -1062,12 +1095,25 @@
 {
 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;


More information about the Python-checkins mailing list

AltStyle によって変換されたページ (->オリジナル) /