Changeset 2533:4e2231a50a71 in livinglogic.python.xist

Show
Ignore:
Timestamp:
05/31/06 14:58:40 (14 years ago)
Author:
Walter Doerwald <walter@…>
Branch:
default
Message:

Enhance helpers.escape() to be able to transform str and unicode objects.

Location:
src/ll/xist
Files:
1 added
1 modified

Legend:

Unmodified
Added
Removed
  • src/ll/xist/helpers.c

    r2520 r2533  
    1111#include "Python.h" 
    1212 
    13 static Py_UNICODE lt[] = { ((Py_UNICODE)'&'), ((Py_UNICODE)'l'), ((Py_UNICODE)'t'), ((Py_UNICODE)';') }; 
    14 static Py_UNICODE gt[] = { ((Py_UNICODE)'&'), ((Py_UNICODE)'g'), ((Py_UNICODE)'t'), ((Py_UNICODE)';') }; 
    15 static Py_UNICODE amp[] = { ((Py_UNICODE)'&'), ((Py_UNICODE)'a'), ((Py_UNICODE)'m'), ((Py_UNICODE)'p'), ((Py_UNICODE)';') }; 
    16 static Py_UNICODE quot[] = { ((Py_UNICODE)'&'), ((Py_UNICODE)'q'), ((Py_UNICODE)'u'), ((Py_UNICODE)'o'), ((Py_UNICODE)'t'), ((Py_UNICODE)';') }; 
    17  
    18 static Py_UNICODE hexdigits[] = { (Py_UNICODE)'0', (Py_UNICODE)'1', (Py_UNICODE)'2', (Py_UNICODE)'3', (Py_UNICODE)'4', (Py_UNICODE)'5', (Py_UNICODE)'6', (Py_UNICODE)'7', (Py_UNICODE)'8', (Py_UNICODE)'9', (Py_UNICODE)'A', (Py_UNICODE)'B', (Py_UNICODE)'C', (Py_UNICODE)'D', (Py_UNICODE)'E', (Py_UNICODE)'F' }; 
    19  
    20 #define COUNTOF(x) (sizeof(x)/sizeof((x)[0])) 
     13 
     14/* define unicode version of escape */ 
     15#define STRINGLIB_NAME escape_unicode 
     16#define STRINGLIB_CHAR Py_UNICODE 
     17#define STRINGLIB_LEN  PyUnicode_GET_SIZE 
     18#define STRINGLIB_NEW  PyUnicode_FromUnicode 
     19#define STRINGLIB_STR  PyUnicode_AS_UNICODE 
     20 
     21#include "helpers.h" 
     22 
     23#undef STRINGLIB_NAME 
     24#undef STRINGLIB_CHAR 
     25#undef STRINGLIB_LEN 
     26#undef STRINGLIB_NEW 
     27#undef STRINGLIB_STR 
     28 
     29 
     30/* define str version of escape */ 
     31#define STRINGLIB_NAME escape_str 
     32#define STRINGLIB_CHAR unsigned char 
     33#define STRINGLIB_LEN PyString_GET_SIZE 
     34#define STRINGLIB_NEW PyString_FromStringAndSize 
     35#define STRINGLIB_STR PyString_AS_STRING 
     36 
     37#include "helpers.h" 
     38 
     39#undef STRINGLIB_NAME 
     40#undef STRINGLIB_CHAR 
     41#undef STRINGLIB_LEN 
     42#undef STRINGLIB_NEW 
     43#undef STRINGLIB_STR 
    2144 
    2245 
    2346static PyObject *escape(PyObject *str, int inattr) 
    2447{ 
    25     int i; 
    26     int oldsize; 
    27     int newsize = 0; 
    28  
    29     oldsize = PyUnicode_GET_SIZE(str); 
    30     for (i = 0; i < oldsize; ++i) 
    31     { 
    32         Py_UNICODE ch = PyUnicode_AS_UNICODE(str)[i]; 
    33         if (ch == ((Py_UNICODE)'<')) 
    34             newsize += COUNTOF(lt); 
    35         else if (ch == (Py_UNICODE)'>') /* Note that we always replace '>' with its entity, not just in case it is part of ']]>' */ 
    36             newsize += COUNTOF(gt); 
    37         else if (ch == (Py_UNICODE)'&') 
    38             newsize += COUNTOF(amp); 
    39         else if ((ch == (Py_UNICODE)'"') && inattr) 
    40             newsize += COUNTOF(quot); 
    41         else if (ch <= 0x8) 
    42             newsize += 4; 
    43         else if ((ch >= 0xB) && (ch <= 0x1F) && (ch != 0xD)) 
    44             newsize += 5; 
    45         else if ((ch >= 0x7F) && (ch <= 0x9F) && (ch != 0x85)) 
    46             newsize += 6; 
    47         else 
    48             newsize++; 
    49     } 
    50     if (oldsize==newsize) 
    51     { 
    52         /* nothing to replace => return original */ 
    53         Py_INCREF(str); 
    54         return str; 
     48    if (PyUnicode_Check(str)) 
     49    { 
     50        return escape_unicode(str, inattr); 
     51    } 
     52    else if (PyString_Check(str)) 
     53    { 
     54        return escape_str(str, inattr); 
    5555    } 
    5656    else 
    5757    { 
    58         PyObject *result = PyUnicode_FromUnicode(NULL, newsize); 
    59         Py_UNICODE *p; 
    60         if (result == NULL) 
    61             return NULL; 
    62         p = PyUnicode_AS_UNICODE(result); 
    63         for (i = 0; i < oldsize; ++i) 
    64         { 
    65             Py_UNICODE ch = PyUnicode_AS_UNICODE(str)[i]; 
    66             if (ch == (Py_UNICODE)'<') 
    67             { 
    68                 Py_UNICODE_COPY(p, lt, COUNTOF(lt)); 
    69                 p += COUNTOF(lt); 
    70             } 
    71             else if (ch == (Py_UNICODE)'>') 
    72             { 
    73                 Py_UNICODE_COPY(p, gt, COUNTOF(gt)); 
    74                 p += COUNTOF(gt); 
    75             } 
    76             else if (ch == (Py_UNICODE)'&') 
    77             { 
    78                 Py_UNICODE_COPY(p, amp, COUNTOF(amp)); 
    79                 p += COUNTOF(amp); 
    80             } 
    81             else if ((ch == (Py_UNICODE)'"') && inattr) 
    82             { 
    83                 Py_UNICODE_COPY(p, quot, COUNTOF(quot)); 
    84                 p += COUNTOF(quot); 
    85             } 
    86             else if (ch <= 0x8) 
    87             { 
    88                 *p++ = (Py_UNICODE)'&'; 
    89                 *p++ = (Py_UNICODE)'#'; 
    90                 *p++ = (Py_UNICODE)('0'+ch); 
    91                 *p++ = (Py_UNICODE)';'; 
    92             } 
    93             else if ((ch >= 0xB) && (ch <= 0x1F) && (ch != 0xD)) 
    94             { 
    95                 *p++ = (Py_UNICODE)'&'; 
    96                 *p++ = (Py_UNICODE)'#'; 
    97                 *p++ = (Py_UNICODE)('0'+ch/10); 
    98                 *p++ = (Py_UNICODE)('0'+ch%10); 
    99                 *p++ = (Py_UNICODE)';'; 
    100             } 
    101             else if ((ch >= 0x7F) && (ch <= 0x9F) && (ch != 0x85)) 
    102             { 
    103                 *p++ = (Py_UNICODE)'&'; 
    104                 *p++ = (Py_UNICODE)'#'; 
    105                 *p++ = (Py_UNICODE)('0'+ch/100); 
    106                 *p++ = (Py_UNICODE)('0'+(ch/10)%10); 
    107                 *p++ = (Py_UNICODE)('0'+ch%10); 
    108                 *p++ = (Py_UNICODE)';'; 
    109             } 
    110             else 
    111                 *p++ = ch; 
    112         } 
    113         return result; 
     58        PyErr_SetString(PyExc_TypeError, "need str or unicode"); 
     59        return NULL; 
    11460    } 
    11561} 
     
    12470 
    12571 
    126 static PyObject *escapetext(PyObject *self, PyObject *args) 
    127 { 
    128     PyObject *str; 
    129  
    130     if (!PyArg_ParseTuple(args, "O!:escapetext", &PyUnicode_Type, &str)) 
    131         return NULL; 
    132  
    133     return escape(str, 0); 
     72static PyObject *escapetext(PyObject *self, PyObject *arg) 
     73{ 
     74    return escape(arg, 0); 
    13475} 
    13576 
     
    14384 
    14485 
    145 static PyObject *escapeattr(PyObject *self, PyObject *args) 
    146 { 
    147     PyObject *str; 
    148  
    149     if (!PyArg_ParseTuple(args, "O!:escapeattr", &PyUnicode_Type, &str)) 
    150         return NULL; 
    151  
    152     return escape(str, 1); 
     86static PyObject *escapeattr(PyObject *self, PyObject *arg) 
     87{ 
     88    return escape(arg, 1); 
    15389} 
    15490 
     
    16197escape sequence."; 
    16298 
     99 
     100static Py_UNICODE hexdigits[] = { (Py_UNICODE)'0', (Py_UNICODE)'1', (Py_UNICODE)'2', (Py_UNICODE)'3', (Py_UNICODE)'4', (Py_UNICODE)'5', (Py_UNICODE)'6', (Py_UNICODE)'7', (Py_UNICODE)'8', (Py_UNICODE)'9', (Py_UNICODE)'A', (Py_UNICODE)'B', (Py_UNICODE)'C', (Py_UNICODE)'D', (Py_UNICODE)'E', (Py_UNICODE)'F' }; 
    163101 
    164102static PyObject *cssescapereplace(PyObject *self, PyObject *args) 
     
    308246 
    309247 
    310 static char strict__doc__[] = 
    311 "strict(unicode, encoding) -> unicode\n\ 
    312 \n\ 
    313 Return a copy of the string S without any replacements."; 
    314  
    315  
    316 static PyObject *strict(PyObject *self, PyObject *args) 
    317 { 
    318     PyObject *str; 
    319     const char *encoding; 
    320  
    321     if (!PyArg_ParseTuple(args, "O!s:strict", &PyUnicode_Type, &str, &encoding)) 
    322         return NULL; 
    323  
    324     Py_INCREF(str); 
    325     return str; 
    326 } 
    327  
    328  
    329248/* ==================================================================== */ 
    330249/* python module interface */ 
     
    333252{ 
    334253    {"cssescapereplace", cssescapereplace, METH_VARARGS, cssescapereplace__doc__ }, 
    335     {"strict",           strict,           METH_VARARGS, strict__doc__ }, 
    336     {"escapetext",       escapetext,       METH_VARARGS, escapetext__doc__}, 
    337     {"escapeattr",       escapeattr,       METH_VARARGS, escapeattr__doc__}, 
     254    {"escapetext",       escapetext,       METH_O      , escapetext__doc__}, 
     255    {"escapeattr",       escapeattr,       METH_O      , escapeattr__doc__}, 
    338256    {NULL, NULL} 
    339257};