| 13 | | /* Node type. */ |
| 14 | | |
| | 26 | static PyObject *PySyck_1QuoteStyle; |
| | 27 | static PyObject *PySyck_2QuoteStyle; |
| | 28 | static PyObject *PySyck_FoldStyle; |
| | 29 | static PyObject *PySyck_LiteralStyle; |
| | 30 | static PyObject *PySyck_PlainStyle; |
| | 31 | |
| | 32 | static PyObject *PySyck_StripChomp; |
| | 33 | static PyObject *PySyck_KeepChomp; |
| | 34 | |
| | 35 | /* The type _syck.Node. */ |
| | 36 | |
| | 37 | PyDoc_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 | |
| | 43 | static 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 | |
| | 70 | PyDoc_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 | |
| | 85 | typedef 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 | |
| | 96 | static int |
| | 97 | PySyckScalar_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 | |
| | 109 | static int |
| | 110 | PySyckScalar_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 | |
| | 122 | static void |
| | 123 | PySyckScalar_dealloc(PySyckScalarObject *self) |
| | 124 | { |
| | 125 | PySyckScalar_clear(self); |
| | 126 | self->ob_type->tp_free((PyObject *)self); |
| | 127 | } |
| | 128 | |
| | 129 | static PyObject * |
| | 130 | PySyckScalar_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 | |
| | 153 | static PyObject * |
| | 154 | PySyckScalar_getkind(PySyckScalarObject *self, void *closure) |
| | 155 | { |
| | 156 | Py_INCREF(PySyck_ScalarKind); |
| | 157 | return PySyck_ScalarKind; |
| | 158 | } |
| | 159 | |
| | 160 | static PyObject * |
| | 161 | PySyckScalar_getvalue(PySyckScalarObject *self, void *closure) |
| | 162 | { |
| | 163 | Py_INCREF(self->value); |
| | 164 | return self->value; |
| | 165 | } |
| | 166 | |
| | 167 | static int |
| | 168 | PySyckScalar_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 | |
| | 186 | static PyObject * |
| | 187 | PySyckScalar_gettag(PySyckScalarObject *self, void *closure) |
| | 188 | { |
| | 189 | PyObject *value = self->tag ? self->tag : Py_None; |
| | 190 | Py_INCREF(value); |
| | 191 | return value; |
| | 192 | } |
| | 193 | |
| | 194 | static int |
| | 195 | PySyckScalar_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 | |
| | 220 | static PyObject * |
| | 221 | PySyckScalar_getanchor(PySyckScalarObject *self, void *closure) |
| | 222 | { |
| | 223 | PyObject *value = self->anchor ? self->anchor : Py_None; |
| | 224 | Py_INCREF(value); |
| | 225 | return value; |
| | 226 | } |
| | 227 | |
| | 228 | static int |
| | 229 | PySyckScalar_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 | |
| | 254 | static PyObject * |
| | 255 | PySyckScalar_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 | |
| | 272 | static int |
| | 273 | PySyckScalar_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 | |
| | 313 | static PyObject * |
| | 314 | PySyckScalar_getindent(PySyckScalarObject *self, void *closure) |
| | 315 | { |
| | 316 | return PyInt_FromLong(self->indent); |
| | 317 | } |
| | 318 | |
| | 319 | static int |
| | 320 | PySyckScalar_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 | |
| | 337 | static PyObject * |
| | 338 | PySyckScalar_getwidth(PySyckScalarObject *self, void *closure) |
| | 339 | { |
| | 340 | return PyInt_FromLong(self->width); |
| | 341 | } |
| | 342 | |
| | 343 | static int |
| | 344 | PySyckScalar_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 | |
| | 361 | static PyObject * |
| | 362 | PySyckScalar_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 | |
| | 376 | static int |
| | 377 | PySyckScalar_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 | |
| | 411 | static int |
| | 412 | PySyckScalar_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 | |
| | 453 | static 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 | |
| | 473 | static 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 | /* |