source: trunk/ext/_syckmodule.c @ 25

Revision 25, 66.0 KB checked in by xi, 9 years ago (diff)

Adding some docstrings.

RevLine 
[3]1
2#include <Python.h>
3#include <syck.h>
4
[14]5/****************************************************************************
6 * Python 2.2 compatibility.
7 ****************************************************************************/
[4]8
[12]9#ifndef PyDoc_STR
10#define PyDoc_VAR(name)         static char name[]
11#define PyDoc_STR(str)          (str)
12#define PyDoc_STRVAR(name, str) PyDoc_VAR(name) = PyDoc_STR(str)
13#endif
14
15#ifndef PyMODINIT_FUNC
16#define PyMODINIT_FUNC  void
17#endif
18
[14]19/****************************************************************************
20 * Global objects: _syck.error, 'scalar', 'seq', 'map',
21 * '1quote', '2quote', 'fold', 'literal', 'plain', '+', '-'.
22 ****************************************************************************/
[12]23
[5]24static PyObject *PySyck_Error;
[4]25
[5]26static PyObject *PySyck_ScalarKind;
27static PyObject *PySyck_SeqKind;
28static PyObject *PySyck_MapKind;
[4]29
[12]30static PyObject *PySyck_1QuoteStyle;
31static PyObject *PySyck_2QuoteStyle;
32static PyObject *PySyck_FoldStyle;
33static PyObject *PySyck_LiteralStyle;
34static PyObject *PySyck_PlainStyle;
[4]35
[12]36static PyObject *PySyck_StripChomp;
37static PyObject *PySyck_KeepChomp;
38
[14]39/****************************************************************************
40 * The type _syck.Node.
41 ****************************************************************************/
[12]42
43PyDoc_STRVAR(PySyckNode_doc,
[15]44    "_syck.Node() -> TypeError\n\n"
[25]45    "_syck.Node is an abstract type. It is the base type for _syck.Scalar,\n"
[12]46    "_syck.Seq, and _syck.Map. You cannot create an instance of _syck.Node\n"
[15]47    "directly. You may use _syck.Node for type checking or subclassing.\n");
[12]48
[4]49typedef struct {
50    PyObject_HEAD
[14]51    /* Common fields for all Node types: */
52    PyObject *value;    /* always an object */
53    PyObject *tag;      /* a string object or NULL */
54    PyObject *anchor;   /* a string object or NULL */
55} PySyckNodeObject;
[12]56
[14]57
[12]58static int
[14]59PySyckNode_clear(PySyckNodeObject *self)
[12]60{
[14]61    PyObject *tmp;
62
63    tmp = self->value;
[12]64    self->value = NULL;
[14]65    Py_XDECREF(tmp);
66
67    tmp = self->tag;
[12]68    self->tag = NULL;
[14]69    Py_XDECREF(tmp);
[12]70
[14]71    tmp = self->anchor;
72    self->value = NULL;
73    Py_XDECREF(tmp);
74
[12]75    return 0;
76}
77
78static int
[14]79PySyckNode_traverse(PySyckNodeObject *self, visitproc visit, void *arg)
[12]80{
[14]81    int ret;
[12]82
[14]83    if (self->value)
84        if ((ret = visit(self->value, arg)) != 0)
85            return ret;
86
87    if (self->tag)
88        if ((ret = visit(self->tag, arg)) != 0)
89            return ret;
90
91    if (self->anchor)
92        if ((ret = visit(self->anchor, arg)) != 0)
93            return ret;
94
[12]95    return 0;
96}
97
98static void
[14]99PySyckNode_dealloc(PySyckNodeObject *self)
[12]100{
[14]101    PySyckNode_clear(self);
[12]102    self->ob_type->tp_free((PyObject *)self);
103}
104
105static PyObject *
[14]106PySyckNode_getkind(PySyckNodeObject *self, PyObject **closure)
[12]107{
[14]108    Py_INCREF(*closure);
109    return *closure;
[12]110}
111
112static PyObject *
[14]113PySyckNode_getvalue(PySyckNodeObject *self, void *closure)
[12]114{
115    Py_INCREF(self->value);
116    return self->value;
117}
118
119static PyObject *
[14]120PySyckNode_gettag(PySyckNodeObject *self, void *closure)
[12]121{
122    PyObject *value = self->tag ? self->tag : Py_None;
123    Py_INCREF(value);
124    return value;
125}
126
127static int
[14]128PySyckNode_settag(PySyckNodeObject *self, PyObject *value, void *closure)
[12]129{
130    if (!value) {
131        PyErr_SetString(PyExc_TypeError, "cannot delete 'tag'");
132        return -1;
133    }
134
135    if (value == Py_None) {
136        Py_XDECREF(self->tag);
137        self->tag = NULL;
138        return 0;
139    }
140
141    if (!PyString_Check(value)) {
142        PyErr_SetString(PyExc_TypeError, "'tag' must be a string");
143        return -1;
144    }
145
146    Py_XDECREF(self->tag);
147    Py_INCREF(value);
148    self->tag = value;
149
150    return 0;
151}
152
153static PyObject *
[14]154PySyckNode_getanchor(PySyckNodeObject *self, void *closure)
[12]155{
156    PyObject *value = self->anchor ? self->anchor : Py_None;
157    Py_INCREF(value);
158    return value;
159}
160
161static int
[14]162PySyckNode_setanchor(PySyckNodeObject *self, PyObject *value, void *closure)
[12]163{
164    if (!value) {
165        PyErr_SetString(PyExc_TypeError, "cannot delete 'anchor'");
166        return -1;
167    }
168
169    if (value == Py_None) {
170        Py_XDECREF(self->anchor);
171        self->anchor = NULL;
172        return 0;
173    }
174
175    if (!PyString_Check(value)) {
176        PyErr_SetString(PyExc_TypeError, "'anchor' must be a string");
177        return -1;
178    }
179
180    Py_XDECREF(self->anchor);
181    Py_INCREF(value);
182    self->anchor = value;
183
184    return 0;
185}
186
[14]187static PyTypeObject PySyckNode_Type = {
188    PyObject_HEAD_INIT(NULL)
189    0,                                          /* ob_size */
190    "_syck.Node",                               /* tp_name */
191    sizeof(PySyckNodeObject),                   /* tp_basicsize */
192    0,                                          /* tp_itemsize */
193    (destructor)PySyckNode_dealloc,             /* tp_dealloc */
194    0,                                          /* tp_print */
195    0,                                          /* tp_getattr */
196    0,                                          /* tp_setattr */
197    0,                                          /* tp_compare */
198    0,                                          /* tp_repr */
199    0,                                          /* tp_as_number */
200    0,                                          /* tp_as_sequence */
201    0,                                          /* tp_as_mapping */
202    0,                                          /* tp_hash */
203    0,                                          /* tp_call */
204    0,                                          /* tp_str */
205    0,                                          /* tp_getattro */
206    0,                                          /* tp_setattro */
207    0,                                          /* tp_as_buffer */
208    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC,  /* tp_flags */
209    PySyckNode_doc,                             /* tp_doc */
210    (traverseproc)PySyckNode_traverse,          /* tp_traverse */
211    (inquiry)PySyckNode_clear,                  /* tp_clear */
212};
213
214/****************************************************************************
215 * The type _syck.Scalar.
216 ****************************************************************************/
217
218PyDoc_STRVAR(PySyckScalar_doc,
219    "Scalar(value='', tag=None, style=None, indent=0, width=0, chomp=None)\n"
220    "      -> a Scalar node\n\n"
221    "_syck.Scalar represents a scalar node in Syck parser and emitter\n"
[25]222    "trees. A scalar node points to a single string value.\n");
[14]223
224typedef struct {
225    PyObject_HEAD
226    /* Common fields for all Node types: */
227    PyObject *value;    /* always a string object */
228    PyObject *tag;      /* a string object or NULL */
229    PyObject *anchor;   /* a string object or NULL */
230    /* Scalar-specific fields: */
231    enum scalar_style style;
232    int indent;
233    int width;
234    char chomp;
235} PySyckScalarObject;
236
[12]237static PyObject *
[14]238PySyckScalar_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
239{
240    PySyckScalarObject *self;
241
242    self = (PySyckScalarObject *)type->tp_alloc(type, 0);
243    if (!self) return NULL;
244
245    self->value = PyString_FromString("");
246    if (!self->value) {
247        Py_DECREF(self);
248        return NULL;
249    }
250
251    self->tag = NULL;
252    self->anchor = NULL;
253    self->style = scalar_none;
254    self->indent = 0;
255    self->width = 0;
256    self->chomp = 0;
257
258    return (PyObject *)self;
259}
260
261static int
262PySyckScalar_setvalue(PySyckScalarObject *self, PyObject *value, void *closure)
263{
264    if (!value) {
265        PyErr_SetString(PyExc_TypeError, "cannot delete 'value'");
266        return -1;
267    }
268    if (!PyString_Check(value)) {
269        PyErr_SetString(PyExc_TypeError, "'value' must be a string");
270        return -1;
271    }
272
273    Py_DECREF(self->value);
274    Py_INCREF(value);
275    self->value = value;
276
277    return 0;
278}
279
280static PyObject *
[12]281PySyckScalar_getstyle(PySyckScalarObject *self, void *closure)
282{
283    PyObject *value;
284
285    switch (self->style) {
286        case scalar_1quote: value = PySyck_1QuoteStyle; break;
287        case scalar_2quote: value = PySyck_2QuoteStyle; break;
288        case scalar_fold: value = PySyck_FoldStyle; break;
289        case scalar_literal: value = PySyck_LiteralStyle; break;
290        case scalar_plain: value = PySyck_PlainStyle; break;
291        default: value = Py_None;
292    }
293
294    Py_INCREF(value);
295    return value;
296}
297
298static int
299PySyckScalar_setstyle(PySyckScalarObject *self, PyObject *value, void *closure)
300{
301    char *str;
302
303    if (!value) {
304        PyErr_SetString(PyExc_TypeError, "cannot delete 'style'");
305        return -1;
306    }
307
308    if (value == Py_None) {
309        self->style = scalar_none;
310        return 0;
311    }
312
313    if (!PyString_Check(value)) {
314        PyErr_SetString(PyExc_TypeError, "'style' must be a string or None");
315        return -1;
316    }
317
318    str = PyString_AsString(value);
319    if (!str) return -1;
320
321    if (strcmp(str, "1quote") == 0)
322        self->style = scalar_1quote;
323    else if (strcmp(str, "2quote") == 0)
324        self->style = scalar_2quote;
325    else if (strcmp(str, "fold") == 0)
326        self->style = scalar_fold;
327    else if (strcmp(str, "literal") == 0)
328        self->style = scalar_literal;
329    else if (strcmp(str, "plain") == 0)
330        self->style = scalar_plain;
331    else {
[17]332        PyErr_SetString(PyExc_ValueError, "unknown 'style'");
[12]333        return -1;
334    }
335
336    return 0;
337}
338
339static PyObject *
340PySyckScalar_getindent(PySyckScalarObject *self, void *closure)
341{
342    return PyInt_FromLong(self->indent);
343}
344
345static int
346PySyckScalar_setindent(PySyckScalarObject *self, PyObject *value, void *closure)
347{
348    if (!value) {
349        PyErr_SetString(PyExc_TypeError, "cannot delete 'indent'");
350        return -1;
351    }
352
353    if (!PyInt_Check(value)) {
354        PyErr_SetString(PyExc_TypeError, "'indent' must be an integer");
355        return -1;
356    }
357
358    self->indent = PyInt_AS_LONG(value);
359
360    return 0;
361}
362
363static PyObject *
364PySyckScalar_getwidth(PySyckScalarObject *self, void *closure)
365{
366    return PyInt_FromLong(self->width);
367}
368
369static int
370PySyckScalar_setwidth(PySyckScalarObject *self, PyObject *value, void *closure)
371{
372    if (!value) {
373        PyErr_SetString(PyExc_TypeError, "cannot delete 'width'");
374        return -1;
375    }
376
377    if (!PyInt_Check(value)) {
378        PyErr_SetString(PyExc_TypeError, "'width' must be an integer");
379        return -1;
380    }
381
382    self->width = PyInt_AS_LONG(value);
383
384    return 0;
385}
386
387static PyObject *
388PySyckScalar_getchomp(PySyckScalarObject *self, void *closure)
389{
390    PyObject *value;
391
392    switch (self->chomp) {
393        case NL_CHOMP: value = PySyck_StripChomp; break;
394        case NL_KEEP: value = PySyck_KeepChomp; break;
395        default: value = Py_None;
396    }
397
398    Py_INCREF(value);
399    return value;
400}
401
402static int
403PySyckScalar_setchomp(PySyckScalarObject *self, PyObject *value, void *closure)
404{
405    char *str;
406
407    if (!value) {
408        PyErr_SetString(PyExc_TypeError, "cannot delete 'chomp'");
409        return -1;
410    }
411
412    if (value == Py_None) {
413        self->chomp = 0;
414        return 0;
415    }
416
417    if (!PyString_Check(value)) {
418        PyErr_SetString(PyExc_TypeError, "'chomp' must be '+', '-', or None");
419        return -1;
420    }
421
422    str = PyString_AsString(value);
423    if (!str) return -1;
424
425    if (strcmp(str, "-") == 0)
426        self->chomp = NL_CHOMP;
427    else if (strcmp(str, "+") == 0)
428        self->chomp = NL_KEEP;
429    else {
430        PyErr_SetString(PyExc_TypeError, "'chomp' must be '+', '-', or None");
431        return -1;
432    }
433
434    return 0;
435}
436
437static int
438PySyckScalar_init(PySyckScalarObject *self, PyObject *args, PyObject *kwds)
439{
440    PyObject *value = NULL;
441    PyObject *tag = NULL;
442    PyObject *anchor = NULL;
443    PyObject *style = NULL;
444    PyObject *indent = NULL;
445    PyObject *width = NULL;
446    PyObject *chomp = NULL;
447
448    static char *kwdlist[] = {"value", "tag", "anchor",
449        "style", "indent", "width", "chomp", NULL};
450
451    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOOOOO", kwdlist,
452                &value, &tag, &anchor, &style, &indent, &width, &chomp))
453        return -1;
454
455    if (value && PySyckScalar_setvalue(self, value, NULL) < 0)
456        return -1;
457
[14]458    if (tag && PySyckNode_settag((PySyckNodeObject *)self, tag, NULL) < 0)
[12]459        return -1;
460
[14]461    if (anchor && PySyckNode_setanchor((PySyckNodeObject *)self, anchor, NULL) < 0)
[12]462        return -1;
463
464    if (style && PySyckScalar_setstyle(self, style, NULL) < 0)
465        return -1;
466
467    if (indent && PySyckScalar_setindent(self, indent, NULL) < 0)
468        return -1;
469
470    if (width && PySyckScalar_setwidth(self, width, NULL) < 0)
471        return -1;
472
473    if (chomp && PySyckScalar_setchomp(self, chomp, NULL) < 0)
474        return -1;
475
476    return 0;
477}
478
479static PyGetSetDef PySyckScalar_getsetters[] = {
[14]480    {"kind", (getter)PySyckNode_getkind, NULL,
[15]481        PyDoc_STR("the node kind, always 'scalar', read-only"),
482        &PySyck_ScalarKind},
[14]483    {"value", (getter)PySyckNode_getvalue, (setter)PySyckScalar_setvalue,
[15]484        PyDoc_STR("the node value, a string"), NULL},
[14]485    {"tag", (getter)PySyckNode_gettag, (setter)PySyckNode_settag,
[15]486        PyDoc_STR("the node tag, a string or None"), NULL},
[14]487    {"anchor", (getter)PySyckNode_getanchor, (setter)PySyckNode_setanchor,
[15]488        PyDoc_STR("the node anchor, a string or None"), NULL},
[12]489    {"style", (getter)PySyckScalar_getstyle, (setter)PySyckScalar_setstyle,
[15]490        PyDoc_STR("the node style, values: None (means literal or plain),\n"
491            "'1quote', '2quote', 'fold', 'literal', 'plain'"), NULL},
[12]492    {"indent", (getter)PySyckScalar_getindent, (setter)PySyckScalar_setindent,
[15]493        PyDoc_STR("the node indentation, an integer"), NULL},
[12]494    {"width", (getter)PySyckScalar_getwidth, (setter)PySyckScalar_setwidth,
[15]495        PyDoc_STR("the node width, an integer"), NULL},
[12]496    {"chomp", (getter)PySyckScalar_getchomp, (setter)PySyckScalar_setchomp,
[15]497        PyDoc_STR("the chomping method,\n"
498            "values: None (clip), '-' (strip), or '+' (keep)"), NULL},
[12]499    {NULL}  /* Sentinel */
500};
501
502static PyTypeObject PySyckScalar_Type = {
503    PyObject_HEAD_INIT(NULL)
504    0,                                          /* ob_size */
505    "_syck.Scalar",                             /* tp_name */
506    sizeof(PySyckScalarObject),                 /* tp_basicsize */
507    0,                                          /* tp_itemsize */
[14]508    0,                                          /* tp_dealloc */
[12]509    0,                                          /* tp_print */
510    0,                                          /* tp_getattr */
511    0,                                          /* tp_setattr */
512    0,                                          /* tp_compare */
513    0,                                          /* tp_repr */
514    0,                                          /* tp_as_number */
515    0,                                          /* tp_as_sequence */
516    0,                                          /* tp_as_mapping */
517    0,                                          /* tp_hash */
518    0,                                          /* tp_call */
519    0,                                          /* tp_str */
520    0,                                          /* tp_getattro */
521    0,                                          /* tp_setattro */
522    0,                                          /* tp_as_buffer */
[14]523    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE,     /* tp_flags */
[12]524    PySyckScalar_doc,                           /* tp_doc */
[14]525    0,                                          /* tp_traverse */
526    0,                                          /* tp_clear */
[12]527    0,                                          /* tp_richcompare */
528    0,                                          /* tp_weaklistoffset */
529    0,                                          /* tp_iter */
530    0,                                          /* tp_iternext */
531    0,                                          /* tp_methods */
532    0,                                          /* tp_members */
533    PySyckScalar_getsetters,                    /* tp_getset */
534    &PySyckNode_Type,                           /* tp_base */
535    0,                                          /* tp_dict */
536    0,                                          /* tp_descr_get */
537    0,                                          /* tp_descr_set */
538    0,                                          /* tp_dictoffset */
539    (initproc)PySyckScalar_init,                /* tp_init */
540    0,                                          /* tp_alloc */
541    PySyckScalar_new,                           /* tp_new */
542};
543
[14]544/****************************************************************************
545 * The type _syck.Seq.
546 ****************************************************************************/
[12]547
[14]548PyDoc_STRVAR(PySyckSeq_doc,
549    "Seq(value=[], tag=None, inline=False) -> a Seq node\n\n"
550    "_syck.Seq represents a sequence node in Syck parser and emitter\n"
[25]551    "trees. A sequence node points to an ordered set of subnodes.\n");
[14]552
553typedef struct {
554    PyObject_HEAD
555    /* Common fields for all Node types: */
556    PyObject *value;    /* always an object */
557    PyObject *tag;      /* a string object or NULL */
558    PyObject *anchor;   /* a string object or NULL */
559    /* Seq-specific fields: */
560    enum seq_style style;
561} PySyckSeqObject;
562
563static PyObject *
564PySyckSeq_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
565{
566    PySyckSeqObject *self;
567
568    self = (PySyckSeqObject *)type->tp_alloc(type, 0);
569    if (!self) return NULL;
570
571    self->value = PyList_New(0);
572    if (!self->value) {
573        Py_DECREF(self);
574        return NULL;
575    }
576
577    self->tag = NULL;
578    self->anchor = NULL;
579    self->style = seq_none;
580
581    return (PyObject *)self;
582}
583
584static int
585PySyckSeq_setvalue(PySyckSeqObject *self, PyObject *value, void *closure)
586{
587    if (!value) {
588        PyErr_SetString(PyExc_TypeError, "cannot delete 'value'");
589        return -1;
590    }
[17]591    if (!PyList_Check(value)) {
592        PyErr_SetString(PyExc_TypeError, "'value' must be a list");
[14]593        return -1;
594    }
595
596    Py_DECREF(self->value);
597    Py_INCREF(value);
598    self->value = value;
599
600    return 0;
601}
602
603static PyObject *
604PySyckSeq_getinline(PySyckSeqObject *self, void *closure)
605{
606    PyObject *value = (self->style == seq_inline) ? Py_True : Py_False;
607
608    Py_INCREF(value);
609    return value;
610}
611
612static int
613PySyckSeq_setinline(PySyckSeqObject *self, PyObject *value, void *closure)
614{
615    if (!value) {
616        PyErr_SetString(PyExc_TypeError, "cannot delete 'inline'");
617        return -1;
618    }
619
620    if (!PyInt_Check(value)) {
621        PyErr_SetString(PyExc_TypeError, "'inline' must be a Boolean object");
622        return -1;
623    }
624
625    self->style = PyInt_AS_LONG(value) ? seq_inline : seq_none;
626
627    return 0;
628}
629
630static int
631PySyckSeq_init(PySyckSeqObject *self, PyObject *args, PyObject *kwds)
632{
633    PyObject *value = NULL;
634    PyObject *tag = NULL;
635    PyObject *anchor = NULL;
636    PyObject *inline_ = NULL;
637
638    static char *kwdlist[] = {"value", "tag", "anchor", "inline", NULL};
639
640    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO", kwdlist,
641                &value, &tag, &anchor, &inline_))
642        return -1;
643
644    if (value && PySyckSeq_setvalue(self, value, NULL) < 0)
645        return -1;
646
647    if (tag && PySyckNode_settag((PySyckNodeObject *)self, tag, NULL) < 0)
648        return -1;
649
650    if (anchor && PySyckNode_setanchor((PySyckNodeObject *)self, anchor, NULL) < 0)
651        return -1;
652
653    if (inline_ && PySyckSeq_setinline(self, inline_, NULL) < 0)
654        return -1;
655
656    return 0;
657}
658
659static PyGetSetDef PySyckSeq_getsetters[] = {
660    {"kind", (getter)PySyckNode_getkind, NULL,
[15]661        PyDoc_STR("the node kind, always 'seq', read-only"), &PySyck_SeqKind},
[14]662    {"value", (getter)PySyckNode_getvalue, (setter)PySyckSeq_setvalue,
[15]663        PyDoc_STR("the node value, a sequence"), NULL},
[14]664    {"tag", (getter)PySyckNode_gettag, (setter)PySyckNode_settag,
[15]665        PyDoc_STR("the node tag, a string or None"), NULL},
[14]666    {"anchor", (getter)PySyckNode_getanchor, (setter)PySyckNode_setanchor,
[15]667        PyDoc_STR("the node anchor, a string or None"), NULL},
[14]668    {"inline", (getter)PySyckSeq_getinline, (setter)PySyckSeq_setinline,
[15]669        PyDoc_STR("the block/flow flag"), NULL},
[14]670    {NULL}  /* Sentinel */
671};
672
673static PyTypeObject PySyckSeq_Type = {
674    PyObject_HEAD_INIT(NULL)
675    0,                                          /* ob_size */
676    "_syck.Seq",                                /* tp_name */
677    sizeof(PySyckSeqObject),                    /* tp_basicsize */
678    0,                                          /* tp_itemsize */
679    0,                                          /* tp_dealloc */
680    0,                                          /* tp_print */
681    0,                                          /* tp_getattr */
682    0,                                          /* tp_setattr */
683    0,                                          /* tp_compare */
684    0,                                          /* tp_repr */
685    0,                                          /* tp_as_number */
686    0,                                          /* tp_as_sequence */
687    0,                                          /* tp_as_mapping */
688    0,                                          /* tp_hash */
689    0,                                          /* tp_call */
690    0,                                          /* tp_str */
691    0,                                          /* tp_getattro */
692    0,                                          /* tp_setattro */
693    0,                                          /* tp_as_buffer */
694    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC,  /* tp_flags */
695    PySyckSeq_doc,                              /* tp_doc */
696    (traverseproc)PySyckNode_traverse,          /* tp_traverse */
697    (inquiry)PySyckNode_clear,                  /* tp_clear */
698    0,                                          /* tp_richcompare */
699    0,                                          /* tp_weaklistoffset */
700    0,                                          /* tp_iter */
701    0,                                          /* tp_iternext */
702    0,                                          /* tp_methods */
703    0,                                          /* tp_members */
704    PySyckSeq_getsetters,                       /* tp_getset */
705    &PySyckNode_Type,                           /* tp_base */
706    0,                                          /* tp_dict */
707    0,                                          /* tp_descr_get */
708    0,                                          /* tp_descr_set */
709    0,                                          /* tp_dictoffset */
710    (initproc)PySyckSeq_init,                   /* tp_init */
711    0,                                          /* tp_alloc */
712    PySyckSeq_new,                              /* tp_new */
713};
714
715/****************************************************************************
716 * The type _syck.Map.
717 ****************************************************************************/
718
719PyDoc_STRVAR(PySyckMap_doc,
[25]720    "Map(value={}, tag=None, inline=False) -> a Map node\n\n"
[14]721    "_syck.Map represents a mapping node in Syck parser and emitter\n"
[25]722    "trees. A mapping node points to an unordered collections of pairs.\n");
[14]723
724typedef struct {
725    PyObject_HEAD
726    /* Common fields for all Node types: */
727    PyObject *value;    /* always an object */
728    PyObject *tag;      /* a string object or NULL */
729    PyObject *anchor;   /* a string object or NULL */
730    /* Map-specific fields: */
731    enum map_style style;
732} PySyckMapObject;
733
734static PyObject *
735PySyckMap_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
736{
737    PySyckMapObject *self;
738
739    self = (PySyckMapObject *)type->tp_alloc(type, 0);
740    if (!self) return NULL;
741
742    self->value = PyDict_New();
743    if (!self->value) {
744        Py_DECREF(self);
745        return NULL;
746    }
747
748    self->tag = NULL;
749    self->anchor = NULL;
750    self->style = seq_none;
751
752    return (PyObject *)self;
753}
754
755static int
756PySyckMap_setvalue(PySyckMapObject *self, PyObject *value, void *closure)
757{
758    if (!value) {
759        PyErr_SetString(PyExc_TypeError, "cannot delete 'value'");
760        return -1;
761    }
[17]762    if (!PyDict_Check(value) && !PyList_Check(value)) {
763        PyErr_SetString(PyExc_TypeError,
764                "'value' must be a list of pairs or a dictionary");
[14]765        return -1;
766    }
767
768    Py_DECREF(self->value);
769    Py_INCREF(value);
770    self->value = value;
771
772    return 0;
773}
774
775static PyObject *
776PySyckMap_getinline(PySyckMapObject *self, void *closure)
777{
778    PyObject *value = (self->style == map_inline) ? Py_True : Py_False;
779
780    Py_INCREF(value);
781    return value;
782}
783
784static int
785PySyckMap_setinline(PySyckMapObject *self, PyObject *value, void *closure)
786{
787    if (!value) {
788        PyErr_SetString(PyExc_TypeError, "cannot delete 'inline'");
789        return -1;
790    }
791
792    if (!PyInt_Check(value)) {
793        PyErr_SetString(PyExc_TypeError, "'inline' must be a Boolean object");
794        return -1;
795    }
796
797    self->style = PyInt_AS_LONG(value) ? map_inline : map_none;
798
799    return 0;
800}
801
802static int
803PySyckMap_init(PySyckMapObject *self, PyObject *args, PyObject *kwds)
804{
805    PyObject *value = NULL;
806    PyObject *tag = NULL;
807    PyObject *anchor = NULL;
808    PyObject *inline_ = NULL;
809
810    static char *kwdlist[] = {"value", "tag", "anchor", "inline", NULL};
811
812    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|OOOO", kwdlist,
813                &value, &tag, &anchor, &inline_))
814        return -1;
815
816    if (value && PySyckMap_setvalue(self, value, NULL) < 0)
817        return -1;
818
819    if (tag && PySyckNode_settag((PySyckNodeObject *)self, tag, NULL) < 0)
820        return -1;
821
822    if (anchor && PySyckNode_setanchor((PySyckNodeObject *)self, anchor, NULL) < 0)
823        return -1;
824
825    if (inline_ && PySyckMap_setinline(self, inline_, NULL) < 0)
826        return -1;
827
828    return 0;
829}
830
831static PyGetSetDef PySyckMap_getsetters[] = {
832    {"kind", (getter)PySyckNode_getkind, NULL,
[15]833        PyDoc_STR("the node kind, always 'map', read-only"), &PySyck_MapKind},
[14]834    {"value", (getter)PySyckNode_getvalue, (setter)PySyckMap_setvalue,
[25]835        PyDoc_STR("the node value, a list of pairs or a dictionary"), NULL},
[14]836    {"tag", (getter)PySyckNode_gettag, (setter)PySyckNode_settag,
[15]837        PyDoc_STR("the node tag, a string or None"), NULL},
[14]838    {"anchor", (getter)PySyckNode_getanchor, (setter)PySyckNode_setanchor,
[15]839        PyDoc_STR("the node anchor, a string or None"), NULL},
[14]840    {"inline", (getter)PySyckMap_getinline, (setter)PySyckMap_setinline,
[15]841        PyDoc_STR("the block/flow flag"), NULL},
[14]842    {NULL}  /* Sentinel */
843};
844
845static PyTypeObject PySyckMap_Type = {
846    PyObject_HEAD_INIT(NULL)
847    0,                                          /* ob_size */
848    "_syck.Map",                                /* tp_name */
849    sizeof(PySyckMapObject),                    /* tp_basicsize */
850    0,                                          /* tp_itemsize */
851    0,                                          /* tp_dealloc */
852    0,                                          /* tp_print */
853    0,                                          /* tp_getattr */
854    0,                                          /* tp_setattr */
855    0,                                          /* tp_compare */
856    0,                                          /* tp_repr */
857    0,                                          /* tp_as_number */
858    0,                                          /* tp_as_sequence */
859    0,                                          /* tp_as_mapping */
860    0,                                          /* tp_hash */
861    0,                                          /* tp_call */
862    0,                                          /* tp_str */
863    0,                                          /* tp_getattro */
864    0,                                          /* tp_setattro */
865    0,                                          /* tp_as_buffer */
866    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC,  /* tp_flags */
867    PySyckMap_doc,                              /* tp_doc */
868    (traverseproc)PySyckNode_traverse,          /* tp_traverse */
869    (inquiry)PySyckNode_clear,                  /* tp_clear */
870    0,                                          /* tp_richcompare */
871    0,                                          /* tp_weaklistoffset */
872    0,                                          /* tp_iter */
873    0,                                          /* tp_iternext */
874    0,                                          /* tp_methods */
875    0,                                          /* tp_members */
876    PySyckMap_getsetters,                       /* tp_getset */
877    &PySyckNode_Type,                           /* tp_base */
878    0,                                          /* tp_dict */
879    0,                                          /* tp_descr_get */
880    0,                                          /* tp_descr_set */
881    0,                                          /* tp_dictoffset */
882    (initproc)PySyckMap_init,                   /* tp_init */
883    0,                                          /* tp_alloc */
884    PySyckMap_new,                              /* tp_new */
885};
886
[15]887/****************************************************************************
888 * The type _syck.Parser.
889 ****************************************************************************/
[14]890
[15]891PyDoc_STRVAR(PySyckParser_doc,
892    "Parser(source, implicit_typing=True, taguri_expansion=True)\n"
893    "      -> a Parser object\n\n"
894    "_syck.Parser is a low-lever wrapper of the Syck parser. It parses\n"
[25]895    "a YAML stream and produces a tree of Nodes.\n");
[15]896
[12]897typedef struct {
898    PyObject_HEAD
[15]899    /* Attributes: */
900    PyObject *source;       /* a string or file-like object */
901    int implicit_typing;
902    int taguri_expansion;
903    /* Internal fields: */
904    PyObject *symbols;      /* symbol table, a list, NULL outside parse() */
905    SyckParser *parser;
906    int parsing;
907    int halt;
908} PySyckParserObject;
[4]909
[15]910static PyObject *
911PySyckParser_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
912{
913    PySyckParserObject *self;
914
915    self = (PySyckParserObject *)type->tp_alloc(type, 0);
916    if (!self) return NULL;
917
918    self->source = NULL;
919    self->implicit_typing = 0;
920    self->taguri_expansion = 0;
921    self->symbols = NULL;
922    self->parser = NULL;
923    self->parsing = 0;
924    self->halt = 1;
925
926    /*
927    self->symbols = PyList_New(0);
928    if (!self->symbols) {
929        Py_DECREF(self);
930        return NULL;
931    }
932    */
933
934    return (PyObject *)self;
935}
936
937static int
938PySyckParser_clear(PySyckParserObject *self)
939{
940    PyObject *tmp;
941
942    if (self->parser) {
943        syck_free_parser(self->parser);
944        self->parser = NULL;
945    }
946
947    tmp = self->source;
948    self->source = NULL;
949    Py_XDECREF(tmp);
950
951    tmp = self->symbols;
952    self->symbols = NULL;
953    Py_XDECREF(tmp);
954
955    return 0;
956}
957
958static int
959PySyckParser_traverse(PySyckParserObject *self, visitproc visit, void *arg)
960{
961    int ret;
962
963    if (self->source)
964        if ((ret = visit(self->source, arg)) != 0)
965            return ret;
966
967    if (self->symbols)
968        if ((ret = visit(self->symbols, arg)) != 0)
969            return ret;
970
971    return 0;
972}
973
[4]974static void
[15]975PySyckParser_dealloc(PySyckParserObject *self)
[4]976{
[15]977    PySyckParser_clear(self);
978    self->ob_type->tp_free((PyObject *)self);
[4]979}
980
981static PyObject *
[15]982PySyckParser_getsource(PySyckParserObject *self, void *closure)
[4]983{
[15]984    PyObject *value = self->source ? self->source : Py_None;
985
986    Py_INCREF(value);
987    return value;
988}
989
990static PyObject *
991PySyckParser_getimplicit_typing(PySyckParserObject *self, void *closure)
992{
993    PyObject *value = self->implicit_typing ? Py_True : Py_False;
994
995    Py_INCREF(value);
996    return value;
997}
998
999static PyObject *
1000PySyckParser_gettaguri_expansion(PySyckParserObject *self, void *closure)
1001{
1002    PyObject *value = self->taguri_expansion ? Py_True : Py_False;
1003
1004    Py_INCREF(value);
1005    return value;
1006}
1007
1008static PyObject *
1009PySyckParser_geteof(PySyckParserObject *self, void *closure)
1010{
1011    PyObject *value = self->halt ? Py_True : Py_False;
1012
1013    Py_INCREF(value);
1014    return value;
1015}
1016
1017static PyGetSetDef PySyckParser_getsetters[] = {
1018    {"source", (getter)PySyckParser_getsource, NULL,
[25]1019        PyDoc_STR("IO source, a string or a file-like object"), NULL},
[15]1020    {"implicit_typing", (getter)PySyckParser_getimplicit_typing, NULL,
1021        PyDoc_STR("implicit typing of builtin YAML types"), NULL},
1022    {"taguri_expansion", (getter)PySyckParser_gettaguri_expansion, NULL,
1023        PyDoc_STR("expansion of types in full taguri"), NULL},
1024    {"eof", (getter)PySyckParser_geteof, NULL,
1025        PyDoc_STR("EOF flag"), NULL},
1026    {NULL}  /* Sentinel */
1027};
1028
1029static SYMID
1030PySyckParser_node_handler(SyckParser *parser, SyckNode *node)
1031{
1032    PySyckParserObject *self = (PySyckParserObject *)parser->bonus;
1033
1034    SYMID index;
1035    PySyckNodeObject *object = NULL;
1036
1037    PyObject *key, *value;
1038    int k;
1039
1040    if (self->halt)
1041        return -1;
1042
1043    switch (node->kind) {
1044
1045        case syck_str_kind:
1046            object = (PySyckNodeObject *)
1047                PySyckScalar_new(&PySyckScalar_Type, NULL, NULL);
1048            if (!object) goto error;
1049            value = PyString_FromStringAndSize(node->data.str->ptr,
1050                    node->data.str->len);
1051            if (!value) goto error;
1052            Py_DECREF(object->value);
1053            object->value = value;
1054            break;
1055
1056        case syck_seq_kind:
1057            object = (PySyckNodeObject *)
1058                PySyckSeq_new(&PySyckSeq_Type, NULL, NULL);
1059            if (!object) goto error;
1060            for (k = 0; k < node->data.list->idx; k++) {
[20]1061                index = syck_seq_read(node, k)-1;
[15]1062                value = PyList_GetItem(self->symbols, index);
1063                if (!value) goto error;
1064                if (PyList_Append(object->value, value) < 0)
1065                    goto error;
1066            }
1067            break;
1068
1069        case syck_map_kind:
1070            object = (PySyckNodeObject *)
1071                PySyckMap_new(&PySyckMap_Type, NULL, NULL);
1072            if (!object) goto error;
1073            for (k = 0; k < node->data.pairs->idx; k++)
1074            {
[20]1075                index = syck_map_read(node, map_key, k)-1;
[15]1076                key = PyList_GetItem(self->symbols, index);
1077                if (!key) goto error;
[20]1078                index = syck_map_read(node, map_value, k)-1;
[15]1079                value = PyList_GetItem(self->symbols, index);
1080                if (!value) goto error;
1081                if (PyDict_SetItem(object->value, key, value) < 0)
1082                    goto error;
1083            }
1084            break;
1085    }
1086
1087    if (node->type_id) {
1088        object->tag = PyString_FromString(node->type_id);
1089        if (!object->tag) goto error;
1090    }
1091
1092    if (node->anchor) {
1093        object->anchor = PyString_FromString(node->anchor);
1094        if (!object->anchor) goto error;
1095    }
1096
1097    if (PyList_Append(self->symbols, (PyObject *)object) < 0)
1098        goto error;
1099
[20]1100    index = PyList_GET_SIZE(self->symbols);
[15]1101    return index;
1102
1103error:
1104    Py_XDECREF(object);
1105    self->halt = 1;
1106    return -1;
1107}
1108
1109static void
1110PySyckParser_error_handler(SyckParser *parser, char *str)
1111{
1112    PySyckParserObject *self = (PySyckParserObject *)parser->bonus;
[4]1113    PyObject *value;
1114
[15]1115    if (self->halt) return;
1116
1117    self->halt = 1;
1118
1119    value = Py_BuildValue("(sii)", str,
1120            parser->linect, parser->cursor - parser->lineptr);
1121    if (value) {
1122        PyErr_SetObject(PySyck_Error, value);
1123    }
1124}
1125
[17]1126SyckNode *
1127PySyckParser_bad_anchor_handler(SyckParser *parser, char *anchor)
1128{
1129    PySyckParserObject *self = (PySyckParserObject *)parser->bonus;
1130
1131    if (!self->halt) {
1132        self->halt = 1;
1133        PyErr_SetString(PyExc_TypeError, "recursive anchors are not implemented");
1134    }
1135
1136    return syck_alloc_str();
1137}
1138
[15]1139static long
1140PySyckParser_read_handler(char *buf, SyckIoFile *file, long max_size, long skip)
1141{
1142    PySyckParserObject *self = (PySyckParserObject *)file->ptr;
1143
1144    PyObject *value;
1145
1146    char *str;
1147    int length;
1148
1149    buf[skip] = '\0';
1150
1151    if (self->halt) {
1152        return skip;
1153    }
1154   
1155    max_size -= skip;
1156
1157    value = PyObject_CallMethod(self->source, "read", "(i)", max_size);
1158    if (!value) {
1159        self->halt = 1;
1160        return skip;
1161    }
1162
1163    if (!PyString_CheckExact(value)) {
1164        Py_DECREF(value);
1165        PyErr_SetString(PyExc_TypeError, "file-like object should return a string");
1166        self->halt = 1;
1167       
1168        return skip;
1169    }
1170
1171    str = PyString_AS_STRING(value);
1172    length = PyString_GET_SIZE(value);
1173    if (!length) {
1174        Py_DECREF(value);
1175        return skip;
1176    }
1177
1178    if (length > max_size) {
1179        Py_DECREF(value);
1180        PyErr_SetString(PyExc_ValueError, "read returns an overly long string");
1181        self->halt = 1;
1182        return skip;
1183    }
1184
1185    memcpy(buf+skip, str, length);
1186    length += skip;
1187    buf[length] = '\0';
1188
1189    Py_DECREF(value);
1190
1191    return length;
1192}
1193
1194static int
1195PySyckParser_init(PySyckParserObject *self, PyObject *args, PyObject *kwds)
1196{
1197    PyObject *source = NULL;
1198    int implicit_typing = 1;
1199    int taguri_expansion = 1;
1200
1201    static char *kwdlist[] = {"source", "implicit_typing", "taguri_expansion",
1202        NULL};
1203
1204    PySyckParser_clear(self);
1205
1206    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|ii", kwdlist,
1207                &source, &implicit_typing, &taguri_expansion))
1208        return -1;
1209
1210    Py_INCREF(source);
1211    self->source = source;
1212
1213    self->implicit_typing = implicit_typing;
1214    self->taguri_expansion = taguri_expansion;
1215
1216    self->parser = syck_new_parser();
1217    self->parser->bonus = self;
1218
1219    if (PyString_CheckExact(self->source)) {
1220        syck_parser_str(self->parser,
1221                PyString_AS_STRING(self->source),
1222                PyString_GET_SIZE(self->source), NULL);
1223    }
1224    /*
1225    else if (PyUnicode_CheckExact(self->source)) {
1226        syck_parser_str(self->parser,
1227                PyUnicode_AS_DATA(self->source),
1228                PyString_GET_DATA_SIZE(self->source), NULL);
1229    }
1230    */
[4]1231    else {
[15]1232        syck_parser_file(self->parser, (FILE *)self, PySyckParser_read_handler);
1233    }
1234
1235    syck_parser_implicit_typing(self->parser, self->implicit_typing);
1236    syck_parser_taguri_expansion(self->parser, self->taguri_expansion);
1237
1238    syck_parser_handler(self->parser, PySyckParser_node_handler);
1239    syck_parser_error_handler(self->parser, PySyckParser_error_handler);
[17]1240    syck_parser_bad_anchor_handler(self->parser, PySyckParser_bad_anchor_handler);
[15]1241
1242    self->parsing = 0;
1243    self->halt = 0;
1244
1245    return 0;
1246}
1247
1248static PyObject *
1249PySyckParser_parse(PySyckParserObject *self)
1250{
1251    SYMID index;
1252    PyObject *value;
1253
1254    if (self->parsing) {
[25]1255        PyErr_SetString(PyExc_RuntimeError,
1256                "do not call Parser.parse while it is already running");
[4]1257        return NULL;
1258    }
1259
[15]1260    if (self->halt) {
1261        Py_INCREF(Py_None);
1262        return Py_None;
1263    }
1264
1265    self->symbols = PyList_New(0);
1266    if (!self->symbols) {
1267        return NULL;
1268    }
1269
1270    self->parsing = 1;
[20]1271    index = syck_parse(self->parser)-1;
[15]1272    self->parsing = 0;
1273
1274    if (self->halt || self->parser->eof) {
1275        Py_DECREF(self->symbols);
1276        self->symbols = NULL;
1277
1278        if (self->halt) return NULL;
1279
1280        self->halt = 1;
1281        Py_INCREF(Py_None);
1282        return Py_None;
1283    }
1284
1285    value = PyList_GetItem(self->symbols, index);
1286
1287    Py_DECREF(self->symbols);
1288    self->symbols = NULL;
1289
[4]1290    return value;
1291}
1292
[15]1293PyDoc_STRVAR(PySyckParser_parse_doc,
1294    "parse() -> the root Node object\n\n"
[25]1295    "Parses the source and returns the root of the Node tree. Call it\n"
1296    "several times to retrieve all documents from the source. On EOF,\n"
1297    "returns None and sets the 'eof' attribute on.\n");
[4]1298
[15]1299static PyMethodDef PySyckParser_methods[] = {
1300    {"parse",  (PyCFunction)PySyckParser_parse,
1301        METH_NOARGS, PySyckParser_parse_doc},
1302    {NULL}  /* Sentinel */
1303};
1304
1305static PyTypeObject PySyckParser_Type = {
[4]1306    PyObject_HEAD_INIT(NULL)
[15]1307    0,                                          /* ob_size */
1308    "_syck.Parser",                             /* tp_name */
1309    sizeof(PySyckParserObject),                 /* tp_basicsize */
1310    0,                                          /* tp_itemsize */
1311    (destructor)PySyckParser_dealloc,           /* tp_dealloc */
1312    0,                                          /* tp_print */
1313    0,                                          /* tp_getattr */
1314    0,                                          /* tp_setattr */
1315    0,                                          /* tp_compare */
1316    0,                                          /* tp_repr */
1317    0,                                          /* tp_as_number */
1318    0,                                          /* tp_as_sequence */
1319    0,                                          /* tp_as_mapping */
1320    0,                                          /* tp_hash */
1321    0,                                          /* tp_call */
1322    0,                                          /* tp_str */
1323    0,                                          /* tp_getattro */
1324    0,                                          /* tp_setattro */
1325    0,                                          /* tp_as_buffer */
1326    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC,  /* tp_flags */
1327    PySyckParser_doc,                           /* tp_doc */
1328    (traverseproc)PySyckParser_traverse,        /* tp_traverse */
1329    (inquiry)PySyckParser_clear,                /* tp_clear */
1330    0,                                          /* tp_richcompare */
1331    0,                                          /* tp_weaklistoffset */
1332    0,                                          /* tp_iter */
1333    0,                                          /* tp_iternext */
1334    PySyckParser_methods,                       /* tp_methods */
1335    0,                                          /* tp_members */
1336    PySyckParser_getsetters,                    /* tp_getset */
1337    0,                                          /* tp_base */
1338    0,                                          /* tp_dict */
1339    0,                                          /* tp_descr_get */
1340    0,                                          /* tp_descr_set */
1341    0,                                          /* tp_dictoffset */
1342    (initproc)PySyckParser_init,                /* tp_init */
1343    0,                                          /* tp_alloc */
1344    PySyckParser_new,                           /* tp_new */
[4]1345};
1346
[16]1347/****************************************************************************
[17]1348 * The type _syck.Emitter.
1349 ****************************************************************************/
1350
1351PyDoc_STRVAR(PySyckEmitter_doc,
[25]1352    "Emitter(output, headless=False, use_header=False, use_version=False,\n"
1353    "        explicit_typing=True, style=None, best_width=80, indent=2)\n"
1354    "                -> an Emitter object\n\n"
1355    "_syck.Emitter is a low-lever wrapper of the Syck emitter. It emits\n"
[17]1356    "a tree of Nodes into a YAML stream.\n");
1357
1358typedef struct {
1359    PyObject_HEAD
1360    /* Attributes: */
1361    PyObject *output;       /* a file-like object */
1362    int headless;
1363    int use_header;
1364    int use_version;
1365    int explicit_typing;
1366    enum scalar_style style;
1367    int best_width;
1368    int indent;
1369    /* Internal fields: */
1370    PyObject *symbols;      /* symbol table, a list, NULL outside emit() */
1371    PyObject *nodes;        /* node -> symbol, a dict, NULL outside emit() */
1372    SyckEmitter *emitter;
1373    int emitting;
1374    int halt;
1375} PySyckEmitterObject;
1376
1377static PyObject *
1378PySyckEmitter_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
1379{
1380    PySyckEmitterObject *self;
1381
1382    self = (PySyckEmitterObject *)type->tp_alloc(type, 0);
1383    if (!self) return NULL;
1384
1385    self->output = NULL;
1386    self->headless = 0;
1387    self->use_header = 0;
1388    self->use_version = 0;
1389    self->explicit_typing = 0;
1390    self->style = scalar_none;
1391    self->best_width = 0;
1392    self->indent = 0;
1393    self->symbols = NULL;
1394    self->nodes = NULL;
1395    self->emitter = NULL;
1396    self->emitting = 0;
1397    self->halt = 1;
1398
1399    return (PyObject *)self;
1400}
1401
1402static int
1403PySyckEmitter_clear(PySyckEmitterObject *self)
1404{
1405    PyObject *tmp;
1406
1407    if (self->emitter) {
1408        syck_free_emitter(self->emitter);
1409        self->emitter = NULL;
1410    }
1411
1412    tmp = self->output;
1413    self->output = NULL;
1414    Py_XDECREF(tmp);
1415
1416    tmp = self->symbols;
1417    self->symbols = NULL;
1418    Py_XDECREF(tmp);
1419
1420    tmp = self->nodes;
1421    self->nodes = NULL;
1422    Py_XDECREF(tmp);
1423
1424    return 0;
1425}
1426
1427static int
1428PySyckEmitter_traverse(PySyckEmitterObject *self, visitproc visit, void *arg)
1429{
1430    int ret;
1431
1432    if (self->output)
1433        if ((ret = visit(self->output, arg)) != 0)
1434            return ret;
1435
1436    if (self->symbols)
1437        if ((ret = visit(self->symbols, arg)) != 0)
1438            return ret;
1439
1440    if (self->nodes)
1441        if ((ret = visit(self->nodes, arg)) != 0)
1442            return ret;
1443
1444    return 0;
1445}
1446
1447static void
1448PySyckEmitter_dealloc(PySyckEmitterObject *self)
1449{
1450    PySyckEmitter_clear(self);
1451    self->ob_type->tp_free((PyObject *)self);
1452}
1453
1454static PyObject *
1455PySyckEmitter_getoutput(PySyckEmitterObject *self, void *closure)
1456{
1457    PyObject *value = self->output ? self->output : Py_None;
1458
1459    Py_INCREF(value);
1460    return value;
1461}
1462
1463static PyObject *
1464PySyckEmitter_getheadless(PySyckEmitterObject *self, void *closure)
1465{
1466    PyObject *value = self->headless ? Py_True : Py_False;
1467
1468    Py_INCREF(value);
1469    return value;
1470}
1471
1472static PyObject *
1473PySyckEmitter_getuse_header(PySyckEmitterObject *self, void *closure)
1474{
1475    PyObject *value = self->use_header ? Py_True : Py_False;
1476
1477    Py_INCREF(value);
1478    return value;
1479}
1480
1481static PyObject *
1482PySyckEmitter_getuse_version(PySyckEmitterObject *self, void *closure)
1483{
1484    PyObject *value = self->use_version ? Py_True : Py_False;
1485
1486    Py_INCREF(value);
1487    return value;
1488}
1489
1490static PyObject *
1491PySyckEmitter_getexplicit_typing(PySyckEmitterObject *self, void *closure)
1492{
1493    PyObject *value = self->explicit_typing ? Py_True : Py_False;
1494
1495    Py_INCREF(value);
1496    return value;
1497}
1498
1499static PyObject *
1500PySyckEmitter_getstyle(PySyckEmitterObject *self, void *closure)
1501{
1502    PyObject *value;
1503
1504    switch (self->style) {
1505        case scalar_1quote: value = PySyck_1QuoteStyle; break;
1506        case scalar_2quote: value = PySyck_2QuoteStyle; break;
1507        case scalar_fold: value = PySyck_FoldStyle; break;
1508        case scalar_literal: value = PySyck_LiteralStyle; break;
1509        case scalar_plain: value = PySyck_PlainStyle; break;
1510        default: value = Py_None;
1511    }
1512
1513    Py_INCREF(value);
1514    return value;
1515}
1516
1517static PyObject *
1518PySyckEmitter_getbest_width(PySyckEmitterObject *self, void *closure)
1519{
1520    return PyInt_FromLong(self->best_width);
1521}
1522
1523static PyObject *
1524PySyckEmitter_getindent(PySyckEmitterObject *self, void *closure)
1525{
1526    return PyInt_FromLong(self->indent);
1527}
1528
1529static PyGetSetDef PySyckEmitter_getsetters[] = {
1530    {"output", (getter)PySyckEmitter_getoutput, NULL,
1531        PyDoc_STR("output stream, a file-like object"), NULL},
1532    {"headless", (getter)PySyckEmitter_getheadless, NULL,
1533        PyDoc_STR("headerless document flag"), NULL},
1534    {"use_header", (getter)PySyckEmitter_getuse_header, NULL,
[25]1535        PyDoc_STR("force header flag"), NULL},
[17]1536    {"use_version", (getter)PySyckEmitter_getuse_version, NULL,
[25]1537        PyDoc_STR("force version flag"), NULL},
[17]1538    {"explicit_typing", (getter)PySyckEmitter_getexplicit_typing, NULL,
1539        PyDoc_STR("explicit typing for all collections"), NULL},
1540    {"style", (getter)PySyckEmitter_getstyle, NULL,
1541        PyDoc_STR("use literal or folded blocks on all text"), NULL},
1542    {"best_width", (getter)PySyckEmitter_getbest_width, NULL,
1543        PyDoc_STR("best width for folded scalars"), NULL},
1544    {"indent", (getter)PySyckEmitter_getindent, NULL,
1545        PyDoc_STR("default indentation"), NULL},
1546    {NULL}  /* Sentinel */
1547};
1548
1549static void
1550PySyckEmitter_node_handler(SyckEmitter *emitter, st_data_t id)
1551{
1552    PySyckEmitterObject *self = (PySyckEmitterObject *)emitter->bonus;
1553
1554    PySyckNodeObject *node;
1555    char *tag = NULL;
1556    PyObject *index;
1557    PyObject *key, *value, *item, *pair;
1558    int j, k, l;
1559    char *str;
1560    int len;
1561    int dict_pos;
1562
1563    if (self->halt) return;
1564
1565    node = (PySyckNodeObject *)PyList_GetItem(self->symbols, id);
1566    if (!node) {
1567        PyErr_SetString(PyExc_RuntimeError, "unknown data id");
1568        self->halt = 1;
1569        return;
1570    }
1571
1572    if (node->tag) {
1573        tag = PyString_AsString(node->tag);
1574        if (!tag) {
1575            self->halt = 1;
1576            return;
1577        }
1578    }
1579
1580    if (PyObject_TypeCheck((PyObject *)node, &PySyckSeq_Type)) {
1581
1582        syck_emit_seq(emitter, tag, ((PySyckSeqObject *)node)->style);
1583
1584        if (!PyList_Check(node->value)) {
1585            PyErr_SetString(PyExc_TypeError, "value of _syck.Seq must be a list");
1586            self->halt = 1;
1587            return;
1588        }
1589        l = PyList_GET_SIZE(node->value);
1590        for (k = 0; k < l; k ++) {
1591            item = PyList_GET_ITEM(node->value, k);
1592            if ((index = PyDict_GetItem(self->nodes, item))) {
1593                syck_emit_item(emitter, PyInt_AS_LONG(index));
1594                if (self->halt) return;
1595            }
1596            else {
1597                PyErr_SetString(PyExc_RuntimeError, "sequence item is not marked");
1598                self->halt = 1;
1599                return;
1600            }
1601        }
1602        syck_emit_end(emitter);
1603    }
1604
1605    else if (PyObject_TypeCheck((PyObject *)node, &PySyckMap_Type)) {
1606
1607        syck_emit_map(emitter, tag, ((PySyckMapObject *)node)->style);
1608       
1609        if (PyList_Check(node->value)) {
1610            l = PyList_GET_SIZE(node->value);
1611            for (k = 0; k < l; k ++) {
1612                pair = PyList_GET_ITEM(node->value, k);
1613                if (!PyTuple_Check(pair) || PyTuple_GET_SIZE(pair) != 2) {
1614                    PyErr_SetString(PyExc_TypeError,
1615                            "value of _syck.Map must be a list of pairs or a dictionary");
1616                    self->halt = 1;
1617                    return;
1618                }
1619                for (j = 0; j < 2; j++) {
1620                    item = PyTuple_GET_ITEM(pair, j);
1621                    if ((index = PyDict_GetItem(self->nodes, item))) {
1622                        syck_emit_item(emitter, PyInt_AS_LONG(index));
1623                        if (self->halt) return;
1624                    }
1625                    else {
1626                        PyErr_SetString(PyExc_RuntimeError, "mapping item is not marked");
1627                        self->halt = 1;
1628                        return;
1629                    }
1630                }
1631            }
1632        }
1633        else if (PyDict_Check(node->value)) {
1634            dict_pos = 0;
1635            while (PyDict_Next(node->value, &dict_pos, &key, &value)) {
1636                for (j = 0; j < 2; j++) {
1637                    item = j ? value : key;
1638                    if ((index = PyDict_GetItem(self->nodes, item))) {
1639                        syck_emit_item(emitter, PyInt_AS_LONG(index));
1640                        if (self->halt) return;
1641                    }
1642                    else {
1643                        PyErr_SetString(PyExc_RuntimeError, "mapping item is not marked");
1644                        self->halt = 1;
1645                        return;
1646                    }
1647                }
1648            }
1649        }
1650        else {
1651            PyErr_SetString(PyExc_TypeError,
1652                    "value of _syck.Map must be a list of pairs or a dictionary");
1653            self->halt = 1;
1654            return;
1655        }
1656
1657        syck_emit_end(emitter);
1658    }
1659
1660    else if (PyObject_TypeCheck((PyObject *)node, &PySyckScalar_Type)) {
1661        if (PyString_AsStringAndSize(node->value, &str, &len) < 0) {
1662            self->halt = 1;
1663            return;
1664        }
1665        syck_emit_scalar(emitter, tag, ((PySyckScalarObject *)node)->style,
1666                ((PySyckScalarObject *)node)->indent,
1667                ((PySyckScalarObject *)node)->width,
1668                ((PySyckScalarObject *)node)->chomp, str, len);
1669    }
1670
1671    else {
1672        PyErr_SetString(PyExc_TypeError, "Node instance is required");
1673        self->halt = 1;
1674        return;
1675    }   
1676}
1677static void
1678PySyckEmitter_write_handler(SyckEmitter *emitter, char *buf, long len)
1679{
1680    PySyckEmitterObject *self = (PySyckEmitterObject *)emitter->bonus;
1681
1682    if (!PyObject_CallMethod(self->output, "write", "(s#)", buf, len))
1683        self->halt = 1;
1684}
1685
1686static int
1687PySyckEmitter_init(PySyckEmitterObject *self, PyObject *args, PyObject *kwds)
1688{
1689    PyObject *output = NULL;
1690    int headless = 0;
1691    int use_header = 0;
1692    int use_version = 0;
1693    int explicit_typing = 0;
1694    PyObject *style = NULL;
1695    int best_width = 80;
1696    int indent = 2;
1697
1698    char *str;
1699
1700    static char *kwdlist[] = {"output", "headless", "use_header",
1701        "use_version", "explicit_typing", "style",
1702        "best_width", "indent", NULL};
1703
1704    PySyckEmitter_clear(self);
1705
1706    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iiiiOii", kwdlist,
1707                &output, &headless, &use_header, &use_version,
1708                &explicit_typing, &style, &best_width, &indent))
1709        return -1;
1710
1711    if (best_width <= 0) {
1712        PyErr_SetString(PyExc_ValueError, "'best_width' must be positive");
1713        return -1;
1714    }
1715    if (indent <= 0) {
1716        PyErr_SetString(PyExc_ValueError, "'indent' must be positive");
1717        return -1;
1718    }
1719
1720    if (!style || style == Py_None) {
1721        self->style = scalar_none;
1722    }
1723    else {
1724        if (!PyString_Check(style)) {
1725            PyErr_SetString(PyExc_TypeError, "'style' must be a string or None");
1726            return -1;
1727        }
1728
1729        str = PyString_AsString(style);
1730        if (!str) return -1;
1731
1732        if (strcmp(str, "1quote") == 0)
1733            self->style = scalar_1quote;
1734        else if (strcmp(str, "2quote") == 0)
1735            self->style = scalar_2quote;
1736        else if (strcmp(str, "fold") == 0)
1737            self->style = scalar_fold;
1738        else if (strcmp(str, "literal") == 0)
1739            self->style = scalar_literal;
1740        else if (strcmp(str, "plain") == 0)
1741            self->style = scalar_plain;
1742        else {
1743            PyErr_SetString(PyExc_ValueError, "unknown 'style'");
1744            return -1;
1745        }
1746    }
1747
1748    self->headless = headless;
1749    self->use_header = use_header;
1750    self->use_version = use_version;
1751    self->explicit_typing = explicit_typing;
1752    self->best_width = best_width;
1753    self->indent = indent;
1754
1755    Py_INCREF(output);
1756    self->output = output;
1757
1758    self->emitting = 0;
1759    self->halt = 0;
1760
1761    return 0;
1762}
1763
1764static int
1765PySyckEmitter_mark(PySyckEmitterObject *self, PyObject *root_node)
1766{
1767    int current, last;
1768    int j, k, l;
1769    PySyckNodeObject *node;
1770    PyObject *item, *key, *value, *pair;
1771    PyObject *index;
1772    int dict_pos;
1773
1774    last = 0;
1775    syck_emitter_mark_node(self->emitter, last);
1776    if (PyList_Append(self->symbols, root_node) < 0)
1777        return -1;
1778    index = PyInt_FromLong(last);
1779    if (!index) return -1;
1780    if (PyDict_SetItem(self->nodes, root_node, index) < 0) {
1781        Py_DECREF(index);
1782        return -1;
1783    }
1784    Py_DECREF(index);
1785
1786    for (current = 0; current < PyList_GET_SIZE(self->symbols); current++) {
1787
1788        node = (PySyckNodeObject *)PyList_GET_ITEM(self->symbols, current);
1789
1790        if (PyObject_TypeCheck((PyObject *)node, &PySyckSeq_Type)) {
1791            if (!PyList_Check(node->value)) {
1792                PyErr_SetString(PyExc_TypeError, "value of _syck.Seq must be a list");
1793                return -1;
1794            }
1795            l = PyList_GET_SIZE(node->value);
1796            for (k = 0; k < l; k ++) {
1797                item = PyList_GET_ITEM(node->value, k);
1798                if ((index = PyDict_GetItem(self->nodes, item))) {
1799                    syck_emitter_mark_node(self->emitter, PyInt_AS_LONG(index));
1800                }
1801                else {
1802                    syck_emitter_mark_node(self->emitter, ++last);
1803                    if (PyList_Append(self->symbols, item) < 0)
1804                        return -1;
1805                    index = PyInt_FromLong(last);
1806                    if (!index) return -1;
1807                    if (PyDict_SetItem(self->nodes, item, index) < 0) {
1808                        Py_DECREF(index);
1809                        return -1;
1810                    }
1811                    Py_DECREF(index);
1812                }
1813            }
1814        }
1815
1816        else if (PyObject_TypeCheck((PyObject *)node, &PySyckMap_Type)) {
1817           
1818            if (PyList_Check(node->value)) {
1819                l = PyList_GET_SIZE(node->value);
1820                for (k = 0; k < l; k ++) {
1821                    pair = PyList_GET_ITEM(node->value, k);
1822                    if (!PyTuple_Check(pair) || PyTuple_GET_SIZE(pair) != 2) {
1823                        PyErr_SetString(PyExc_TypeError,
1824                                "value of _syck.Map must be a list of pairs or a dictionary");
1825                        return -1;
1826                    }
1827                    for (j = 0; j < 2; j++) {
1828                        item = PyTuple_GET_ITEM(pair, j);
1829                        if ((index = PyDict_GetItem(self->nodes, item))) {
1830                            syck_emitter_mark_node(self->emitter, PyInt_AS_LONG(index));
1831                        }
1832                        else {
1833                            syck_emitter_mark_node(self->emitter, ++last);
1834                            if (PyList_Append(self->symbols, item) < 0)
1835                                return -1;
1836                            index = PyInt_FromLong(last);
1837                            if (!index) return -1;
1838                            if (PyDict_SetItem(self->nodes, item, index) < 0) {
1839                                Py_DECREF(index);
1840                                return -1;
1841                            }
1842                            Py_DECREF(index);
1843                        }
1844                    }
1845                }
1846               
1847            }
1848            else if (PyDict_Check(node->value)) {
1849                dict_pos = 0;
1850                while (PyDict_Next(node->value, &dict_pos, &key, &value)) {
1851                    for (j = 0; j < 2; j++) {
1852                        item = j ? value : key;
1853                        if ((index = PyDict_GetItem(self->nodes, item))) {
1854                            syck_emitter_mark_node(self->emitter, PyInt_AS_LONG(index));
1855                        }
1856                        else {
1857                            syck_emitter_mark_node(self->emitter, ++last);
1858                            if (PyList_Append(self->symbols, item) < 0)
1859                                return -1;
1860                            index = PyInt_FromLong(last);
1861                            if (!index) return -1;
1862                            if (PyDict_SetItem(self->nodes, item, index) < 0) {
1863                                Py_DECREF(index);
1864                                return -1;
1865                            }
1866                            Py_DECREF(index);
1867                        }
1868                    }
1869                }
1870            }
1871            else {
1872                PyErr_SetString(PyExc_TypeError,
1873                        "value of _syck.Map must be a list of pairs or a dictionary");
1874                return -1;
1875            }
1876        }
1877
1878        else if (!PyObject_TypeCheck((PyObject *)node, &PySyckScalar_Type)) {
1879            PyErr_SetString(PyExc_TypeError, "Node instance is required");
1880            return -1;
1881        }   
1882    }
1883    return 0;
1884}
1885
1886static PyObject *
1887PySyckEmitter_emit(PySyckEmitterObject *self, PyObject *args)
1888{
1889    PyObject *node;
1890
1891    if (self->emitting) {
1892        PyErr_SetString(PyExc_RuntimeError, "do not call Emitter.emit while it is already emitting");
1893        return NULL;
1894    }
1895
1896    if (self->halt) {
1897        Py_INCREF(Py_None);
1898        return Py_None;
1899    }
1900
1901    if (!PyArg_ParseTuple(args, "O", &node))
1902        return NULL;
1903
1904    self->emitting = 1;
1905
1906
1907    self->symbols = PyList_New(0);
1908    if (!self->symbols) {
1909        return NULL;
1910    }
1911    self->nodes = PyDict_New();
1912    if (!self->nodes) {
1913        Py_DECREF(self->symbols);
1914        self->symbols = NULL;
1915        return NULL;
1916    }
1917
1918    self->emitter = syck_new_emitter();
1919    self->emitter->bonus = self;
1920    self->emitter->headless = self->headless;
1921    self->emitter->use_header = self->use_header;
1922    self->emitter->use_version = self->use_version;
1923    self->emitter->explicit_typing = self->explicit_typing;
1924    self->emitter->style = self->style;
1925    self->emitter->best_width = self->best_width;
1926    self->emitter->indent = self->indent;
1927
1928    syck_emitter_handler(self->emitter, PySyckEmitter_node_handler);
1929    syck_output_handler(self->emitter, PySyckEmitter_write_handler);
1930
1931    if (PySyckEmitter_mark(self, node) < 0) {
1932        Py_DECREF(self->symbols);
1933        self->symbols = NULL;
1934        Py_DECREF(self->nodes);
1935        self->nodes = NULL;
1936        self->emitting = 0;
1937        self->halt = 1;
1938        syck_free_emitter(self->emitter);
1939        self->emitter = NULL;
1940        return NULL;
1941    }
1942
1943    syck_emit(self->emitter, 0);
1944    syck_emitter_flush(self->emitter, 0);
1945
1946    syck_free_emitter(self->emitter);
1947    self->emitter = NULL;
1948
1949    self->emitting = 0;
1950
1951    Py_DECREF(self->symbols);
1952    self->symbols = NULL;
1953    Py_DECREF(self->nodes);
1954    self->nodes = NULL;
1955
1956    if (self->halt) return NULL;
1957
1958    Py_INCREF(Py_None);
1959    return Py_None;
1960}
1961
1962PyDoc_STRVAR(PySyckEmitter_emit_doc,
1963    "emit(root_node) -> None\n\n"
[25]1964    "Emits the Node tree to the output.\n");
[17]1965
1966static PyMethodDef PySyckEmitter_methods[] = {
1967    {"emit",  (PyCFunction)PySyckEmitter_emit,
1968        METH_VARARGS, PySyckEmitter_emit_doc},
1969    {NULL}  /* Sentinel */
1970};
1971
1972static PyTypeObject PySyckEmitter_Type = {
1973    PyObject_HEAD_INIT(NULL)
1974    0,                                          /* ob_size */
1975    "_syck.Emitter",                            /* tp_name */
1976    sizeof(PySyckEmitterObject),                /* tp_basicsize */
1977    0,                                          /* tp_itemsize */
1978    (destructor)PySyckEmitter_dealloc,          /* tp_dealloc */
1979    0,                                          /* tp_print */
1980    0,                                          /* tp_getattr */
1981    0,                                          /* tp_setattr */
1982    0,                                          /* tp_compare */
1983    0,                                          /* tp_repr */
1984    0,                                          /* tp_as_number */
1985    0,                                          /* tp_as_sequence */
1986    0,                                          /* tp_as_mapping */
1987    0,                                          /* tp_hash */
1988    0,                                          /* tp_call */
1989    0,                                          /* tp_str */
1990    0,                                          /* tp_getattro */
1991    0,                                          /* tp_setattro */
1992    0,                                          /* tp_as_buffer */
1993    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC,  /* tp_flags */
1994    PySyckEmitter_doc,                          /* tp_doc */
1995    (traverseproc)PySyckEmitter_traverse,       /* tp_traverse */
1996    (inquiry)PySyckEmitter_clear,               /* tp_clear */
1997    0,                                          /* tp_richcompare */
1998    0,                                          /* tp_weaklistoffset */
1999    0,                                          /* tp_iter */
2000    0,                                          /* tp_iternext */
2001    PySyckEmitter_methods,                      /* tp_methods */
2002    0,                                          /* tp_members */
2003    PySyckEmitter_getsetters,                   /* tp_getset */
2004    0,                                          /* tp_base */
2005    0,                                          /* tp_dict */
2006    0,                                          /* tp_descr_get */
2007    0,                                          /* tp_descr_set */
2008    0,                                          /* tp_dictoffset */
2009    (initproc)PySyckEmitter_init,               /* tp_init */
2010    0,                                          /* tp_alloc */
2011    PySyckEmitter_new,                          /* tp_new */
2012};
2013
2014/****************************************************************************
[16]2015 * The module _syck.
2016 ****************************************************************************/
[15]2017
[12]2018static PyMethodDef PySyck_methods[] = {
2019    {NULL}  /* Sentinel */
2020};
2021
2022PyDoc_STRVAR(PySyck_doc,
[25]2023    "_syck is a low-level wrapper for the Syck YAML parser and emitter.\n"
2024    "Do not use it directly, use the module 'syck' instead.\n");
[12]2025
[25]2026static int
2027add_slotnames(PyTypeObject *type)
2028{
2029    PyObject *slotnames;
2030    PyObject *name;
2031    PyGetSetDef *getsetter;
2032
2033    if (!type->tp_getset) return 0;
2034    if (!type->tp_dict) return 0;
2035
2036    slotnames = PyList_New(0);
2037    if (!slotnames) return -1;
2038
2039    for (getsetter = type->tp_getset; getsetter->name; getsetter++) {
2040        if (!getsetter->set) continue;
2041        name = PyString_FromString(getsetter->name);
2042        if (!name) {
2043           Py_DECREF(slotnames);
2044           return -1;
2045        }
2046        if (PyList_Append(slotnames, name) < 0) {
2047            Py_DECREF(name);
2048            Py_DECREF(slotnames);
2049            return -1;
2050        }
2051        Py_DECREF(name);
2052    }
2053
2054    if (PyDict_SetItemString(type->tp_dict, "__slotnames__", slotnames) < 0) {
2055        Py_DECREF(slotnames);
2056        return -1;
2057    }
2058
2059    Py_DECREF(slotnames);
2060    return 0;
2061}
2062
[12]2063PyMODINIT_FUNC
2064init_syck(void)
2065{
2066    PyObject *m;
2067
2068    if (PyType_Ready(&PySyckNode_Type) < 0)
2069        return;
2070    if (PyType_Ready(&PySyckScalar_Type) < 0)
2071        return;
[25]2072    if (add_slotnames(&PySyckScalar_Type) < 0)
2073        return;
[14]2074    if (PyType_Ready(&PySyckSeq_Type) < 0)
2075        return;
[25]2076    if (add_slotnames(&PySyckSeq_Type) < 0)
2077        return;
[14]2078    if (PyType_Ready(&PySyckMap_Type) < 0)
2079        return;
[25]2080    if (add_slotnames(&PySyckMap_Type) < 0)
2081        return;
[15]2082    if (PyType_Ready(&PySyckParser_Type) < 0)
2083        return;
[17]2084    if (PyType_Ready(&PySyckEmitter_Type) < 0)
2085        return;
[12]2086   
2087    PySyck_Error = PyErr_NewException("_syck.error", NULL, NULL);
2088    if (!PySyck_Error) return;
2089
2090    PySyck_ScalarKind = PyString_FromString("scalar");
2091    if (!PySyck_ScalarKind) return;
2092    PySyck_SeqKind = PyString_FromString("seq");
2093    if (!PySyck_SeqKind) return;
2094    PySyck_MapKind = PyString_FromString("map");
2095    if (!PySyck_MapKind) return;
2096
2097    PySyck_1QuoteStyle = PyString_FromString("1quote");
2098    if (!PySyck_1QuoteStyle) return;
2099    PySyck_2QuoteStyle = PyString_FromString("2quote");
2100    if (!PySyck_2QuoteStyle) return;
2101    PySyck_FoldStyle = PyString_FromString("fold");
2102    if (!PySyck_FoldStyle) return;
2103    PySyck_LiteralStyle = PyString_FromString("literal");
2104    if (!PySyck_LiteralStyle) return;
2105    PySyck_PlainStyle = PyString_FromString("plain");
2106    if (!PySyck_PlainStyle) return;
2107
2108    PySyck_StripChomp = PyString_FromString("-");
2109    if (!PySyck_StripChomp) return;
2110    PySyck_KeepChomp = PyString_FromString("+");
2111    if (!PySyck_KeepChomp) return;
2112
2113    m = Py_InitModule3("_syck", PySyck_methods, PySyck_doc);
2114
[15]2115    Py_INCREF(PySyck_Error);
2116    if (PyModule_AddObject(m, "error", (PyObject *)PySyck_Error) < 0)
2117        return;
[12]2118    Py_INCREF(&PySyckNode_Type);
2119    if (PyModule_AddObject(m, "Node", (PyObject *)&PySyckNode_Type) < 0)
2120        return;
2121    Py_INCREF(&PySyckScalar_Type);
2122    if (PyModule_AddObject(m, "Scalar", (PyObject *)&PySyckScalar_Type) < 0)
2123        return;
[14]2124    Py_INCREF(&PySyckSeq_Type);
2125    if (PyModule_AddObject(m, "Seq", (PyObject *)&PySyckSeq_Type) < 0)
2126        return;
2127    Py_INCREF(&PySyckMap_Type);
2128    if (PyModule_AddObject(m, "Map", (PyObject *)&PySyckMap_Type) < 0)
2129        return;
[15]2130    Py_INCREF(&PySyckParser_Type);
2131    if (PyModule_AddObject(m, "Parser", (PyObject *)&PySyckParser_Type) < 0)
2132        return;
[17]2133    Py_INCREF(&PySyckEmitter_Type);
2134    if (PyModule_AddObject(m, "Emitter", (PyObject *)&PySyckEmitter_Type) < 0)
2135        return;
[12]2136}
2137
Note: See TracBrowser for help on using the repository browser.