Changeset 12


Ignore:
Timestamp:
07/27/05 19:47:47 (8 years ago)
Author:
xi
Message:

Add _syck.Node and _syck.Scalar types.

Location:
trunk
Files:
1 added
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/ext/_syckmodule.c

    r9 r12  
    33#include <syck.h> 
    44 
    5 /* Global objects. */ 
     5/* Python 2.2 compatibility. */ 
     6 
     7#ifndef PyDoc_STR 
     8#define PyDoc_VAR(name)         static char name[] 
     9#define PyDoc_STR(str)          (str) 
     10#define PyDoc_STRVAR(name, str) PyDoc_VAR(name) = PyDoc_STR(str) 
     11#endif 
     12 
     13#ifndef PyMODINIT_FUNC 
     14#define PyMODINIT_FUNC  void 
     15#endif 
     16 
     17/* Global objects: _syck.error, 'scalar', 'seq', 'map', 
     18    '1quote', '2quote', 'fold', 'literal', 'plain', '+', '-'. */ 
    619 
    720static PyObject *PySyck_Error; 
     
    1124static PyObject *PySyck_MapKind; 
    1225 
    13 /* Node type. */ 
    14  
     26static PyObject *PySyck_1QuoteStyle; 
     27static PyObject *PySyck_2QuoteStyle; 
     28static PyObject *PySyck_FoldStyle; 
     29static PyObject *PySyck_LiteralStyle; 
     30static PyObject *PySyck_PlainStyle; 
     31 
     32static PyObject *PySyck_StripChomp; 
     33static PyObject *PySyck_KeepChomp; 
     34 
     35/* The type _syck.Node. */ 
     36 
     37PyDoc_STRVAR(PySyckNode_doc, 
     38    "The base Node type\n\n" 
     39    "_syck.Node is an abstract type. It is a base type for _syck.Scalar,\n" 
     40    "_syck.Seq, and _syck.Map. You cannot create an instance of _syck.Node\n" 
     41    "directly. You may use _syck.Node for type checking.\n"); 
     42 
     43static PyTypeObject PySyckNode_Type = { 
     44    PyObject_HEAD_INIT(NULL) 
     45    0,                                          /* ob_size */ 
     46    "_syck.Node",                               /* tp_name */ 
     47    sizeof(PyObject),                           /* tp_basicsize */ 
     48    0,                                          /* tp_itemsize */ 
     49    0,                                          /* tp_dealloc */ 
     50    0,                                          /* tp_print */ 
     51    0,                                          /* tp_getattr */ 
     52    0,                                          /* tp_setattr */ 
     53    0,                                          /* tp_compare */ 
     54    0,                                          /* tp_repr */ 
     55    0,                                          /* tp_as_number */ 
     56    0,                                          /* tp_as_sequence */ 
     57    0,                                          /* tp_as_mapping */ 
     58    0,                                          /* tp_hash */ 
     59    0,                                          /* tp_call */ 
     60    0,                                          /* tp_str */ 
     61    0,                                          /* tp_getattro */ 
     62    0,                                          /* tp_setattro */ 
     63    0,                                          /* tp_as_buffer */ 
     64    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,     /* tp_flags */ 
     65    PySyckNode_doc,                             /* tp_doc */ 
     66}; 
     67 
     68/* The type _syck.Scalar */ 
     69 
     70PyDoc_STRVAR(PySyckScalar_doc, 
     71    "The Scalar node type\n\n" 
     72    "_syck.Scalar represents a scalar node in Syck parser and emitter\n" 
     73    "graph. A scalar node points to a single string value.\n\n" 
     74    "Attributes:\n\n" 
     75    "kind -- always 'scalar'; read-only\n" 
     76    "value -- the node value, a string\n" 
     77    "tag -- the node tag; a string or None\n" 
     78    "anchor -- the name of the node anchor or None; read-only\n" 
     79    "style -- the node style; None (means literal or plain),\n" 
     80    "         '1quote', '2quote', 'fold', 'literal', 'plain'\n" 
     81    "indent -- indentation, an integer; 0 means default\n" 
     82    "width -- the preferred width; 0 means default\n" 
     83    "chomp -- None (clip), '-' (strip), or '+' (keep)\n"); 
     84 
     85typedef struct { 
     86    PyObject_HEAD 
     87    PyObject *value; 
     88    PyObject *tag; 
     89    PyObject *anchor; 
     90    enum scalar_style style; 
     91    int indent; 
     92    int width; 
     93    char chomp; 
     94} PySyckScalarObject; 
     95 
     96static int 
     97PySyckScalar_clear(PySyckScalarObject *self) 
     98{ 
     99    Py_XDECREF(self->value); 
     100    self->value = NULL; 
     101    Py_XDECREF(self->tag); 
     102    self->tag = NULL; 
     103    Py_XDECREF(self->anchor); 
     104    self->anchor = NULL; 
     105 
     106    return 0; 
     107} 
     108 
     109static int 
     110PySyckScalar_traverse(PySyckScalarObject *self, visitproc visit, void *arg) 
     111{ 
     112    if (self->value && visit(self->value, arg) < 0) 
     113        return -1; 
     114    if (self->tag && visit(self->tag, arg) < 0) 
     115        return -1; 
     116    if (self->anchor && visit(self->anchor, arg) < 0) 
     117        return -1; 
     118 
     119    return 0; 
     120} 
     121 
     122static void 
     123PySyckScalar_dealloc(PySyckScalarObject *self) 
     124{ 
     125    PySyckScalar_clear(self); 
     126    self->ob_type->tp_free((PyObject *)self); 
     127} 
     128 
     129static PyObject * 
     130PySyckScalar_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 
     131{ 
     132    PySyckScalarObject *self; 
     133 
     134    self = (PySyckScalarObject *)type->tp_alloc(type, 0); 
     135    if (!self) return NULL; 
     136 
     137    self->value = PyString_FromString(""); 
     138    if (!self->value) { 
     139        Py_DECREF(self); 
     140        return NULL; 
     141    } 
     142 
     143    self->tag = NULL; 
     144    self->anchor = NULL; 
     145    self->style = scalar_none; 
     146    self->indent = 0; 
     147    self->width = 0; 
     148    self->chomp = 0; 
     149 
     150    return (PyObject *)self; 
     151} 
     152 
     153static PyObject * 
     154PySyckScalar_getkind(PySyckScalarObject *self, void *closure) 
     155{ 
     156    Py_INCREF(PySyck_ScalarKind); 
     157    return PySyck_ScalarKind; 
     158} 
     159 
     160static PyObject * 
     161PySyckScalar_getvalue(PySyckScalarObject *self, void *closure) 
     162{ 
     163    Py_INCREF(self->value); 
     164    return self->value; 
     165} 
     166 
     167static int 
     168PySyckScalar_setvalue(PySyckScalarObject *self, PyObject *value, void *closure) 
     169{ 
     170    if (!value) { 
     171        PyErr_SetString(PyExc_TypeError, "cannot delete 'value'"); 
     172        return -1; 
     173    } 
     174    if (!PyString_Check(value)) { 
     175        PyErr_SetString(PyExc_TypeError, "'value' must be a string"); 
     176        return -1; 
     177    } 
     178 
     179    Py_DECREF(self->value); 
     180    Py_INCREF(value); 
     181    self->value = value; 
     182 
     183    return 0; 
     184} 
     185 
     186static PyObject * 
     187PySyckScalar_gettag(PySyckScalarObject *self, void *closure) 
     188{ 
     189    PyObject *value = self->tag ? self->tag : Py_None; 
     190    Py_INCREF(value); 
     191    return value; 
     192} 
     193 
     194static int 
     195PySyckScalar_settag(PySyckScalarObject *self, PyObject *value, void *closure) 
     196{ 
     197    if (!value) { 
     198        PyErr_SetString(PyExc_TypeError, "cannot delete 'tag'"); 
     199        return -1; 
     200    } 
     201 
     202    if (value == Py_None) { 
     203        Py_XDECREF(self->tag); 
     204        self->tag = NULL; 
     205        return 0; 
     206    } 
     207 
     208    if (!PyString_Check(value)) { 
     209        PyErr_SetString(PyExc_TypeError, "'tag' must be a string"); 
     210        return -1; 
     211    } 
     212 
     213    Py_XDECREF(self->tag); 
     214    Py_INCREF(value); 
     215    self->tag = value; 
     216 
     217    return 0; 
     218} 
     219 
     220static PyObject * 
     221PySyckScalar_getanchor(PySyckScalarObject *self, void *closure) 
     222{ 
     223    PyObject *value = self->anchor ? self->anchor : Py_None; 
     224    Py_INCREF(value); 
     225    return value; 
     226} 
     227 
     228static int 
     229PySyckScalar_setanchor(PySyckScalarObject *self, PyObject *value, void *closure) 
     230{ 
     231    if (!value) { 
     232        PyErr_SetString(PyExc_TypeError, "cannot delete 'anchor'"); 
     233        return -1; 
     234    } 
     235 
     236    if (value == Py_None) { 
     237        Py_XDECREF(self->anchor); 
     238        self->anchor = NULL; 
     239        return 0; 
     240    } 
     241 
     242    if (!PyString_Check(value)) { 
     243        PyErr_SetString(PyExc_TypeError, "'anchor' must be a string"); 
     244        return -1; 
     245    } 
     246 
     247    Py_XDECREF(self->anchor); 
     248    Py_INCREF(value); 
     249    self->anchor = value; 
     250 
     251    return 0; 
     252} 
     253 
     254static PyObject * 
     255PySyckScalar_getstyle(PySyckScalarObject *self, void *closure) 
     256{ 
     257    PyObject *value; 
     258 
     259    switch (self->style) { 
     260        case scalar_1quote: value = PySyck_1QuoteStyle; break; 
     261        case scalar_2quote: value = PySyck_2QuoteStyle; break; 
     262        case scalar_fold: value = PySyck_FoldStyle; break; 
     263        case scalar_literal: value = PySyck_LiteralStyle; break; 
     264        case scalar_plain: value = PySyck_PlainStyle; break; 
     265        default: value = Py_None; 
     266    } 
     267 
     268    Py_INCREF(value); 
     269    return value; 
     270} 
     271 
     272static int 
     273PySyckScalar_setstyle(PySyckScalarObject *self, PyObject *value, void *closure) 
     274{ 
     275    char *str; 
     276 
     277    if (!value) { 
     278        PyErr_SetString(PyExc_TypeError, "cannot delete 'style'"); 
     279        return -1; 
     280    } 
     281 
     282    if (value == Py_None) { 
     283        self->style = scalar_none; 
     284        return 0; 
     285    } 
     286 
     287    if (!PyString_Check(value)) { 
     288        PyErr_SetString(PyExc_TypeError, "'style' must be a string or None"); 
     289        return -1; 
     290    } 
     291 
     292    str = PyString_AsString(value); 
     293    if (!str) return -1; 
     294 
     295    if (strcmp(str, "1quote") == 0) 
     296        self->style = scalar_1quote; 
     297    else if (strcmp(str, "2quote") == 0) 
     298        self->style = scalar_2quote; 
     299    else if (strcmp(str, "fold") == 0) 
     300        self->style = scalar_fold; 
     301    else if (strcmp(str, "literal") == 0) 
     302        self->style = scalar_literal; 
     303    else if (strcmp(str, "plain") == 0) 
     304        self->style = scalar_plain; 
     305    else { 
     306        PyErr_SetString(PyExc_TypeError, "unknown 'style'"); 
     307        return -1; 
     308    } 
     309 
     310    return 0; 
     311} 
     312 
     313static PyObject * 
     314PySyckScalar_getindent(PySyckScalarObject *self, void *closure) 
     315{ 
     316    return PyInt_FromLong(self->indent); 
     317} 
     318 
     319static int 
     320PySyckScalar_setindent(PySyckScalarObject *self, PyObject *value, void *closure) 
     321{ 
     322    if (!value) { 
     323        PyErr_SetString(PyExc_TypeError, "cannot delete 'indent'"); 
     324        return -1; 
     325    } 
     326 
     327    if (!PyInt_Check(value)) { 
     328        PyErr_SetString(PyExc_TypeError, "'indent' must be an integer"); 
     329        return -1; 
     330    } 
     331 
     332    self->indent = PyInt_AS_LONG(value); 
     333 
     334    return 0; 
     335} 
     336 
     337static PyObject * 
     338PySyckScalar_getwidth(PySyckScalarObject *self, void *closure) 
     339{ 
     340    return PyInt_FromLong(self->width); 
     341} 
     342 
     343static int 
     344PySyckScalar_setwidth(PySyckScalarObject *self, PyObject *value, void *closure) 
     345{ 
     346    if (!value) { 
     347        PyErr_SetString(PyExc_TypeError, "cannot delete 'width'"); 
     348        return -1; 
     349    } 
     350 
     351    if (!PyInt_Check(value)) { 
     352        PyErr_SetString(PyExc_TypeError, "'width' must be an integer"); 
     353        return -1; 
     354    } 
     355 
     356    self->width = PyInt_AS_LONG(value); 
     357 
     358    return 0; 
     359} 
     360 
     361static PyObject * 
     362PySyckScalar_getchomp(PySyckScalarObject *self, void *closure) 
     363{ 
     364    PyObject *value; 
     365 
     366    switch (self->chomp) { 
     367        case NL_CHOMP: value = PySyck_StripChomp; break; 
     368        case NL_KEEP: value = PySyck_KeepChomp; break; 
     369        default: value = Py_None; 
     370    } 
     371 
     372    Py_INCREF(value); 
     373    return value; 
     374} 
     375 
     376static int 
     377PySyckScalar_setchomp(PySyckScalarObject *self, PyObject *value, void *closure) 
     378{ 
     379    char *str; 
     380 
     381    if (!value) { 
     382        PyErr_SetString(PyExc_TypeError, "cannot delete 'chomp'"); 
     383        return -1; 
     384    } 
     385 
     386    if (value == Py_None) { 
     387        self->chomp = 0; 
     388        return 0; 
     389    } 
     390 
     391    if (!PyString_Check(value)) { 
     392        PyErr_SetString(PyExc_TypeError, "'chomp' must be '+', '-', or None"); 
     393        return -1; 
     394    } 
     395 
     396    str = PyString_AsString(value); 
     397    if (!str) return -1; 
     398 
     399    if (strcmp(str, "-") == 0) 
     400        self->chomp = NL_CHOMP; 
     401    else if (strcmp(str, "+") == 0) 
     402        self->chomp = NL_KEEP; 
     403    else { 
     404        PyErr_SetString(PyExc_TypeError, "'chomp' must be '+', '-', or None"); 
     405        return -1; 
     406    } 
     407 
     408    return 0; 
     409} 
     410 
     411static int 
     412PySyckScalar_init(PySyckScalarObject *self, PyObject *args, PyObject *kwds) 
     413{ 
     414    PyObject *value = NULL; 
     415    PyObject *tag = NULL; 
     416    PyObject *anchor = NULL; 
     417    PyObject *style = NULL; 
     418    PyObject *indent = NULL; 
     419    PyObject *width = NULL; 
     420    PyObject *chomp = NULL; 
     421 
     422    static char *kwdlist[] = {"value", "tag", "anchor", 
     423        "style", "indent", "width", "chomp", NULL}; 
     424 
     425    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOOO", kwdlist, 
     426                &value, &tag, &anchor, &style, &indent, &width, &chomp)) 
     427        return -1; 
     428 
     429    if (value && PySyckScalar_setvalue(self, value, NULL) < 0) 
     430        return -1; 
     431 
     432    if (tag && PySyckScalar_settag(self, tag, NULL) < 0) 
     433        return -1; 
     434 
     435    if (anchor && PySyckScalar_setanchor(self, anchor, NULL) < 0) 
     436        return -1; 
     437 
     438    if (style && PySyckScalar_setstyle(self, style, NULL) < 0) 
     439        return -1; 
     440 
     441    if (indent && PySyckScalar_setindent(self, indent, NULL) < 0) 
     442        return -1; 
     443 
     444    if (width && PySyckScalar_setwidth(self, width, NULL) < 0) 
     445        return -1; 
     446 
     447    if (chomp && PySyckScalar_setchomp(self, chomp, NULL) < 0) 
     448        return -1; 
     449 
     450    return 0; 
     451} 
     452 
     453static PyGetSetDef PySyckScalar_getsetters[] = { 
     454    {"kind", (getter)PySyckScalar_getkind, NULL, 
     455        "the node kind", NULL}, 
     456    {"value", (getter)PySyckScalar_getvalue, (setter)PySyckScalar_setvalue, 
     457        "the node value", NULL}, 
     458    {"tag", (getter)PySyckScalar_gettag, (setter)PySyckScalar_settag, 
     459        "the node tag", NULL}, 
     460    {"anchor", (getter)PySyckScalar_getanchor, (setter)PySyckScalar_setanchor, 
     461        "the node anchor", NULL}, 
     462    {"style", (getter)PySyckScalar_getstyle, (setter)PySyckScalar_setstyle, 
     463        "the node style", NULL}, 
     464    {"indent", (getter)PySyckScalar_getindent, (setter)PySyckScalar_setindent, 
     465        "the field indentation", NULL}, 
     466    {"width", (getter)PySyckScalar_getwidth, (setter)PySyckScalar_setwidth, 
     467        "the field width", NULL}, 
     468    {"chomp", (getter)PySyckScalar_getchomp, (setter)PySyckScalar_setchomp, 
     469        "the chomping method", NULL}, 
     470    {NULL}  /* Sentinel */ 
     471}; 
     472 
     473static PyTypeObject PySyckScalar_Type = { 
     474    PyObject_HEAD_INIT(NULL) 
     475    0,                                          /* ob_size */ 
     476    "_syck.Scalar",                             /* tp_name */ 
     477    sizeof(PySyckScalarObject),                 /* tp_basicsize */ 
     478    0,                                          /* tp_itemsize */ 
     479    (destructor)PySyckScalar_dealloc,           /* tp_dealloc */ 
     480    0,                                          /* tp_print */ 
     481    0,                                          /* tp_getattr */ 
     482    0,                                          /* tp_setattr */ 
     483    0,                                          /* tp_compare */ 
     484    0,                                          /* tp_repr */ 
     485    0,                                          /* tp_as_number */ 
     486    0,                                          /* tp_as_sequence */ 
     487    0,                                          /* tp_as_mapping */ 
     488    0,                                          /* tp_hash */ 
     489    0,                                          /* tp_call */ 
     490    0,                                          /* tp_str */ 
     491    0,                                          /* tp_getattro */ 
     492    0,                                          /* tp_setattro */ 
     493    0,                                          /* tp_as_buffer */ 
     494    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC,  /* tp_flags */ 
     495    PySyckScalar_doc,                           /* tp_doc */ 
     496    (traverseproc)PySyckScalar_traverse,        /* tp_traverse */ 
     497    (inquiry)PySyckScalar_clear,                /* tp_clear */ 
     498    0,                                          /* tp_richcompare */ 
     499    0,                                          /* tp_weaklistoffset */ 
     500    0,                                          /* tp_iter */ 
     501    0,                                          /* tp_iternext */ 
     502    0,                                          /* tp_methods */ 
     503    0,                                          /* tp_members */ 
     504    PySyckScalar_getsetters,                    /* tp_getset */ 
     505    &PySyckNode_Type,                           /* tp_base */ 
     506    0,                                          /* tp_dict */ 
     507    0,                                          /* tp_descr_get */ 
     508    0,                                          /* tp_descr_set */ 
     509    0,                                          /* tp_dictoffset */ 
     510    (initproc)PySyckScalar_init,                /* tp_init */ 
     511    0,                                          /* tp_alloc */ 
     512    PySyckScalar_new,                           /* tp_new */ 
     513}; 
     514 
     515 
     516/* 
    15517typedef struct { 
    16518    PyObject_HEAD 
     
    49551} 
    50552 
    51 static char PySyckNode_doc[] = 
    52     "Node object\n" 
    53     "\n" 
    54     "Attributes of the Node object:\n\n" 
    55     "kind -- 'scalar', 'seq', or 'map'.\n" 
    56     "type_id -- the tag of the node.\n" 
    57     "value -- the value of the node, a string, list or dict object.\n"; 
    58  
     553 
     554*/ 
     555#if 0 
     556     
    59557static PyTypeObject PySyckNode_Type = { 
    60558    PyObject_HEAD_INIT(NULL) 
     
    133631    "Node object cannot be created explicitly. Use _syck.Parser.parse() instead."; 
    134632 
     633 
     634*/ 
     635 
    135636/* Parser type. */ 
    136637 
     
    5231024} 
    5241025 
     1026#endif 
     1027 
     1028/* The module _syck. */ 
     1029 
     1030static PyMethodDef PySyck_methods[] = { 
     1031    {NULL}  /* Sentinel */ 
     1032}; 
     1033 
     1034PyDoc_STRVAR(PySyck_doc, 
     1035    "The low-level wrapper for the Syck YAML parser and emitter\n\n" 
     1036    "Types:\n\n" 
     1037    "Node -- the base Node type\n"); 
     1038 
     1039PyMODINIT_FUNC 
     1040init_syck(void) 
     1041{ 
     1042    PyObject *m; 
     1043 
     1044    if (PyType_Ready(&PySyckNode_Type) < 0) 
     1045        return; 
     1046    if (PyType_Ready(&PySyckScalar_Type) < 0) 
     1047        return; 
     1048     
     1049    PySyck_Error = PyErr_NewException("_syck.error", NULL, NULL); 
     1050    if (!PySyck_Error) return; 
     1051 
     1052    PySyck_ScalarKind = PyString_FromString("scalar"); 
     1053    if (!PySyck_ScalarKind) return; 
     1054    PySyck_SeqKind = PyString_FromString("seq"); 
     1055    if (!PySyck_SeqKind) return; 
     1056    PySyck_MapKind = PyString_FromString("map"); 
     1057    if (!PySyck_MapKind) return; 
     1058 
     1059    PySyck_1QuoteStyle = PyString_FromString("1quote"); 
     1060    if (!PySyck_1QuoteStyle) return; 
     1061    PySyck_2QuoteStyle = PyString_FromString("2quote"); 
     1062    if (!PySyck_2QuoteStyle) return; 
     1063    PySyck_FoldStyle = PyString_FromString("fold"); 
     1064    if (!PySyck_FoldStyle) return; 
     1065    PySyck_LiteralStyle = PyString_FromString("literal"); 
     1066    if (!PySyck_LiteralStyle) return; 
     1067    PySyck_PlainStyle = PyString_FromString("plain"); 
     1068    if (!PySyck_PlainStyle) return; 
     1069 
     1070    PySyck_StripChomp = PyString_FromString("-"); 
     1071    if (!PySyck_StripChomp) return; 
     1072    PySyck_KeepChomp = PyString_FromString("+"); 
     1073    if (!PySyck_KeepChomp) return; 
     1074 
     1075    m = Py_InitModule3("_syck", PySyck_methods, PySyck_doc); 
     1076 
     1077    Py_INCREF(&PySyckNode_Type); 
     1078    if (PyModule_AddObject(m, "Node", (PyObject *)&PySyckNode_Type) < 0) 
     1079        return; 
     1080 
     1081    Py_INCREF(&PySyckScalar_Type); 
     1082    if (PyModule_AddObject(m, "Scalar", (PyObject *)&PySyckScalar_Type) < 0) 
     1083        return; 
     1084} 
     1085 
     1086 
  • trunk/tests/test_syck.py

    r9 r12  
    22import unittest 
    33 
    4 from test_low_parser import * 
    5 from test_high_parser import * 
     4from test_low_level_node import * 
     5#from test_low_parser import * 
     6#from test_high_parser import * 
    67 
    78def main(module='__main__'): 
Note: See TracChangeset for help on using the changeset viewer.