]> git.proxmox.com Git - mirror_edk2.git/blobdiff - AppPkg/Applications/Python/Python-2.7.2/Modules/_csv.c
edk2: Remove AppPkg, StdLib, StdLibPrivateInternalFiles
[mirror_edk2.git] / AppPkg / Applications / Python / Python-2.7.2 / Modules / _csv.c
diff --git a/AppPkg/Applications/Python/Python-2.7.2/Modules/_csv.c b/AppPkg/Applications/Python/Python-2.7.2/Modules/_csv.c
deleted file mode 100644 (file)
index fc9e454..0000000
+++ /dev/null
@@ -1,1611 +0,0 @@
-/* csv module */\r
-\r
-/*\r
-\r
-This module provides the low-level underpinnings of a CSV reading/writing\r
-module.  Users should not use this module directly, but import the csv.py\r
-module instead.\r
-\r
-**** For people modifying this code, please note that as of this writing\r
-**** (2003-03-23), it is intended that this code should work with Python\r
-**** 2.2.\r
-\r
-*/\r
-\r
-#define MODULE_VERSION "1.0"\r
-\r
-#include "Python.h"\r
-#include "structmember.h"\r
-\r
-\r
-/* begin 2.2 compatibility macros */\r
-#ifndef PyDoc_STRVAR\r
-/* Define macros for inline documentation. */\r
-#define PyDoc_VAR(name) static char name[]\r
-#define PyDoc_STRVAR(name,str) PyDoc_VAR(name) = PyDoc_STR(str)\r
-#ifdef WITH_DOC_STRINGS\r
-#define PyDoc_STR(str) str\r
-#else\r
-#define PyDoc_STR(str) ""\r
-#endif\r
-#endif /* ifndef PyDoc_STRVAR */\r
-\r
-#ifndef PyMODINIT_FUNC\r
-#       if defined(__cplusplus)\r
-#               define PyMODINIT_FUNC extern "C" void\r
-#       else /* __cplusplus */\r
-#               define PyMODINIT_FUNC void\r
-#       endif /* __cplusplus */\r
-#endif\r
-\r
-#ifndef Py_CLEAR\r
-#define Py_CLEAR(op)                                            \\r
-    do {                                                        \\r
-        if (op) {                                               \\r
-            PyObject *tmp = (PyObject *)(op);                   \\r
-            (op) = NULL;                                        \\r
-            Py_DECREF(tmp);                                     \\r
-        }                                                       \\r
-    } while (0)\r
-#endif\r
-#ifndef Py_VISIT\r
-#define Py_VISIT(op)                                                    \\r
-    do {                                                                \\r
-        if (op) {                                                       \\r
-            int vret = visit((PyObject *)(op), arg);                    \\r
-            if (vret)                                                   \\r
-                return vret;                                            \\r
-        }                                                               \\r
-    } while (0)\r
-#endif\r
-\r
-/* end 2.2 compatibility macros */\r
-\r
-#define IS_BASESTRING(o) \\r
-    PyObject_TypeCheck(o, &PyBaseString_Type)\r
-\r
-static PyObject *error_obj;     /* CSV exception */\r
-static PyObject *dialects;      /* Dialect registry */\r
-static long field_limit = 128 * 1024;   /* max parsed field size */\r
-\r
-typedef enum {\r
-    START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD,\r
-    IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD,\r
-    EAT_CRNL\r
-} ParserState;\r
-\r
-typedef enum {\r
-    QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE\r
-} QuoteStyle;\r
-\r
-typedef struct {\r
-    QuoteStyle style;\r
-    char *name;\r
-} StyleDesc;\r
-\r
-static StyleDesc quote_styles[] = {\r
-    { QUOTE_MINIMAL,    "QUOTE_MINIMAL" },\r
-    { QUOTE_ALL,        "QUOTE_ALL" },\r
-    { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" },\r
-    { QUOTE_NONE,       "QUOTE_NONE" },\r
-    { 0 }\r
-};\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-\r
-    int doublequote;            /* is " represented by ""? */\r
-    char delimiter;             /* field separator */\r
-    char quotechar;             /* quote character */\r
-    char escapechar;            /* escape character */\r
-    int skipinitialspace;       /* ignore spaces following delimiter? */\r
-    PyObject *lineterminator; /* string to write between records */\r
-    int quoting;                /* style of quoting to write */\r
-\r
-    int strict;                 /* raise exception on bad CSV */\r
-} DialectObj;\r
-\r
-staticforward PyTypeObject Dialect_Type;\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-\r
-    PyObject *input_iter;   /* iterate over this for input lines */\r
-\r
-    DialectObj *dialect;    /* parsing dialect */\r
-\r
-    PyObject *fields;           /* field list for current record */\r
-    ParserState state;          /* current CSV parse state */\r
-    char *field;                /* build current field in here */\r
-    int field_size;             /* size of allocated buffer */\r
-    int field_len;              /* length of current field */\r
-    int numeric_field;          /* treat field as numeric */\r
-    unsigned long line_num;     /* Source-file line number */\r
-} ReaderObj;\r
-\r
-staticforward PyTypeObject Reader_Type;\r
-\r
-#define ReaderObject_Check(v)   (Py_TYPE(v) == &Reader_Type)\r
-\r
-typedef struct {\r
-    PyObject_HEAD\r
-\r
-    PyObject *writeline;    /* write output lines to this file */\r
-\r
-    DialectObj *dialect;    /* parsing dialect */\r
-\r
-    char *rec;                  /* buffer for parser.join */\r
-    int rec_size;               /* size of allocated record */\r
-    int rec_len;                /* length of record */\r
-    int num_fields;             /* number of fields in record */\r
-} WriterObj;\r
-\r
-staticforward PyTypeObject Writer_Type;\r
-\r
-/*\r
- * DIALECT class\r
- */\r
-\r
-static PyObject *\r
-get_dialect_from_registry(PyObject * name_obj)\r
-{\r
-    PyObject *dialect_obj;\r
-\r
-    dialect_obj = PyDict_GetItem(dialects, name_obj);\r
-    if (dialect_obj == NULL) {\r
-        if (!PyErr_Occurred())\r
-            PyErr_Format(error_obj, "unknown dialect");\r
-    }\r
-    else\r
-        Py_INCREF(dialect_obj);\r
-    return dialect_obj;\r
-}\r
-\r
-static PyObject *\r
-get_string(PyObject *str)\r
-{\r
-    Py_XINCREF(str);\r
-    return str;\r
-}\r
-\r
-static PyObject *\r
-get_nullchar_as_None(char c)\r
-{\r
-    if (c == '\0') {\r
-        Py_INCREF(Py_None);\r
-        return Py_None;\r
-    }\r
-    else\r
-        return PyString_FromStringAndSize((char*)&c, 1);\r
-}\r
-\r
-static PyObject *\r
-Dialect_get_lineterminator(DialectObj *self)\r
-{\r
-    return get_string(self->lineterminator);\r
-}\r
-\r
-static PyObject *\r
-Dialect_get_escapechar(DialectObj *self)\r
-{\r
-    return get_nullchar_as_None(self->escapechar);\r
-}\r
-\r
-static PyObject *\r
-Dialect_get_quotechar(DialectObj *self)\r
-{\r
-    return get_nullchar_as_None(self->quotechar);\r
-}\r
-\r
-static PyObject *\r
-Dialect_get_quoting(DialectObj *self)\r
-{\r
-    return PyInt_FromLong(self->quoting);\r
-}\r
-\r
-static int\r
-_set_bool(const char *name, int *target, PyObject *src, int dflt)\r
-{\r
-    if (src == NULL)\r
-        *target = dflt;\r
-    else\r
-        *target = PyObject_IsTrue(src);\r
-    return 0;\r
-}\r
-\r
-static int\r
-_set_int(const char *name, int *target, PyObject *src, int dflt)\r
-{\r
-    if (src == NULL)\r
-        *target = dflt;\r
-    else {\r
-        if (!PyInt_Check(src)) {\r
-            PyErr_Format(PyExc_TypeError,\r
-                         "\"%s\" must be an integer", name);\r
-            return -1;\r
-        }\r
-        *target = PyInt_AsLong(src);\r
-    }\r
-    return 0;\r
-}\r
-\r
-static int\r
-_set_char(const char *name, char *target, PyObject *src, char dflt)\r
-{\r
-    if (src == NULL)\r
-        *target = dflt;\r
-    else {\r
-        if (src == Py_None || PyString_Size(src) == 0)\r
-            *target = '\0';\r
-        else if (!PyString_Check(src) || PyString_Size(src) != 1) {\r
-            PyErr_Format(PyExc_TypeError,\r
-                         "\"%s\" must be an 1-character string",\r
-                         name);\r
-            return -1;\r
-        }\r
-        else {\r
-            char *s = PyString_AsString(src);\r
-            if (s == NULL)\r
-                return -1;\r
-            *target = s[0];\r
-        }\r
-    }\r
-    return 0;\r
-}\r
-\r
-static int\r
-_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)\r
-{\r
-    if (src == NULL)\r
-        *target = PyString_FromString(dflt);\r
-    else {\r
-        if (src == Py_None)\r
-            *target = NULL;\r
-        else if (!IS_BASESTRING(src)) {\r
-            PyErr_Format(PyExc_TypeError,\r
-                         "\"%s\" must be an string", name);\r
-            return -1;\r
-        }\r
-        else {\r
-            Py_XDECREF(*target);\r
-            Py_INCREF(src);\r
-            *target = src;\r
-        }\r
-    }\r
-    return 0;\r
-}\r
-\r
-static int\r
-dialect_check_quoting(int quoting)\r
-{\r
-    StyleDesc *qs = quote_styles;\r
-\r
-    for (qs = quote_styles; qs->name; qs++) {\r
-        if (qs->style == quoting)\r
-            return 0;\r
-    }\r
-    PyErr_Format(PyExc_TypeError, "bad \"quoting\" value");\r
-    return -1;\r
-}\r
-\r
-#define D_OFF(x) offsetof(DialectObj, x)\r
-\r
-static struct PyMemberDef Dialect_memberlist[] = {\r
-    { "delimiter",          T_CHAR, D_OFF(delimiter), READONLY },\r
-    { "skipinitialspace",   T_INT, D_OFF(skipinitialspace), READONLY },\r
-    { "doublequote",        T_INT, D_OFF(doublequote), READONLY },\r
-    { "strict",             T_INT, D_OFF(strict), READONLY },\r
-    { NULL }\r
-};\r
-\r
-static PyGetSetDef Dialect_getsetlist[] = {\r
-    { "escapechar",             (getter)Dialect_get_escapechar},\r
-    { "lineterminator",         (getter)Dialect_get_lineterminator},\r
-    { "quotechar",              (getter)Dialect_get_quotechar},\r
-    { "quoting",                (getter)Dialect_get_quoting},\r
-    {NULL},\r
-};\r
-\r
-static void\r
-Dialect_dealloc(DialectObj *self)\r
-{\r
-    Py_XDECREF(self->lineterminator);\r
-    Py_TYPE(self)->tp_free((PyObject *)self);\r
-}\r
-\r
-static char *dialect_kws[] = {\r
-    "dialect",\r
-    "delimiter",\r
-    "doublequote",\r
-    "escapechar",\r
-    "lineterminator",\r
-    "quotechar",\r
-    "quoting",\r
-    "skipinitialspace",\r
-    "strict",\r
-    NULL\r
-};\r
-\r
-static PyObject *\r
-dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)\r
-{\r
-    DialectObj *self;\r
-    PyObject *ret = NULL;\r
-    PyObject *dialect = NULL;\r
-    PyObject *delimiter = NULL;\r
-    PyObject *doublequote = NULL;\r
-    PyObject *escapechar = NULL;\r
-    PyObject *lineterminator = NULL;\r
-    PyObject *quotechar = NULL;\r
-    PyObject *quoting = NULL;\r
-    PyObject *skipinitialspace = NULL;\r
-    PyObject *strict = NULL;\r
-\r
-    if (!PyArg_ParseTupleAndKeywords(args, kwargs,\r
-                                     "|OOOOOOOOO", dialect_kws,\r
-                                     &dialect,\r
-                                     &delimiter,\r
-                                     &doublequote,\r
-                                     &escapechar,\r
-                                     &lineterminator,\r
-                                     &quotechar,\r
-                                     &quoting,\r
-                                     &skipinitialspace,\r
-                                     &strict))\r
-        return NULL;\r
-\r
-    if (dialect != NULL) {\r
-        if (IS_BASESTRING(dialect)) {\r
-            dialect = get_dialect_from_registry(dialect);\r
-            if (dialect == NULL)\r
-                return NULL;\r
-        }\r
-        else\r
-            Py_INCREF(dialect);\r
-        /* Can we reuse this instance? */\r
-        if (PyObject_TypeCheck(dialect, &Dialect_Type) &&\r
-            delimiter == 0 &&\r
-            doublequote == 0 &&\r
-            escapechar == 0 &&\r
-            lineterminator == 0 &&\r
-            quotechar == 0 &&\r
-            quoting == 0 &&\r
-            skipinitialspace == 0 &&\r
-            strict == 0)\r
-            return dialect;\r
-    }\r
-\r
-    self = (DialectObj *)type->tp_alloc(type, 0);\r
-    if (self == NULL) {\r
-        Py_XDECREF(dialect);\r
-        return NULL;\r
-    }\r
-    self->lineterminator = NULL;\r
-\r
-    Py_XINCREF(delimiter);\r
-    Py_XINCREF(doublequote);\r
-    Py_XINCREF(escapechar);\r
-    Py_XINCREF(lineterminator);\r
-    Py_XINCREF(quotechar);\r
-    Py_XINCREF(quoting);\r
-    Py_XINCREF(skipinitialspace);\r
-    Py_XINCREF(strict);\r
-    if (dialect != NULL) {\r
-#define DIALECT_GETATTR(v, n) \\r
-        if (v == NULL) \\r
-            v = PyObject_GetAttrString(dialect, n)\r
-        DIALECT_GETATTR(delimiter, "delimiter");\r
-        DIALECT_GETATTR(doublequote, "doublequote");\r
-        DIALECT_GETATTR(escapechar, "escapechar");\r
-        DIALECT_GETATTR(lineterminator, "lineterminator");\r
-        DIALECT_GETATTR(quotechar, "quotechar");\r
-        DIALECT_GETATTR(quoting, "quoting");\r
-        DIALECT_GETATTR(skipinitialspace, "skipinitialspace");\r
-        DIALECT_GETATTR(strict, "strict");\r
-        PyErr_Clear();\r
-    }\r
-\r
-    /* check types and convert to C values */\r
-#define DIASET(meth, name, target, src, dflt) \\r
-    if (meth(name, target, src, dflt)) \\r
-        goto err\r
-    DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ',');\r
-    DIASET(_set_bool, "doublequote", &self->doublequote, doublequote, 1);\r
-    DIASET(_set_char, "escapechar", &self->escapechar, escapechar, 0);\r
-    DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n");\r
-    DIASET(_set_char, "quotechar", &self->quotechar, quotechar, '"');\r
-    DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL);\r
-    DIASET(_set_bool, "skipinitialspace", &self->skipinitialspace, skipinitialspace, 0);\r
-    DIASET(_set_bool, "strict", &self->strict, strict, 0);\r
-\r
-    /* validate options */\r
-    if (dialect_check_quoting(self->quoting))\r
-        goto err;\r
-    if (self->delimiter == 0) {\r
-        PyErr_SetString(PyExc_TypeError, "delimiter must be set");\r
-        goto err;\r
-    }\r
-    if (quotechar == Py_None && quoting == NULL)\r
-        self->quoting = QUOTE_NONE;\r
-    if (self->quoting != QUOTE_NONE && self->quotechar == 0) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-                        "quotechar must be set if quoting enabled");\r
-        goto err;\r
-    }\r
-    if (self->lineterminator == 0) {\r
-        PyErr_SetString(PyExc_TypeError, "lineterminator must be set");\r
-        goto err;\r
-    }\r
-\r
-    ret = (PyObject *)self;\r
-    Py_INCREF(self);\r
-err:\r
-    Py_XDECREF(self);\r
-    Py_XDECREF(dialect);\r
-    Py_XDECREF(delimiter);\r
-    Py_XDECREF(doublequote);\r
-    Py_XDECREF(escapechar);\r
-    Py_XDECREF(lineterminator);\r
-    Py_XDECREF(quotechar);\r
-    Py_XDECREF(quoting);\r
-    Py_XDECREF(skipinitialspace);\r
-    Py_XDECREF(strict);\r
-    return ret;\r
-}\r
-\r
-\r
-PyDoc_STRVAR(Dialect_Type_doc,\r
-"CSV dialect\n"\r
-"\n"\r
-"The Dialect type records CSV parsing and generation options.\n");\r
-\r
-static PyTypeObject Dialect_Type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "_csv.Dialect",                         /* tp_name */\r
-    sizeof(DialectObj),                     /* tp_basicsize */\r
-    0,                                      /* tp_itemsize */\r
-    /*  methods  */\r
-    (destructor)Dialect_dealloc,            /* tp_dealloc */\r
-    (printfunc)0,                           /* tp_print */\r
-    (getattrfunc)0,                         /* tp_getattr */\r
-    (setattrfunc)0,                         /* tp_setattr */\r
-    (cmpfunc)0,                             /* tp_compare */\r
-    (reprfunc)0,                            /* tp_repr */\r
-    0,                                      /* tp_as_number */\r
-    0,                                      /* tp_as_sequence */\r
-    0,                                      /* tp_as_mapping */\r
-    (hashfunc)0,                            /* tp_hash */\r
-    (ternaryfunc)0,                         /* tp_call */\r
-    (reprfunc)0,                                /* tp_str */\r
-    0,                                      /* tp_getattro */\r
-    0,                                      /* tp_setattro */\r
-    0,                                      /* tp_as_buffer */\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /* tp_flags */\r
-    Dialect_Type_doc,                       /* tp_doc */\r
-    0,                                      /* tp_traverse */\r
-    0,                                      /* tp_clear */\r
-    0,                                      /* tp_richcompare */\r
-    0,                                      /* tp_weaklistoffset */\r
-    0,                                      /* tp_iter */\r
-    0,                                      /* tp_iternext */\r
-    0,                                          /* tp_methods */\r
-    Dialect_memberlist,                     /* tp_members */\r
-    Dialect_getsetlist,                     /* tp_getset */\r
-    0,                                          /* tp_base */\r
-    0,                                          /* tp_dict */\r
-    0,                                          /* tp_descr_get */\r
-    0,                                          /* tp_descr_set */\r
-    0,                                          /* tp_dictoffset */\r
-    0,                                          /* tp_init */\r
-    0,                                          /* tp_alloc */\r
-    dialect_new,                                /* tp_new */\r
-    0,                                          /* tp_free */\r
-};\r
-\r
-/*\r
- * Return an instance of the dialect type, given a Python instance or kwarg\r
- * description of the dialect\r
- */\r
-static PyObject *\r
-_call_dialect(PyObject *dialect_inst, PyObject *kwargs)\r
-{\r
-    PyObject *ctor_args;\r
-    PyObject *dialect;\r
-\r
-    ctor_args = Py_BuildValue(dialect_inst ? "(O)" : "()", dialect_inst);\r
-    if (ctor_args == NULL)\r
-        return NULL;\r
-    dialect = PyObject_Call((PyObject *)&Dialect_Type, ctor_args, kwargs);\r
-    Py_DECREF(ctor_args);\r
-    return dialect;\r
-}\r
-\r
-/*\r
- * READER\r
- */\r
-static int\r
-parse_save_field(ReaderObj *self)\r
-{\r
-    PyObject *field;\r
-\r
-    field = PyString_FromStringAndSize(self->field, self->field_len);\r
-    if (field == NULL)\r
-        return -1;\r
-    self->field_len = 0;\r
-    if (self->numeric_field) {\r
-        PyObject *tmp;\r
-\r
-        self->numeric_field = 0;\r
-        tmp = PyNumber_Float(field);\r
-        if (tmp == NULL) {\r
-            Py_DECREF(field);\r
-            return -1;\r
-        }\r
-        Py_DECREF(field);\r
-        field = tmp;\r
-    }\r
-    PyList_Append(self->fields, field);\r
-    Py_DECREF(field);\r
-    return 0;\r
-}\r
-\r
-static int\r
-parse_grow_buff(ReaderObj *self)\r
-{\r
-    if (self->field_size == 0) {\r
-        self->field_size = 4096;\r
-        if (self->field != NULL)\r
-            PyMem_Free(self->field);\r
-        self->field = PyMem_Malloc(self->field_size);\r
-    }\r
-    else {\r
-        if (self->field_size > INT_MAX / 2) {\r
-            PyErr_NoMemory();\r
-            return 0;\r
-        }\r
-        self->field_size *= 2;\r
-        self->field = PyMem_Realloc(self->field, self->field_size);\r
-    }\r
-    if (self->field == NULL) {\r
-        PyErr_NoMemory();\r
-        return 0;\r
-    }\r
-    return 1;\r
-}\r
-\r
-static int\r
-parse_add_char(ReaderObj *self, char c)\r
-{\r
-    if (self->field_len >= field_limit) {\r
-        PyErr_Format(error_obj, "field larger than field limit (%ld)",\r
-                     field_limit);\r
-        return -1;\r
-    }\r
-    if (self->field_len == self->field_size && !parse_grow_buff(self))\r
-        return -1;\r
-    self->field[self->field_len++] = c;\r
-    return 0;\r
-}\r
-\r
-static int\r
-parse_process_char(ReaderObj *self, char c)\r
-{\r
-    DialectObj *dialect = self->dialect;\r
-\r
-    switch (self->state) {\r
-    case START_RECORD:\r
-        /* start of record */\r
-        if (c == '\0')\r
-            /* empty line - return [] */\r
-            break;\r
-        else if (c == '\n' || c == '\r') {\r
-            self->state = EAT_CRNL;\r
-            break;\r
-        }\r
-        /* normal character - handle as START_FIELD */\r
-        self->state = START_FIELD;\r
-        /* fallthru */\r
-    case START_FIELD:\r
-        /* expecting field */\r
-        if (c == '\n' || c == '\r' || c == '\0') {\r
-            /* save empty field - return [fields] */\r
-            if (parse_save_field(self) < 0)\r
-                return -1;\r
-            self->state = (c == '\0' ? START_RECORD : EAT_CRNL);\r
-        }\r
-        else if (c == dialect->quotechar &&\r
-                 dialect->quoting != QUOTE_NONE) {\r
-            /* start quoted field */\r
-            self->state = IN_QUOTED_FIELD;\r
-        }\r
-        else if (c == dialect->escapechar) {\r
-            /* possible escaped character */\r
-            self->state = ESCAPED_CHAR;\r
-        }\r
-        else if (c == ' ' && dialect->skipinitialspace)\r
-            /* ignore space at start of field */\r
-            ;\r
-        else if (c == dialect->delimiter) {\r
-            /* save empty field */\r
-            if (parse_save_field(self) < 0)\r
-                return -1;\r
-        }\r
-        else {\r
-            /* begin new unquoted field */\r
-            if (dialect->quoting == QUOTE_NONNUMERIC)\r
-                self->numeric_field = 1;\r
-            if (parse_add_char(self, c) < 0)\r
-                return -1;\r
-            self->state = IN_FIELD;\r
-        }\r
-        break;\r
-\r
-    case ESCAPED_CHAR:\r
-        if (c == '\0')\r
-            c = '\n';\r
-        if (parse_add_char(self, c) < 0)\r
-            return -1;\r
-        self->state = IN_FIELD;\r
-        break;\r
-\r
-    case IN_FIELD:\r
-        /* in unquoted field */\r
-        if (c == '\n' || c == '\r' || c == '\0') {\r
-            /* end of line - return [fields] */\r
-            if (parse_save_field(self) < 0)\r
-                return -1;\r
-            self->state = (c == '\0' ? START_RECORD : EAT_CRNL);\r
-        }\r
-        else if (c == dialect->escapechar) {\r
-            /* possible escaped character */\r
-            self->state = ESCAPED_CHAR;\r
-        }\r
-        else if (c == dialect->delimiter) {\r
-            /* save field - wait for new field */\r
-            if (parse_save_field(self) < 0)\r
-                return -1;\r
-            self->state = START_FIELD;\r
-        }\r
-        else {\r
-            /* normal character - save in field */\r
-            if (parse_add_char(self, c) < 0)\r
-                return -1;\r
-        }\r
-        break;\r
-\r
-    case IN_QUOTED_FIELD:\r
-        /* in quoted field */\r
-        if (c == '\0')\r
-            ;\r
-        else if (c == dialect->escapechar) {\r
-            /* Possible escape character */\r
-            self->state = ESCAPE_IN_QUOTED_FIELD;\r
-        }\r
-        else if (c == dialect->quotechar &&\r
-                 dialect->quoting != QUOTE_NONE) {\r
-            if (dialect->doublequote) {\r
-                /* doublequote; " represented by "" */\r
-                self->state = QUOTE_IN_QUOTED_FIELD;\r
-            }\r
-            else {\r
-                /* end of quote part of field */\r
-                self->state = IN_FIELD;\r
-            }\r
-        }\r
-        else {\r
-            /* normal character - save in field */\r
-            if (parse_add_char(self, c) < 0)\r
-                return -1;\r
-        }\r
-        break;\r
-\r
-    case ESCAPE_IN_QUOTED_FIELD:\r
-        if (c == '\0')\r
-            c = '\n';\r
-        if (parse_add_char(self, c) < 0)\r
-            return -1;\r
-        self->state = IN_QUOTED_FIELD;\r
-        break;\r
-\r
-    case QUOTE_IN_QUOTED_FIELD:\r
-        /* doublequote - seen a quote in an quoted field */\r
-        if (dialect->quoting != QUOTE_NONE &&\r
-            c == dialect->quotechar) {\r
-            /* save "" as " */\r
-            if (parse_add_char(self, c) < 0)\r
-                return -1;\r
-            self->state = IN_QUOTED_FIELD;\r
-        }\r
-        else if (c == dialect->delimiter) {\r
-            /* save field - wait for new field */\r
-            if (parse_save_field(self) < 0)\r
-                return -1;\r
-            self->state = START_FIELD;\r
-        }\r
-        else if (c == '\n' || c == '\r' || c == '\0') {\r
-            /* end of line - return [fields] */\r
-            if (parse_save_field(self) < 0)\r
-                return -1;\r
-            self->state = (c == '\0' ? START_RECORD : EAT_CRNL);\r
-        }\r
-        else if (!dialect->strict) {\r
-            if (parse_add_char(self, c) < 0)\r
-                return -1;\r
-            self->state = IN_FIELD;\r
-        }\r
-        else {\r
-            /* illegal */\r
-            PyErr_Format(error_obj, "'%c' expected after '%c'",\r
-                            dialect->delimiter,\r
-                            dialect->quotechar);\r
-            return -1;\r
-        }\r
-        break;\r
-\r
-    case EAT_CRNL:\r
-        if (c == '\n' || c == '\r')\r
-            ;\r
-        else if (c == '\0')\r
-            self->state = START_RECORD;\r
-        else {\r
-            PyErr_Format(error_obj, "new-line character seen in unquoted field - do you need to open the file in universal-newline mode?");\r
-            return -1;\r
-        }\r
-        break;\r
-\r
-    }\r
-    return 0;\r
-}\r
-\r
-static int\r
-parse_reset(ReaderObj *self)\r
-{\r
-    Py_XDECREF(self->fields);\r
-    self->fields = PyList_New(0);\r
-    if (self->fields == NULL)\r
-        return -1;\r
-    self->field_len = 0;\r
-    self->state = START_RECORD;\r
-    self->numeric_field = 0;\r
-    return 0;\r
-}\r
-\r
-static PyObject *\r
-Reader_iternext(ReaderObj *self)\r
-{\r
-    PyObject *lineobj;\r
-    PyObject *fields = NULL;\r
-    char *line, c;\r
-    int linelen;\r
-\r
-    if (parse_reset(self) < 0)\r
-        return NULL;\r
-    do {\r
-        lineobj = PyIter_Next(self->input_iter);\r
-        if (lineobj == NULL) {\r
-            /* End of input OR exception */\r
-            if (!PyErr_Occurred() && self->field_len != 0)\r
-                PyErr_Format(error_obj,\r
-                             "newline inside string");\r
-            return NULL;\r
-        }\r
-        ++self->line_num;\r
-\r
-        line = PyString_AsString(lineobj);\r
-        linelen = PyString_Size(lineobj);\r
-\r
-        if (line == NULL || linelen < 0) {\r
-            Py_DECREF(lineobj);\r
-            return NULL;\r
-        }\r
-        while (linelen--) {\r
-            c = *line++;\r
-            if (c == '\0') {\r
-                Py_DECREF(lineobj);\r
-                PyErr_Format(error_obj,\r
-                             "line contains NULL byte");\r
-                goto err;\r
-            }\r
-            if (parse_process_char(self, c) < 0) {\r
-                Py_DECREF(lineobj);\r
-                goto err;\r
-            }\r
-        }\r
-        Py_DECREF(lineobj);\r
-        if (parse_process_char(self, 0) < 0)\r
-            goto err;\r
-    } while (self->state != START_RECORD);\r
-\r
-    fields = self->fields;\r
-    self->fields = NULL;\r
-err:\r
-    return fields;\r
-}\r
-\r
-static void\r
-Reader_dealloc(ReaderObj *self)\r
-{\r
-    PyObject_GC_UnTrack(self);\r
-    Py_XDECREF(self->dialect);\r
-    Py_XDECREF(self->input_iter);\r
-    Py_XDECREF(self->fields);\r
-    if (self->field != NULL)\r
-        PyMem_Free(self->field);\r
-    PyObject_GC_Del(self);\r
-}\r
-\r
-static int\r
-Reader_traverse(ReaderObj *self, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(self->dialect);\r
-    Py_VISIT(self->input_iter);\r
-    Py_VISIT(self->fields);\r
-    return 0;\r
-}\r
-\r
-static int\r
-Reader_clear(ReaderObj *self)\r
-{\r
-    Py_CLEAR(self->dialect);\r
-    Py_CLEAR(self->input_iter);\r
-    Py_CLEAR(self->fields);\r
-    return 0;\r
-}\r
-\r
-PyDoc_STRVAR(Reader_Type_doc,\r
-"CSV reader\n"\r
-"\n"\r
-"Reader objects are responsible for reading and parsing tabular data\n"\r
-"in CSV format.\n"\r
-);\r
-\r
-static struct PyMethodDef Reader_methods[] = {\r
-    { NULL, NULL }\r
-};\r
-#define R_OFF(x) offsetof(ReaderObj, x)\r
-\r
-static struct PyMemberDef Reader_memberlist[] = {\r
-    { "dialect", T_OBJECT, R_OFF(dialect), RO },\r
-    { "line_num", T_ULONG, R_OFF(line_num), RO },\r
-    { NULL }\r
-};\r
-\r
-\r
-static PyTypeObject Reader_Type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "_csv.reader",                          /*tp_name*/\r
-    sizeof(ReaderObj),                      /*tp_basicsize*/\r
-    0,                                      /*tp_itemsize*/\r
-    /* methods */\r
-    (destructor)Reader_dealloc,             /*tp_dealloc*/\r
-    (printfunc)0,                           /*tp_print*/\r
-    (getattrfunc)0,                         /*tp_getattr*/\r
-    (setattrfunc)0,                         /*tp_setattr*/\r
-    (cmpfunc)0,                             /*tp_compare*/\r
-    (reprfunc)0,                            /*tp_repr*/\r
-    0,                                      /*tp_as_number*/\r
-    0,                                      /*tp_as_sequence*/\r
-    0,                                      /*tp_as_mapping*/\r
-    (hashfunc)0,                            /*tp_hash*/\r
-    (ternaryfunc)0,                         /*tp_call*/\r
-    (reprfunc)0,                                /*tp_str*/\r
-    0,                                      /*tp_getattro*/\r
-    0,                                      /*tp_setattro*/\r
-    0,                                      /*tp_as_buffer*/\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |\r
-        Py_TPFLAGS_HAVE_GC,                     /*tp_flags*/\r
-    Reader_Type_doc,                        /*tp_doc*/\r
-    (traverseproc)Reader_traverse,          /*tp_traverse*/\r
-    (inquiry)Reader_clear,                  /*tp_clear*/\r
-    0,                                      /*tp_richcompare*/\r
-    0,                                      /*tp_weaklistoffset*/\r
-    PyObject_SelfIter,                          /*tp_iter*/\r
-    (getiterfunc)Reader_iternext,           /*tp_iternext*/\r
-    Reader_methods,                         /*tp_methods*/\r
-    Reader_memberlist,                      /*tp_members*/\r
-    0,                                      /*tp_getset*/\r
-\r
-};\r
-\r
-static PyObject *\r
-csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)\r
-{\r
-    PyObject * iterator, * dialect = NULL;\r
-    ReaderObj * self = PyObject_GC_New(ReaderObj, &Reader_Type);\r
-\r
-    if (!self)\r
-        return NULL;\r
-\r
-    self->dialect = NULL;\r
-    self->fields = NULL;\r
-    self->input_iter = NULL;\r
-    self->field = NULL;\r
-    self->field_size = 0;\r
-    self->line_num = 0;\r
-\r
-    if (parse_reset(self) < 0) {\r
-        Py_DECREF(self);\r
-        return NULL;\r
-    }\r
-\r
-    if (!PyArg_UnpackTuple(args, "", 1, 2, &iterator, &dialect)) {\r
-        Py_DECREF(self);\r
-        return NULL;\r
-    }\r
-    self->input_iter = PyObject_GetIter(iterator);\r
-    if (self->input_iter == NULL) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-                        "argument 1 must be an iterator");\r
-        Py_DECREF(self);\r
-        return NULL;\r
-    }\r
-    self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);\r
-    if (self->dialect == NULL) {\r
-        Py_DECREF(self);\r
-        return NULL;\r
-    }\r
-\r
-    PyObject_GC_Track(self);\r
-    return (PyObject *)self;\r
-}\r
-\r
-/*\r
- * WRITER\r
- */\r
-/* ---------------------------------------------------------------- */\r
-static void\r
-join_reset(WriterObj *self)\r
-{\r
-    self->rec_len = 0;\r
-    self->num_fields = 0;\r
-}\r
-\r
-#define MEM_INCR 32768\r
-\r
-/* Calculate new record length or append field to record.  Return new\r
- * record length.\r
- */\r
-static int\r
-join_append_data(WriterObj *self, char *field, int quote_empty,\r
-                 int *quoted, int copy_phase)\r
-{\r
-    DialectObj *dialect = self->dialect;\r
-    int i, rec_len;\r
-    char *lineterm;\r
-\r
-#define ADDCH(c) \\r
-    do {\\r
-        if (copy_phase) \\r
-            self->rec[rec_len] = c;\\r
-        rec_len++;\\r
-    } while(0)\r
-\r
-    lineterm = PyString_AsString(dialect->lineterminator);\r
-    if (lineterm == NULL)\r
-        return -1;\r
-\r
-    rec_len = self->rec_len;\r
-\r
-    /* If this is not the first field we need a field separator */\r
-    if (self->num_fields > 0)\r
-        ADDCH(dialect->delimiter);\r
-\r
-    /* Handle preceding quote */\r
-    if (copy_phase && *quoted)\r
-        ADDCH(dialect->quotechar);\r
-\r
-    /* Copy/count field data */\r
-    for (i = 0;; i++) {\r
-        char c = field[i];\r
-        int want_escape = 0;\r
-\r
-        if (c == '\0')\r
-            break;\r
-\r
-        if (c == dialect->delimiter ||\r
-            c == dialect->escapechar ||\r
-            c == dialect->quotechar ||\r
-            strchr(lineterm, c)) {\r
-            if (dialect->quoting == QUOTE_NONE)\r
-                want_escape = 1;\r
-            else {\r
-                if (c == dialect->quotechar) {\r
-                    if (dialect->doublequote)\r
-                        ADDCH(dialect->quotechar);\r
-                    else\r
-                        want_escape = 1;\r
-                }\r
-                if (!want_escape)\r
-                    *quoted = 1;\r
-            }\r
-            if (want_escape) {\r
-                if (!dialect->escapechar) {\r
-                    PyErr_Format(error_obj,\r
-                                 "need to escape, but no escapechar set");\r
-                    return -1;\r
-                }\r
-                ADDCH(dialect->escapechar);\r
-            }\r
-        }\r
-        /* Copy field character into record buffer.\r
-         */\r
-        ADDCH(c);\r
-    }\r
-\r
-    /* If field is empty check if it needs to be quoted.\r
-     */\r
-    if (i == 0 && quote_empty) {\r
-        if (dialect->quoting == QUOTE_NONE) {\r
-            PyErr_Format(error_obj,\r
-                         "single empty field record must be quoted");\r
-            return -1;\r
-        }\r
-        else\r
-            *quoted = 1;\r
-    }\r
-\r
-    if (*quoted) {\r
-        if (copy_phase)\r
-            ADDCH(dialect->quotechar);\r
-        else\r
-            rec_len += 2;\r
-    }\r
-    return rec_len;\r
-#undef ADDCH\r
-}\r
-\r
-static int\r
-join_check_rec_size(WriterObj *self, int rec_len)\r
-{\r
-\r
-    if (rec_len < 0 || rec_len > INT_MAX - MEM_INCR) {\r
-        PyErr_NoMemory();\r
-        return 0;\r
-    }\r
-\r
-    if (rec_len > self->rec_size) {\r
-        if (self->rec_size == 0) {\r
-            self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;\r
-            if (self->rec != NULL)\r
-                PyMem_Free(self->rec);\r
-            self->rec = PyMem_Malloc(self->rec_size);\r
-        }\r
-        else {\r
-            char *old_rec = self->rec;\r
-\r
-            self->rec_size = (rec_len / MEM_INCR + 1) * MEM_INCR;\r
-            self->rec = PyMem_Realloc(self->rec, self->rec_size);\r
-            if (self->rec == NULL)\r
-                PyMem_Free(old_rec);\r
-        }\r
-        if (self->rec == NULL) {\r
-            PyErr_NoMemory();\r
-            return 0;\r
-        }\r
-    }\r
-    return 1;\r
-}\r
-\r
-static int\r
-join_append(WriterObj *self, char *field, int *quoted, int quote_empty)\r
-{\r
-    int rec_len;\r
-\r
-    rec_len = join_append_data(self, field, quote_empty, quoted, 0);\r
-    if (rec_len < 0)\r
-        return 0;\r
-\r
-    /* grow record buffer if necessary */\r
-    if (!join_check_rec_size(self, rec_len))\r
-        return 0;\r
-\r
-    self->rec_len = join_append_data(self, field, quote_empty, quoted, 1);\r
-    self->num_fields++;\r
-\r
-    return 1;\r
-}\r
-\r
-static int\r
-join_append_lineterminator(WriterObj *self)\r
-{\r
-    int terminator_len;\r
-    char *terminator;\r
-\r
-    terminator_len = PyString_Size(self->dialect->lineterminator);\r
-    if (terminator_len == -1)\r
-        return 0;\r
-\r
-    /* grow record buffer if necessary */\r
-    if (!join_check_rec_size(self, self->rec_len + terminator_len))\r
-        return 0;\r
-\r
-    terminator = PyString_AsString(self->dialect->lineterminator);\r
-    if (terminator == NULL)\r
-        return 0;\r
-    memmove(self->rec + self->rec_len, terminator, terminator_len);\r
-    self->rec_len += terminator_len;\r
-\r
-    return 1;\r
-}\r
-\r
-PyDoc_STRVAR(csv_writerow_doc,\r
-"writerow(sequence)\n"\r
-"\n"\r
-"Construct and write a CSV record from a sequence of fields.  Non-string\n"\r
-"elements will be converted to string.");\r
-\r
-static PyObject *\r
-csv_writerow(WriterObj *self, PyObject *seq)\r
-{\r
-    DialectObj *dialect = self->dialect;\r
-    int len, i;\r
-\r
-    if (!PySequence_Check(seq))\r
-        return PyErr_Format(error_obj, "sequence expected");\r
-\r
-    len = PySequence_Length(seq);\r
-    if (len < 0)\r
-        return NULL;\r
-\r
-    /* Join all fields in internal buffer.\r
-     */\r
-    join_reset(self);\r
-    for (i = 0; i < len; i++) {\r
-        PyObject *field;\r
-        int append_ok;\r
-        int quoted;\r
-\r
-        field = PySequence_GetItem(seq, i);\r
-        if (field == NULL)\r
-            return NULL;\r
-\r
-        switch (dialect->quoting) {\r
-        case QUOTE_NONNUMERIC:\r
-            quoted = !PyNumber_Check(field);\r
-            break;\r
-        case QUOTE_ALL:\r
-            quoted = 1;\r
-            break;\r
-        default:\r
-            quoted = 0;\r
-            break;\r
-        }\r
-\r
-        if (PyString_Check(field)) {\r
-            append_ok = join_append(self,\r
-                                    PyString_AS_STRING(field),\r
-                                    &quoted, len == 1);\r
-            Py_DECREF(field);\r
-        }\r
-        else if (field == Py_None) {\r
-            append_ok = join_append(self, "", &quoted, len == 1);\r
-            Py_DECREF(field);\r
-        }\r
-        else {\r
-            PyObject *str;\r
-\r
-            str = PyObject_Str(field);\r
-            Py_DECREF(field);\r
-            if (str == NULL)\r
-                return NULL;\r
-\r
-            append_ok = join_append(self, PyString_AS_STRING(str),\r
-                                    &quoted, len == 1);\r
-            Py_DECREF(str);\r
-        }\r
-        if (!append_ok)\r
-            return NULL;\r
-    }\r
-\r
-    /* Add line terminator.\r
-     */\r
-    if (!join_append_lineterminator(self))\r
-        return 0;\r
-\r
-    return PyObject_CallFunction(self->writeline,\r
-                                 "(s#)", self->rec, self->rec_len);\r
-}\r
-\r
-PyDoc_STRVAR(csv_writerows_doc,\r
-"writerows(sequence of sequences)\n"\r
-"\n"\r
-"Construct and write a series of sequences to a csv file.  Non-string\n"\r
-"elements will be converted to string.");\r
-\r
-static PyObject *\r
-csv_writerows(WriterObj *self, PyObject *seqseq)\r
-{\r
-    PyObject *row_iter, *row_obj, *result;\r
-\r
-    row_iter = PyObject_GetIter(seqseq);\r
-    if (row_iter == NULL) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-                        "writerows() argument must be iterable");\r
-        return NULL;\r
-    }\r
-    while ((row_obj = PyIter_Next(row_iter))) {\r
-        result = csv_writerow(self, row_obj);\r
-        Py_DECREF(row_obj);\r
-        if (!result) {\r
-            Py_DECREF(row_iter);\r
-            return NULL;\r
-        }\r
-        else\r
-             Py_DECREF(result);\r
-    }\r
-    Py_DECREF(row_iter);\r
-    if (PyErr_Occurred())\r
-        return NULL;\r
-    Py_INCREF(Py_None);\r
-    return Py_None;\r
-}\r
-\r
-static struct PyMethodDef Writer_methods[] = {\r
-    { "writerow", (PyCFunction)csv_writerow, METH_O, csv_writerow_doc},\r
-    { "writerows", (PyCFunction)csv_writerows, METH_O, csv_writerows_doc},\r
-    { NULL, NULL }\r
-};\r
-\r
-#define W_OFF(x) offsetof(WriterObj, x)\r
-\r
-static struct PyMemberDef Writer_memberlist[] = {\r
-    { "dialect", T_OBJECT, W_OFF(dialect), RO },\r
-    { NULL }\r
-};\r
-\r
-static void\r
-Writer_dealloc(WriterObj *self)\r
-{\r
-    PyObject_GC_UnTrack(self);\r
-    Py_XDECREF(self->dialect);\r
-    Py_XDECREF(self->writeline);\r
-    if (self->rec != NULL)\r
-        PyMem_Free(self->rec);\r
-    PyObject_GC_Del(self);\r
-}\r
-\r
-static int\r
-Writer_traverse(WriterObj *self, visitproc visit, void *arg)\r
-{\r
-    Py_VISIT(self->dialect);\r
-    Py_VISIT(self->writeline);\r
-    return 0;\r
-}\r
-\r
-static int\r
-Writer_clear(WriterObj *self)\r
-{\r
-    Py_CLEAR(self->dialect);\r
-    Py_CLEAR(self->writeline);\r
-    return 0;\r
-}\r
-\r
-PyDoc_STRVAR(Writer_Type_doc,\r
-"CSV writer\n"\r
-"\n"\r
-"Writer objects are responsible for generating tabular data\n"\r
-"in CSV format from sequence input.\n"\r
-);\r
-\r
-static PyTypeObject Writer_Type = {\r
-    PyVarObject_HEAD_INIT(NULL, 0)\r
-    "_csv.writer",                          /*tp_name*/\r
-    sizeof(WriterObj),                      /*tp_basicsize*/\r
-    0,                                      /*tp_itemsize*/\r
-    /* methods */\r
-    (destructor)Writer_dealloc,             /*tp_dealloc*/\r
-    (printfunc)0,                           /*tp_print*/\r
-    (getattrfunc)0,                         /*tp_getattr*/\r
-    (setattrfunc)0,                         /*tp_setattr*/\r
-    (cmpfunc)0,                             /*tp_compare*/\r
-    (reprfunc)0,                            /*tp_repr*/\r
-    0,                                      /*tp_as_number*/\r
-    0,                                      /*tp_as_sequence*/\r
-    0,                                      /*tp_as_mapping*/\r
-    (hashfunc)0,                            /*tp_hash*/\r
-    (ternaryfunc)0,                         /*tp_call*/\r
-    (reprfunc)0,                            /*tp_str*/\r
-    0,                                      /*tp_getattro*/\r
-    0,                                      /*tp_setattro*/\r
-    0,                                      /*tp_as_buffer*/\r
-    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE |\r
-        Py_TPFLAGS_HAVE_GC,                     /*tp_flags*/\r
-    Writer_Type_doc,\r
-    (traverseproc)Writer_traverse,          /*tp_traverse*/\r
-    (inquiry)Writer_clear,                  /*tp_clear*/\r
-    0,                                      /*tp_richcompare*/\r
-    0,                                      /*tp_weaklistoffset*/\r
-    (getiterfunc)0,                         /*tp_iter*/\r
-    (getiterfunc)0,                         /*tp_iternext*/\r
-    Writer_methods,                         /*tp_methods*/\r
-    Writer_memberlist,                      /*tp_members*/\r
-    0,                                      /*tp_getset*/\r
-};\r
-\r
-static PyObject *\r
-csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)\r
-{\r
-    PyObject * output_file, * dialect = NULL;\r
-    WriterObj * self = PyObject_GC_New(WriterObj, &Writer_Type);\r
-\r
-    if (!self)\r
-        return NULL;\r
-\r
-    self->dialect = NULL;\r
-    self->writeline = NULL;\r
-\r
-    self->rec = NULL;\r
-    self->rec_size = 0;\r
-    self->rec_len = 0;\r
-    self->num_fields = 0;\r
-\r
-    if (!PyArg_UnpackTuple(args, "", 1, 2, &output_file, &dialect)) {\r
-        Py_DECREF(self);\r
-        return NULL;\r
-    }\r
-    self->writeline = PyObject_GetAttrString(output_file, "write");\r
-    if (self->writeline == NULL || !PyCallable_Check(self->writeline)) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-                        "argument 1 must have a \"write\" method");\r
-        Py_DECREF(self);\r
-        return NULL;\r
-    }\r
-    self->dialect = (DialectObj *)_call_dialect(dialect, keyword_args);\r
-    if (self->dialect == NULL) {\r
-        Py_DECREF(self);\r
-        return NULL;\r
-    }\r
-    PyObject_GC_Track(self);\r
-    return (PyObject *)self;\r
-}\r
-\r
-/*\r
- * DIALECT REGISTRY\r
- */\r
-static PyObject *\r
-csv_list_dialects(PyObject *module, PyObject *args)\r
-{\r
-    return PyDict_Keys(dialects);\r
-}\r
-\r
-static PyObject *\r
-csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs)\r
-{\r
-    PyObject *name_obj, *dialect_obj = NULL;\r
-    PyObject *dialect;\r
-\r
-    if (!PyArg_UnpackTuple(args, "", 1, 2, &name_obj, &dialect_obj))\r
-        return NULL;\r
-    if (!IS_BASESTRING(name_obj)) {\r
-        PyErr_SetString(PyExc_TypeError,\r
-                        "dialect name must be a string or unicode");\r
-        return NULL;\r
-    }\r
-    dialect = _call_dialect(dialect_obj, kwargs);\r
-    if (dialect == NULL)\r
-        return NULL;\r
-    if (PyDict_SetItem(dialects, name_obj, dialect) < 0) {\r
-        Py_DECREF(dialect);\r
-        return NULL;\r
-    }\r
-    Py_DECREF(dialect);\r
-    Py_INCREF(Py_None);\r
-    return Py_None;\r
-}\r
-\r
-static PyObject *\r
-csv_unregister_dialect(PyObject *module, PyObject *name_obj)\r
-{\r
-    if (PyDict_DelItem(dialects, name_obj) < 0)\r
-        return PyErr_Format(error_obj, "unknown dialect");\r
-    Py_INCREF(Py_None);\r
-    return Py_None;\r
-}\r
-\r
-static PyObject *\r
-csv_get_dialect(PyObject *module, PyObject *name_obj)\r
-{\r
-    return get_dialect_from_registry(name_obj);\r
-}\r
-\r
-static PyObject *\r
-csv_field_size_limit(PyObject *module, PyObject *args)\r
-{\r
-    PyObject *new_limit = NULL;\r
-    long old_limit = field_limit;\r
-\r
-    if (!PyArg_UnpackTuple(args, "field_size_limit", 0, 1, &new_limit))\r
-        return NULL;\r
-    if (new_limit != NULL) {\r
-        if (!PyInt_Check(new_limit)) {\r
-            PyErr_Format(PyExc_TypeError,\r
-                         "limit must be an integer");\r
-            return NULL;\r
-        }\r
-        field_limit = PyInt_AsLong(new_limit);\r
-    }\r
-    return PyInt_FromLong(old_limit);\r
-}\r
-\r
-/*\r
- * MODULE\r
- */\r
-\r
-PyDoc_STRVAR(csv_module_doc,\r
-"CSV parsing and writing.\n"\r
-"\n"\r
-"This module provides classes that assist in the reading and writing\n"\r
-"of Comma Separated Value (CSV) files, and implements the interface\n"\r
-"described by PEP 305.  Although many CSV files are simple to parse,\n"\r
-"the format is not formally defined by a stable specification and\n"\r
-"is subtle enough that parsing lines of a CSV file with something\n"\r
-"like line.split(\",\") is bound to fail.  The module supports three\n"\r
-"basic APIs: reading, writing, and registration of dialects.\n"\r
-"\n"\r
-"\n"\r
-"DIALECT REGISTRATION:\n"\r
-"\n"\r
-"Readers and writers support a dialect argument, which is a convenient\n"\r
-"handle on a group of settings.  When the dialect argument is a string,\n"\r
-"it identifies one of the dialects previously registered with the module.\n"\r
-"If it is a class or instance, the attributes of the argument are used as\n"\r
-"the settings for the reader or writer:\n"\r
-"\n"\r
-"    class excel:\n"\r
-"        delimiter = ','\n"\r
-"        quotechar = '\"'\n"\r
-"        escapechar = None\n"\r
-"        doublequote = True\n"\r
-"        skipinitialspace = False\n"\r
-"        lineterminator = '\\r\\n'\n"\r
-"        quoting = QUOTE_MINIMAL\n"\r
-"\n"\r
-"SETTINGS:\n"\r
-"\n"\r
-"    * quotechar - specifies a one-character string to use as the \n"\r
-"        quoting character.  It defaults to '\"'.\n"\r
-"    * delimiter - specifies a one-character string to use as the \n"\r
-"        field separator.  It defaults to ','.\n"\r
-"    * skipinitialspace - specifies how to interpret whitespace which\n"\r
-"        immediately follows a delimiter.  It defaults to False, which\n"\r
-"        means that whitespace immediately following a delimiter is part\n"\r
-"        of the following field.\n"\r
-"    * lineterminator -  specifies the character sequence which should \n"\r
-"        terminate rows.\n"\r
-"    * quoting - controls when quotes should be generated by the writer.\n"\r
-"        It can take on any of the following module constants:\n"\r
-"\n"\r
-"        csv.QUOTE_MINIMAL means only when required, for example, when a\n"\r
-"            field contains either the quotechar or the delimiter\n"\r
-"        csv.QUOTE_ALL means that quotes are always placed around fields.\n"\r
-"        csv.QUOTE_NONNUMERIC means that quotes are always placed around\n"\r
-"            fields which do not parse as integers or floating point\n"\r
-"            numbers.\n"\r
-"        csv.QUOTE_NONE means that quotes are never placed around fields.\n"\r
-"    * escapechar - specifies a one-character string used to escape \n"\r
-"        the delimiter when quoting is set to QUOTE_NONE.\n"\r
-"    * doublequote - controls the handling of quotes inside fields.  When\n"\r
-"        True, two consecutive quotes are interpreted as one during read,\n"\r
-"        and when writing, each quote character embedded in the data is\n"\r
-"        written as two quotes\n");\r
-\r
-PyDoc_STRVAR(csv_reader_doc,\r
-"    csv_reader = reader(iterable [, dialect='excel']\n"\r
-"                        [optional keyword args])\n"\r
-"    for row in csv_reader:\n"\r
-"        process(row)\n"\r
-"\n"\r
-"The \"iterable\" argument can be any object that returns a line\n"\r
-"of input for each iteration, such as a file object or a list.  The\n"\r
-"optional \"dialect\" parameter is discussed below.  The function\n"\r
-"also accepts optional keyword arguments which override settings\n"\r
-"provided by the dialect.\n"\r
-"\n"\r
-"The returned object is an iterator.  Each iteration returns a row\n"\r
-"of the CSV file (which can span multiple input lines):\n");\r
-\r
-PyDoc_STRVAR(csv_writer_doc,\r
-"    csv_writer = csv.writer(fileobj [, dialect='excel']\n"\r
-"                            [optional keyword args])\n"\r
-"    for row in sequence:\n"\r
-"        csv_writer.writerow(row)\n"\r
-"\n"\r
-"    [or]\n"\r
-"\n"\r
-"    csv_writer = csv.writer(fileobj [, dialect='excel']\n"\r
-"                            [optional keyword args])\n"\r
-"    csv_writer.writerows(rows)\n"\r
-"\n"\r
-"The \"fileobj\" argument can be any object that supports the file API.\n");\r
-\r
-PyDoc_STRVAR(csv_list_dialects_doc,\r
-"Return a list of all know dialect names.\n"\r
-"    names = csv.list_dialects()");\r
-\r
-PyDoc_STRVAR(csv_get_dialect_doc,\r
-"Return the dialect instance associated with name.\n"\r
-"    dialect = csv.get_dialect(name)");\r
-\r
-PyDoc_STRVAR(csv_register_dialect_doc,\r
-"Create a mapping from a string name to a dialect class.\n"\r
-"    dialect = csv.register_dialect(name, dialect)");\r
-\r
-PyDoc_STRVAR(csv_unregister_dialect_doc,\r
-"Delete the name/dialect mapping associated with a string name.\n"\r
-"    csv.unregister_dialect(name)");\r
-\r
-PyDoc_STRVAR(csv_field_size_limit_doc,\r
-"Sets an upper limit on parsed fields.\n"\r
-"    csv.field_size_limit([limit])\n"\r
-"\n"\r
-"Returns old limit. If limit is not given, no new limit is set and\n"\r
-"the old limit is returned");\r
-\r
-static struct PyMethodDef csv_methods[] = {\r
-    { "reader", (PyCFunction)csv_reader,\r
-        METH_VARARGS | METH_KEYWORDS, csv_reader_doc},\r
-    { "writer", (PyCFunction)csv_writer,\r
-        METH_VARARGS | METH_KEYWORDS, csv_writer_doc},\r
-    { "list_dialects", (PyCFunction)csv_list_dialects,\r
-        METH_NOARGS, csv_list_dialects_doc},\r
-    { "register_dialect", (PyCFunction)csv_register_dialect,\r
-        METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},\r
-    { "unregister_dialect", (PyCFunction)csv_unregister_dialect,\r
-        METH_O, csv_unregister_dialect_doc},\r
-    { "get_dialect", (PyCFunction)csv_get_dialect,\r
-        METH_O, csv_get_dialect_doc},\r
-    { "field_size_limit", (PyCFunction)csv_field_size_limit,\r
-        METH_VARARGS, csv_field_size_limit_doc},\r
-    { NULL, NULL }\r
-};\r
-\r
-PyMODINIT_FUNC\r
-init_csv(void)\r
-{\r
-    PyObject *module;\r
-    StyleDesc *style;\r
-\r
-    if (PyType_Ready(&Dialect_Type) < 0)\r
-        return;\r
-\r
-    if (PyType_Ready(&Reader_Type) < 0)\r
-        return;\r
-\r
-    if (PyType_Ready(&Writer_Type) < 0)\r
-        return;\r
-\r
-    /* Create the module and add the functions */\r
-    module = Py_InitModule3("_csv", csv_methods, csv_module_doc);\r
-    if (module == NULL)\r
-        return;\r
-\r
-    /* Add version to the module. */\r
-    if (PyModule_AddStringConstant(module, "__version__",\r
-                                   MODULE_VERSION) == -1)\r
-        return;\r
-\r
-    /* Add _dialects dictionary */\r
-    dialects = PyDict_New();\r
-    if (dialects == NULL)\r
-        return;\r
-    if (PyModule_AddObject(module, "_dialects", dialects))\r
-        return;\r
-\r
-    /* Add quote styles into dictionary */\r
-    for (style = quote_styles; style->name; style++) {\r
-        if (PyModule_AddIntConstant(module, style->name,\r
-                                    style->style) == -1)\r
-            return;\r
-    }\r
-\r
-    /* Add the Dialect type */\r
-    Py_INCREF(&Dialect_Type);\r
-    if (PyModule_AddObject(module, "Dialect", (PyObject *)&Dialect_Type))\r
-        return;\r
-\r
-    /* Add the CSV exception object to the module. */\r
-    error_obj = PyErr_NewException("_csv.Error", NULL, NULL);\r
-    if (error_obj == NULL)\r
-        return;\r
-    PyModule_AddObject(module, "Error", error_obj);\r
-}\r