Changeset 17


Ignore:
Timestamp:
07/31/05 15:12:14 (9 years ago)
Author:
xi
Message:

Add _syck.Emitter (finally closes #19).

Location:
trunk
Files:
2 added
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/ext/_syckmodule.c

    r16 r17  
    330330        self->style = scalar_plain; 
    331331    else { 
    332         PyErr_SetString(PyExc_TypeError, "unknown 'style'"); 
     332        PyErr_SetString(PyExc_ValueError, "unknown 'style'"); 
    333333        return -1; 
    334334    } 
     
    589589        return -1; 
    590590    } 
    591     if (!PySequence_Check(value)) { /* PySequence_Check always succeeds */ 
    592         PyErr_SetString(PyExc_TypeError, "'value' must be a sequence"); 
     591    if (!PyList_Check(value)) { 
     592        PyErr_SetString(PyExc_TypeError, "'value' must be a list"); 
    593593        return -1; 
    594594    } 
     
    760760        return -1; 
    761761    } 
    762     if (!PyMapping_Check(value)) { /* PyMapping_Check always succeeds */ 
    763         PyErr_SetString(PyExc_TypeError, "'value' must be a mapping"); 
     762    if (!PyDict_Check(value) && !PyList_Check(value)) { 
     763        PyErr_SetString(PyExc_TypeError, 
     764                "'value' must be a list of pairs or a dictionary"); 
    764765        return -1; 
    765766    } 
     
    11231124} 
    11241125 
     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 
    11251139static long 
    11261140PySyckParser_read_handler(char *buf, SyckIoFile *file, long max_size, long skip) 
     
    12241238    syck_parser_handler(self->parser, PySyckParser_node_handler); 
    12251239    syck_parser_error_handler(self->parser, PySyckParser_error_handler); 
    1226     /* 
    1227     syck_parser_bad_anchor_handler(parser, PySyckParser_bad_anchor_handler); 
    1228     */ 
     1240    syck_parser_bad_anchor_handler(self->parser, PySyckParser_bad_anchor_handler); 
    12291241 
    12301242    self->parsing = 0; 
     
    13321344 
    13331345/**************************************************************************** 
     1346 * The type _syck.Emitter. 
     1347 ****************************************************************************/ 
     1348 
     1349PyDoc_STRVAR(PySyckEmitter_doc, 
     1350    "Emitter(output, headless=False, use_header=True, explicit_typing=True," 
     1351    "        style=None, best_width=80, indent=2) -> an Emitter object\n\n" 
     1352    "_syck.Emitter is a low-lever wrapper of the Syck emitter. It emit\n" 
     1353    "a tree of Nodes into a YAML stream.\n"); 
     1354 
     1355typedef struct { 
     1356    PyObject_HEAD 
     1357    /* Attributes: */ 
     1358    PyObject *output;       /* a file-like object */ 
     1359    int headless; 
     1360    int use_header; 
     1361    int use_version; 
     1362    int explicit_typing; 
     1363    enum scalar_style style; 
     1364    int best_width; 
     1365    int indent; 
     1366    /* Internal fields: */ 
     1367    PyObject *symbols;      /* symbol table, a list, NULL outside emit() */ 
     1368    PyObject *nodes;        /* node -> symbol, a dict, NULL outside emit() */ 
     1369    SyckEmitter *emitter; 
     1370    int emitting; 
     1371    int halt; 
     1372} PySyckEmitterObject; 
     1373 
     1374static PyObject * 
     1375PySyckEmitter_new(PyTypeObject *type, PyObject *args, PyObject *kwds) 
     1376{ 
     1377    PySyckEmitterObject *self; 
     1378 
     1379    self = (PySyckEmitterObject *)type->tp_alloc(type, 0); 
     1380    if (!self) return NULL; 
     1381 
     1382    self->output = NULL; 
     1383    self->headless = 0; 
     1384    self->use_header = 0; 
     1385    self->use_version = 0; 
     1386    self->explicit_typing = 0; 
     1387    self->style = scalar_none; 
     1388    self->best_width = 0; 
     1389    self->indent = 0; 
     1390    self->symbols = NULL; 
     1391    self->nodes = NULL; 
     1392    self->emitter = NULL; 
     1393    self->emitting = 0; 
     1394    self->halt = 1; 
     1395 
     1396    return (PyObject *)self; 
     1397} 
     1398 
     1399static int 
     1400PySyckEmitter_clear(PySyckEmitterObject *self) 
     1401{ 
     1402    PyObject *tmp; 
     1403 
     1404    if (self->emitter) { 
     1405        syck_free_emitter(self->emitter); 
     1406        self->emitter = NULL; 
     1407    } 
     1408 
     1409    tmp = self->output; 
     1410    self->output = NULL; 
     1411    Py_XDECREF(tmp); 
     1412 
     1413    tmp = self->symbols; 
     1414    self->symbols = NULL; 
     1415    Py_XDECREF(tmp); 
     1416 
     1417    tmp = self->nodes; 
     1418    self->nodes = NULL; 
     1419    Py_XDECREF(tmp); 
     1420 
     1421    return 0; 
     1422} 
     1423 
     1424static int 
     1425PySyckEmitter_traverse(PySyckEmitterObject *self, visitproc visit, void *arg) 
     1426{ 
     1427    int ret; 
     1428 
     1429    if (self->output) 
     1430        if ((ret = visit(self->output, arg)) != 0) 
     1431            return ret; 
     1432 
     1433    if (self->symbols) 
     1434        if ((ret = visit(self->symbols, arg)) != 0) 
     1435            return ret; 
     1436 
     1437    if (self->nodes) 
     1438        if ((ret = visit(self->nodes, arg)) != 0) 
     1439            return ret; 
     1440 
     1441    return 0; 
     1442} 
     1443 
     1444static void 
     1445PySyckEmitter_dealloc(PySyckEmitterObject *self) 
     1446{ 
     1447    PySyckEmitter_clear(self); 
     1448    self->ob_type->tp_free((PyObject *)self); 
     1449} 
     1450 
     1451static PyObject * 
     1452PySyckEmitter_getoutput(PySyckEmitterObject *self, void *closure) 
     1453{ 
     1454    PyObject *value = self->output ? self->output : Py_None; 
     1455 
     1456    Py_INCREF(value); 
     1457    return value; 
     1458} 
     1459 
     1460static PyObject * 
     1461PySyckEmitter_getheadless(PySyckEmitterObject *self, void *closure) 
     1462{ 
     1463    PyObject *value = self->headless ? Py_True : Py_False; 
     1464 
     1465    Py_INCREF(value); 
     1466    return value; 
     1467} 
     1468 
     1469static PyObject * 
     1470PySyckEmitter_getuse_header(PySyckEmitterObject *self, void *closure) 
     1471{ 
     1472    PyObject *value = self->use_header ? Py_True : Py_False; 
     1473 
     1474    Py_INCREF(value); 
     1475    return value; 
     1476} 
     1477 
     1478static PyObject * 
     1479PySyckEmitter_getuse_version(PySyckEmitterObject *self, void *closure) 
     1480{ 
     1481    PyObject *value = self->use_version ? Py_True : Py_False; 
     1482 
     1483    Py_INCREF(value); 
     1484    return value; 
     1485} 
     1486 
     1487static PyObject * 
     1488PySyckEmitter_getexplicit_typing(PySyckEmitterObject *self, void *closure) 
     1489{ 
     1490    PyObject *value = self->explicit_typing ? Py_True : Py_False; 
     1491 
     1492    Py_INCREF(value); 
     1493    return value; 
     1494} 
     1495 
     1496static PyObject * 
     1497PySyckEmitter_getstyle(PySyckEmitterObject *self, void *closure) 
     1498{ 
     1499    PyObject *value; 
     1500 
     1501    switch (self->style) { 
     1502        case scalar_1quote: value = PySyck_1QuoteStyle; break; 
     1503        case scalar_2quote: value = PySyck_2QuoteStyle; break; 
     1504        case scalar_fold: value = PySyck_FoldStyle; break; 
     1505        case scalar_literal: value = PySyck_LiteralStyle; break; 
     1506        case scalar_plain: value = PySyck_PlainStyle; break; 
     1507        default: value = Py_None; 
     1508    } 
     1509 
     1510    Py_INCREF(value); 
     1511    return value; 
     1512} 
     1513 
     1514static PyObject * 
     1515PySyckEmitter_getbest_width(PySyckEmitterObject *self, void *closure) 
     1516{ 
     1517    return PyInt_FromLong(self->best_width); 
     1518} 
     1519 
     1520static PyObject * 
     1521PySyckEmitter_getindent(PySyckEmitterObject *self, void *closure) 
     1522{ 
     1523    return PyInt_FromLong(self->indent); 
     1524} 
     1525 
     1526static PyGetSetDef PySyckEmitter_getsetters[] = { 
     1527    {"output", (getter)PySyckEmitter_getoutput, NULL, 
     1528        PyDoc_STR("output stream, a file-like object"), NULL}, 
     1529    {"headless", (getter)PySyckEmitter_getheadless, NULL, 
     1530        PyDoc_STR("headerless document flag"), NULL}, 
     1531    {"use_header", (getter)PySyckEmitter_getuse_header, NULL, 
     1532        PyDoc_STR("force header"), NULL}, 
     1533    {"use_version", (getter)PySyckEmitter_getuse_version, NULL, 
     1534        PyDoc_STR("force version"), NULL}, 
     1535    {"explicit_typing", (getter)PySyckEmitter_getexplicit_typing, NULL, 
     1536        PyDoc_STR("explicit typing for all collections"), NULL}, 
     1537    {"style", (getter)PySyckEmitter_getstyle, NULL, 
     1538        PyDoc_STR("use literal or folded blocks on all text"), NULL}, 
     1539    {"best_width", (getter)PySyckEmitter_getbest_width, NULL, 
     1540        PyDoc_STR("best width for folded scalars"), NULL}, 
     1541    {"indent", (getter)PySyckEmitter_getindent, NULL, 
     1542        PyDoc_STR("default indentation"), NULL}, 
     1543    {NULL}  /* Sentinel */ 
     1544}; 
     1545 
     1546static void 
     1547PySyckEmitter_node_handler(SyckEmitter *emitter, st_data_t id) 
     1548{ 
     1549    PySyckEmitterObject *self = (PySyckEmitterObject *)emitter->bonus; 
     1550 
     1551    PySyckNodeObject *node; 
     1552    char *tag = NULL; 
     1553    PyObject *index; 
     1554    PyObject *key, *value, *item, *pair; 
     1555    int j, k, l; 
     1556    char *str; 
     1557    int len; 
     1558    int dict_pos; 
     1559 
     1560    if (self->halt) return; 
     1561 
     1562    node = (PySyckNodeObject *)PyList_GetItem(self->symbols, id); 
     1563    if (!node) { 
     1564        PyErr_SetString(PyExc_RuntimeError, "unknown data id"); 
     1565        self->halt = 1; 
     1566        return; 
     1567    } 
     1568 
     1569    if (node->tag) { 
     1570        tag = PyString_AsString(node->tag); 
     1571        if (!tag) { 
     1572            self->halt = 1; 
     1573            return; 
     1574        } 
     1575    } 
     1576 
     1577    if (PyObject_TypeCheck((PyObject *)node, &PySyckSeq_Type)) { 
     1578 
     1579        syck_emit_seq(emitter, tag, ((PySyckSeqObject *)node)->style); 
     1580 
     1581        if (!PyList_Check(node->value)) { 
     1582            PyErr_SetString(PyExc_TypeError, "value of _syck.Seq must be a list"); 
     1583            self->halt = 1; 
     1584            return; 
     1585        } 
     1586        l = PyList_GET_SIZE(node->value); 
     1587        for (k = 0; k < l; k ++) { 
     1588            item = PyList_GET_ITEM(node->value, k); 
     1589            if ((index = PyDict_GetItem(self->nodes, item))) { 
     1590                syck_emit_item(emitter, PyInt_AS_LONG(index)); 
     1591                if (self->halt) return; 
     1592            } 
     1593            else { 
     1594                PyErr_SetString(PyExc_RuntimeError, "sequence item is not marked"); 
     1595                self->halt = 1; 
     1596                return; 
     1597            } 
     1598        } 
     1599        syck_emit_end(emitter); 
     1600    } 
     1601 
     1602    else if (PyObject_TypeCheck((PyObject *)node, &PySyckMap_Type)) { 
     1603 
     1604        syck_emit_map(emitter, tag, ((PySyckMapObject *)node)->style); 
     1605         
     1606        if (PyList_Check(node->value)) { 
     1607            l = PyList_GET_SIZE(node->value); 
     1608            for (k = 0; k < l; k ++) { 
     1609                pair = PyList_GET_ITEM(node->value, k); 
     1610                if (!PyTuple_Check(pair) || PyTuple_GET_SIZE(pair) != 2) { 
     1611                    PyErr_SetString(PyExc_TypeError, 
     1612                            "value of _syck.Map must be a list of pairs or a dictionary"); 
     1613                    self->halt = 1; 
     1614                    return; 
     1615                } 
     1616                for (j = 0; j < 2; j++) { 
     1617                    item = PyTuple_GET_ITEM(pair, j); 
     1618                    if ((index = PyDict_GetItem(self->nodes, item))) { 
     1619                        syck_emit_item(emitter, PyInt_AS_LONG(index)); 
     1620                        if (self->halt) return; 
     1621                    } 
     1622                    else { 
     1623                        PyErr_SetString(PyExc_RuntimeError, "mapping item is not marked"); 
     1624                        self->halt = 1; 
     1625                        return; 
     1626                    } 
     1627                } 
     1628            } 
     1629        } 
     1630        else if (PyDict_Check(node->value)) { 
     1631            dict_pos = 0; 
     1632            while (PyDict_Next(node->value, &dict_pos, &key, &value)) { 
     1633                for (j = 0; j < 2; j++) { 
     1634                    item = j ? value : key; 
     1635                    if ((index = PyDict_GetItem(self->nodes, item))) { 
     1636                        syck_emit_item(emitter, PyInt_AS_LONG(index)); 
     1637                        if (self->halt) return; 
     1638                    } 
     1639                    else { 
     1640                        PyErr_SetString(PyExc_RuntimeError, "mapping item is not marked"); 
     1641                        self->halt = 1; 
     1642                        return; 
     1643                    } 
     1644                } 
     1645            } 
     1646        } 
     1647        else { 
     1648            PyErr_SetString(PyExc_TypeError, 
     1649                    "value of _syck.Map must be a list of pairs or a dictionary"); 
     1650            self->halt = 1; 
     1651            return; 
     1652        } 
     1653 
     1654        syck_emit_end(emitter); 
     1655    } 
     1656 
     1657    else if (PyObject_TypeCheck((PyObject *)node, &PySyckScalar_Type)) { 
     1658        if (PyString_AsStringAndSize(node->value, &str, &len) < 0) { 
     1659            self->halt = 1; 
     1660            return; 
     1661        } 
     1662        syck_emit_scalar(emitter, tag, ((PySyckScalarObject *)node)->style, 
     1663                ((PySyckScalarObject *)node)->indent, 
     1664                ((PySyckScalarObject *)node)->width, 
     1665                ((PySyckScalarObject *)node)->chomp, str, len); 
     1666    } 
     1667 
     1668    else { 
     1669        PyErr_SetString(PyExc_TypeError, "Node instance is required"); 
     1670        self->halt = 1; 
     1671        return; 
     1672    }    
     1673} 
     1674static void 
     1675PySyckEmitter_write_handler(SyckEmitter *emitter, char *buf, long len) 
     1676{ 
     1677    PySyckEmitterObject *self = (PySyckEmitterObject *)emitter->bonus; 
     1678 
     1679    if (!PyObject_CallMethod(self->output, "write", "(s#)", buf, len)) 
     1680        self->halt = 1; 
     1681} 
     1682 
     1683static int 
     1684PySyckEmitter_init(PySyckEmitterObject *self, PyObject *args, PyObject *kwds) 
     1685{ 
     1686    PyObject *output = NULL; 
     1687    int headless = 0; 
     1688    int use_header = 0; 
     1689    int use_version = 0; 
     1690    int explicit_typing = 0; 
     1691    PyObject *style = NULL; 
     1692    int best_width = 80; 
     1693    int indent = 2; 
     1694 
     1695    char *str; 
     1696 
     1697    static char *kwdlist[] = {"output", "headless", "use_header", 
     1698        "use_version", "explicit_typing", "style", 
     1699        "best_width", "indent", NULL}; 
     1700 
     1701    PySyckEmitter_clear(self); 
     1702 
     1703    if (!PyArg_ParseTupleAndKeywords(args, kwds, "O|iiiiOii", kwdlist, 
     1704                &output, &headless, &use_header, &use_version, 
     1705                &explicit_typing, &style, &best_width, &indent)) 
     1706        return -1; 
     1707 
     1708    if (best_width <= 0) { 
     1709        PyErr_SetString(PyExc_ValueError, "'best_width' must be positive"); 
     1710        return -1; 
     1711    } 
     1712    if (indent <= 0) { 
     1713        PyErr_SetString(PyExc_ValueError, "'indent' must be positive"); 
     1714        return -1; 
     1715    } 
     1716 
     1717    if (!style || style == Py_None) { 
     1718        self->style = scalar_none; 
     1719    } 
     1720    else { 
     1721        if (!PyString_Check(style)) { 
     1722            PyErr_SetString(PyExc_TypeError, "'style' must be a string or None"); 
     1723            return -1; 
     1724        } 
     1725 
     1726        str = PyString_AsString(style); 
     1727        if (!str) return -1; 
     1728 
     1729        if (strcmp(str, "1quote") == 0) 
     1730            self->style = scalar_1quote; 
     1731        else if (strcmp(str, "2quote") == 0) 
     1732            self->style = scalar_2quote; 
     1733        else if (strcmp(str, "fold") == 0) 
     1734            self->style = scalar_fold; 
     1735        else if (strcmp(str, "literal") == 0) 
     1736            self->style = scalar_literal; 
     1737        else if (strcmp(str, "plain") == 0) 
     1738            self->style = scalar_plain; 
     1739        else { 
     1740            PyErr_SetString(PyExc_ValueError, "unknown 'style'"); 
     1741            return -1; 
     1742        } 
     1743    } 
     1744 
     1745    self->headless = headless; 
     1746    self->use_header = use_header; 
     1747    self->use_version = use_version; 
     1748    self->explicit_typing = explicit_typing; 
     1749    self->best_width = best_width; 
     1750    self->indent = indent; 
     1751 
     1752    Py_INCREF(output); 
     1753    self->output = output; 
     1754 
     1755/* 
     1756    self->emitter = syck_new_emitter(); 
     1757    self->emitter->bonus = self; 
     1758    self->emitter->headless = self->headless; 
     1759    self->emitter->use_header = use_header; 
     1760    self->emitter->use_version = use_version; 
     1761    self->emitter->explicit_typing = explicit_typing; 
     1762    self->emitter->style = self->style; 
     1763    self->emitter->best_width = self->best_width; 
     1764    self->emitter->indent = self->indent; 
     1765 
     1766    syck_emitter_handler(self->emitter, PySyckEmitter_node_handler); 
     1767    syck_output_handler(self->emitter, PySyckEmitter_write_handler); 
     1768*/ 
     1769 
     1770    self->emitting = 0; 
     1771    self->halt = 0; 
     1772 
     1773    return 0; 
     1774} 
     1775 
     1776static int 
     1777PySyckEmitter_mark(PySyckEmitterObject *self, PyObject *root_node) 
     1778{ 
     1779    int current, last; 
     1780    int j, k, l; 
     1781    PySyckNodeObject *node; 
     1782    PyObject *item, *key, *value, *pair; 
     1783    PyObject *index; 
     1784    int dict_pos; 
     1785 
     1786    last = 0; 
     1787    syck_emitter_mark_node(self->emitter, last); 
     1788    if (PyList_Append(self->symbols, root_node) < 0) 
     1789        return -1; 
     1790    index = PyInt_FromLong(last); 
     1791    if (!index) return -1; 
     1792    if (PyDict_SetItem(self->nodes, root_node, index) < 0) { 
     1793        Py_DECREF(index); 
     1794        return -1; 
     1795    } 
     1796    Py_DECREF(index); 
     1797 
     1798    for (current = 0; current < PyList_GET_SIZE(self->symbols); current++) { 
     1799 
     1800        node = (PySyckNodeObject *)PyList_GET_ITEM(self->symbols, current); 
     1801 
     1802        if (PyObject_TypeCheck((PyObject *)node, &PySyckSeq_Type)) { 
     1803            if (!PyList_Check(node->value)) { 
     1804                PyErr_SetString(PyExc_TypeError, "value of _syck.Seq must be a list"); 
     1805                return -1; 
     1806            } 
     1807            l = PyList_GET_SIZE(node->value); 
     1808            for (k = 0; k < l; k ++) { 
     1809                item = PyList_GET_ITEM(node->value, k); 
     1810                if ((index = PyDict_GetItem(self->nodes, item))) { 
     1811                    syck_emitter_mark_node(self->emitter, PyInt_AS_LONG(index)); 
     1812                } 
     1813                else { 
     1814                    syck_emitter_mark_node(self->emitter, ++last); 
     1815                    if (PyList_Append(self->symbols, item) < 0) 
     1816                        return -1; 
     1817                    index = PyInt_FromLong(last); 
     1818                    if (!index) return -1; 
     1819                    if (PyDict_SetItem(self->nodes, item, index) < 0) { 
     1820                        Py_DECREF(index); 
     1821                        return -1; 
     1822                    } 
     1823                    Py_DECREF(index); 
     1824                } 
     1825            } 
     1826        } 
     1827 
     1828        else if (PyObject_TypeCheck((PyObject *)node, &PySyckMap_Type)) { 
     1829             
     1830            if (PyList_Check(node->value)) { 
     1831                l = PyList_GET_SIZE(node->value); 
     1832                for (k = 0; k < l; k ++) { 
     1833                    pair = PyList_GET_ITEM(node->value, k); 
     1834                    if (!PyTuple_Check(pair) || PyTuple_GET_SIZE(pair) != 2) { 
     1835                        PyErr_SetString(PyExc_TypeError, 
     1836                                "value of _syck.Map must be a list of pairs or a dictionary"); 
     1837                        return -1; 
     1838                    } 
     1839                    for (j = 0; j < 2; j++) { 
     1840                        item = PyTuple_GET_ITEM(pair, j); 
     1841                        if ((index = PyDict_GetItem(self->nodes, item))) { 
     1842                            syck_emitter_mark_node(self->emitter, PyInt_AS_LONG(index)); 
     1843                        } 
     1844                        else { 
     1845                            syck_emitter_mark_node(self->emitter, ++last); 
     1846                            if (PyList_Append(self->symbols, item) < 0) 
     1847                                return -1; 
     1848                            index = PyInt_FromLong(last); 
     1849                            if (!index) return -1; 
     1850                            if (PyDict_SetItem(self->nodes, item, index) < 0) { 
     1851                                Py_DECREF(index); 
     1852                                return -1; 
     1853                            } 
     1854                            Py_DECREF(index); 
     1855                        } 
     1856                    } 
     1857                } 
     1858                 
     1859            } 
     1860            else if (PyDict_Check(node->value)) { 
     1861                dict_pos = 0; 
     1862                while (PyDict_Next(node->value, &dict_pos, &key, &value)) { 
     1863                    for (j = 0; j < 2; j++) { 
     1864                        item = j ? value : key; 
     1865                        if ((index = PyDict_GetItem(self->nodes, item))) { 
     1866                            syck_emitter_mark_node(self->emitter, PyInt_AS_LONG(index)); 
     1867                        } 
     1868                        else { 
     1869                            syck_emitter_mark_node(self->emitter, ++last); 
     1870                            if (PyList_Append(self->symbols, item) < 0) 
     1871                                return -1; 
     1872                            index = PyInt_FromLong(last); 
     1873                            if (!index) return -1; 
     1874                            if (PyDict_SetItem(self->nodes, item, index) < 0) { 
     1875                                Py_DECREF(index); 
     1876                                return -1; 
     1877                            } 
     1878                            Py_DECREF(index); 
     1879                        } 
     1880                    } 
     1881                } 
     1882            } 
     1883            else { 
     1884                PyErr_SetString(PyExc_TypeError, 
     1885                        "value of _syck.Map must be a list of pairs or a dictionary"); 
     1886                return -1; 
     1887            } 
     1888        } 
     1889 
     1890        else if (!PyObject_TypeCheck((PyObject *)node, &PySyckScalar_Type)) { 
     1891            PyErr_SetString(PyExc_TypeError, "Node instance is required"); 
     1892            return -1; 
     1893        }    
     1894    } 
     1895    return 0; 
     1896} 
     1897 
     1898static PyObject * 
     1899PySyckEmitter_emit(PySyckEmitterObject *self, PyObject *args) 
     1900{ 
     1901    PyObject *node; 
     1902 
     1903    if (self->emitting) { 
     1904        PyErr_SetString(PyExc_RuntimeError, "do not call Emitter.emit while it is already emitting"); 
     1905        return NULL; 
     1906    } 
     1907 
     1908    if (self->halt) { 
     1909        Py_INCREF(Py_None); 
     1910        return Py_None; 
     1911    } 
     1912 
     1913    if (!PyArg_ParseTuple(args, "O", &node)) 
     1914        return NULL; 
     1915 
     1916    self->emitting = 1; 
     1917 
     1918 
     1919    self->symbols = PyList_New(0); 
     1920    if (!self->symbols) { 
     1921        return NULL; 
     1922    } 
     1923    self->nodes = PyDict_New(); 
     1924    if (!self->nodes) { 
     1925        Py_DECREF(self->symbols); 
     1926        self->symbols = NULL; 
     1927        return NULL; 
     1928    } 
     1929 
     1930    self->emitter = syck_new_emitter(); 
     1931    self->emitter->bonus = self; 
     1932    self->emitter->headless = self->headless; 
     1933    self->emitter->use_header = self->use_header; 
     1934    self->emitter->use_version = self->use_version; 
     1935    self->emitter->explicit_typing = self->explicit_typing; 
     1936    self->emitter->style = self->style; 
     1937    self->emitter->best_width = self->best_width; 
     1938    self->emitter->indent = self->indent; 
     1939 
     1940    syck_emitter_handler(self->emitter, PySyckEmitter_node_handler); 
     1941    syck_output_handler(self->emitter, PySyckEmitter_write_handler); 
     1942 
     1943    if (PySyckEmitter_mark(self, node) < 0) { 
     1944        Py_DECREF(self->symbols); 
     1945        self->symbols = NULL; 
     1946        Py_DECREF(self->nodes); 
     1947        self->nodes = NULL; 
     1948        self->emitting = 0; 
     1949        self->halt = 1; 
     1950        syck_free_emitter(self->emitter); 
     1951        self->emitter = NULL; 
     1952        return NULL; 
     1953    } 
     1954 
     1955    syck_emit(self->emitter, 0); 
     1956    syck_emitter_flush(self->emitter, 0); 
     1957 
     1958    syck_free_emitter(self->emitter); 
     1959    self->emitter = NULL; 
     1960 
     1961    self->emitting = 0; 
     1962 
     1963    Py_DECREF(self->symbols); 
     1964    self->symbols = NULL; 
     1965    Py_DECREF(self->nodes); 
     1966    self->nodes = NULL; 
     1967 
     1968    if (self->halt) return NULL; 
     1969 
     1970    Py_INCREF(Py_None); 
     1971    return Py_None; 
     1972} 
     1973 
     1974PyDoc_STRVAR(PySyckEmitter_emit_doc, 
     1975    "emit(root_node) -> None\n\n" 
     1976    "Emit the Node tree to the output.\n"); 
     1977 
     1978static PyMethodDef PySyckEmitter_methods[] = { 
     1979    {"emit",  (PyCFunction)PySyckEmitter_emit, 
     1980        METH_VARARGS, PySyckEmitter_emit_doc}, 
     1981    {NULL}  /* Sentinel */ 
     1982}; 
     1983 
     1984static PyTypeObject PySyckEmitter_Type = { 
     1985    PyObject_HEAD_INIT(NULL) 
     1986    0,                                          /* ob_size */ 
     1987    "_syck.Emitter",                            /* tp_name */ 
     1988    sizeof(PySyckEmitterObject),                /* tp_basicsize */ 
     1989    0,                                          /* tp_itemsize */ 
     1990    (destructor)PySyckEmitter_dealloc,          /* tp_dealloc */ 
     1991    0,                                          /* tp_print */ 
     1992    0,                                          /* tp_getattr */ 
     1993    0,                                          /* tp_setattr */ 
     1994    0,                                          /* tp_compare */ 
     1995    0,                                          /* tp_repr */ 
     1996    0,                                          /* tp_as_number */ 
     1997    0,                                          /* tp_as_sequence */ 
     1998    0,                                          /* tp_as_mapping */ 
     1999    0,                                          /* tp_hash */ 
     2000    0,                                          /* tp_call */ 
     2001    0,                                          /* tp_str */ 
     2002    0,                                          /* tp_getattro */ 
     2003    0,                                          /* tp_setattro */ 
     2004    0,                                          /* tp_as_buffer */ 
     2005    Py_TPFLAGS_DEFAULT|Py_TPFLAGS_BASETYPE|Py_TPFLAGS_HAVE_GC,  /* tp_flags */ 
     2006    PySyckEmitter_doc,                          /* tp_doc */ 
     2007    (traverseproc)PySyckEmitter_traverse,       /* tp_traverse */ 
     2008    (inquiry)PySyckEmitter_clear,               /* tp_clear */ 
     2009    0,                                          /* tp_richcompare */ 
     2010    0,                                          /* tp_weaklistoffset */ 
     2011    0,                                          /* tp_iter */ 
     2012    0,                                          /* tp_iternext */ 
     2013    PySyckEmitter_methods,                      /* tp_methods */ 
     2014    0,                                          /* tp_members */ 
     2015    PySyckEmitter_getsetters,                   /* tp_getset */ 
     2016    0,                                          /* tp_base */ 
     2017    0,                                          /* tp_dict */ 
     2018    0,                                          /* tp_descr_get */ 
     2019    0,                                          /* tp_descr_set */ 
     2020    0,                                          /* tp_dictoffset */ 
     2021    (initproc)PySyckEmitter_init,               /* tp_init */ 
     2022    0,                                          /* tp_alloc */ 
     2023    PySyckEmitter_new,                          /* tp_new */ 
     2024}; 
     2025 
     2026/**************************************************************************** 
    13342027 * The module _syck. 
    13352028 ****************************************************************************/ 
     
    13572050    if (PyType_Ready(&PySyckParser_Type) < 0) 
    13582051        return; 
     2052    if (PyType_Ready(&PySyckEmitter_Type) < 0) 
     2053        return; 
    13592054     
    13602055    PySyck_Error = PyErr_NewException("_syck.error", NULL, NULL); 
     
    13892084    if (PyModule_AddObject(m, "error", (PyObject *)PySyck_Error) < 0) 
    13902085        return; 
    1391  
    13922086    Py_INCREF(&PySyckNode_Type); 
    13932087    if (PyModule_AddObject(m, "Node", (PyObject *)&PySyckNode_Type) < 0) 
    13942088        return; 
    1395  
    13962089    Py_INCREF(&PySyckScalar_Type); 
    13972090    if (PyModule_AddObject(m, "Scalar", (PyObject *)&PySyckScalar_Type) < 0) 
    13982091        return; 
    1399  
    14002092    Py_INCREF(&PySyckSeq_Type); 
    14012093    if (PyModule_AddObject(m, "Seq", (PyObject *)&PySyckSeq_Type) < 0) 
    14022094        return; 
    1403  
    14042095    Py_INCREF(&PySyckMap_Type); 
    14052096    if (PyModule_AddObject(m, "Map", (PyObject *)&PySyckMap_Type) < 0) 
    14062097        return; 
    1407  
    14082098    Py_INCREF(&PySyckParser_Type); 
    14092099    if (PyModule_AddObject(m, "Parser", (PyObject *)&PySyckParser_Type) < 0) 
    14102100        return; 
    1411 } 
    1412  
     2101    Py_INCREF(&PySyckEmitter_Type); 
     2102    if (PyModule_AddObject(m, "Emitter", (PyObject *)&PySyckEmitter_Type) < 0) 
     2103        return; 
     2104} 
     2105 
  • trunk/sandbox/emit-it/emit-it.c

    r11 r17  
    1717    switch (id) { 
    1818        case 1: 
    19             syck_emit_seq(e, NULL, seq_none); 
     19            syck_emit_seq(e, "tag:domainmyseq.tld,2002:zz", seq_none); 
    2020            syck_emit_item(e, 2); 
    2121            syck_emit_item(e, 3); 
    2222            syck_emit_item(e, 4); 
     23/*            syck_emit_item(e, 2); 
     24            syck_emit_item(e, 1);*/ 
    2325            syck_emit_end(e); 
    2426            break; 
    2527        case 2: 
    26             syck_emit_scalar(e, NULL, scalar_none, 0, 0, 0, "Mark McGwire", strlen("Mark McGwire")); 
     28            syck_emit_scalar(e, "tag:yaml.org,2002:str", scalar_none, 0, 0, 0, "Mark McGwire ", strlen("Mark McGwire ")); 
    2729            break; 
    2830        case 3: 
    29             syck_emit_scalar(e, NULL, scalar_none, 0, 0, 0, "Sammy Sosa", strlen("Sammy Sosa")); 
     31            syck_emit_scalar(e, "tag:python.yaml.org,2002:object", scalar_none, 0, 0, 0, "Sammy Sosa", strlen("Sammy Sosa")); 
    3032            break; 
    3133        case 4: 
    32             syck_emit_scalar(e, NULL, scalar_none, 0, 0, 0, "Ken Griffey", strlen("Ken Griffey")); 
     34            syck_emit_scalar(e, "x-private:myowntype", scalar_none, 0, 0, 0, "Ken Griffey", strlen("Ken Griffey")); 
    3335            break; 
    3436    } 
     
    4648    syck_emitter_mark_node(e, 3); 
    4749    syck_emitter_mark_node(e, 4); 
     50/*    syck_emitter_mark_node(e, 2); 
     51    syck_emitter_mark_node(e, 1);*/ 
    4852    syck_emit(e, 1); 
    4953    syck_emitter_flush(e, 0); 
  • trunk/tests/test_node.py

    r16 r17  
    3434        self.assertRaises(TypeError, lambda: setattr(scalar, 'value', [])) 
    3535        self.assertRaises(TypeError, lambda: setattr(scalar, 'tag', [])) 
    36         self.assertRaises(TypeError, lambda: setattr(scalar, 'style', 'block')) 
     36        self.assertRaises(ValueError, lambda: setattr(scalar, 'style', 'block')) 
    3737        self.assertRaises(TypeError, lambda: setattr(scalar, 'style', [])) 
    3838        self.assertRaises(TypeError, lambda: setattr(scalar, 'indent', '1')) 
  • trunk/tests/test_parser.py

    r16 r17  
    160160] 
    161161 
     162RECURSIVE = """ 
     163--- &id002 
     164- &id001 Mark McGwire 
     165- Sammy Sosa 
     166- Ken Griffey 
     167- *id001 
     168- *id002 
     169""" 
     170 
    162171class TestAttributes(unittest.TestCase): 
    163172 
     
    344353            self.assertEqual(node.tag, tag) 
    345354 
     355class TestRecursive(unittest.TestCase): 
     356 
     357    def testRecursive(self): 
     358        parser = _syck.Parser(RECURSIVE) 
     359        self.assertRaises(TypeError, lambda: parser.parse()) 
     360 
  • trunk/tests/test_syck.py

    r16 r17  
    55from test_parser import * 
    66from test_loader import * 
     7from test_emitter import * 
    78 
    89def main(module='__main__'): 
Note: See TracChangeset for help on using the changeset viewer.