/* csv module */

/*

This module provides the low-level underpinnings of a CSV reading/writing
module.  Users should not use this module directly, but import the csv.py
module instead.

*/

// clinic/_csv.c.h uses internal pycore_modsupport.h API
#ifndef Py_BUILD_CORE_BUILTIN
#  define Py_BUILD_CORE_MODULE 1
#endif

#include "Python.h"
#include "pycore_pyatomic_ft_wrappers.h"

#include <stddef.h>               // offsetof()
#include <stdbool.h>

/*[clinic input]
module _csv
[clinic start generated code]*/
/*[clinic end generated code: output=da39a3ee5e6b4b0d input=385118b71aa43706]*/

#include "clinic/_csv.c.h"
#define NOT_SET ((Py_UCS4)-1)
#define EOL ((Py_UCS4)-2)


typedef struct {
    PyObject *error_obj;   /* CSV exception */
    PyObject *dialects;   /* Dialect registry */
    PyTypeObject *dialect_type;
    PyTypeObject *reader_type;
    PyTypeObject *writer_type;
    Py_ssize_t field_limit;   /* max parsed field size */
    PyObject *str_write;
} _csvstate;

static struct PyModuleDef _csvmodule;

static inline _csvstate*
get_csv_state(PyObject *module)
{
    void *state = PyModule_GetState(module);
    assert(state != NULL);
    return (_csvstate *)state;
}

static int
_csv_clear(PyObject *module)
{
    _csvstate *module_state = PyModule_GetState(module);
    Py_CLEAR(module_state->error_obj);
    Py_CLEAR(module_state->dialects);
    Py_CLEAR(module_state->dialect_type);
    Py_CLEAR(module_state->reader_type);
    Py_CLEAR(module_state->writer_type);
    Py_CLEAR(module_state->str_write);
    return 0;
}

static int
_csv_traverse(PyObject *module, visitproc visit, void *arg)
{
    _csvstate *module_state = PyModule_GetState(module);
    Py_VISIT(module_state->error_obj);
    Py_VISIT(module_state->dialects);
    Py_VISIT(module_state->dialect_type);
    Py_VISIT(module_state->reader_type);
    Py_VISIT(module_state->writer_type);
    return 0;
}

static void
_csv_free(void *module)
{
    (void)_csv_clear((PyObject *)module);
}

typedef enum {
    START_RECORD, START_FIELD, ESCAPED_CHAR, IN_FIELD,
    IN_QUOTED_FIELD, ESCAPE_IN_QUOTED_FIELD, QUOTE_IN_QUOTED_FIELD,
    EAT_CRNL,AFTER_ESCAPED_CRNL
} ParserState;

typedef enum {
    QUOTE_MINIMAL, QUOTE_ALL, QUOTE_NONNUMERIC, QUOTE_NONE,
    QUOTE_STRINGS, QUOTE_NOTNULL
} QuoteStyle;

typedef struct {
    QuoteStyle style;
    const char *name;
} StyleDesc;

static const StyleDesc quote_styles[] = {
    { QUOTE_MINIMAL,    "QUOTE_MINIMAL" },
    { QUOTE_ALL,        "QUOTE_ALL" },
    { QUOTE_NONNUMERIC, "QUOTE_NONNUMERIC" },
    { QUOTE_NONE,       "QUOTE_NONE" },
    { QUOTE_STRINGS,    "QUOTE_STRINGS" },
    { QUOTE_NOTNULL,    "QUOTE_NOTNULL" },
    { 0 }
};

typedef struct {
    PyObject_HEAD

    char doublequote;           /* is " represented by ""? */
    char skipinitialspace;      /* ignore spaces following delimiter? */
    char strict;                /* raise exception on bad CSV */
    int quoting;                /* style of quoting to write */
    Py_UCS4 delimiter;          /* field separator */
    Py_UCS4 quotechar;          /* quote character */
    Py_UCS4 escapechar;         /* escape character */
    PyObject *lineterminator;   /* string to write between records */

} DialectObj;

typedef struct {
    PyObject_HEAD

    PyObject *input_iter;   /* iterate over this for input lines */

    DialectObj *dialect;    /* parsing dialect */

    PyObject *fields;           /* field list for current record */
    ParserState state;          /* current CSV parse state */
    Py_UCS4 *field;             /* temporary buffer */
    Py_ssize_t field_size;      /* size of allocated buffer */
    Py_ssize_t field_len;       /* length of current field */
    bool unquoted_field;        /* true if no quotes around the current field */
    unsigned long line_num;     /* Source-file line number */
} ReaderObj;

typedef struct {
    PyObject_HEAD

    PyObject *write;    /* write output lines to this file */

    DialectObj *dialect;    /* parsing dialect */

    Py_UCS4 *rec;            /* buffer for parser.join */
    Py_ssize_t rec_size;        /* size of allocated record */
    Py_ssize_t rec_len;         /* length of record */
    int num_fields;             /* number of fields in record */

    PyObject *error_obj;       /* cached error object */
} WriterObj;

#define _DialectObj_CAST(op)    ((DialectObj *)(op))
#define _ReaderObj_CAST(op)     ((ReaderObj *)(op))
#define _WriterObj_CAST(op)     ((WriterObj *)(op))

/*
 * DIALECT class
 */

static PyObject *
get_dialect_from_registry(PyObject *name_obj, _csvstate *module_state)
{
    PyObject *dialect_obj;
    if (PyDict_GetItemRef(module_state->dialects, name_obj, &dialect_obj) == 0) {
        PyErr_SetString(module_state->error_obj, "unknown dialect");
    }
    return dialect_obj;
}

static PyObject *
get_char_or_None(Py_UCS4 c)
{
    if (c == NOT_SET) {
        Py_RETURN_NONE;
    }
    else
        return PyUnicode_FromOrdinal(c);
}

static PyObject *
Dialect_get_lineterminator(PyObject *op, void *Py_UNUSED(ignored))
{
    DialectObj *self = _DialectObj_CAST(op);
    return Py_XNewRef(self->lineterminator);
}

static PyObject *
Dialect_get_delimiter(PyObject *op, void *Py_UNUSED(ignored))
{
    DialectObj *self = _DialectObj_CAST(op);
    return get_char_or_None(self->delimiter);
}

static PyObject *
Dialect_get_escapechar(PyObject *op, void *Py_UNUSED(ignored))
{
    DialectObj *self = _DialectObj_CAST(op);
    return get_char_or_None(self->escapechar);
}

static PyObject *
Dialect_get_quotechar(PyObject *op, void *Py_UNUSED(ignored))
{
    DialectObj *self = _DialectObj_CAST(op);
    return get_char_or_None(self->quotechar);
}

static PyObject *
Dialect_get_quoting(PyObject *op, void *Py_UNUSED(ignored))
{
    DialectObj *self = _DialectObj_CAST(op);
    return PyLong_FromLong(self->quoting);
}

static int
_set_bool(const char *name, char *target, PyObject *src, bool dflt)
{
    if (src == NULL)
        *target = dflt;
    else {
        int b = PyObject_IsTrue(src);
        if (b < 0)
            return -1;
        *target = (char)b;
    }
    return 0;
}

static int
_set_int(const char *name, int *target, PyObject *src, int dflt)
{
    if (src == NULL)
        *target = dflt;
    else {
        int value;
        if (!PyLong_CheckExact(src)) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be an integer, not %T", name, src);
            return -1;
        }
        value = PyLong_AsInt(src);
        if (value == -1 && PyErr_Occurred()) {
            return -1;
        }
        *target = value;
    }
    return 0;
}

static int
_set_char_or_none(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt)
{
    if (src == NULL) {
        *target = dflt;
    }
    else if (src == Py_None) {
        *target = NOT_SET;
    }
    else {
        // similar to PyArg_Parse("C?")
        if (!PyUnicode_Check(src)) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a unicode character or None, not %T",
                         name, src);
            return -1;
        }
        Py_ssize_t len = PyUnicode_GetLength(src);
        if (len < 0) {
            return -1;
        }
        if (len != 1) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a unicode character or None, "
                         "not a string of length %zd",
                         name, len);
            return -1;
        }
        *target = PyUnicode_READ_CHAR(src, 0);
    }
    return 0;
}

static int
_set_char(const char *name, Py_UCS4 *target, PyObject *src, Py_UCS4 dflt)
{
    if (src == NULL) {
        *target = dflt;
    }
    else {
        // similar to PyArg_Parse("C")
        if (!PyUnicode_Check(src)) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a unicode character, not %T",
                         name, src);
            return -1;
        }
        Py_ssize_t len = PyUnicode_GetLength(src);
        if (len < 0) {
            return -1;
        }
        if (len != 1) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a unicode character, "
                         "not a string of length %zd",
                         name, len);
            return -1;
        }
        *target = PyUnicode_READ_CHAR(src, 0);
    }
    return 0;
}

static int
_set_str(const char *name, PyObject **target, PyObject *src, const char *dflt)
{
    if (src == NULL) {
        *target = PyUnicode_DecodeASCII(dflt, strlen(dflt), NULL);
        if (*target == NULL) {
            return -1;
        }
    }
    else {
        if (!PyUnicode_Check(src)) {
            PyErr_Format(PyExc_TypeError,
                         "\"%s\" must be a string, not %T", name, src);
            return -1;
        }
        Py_XSETREF(*target, Py_NewRef(src));
    }
    return 0;
}

static int
dialect_check_quoting(int quoting)
{
    const StyleDesc *qs;

    for (qs = quote_styles; qs->name; qs++) {
        if ((int)qs->style == quoting)
            return 0;
    }
    PyErr_Format(PyExc_TypeError, "bad \"quoting\" value");
    return -1;
}

static int
dialect_check_char(const char *name, Py_UCS4 c, DialectObj *dialect, bool allowspace)
{
    if (c == '\r' || c == '\n' || (c == ' ' && !allowspace)) {
        PyErr_Format(PyExc_ValueError, "bad %s value", name);
        return -1;
    }
    if (PyUnicode_FindChar(
        dialect->lineterminator, c, 0,
        PyUnicode_GET_LENGTH(dialect->lineterminator), 1) >= 0)
    {
        PyErr_Format(PyExc_ValueError, "bad %s or lineterminator value", name);
        return -1;
    }
    return 0;
}

 static int
dialect_check_chars(const char *name1, const char *name2, Py_UCS4 c1, Py_UCS4 c2)
{
    if (c1 == c2 && c1 != NOT_SET) {
        PyErr_Format(PyExc_ValueError, "bad %s or %s value", name1, name2);
        return -1;
    }
    return 0;
}

#define D_OFF(x) offsetof(DialectObj, x)

static struct PyMemberDef Dialect_memberlist[] = {
    { "skipinitialspace",   Py_T_BOOL, D_OFF(skipinitialspace), Py_READONLY },
    { "doublequote",        Py_T_BOOL, D_OFF(doublequote), Py_READONLY },
    { "strict",             Py_T_BOOL, D_OFF(strict), Py_READONLY },
    { NULL }
};

#undef D_OFF

static PyGetSetDef Dialect_getsetlist[] = {
    {"delimiter",          Dialect_get_delimiter},
    {"escapechar",         Dialect_get_escapechar},
    {"lineterminator",     Dialect_get_lineterminator},
    {"quotechar",          Dialect_get_quotechar},
    {"quoting",            Dialect_get_quoting},
    {NULL},
};

static void
Dialect_dealloc(PyObject *self)
{
    PyTypeObject *tp = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    tp->tp_clear((PyObject *)self);
    PyObject_GC_Del(self);
    Py_DECREF(tp);
}

static char *dialect_kws[] = {
    "dialect",
    "delimiter",
    "doublequote",
    "escapechar",
    "lineterminator",
    "quotechar",
    "quoting",
    "skipinitialspace",
    "strict",
    NULL
};

static _csvstate *
_csv_state_from_type(PyTypeObject *type, const char *name)
{
    PyObject *module = PyType_GetModuleByDef(type, &_csvmodule);
    if (module == NULL) {
        return NULL;
    }
    _csvstate *module_state = PyModule_GetState(module);
    if (module_state == NULL) {
        PyErr_Format(PyExc_SystemError,
                     "%s: No _csv module state found", name);
        return NULL;
    }
    return module_state;
}

static PyObject *
dialect_new(PyTypeObject *type, PyObject *args, PyObject *kwargs)
{
    DialectObj *self;
    PyObject *ret = NULL;
    PyObject *dialect = NULL;
    PyObject *delimiter = NULL;
    PyObject *doublequote = NULL;
    PyObject *escapechar = NULL;
    PyObject *lineterminator = NULL;
    PyObject *quotechar = NULL;
    PyObject *quoting = NULL;
    PyObject *skipinitialspace = NULL;
    PyObject *strict = NULL;

    if (!PyArg_ParseTupleAndKeywords(args, kwargs,
                                     "|OOOOOOOOO", dialect_kws,
                                     &dialect,
                                     &delimiter,
                                     &doublequote,
                                     &escapechar,
                                     &lineterminator,
                                     &quotechar,
                                     &quoting,
                                     &skipinitialspace,
                                     &strict))
        return NULL;

    _csvstate *module_state = _csv_state_from_type(type, "dialect_new");
    if (module_state == NULL) {
        return NULL;
    }

    if (dialect != NULL) {
        if (PyUnicode_Check(dialect)) {
            dialect = get_dialect_from_registry(dialect, module_state);
            if (dialect == NULL)
                return NULL;
        }
        else
            Py_INCREF(dialect);
        /* Can we reuse this instance? */
        if (PyObject_TypeCheck(dialect, module_state->dialect_type) &&
            delimiter == NULL &&
            doublequote == NULL &&
            escapechar == NULL &&
            lineterminator == NULL &&
            quotechar == NULL &&
            quoting == NULL &&
            skipinitialspace == NULL &&
            strict == NULL)
            return dialect;
    }

    self = (DialectObj *)type->tp_alloc(type, 0);
    if (self == NULL) {
        Py_CLEAR(dialect);
        return NULL;
    }
    self->lineterminator = NULL;

    Py_XINCREF(delimiter);
    Py_XINCREF(doublequote);
    Py_XINCREF(escapechar);
    Py_XINCREF(lineterminator);
    Py_XINCREF(quotechar);
    Py_XINCREF(quoting);
    Py_XINCREF(skipinitialspace);
    Py_XINCREF(strict);
    if (dialect != NULL) {
#define DIALECT_GETATTR(v, n)                                               \
        do {                                                                \
            if (v == NULL) {                                                \
                if (PyObject_GetOptionalAttrString(dialect, n, &v) < 0) {   \
                    goto err;                                               \
                }                                                           \
            }                                                               \
        } while (0)
        DIALECT_GETATTR(delimiter, "delimiter");
        DIALECT_GETATTR(doublequote, "doublequote");
        DIALECT_GETATTR(escapechar, "escapechar");
        DIALECT_GETATTR(lineterminator, "lineterminator");
        DIALECT_GETATTR(quotechar, "quotechar");
        DIALECT_GETATTR(quoting, "quoting");
        DIALECT_GETATTR(skipinitialspace, "skipinitialspace");
        DIALECT_GETATTR(strict, "strict");
    }
#undef DIALECT_GETATTR

    /* check types and convert to C values */
#define DIASET(meth, name, target, src, dflt) \
    if (meth(name, target, src, dflt)) \
        goto err
    DIASET(_set_char, "delimiter", &self->delimiter, delimiter, ',');
    DIASET(_set_bool, "doublequote", &self->doublequote, doublequote, true);
    DIASET(_set_char_or_none, "escapechar", &self->escapechar, escapechar, NOT_SET);
    DIASET(_set_str, "lineterminator", &self->lineterminator, lineterminator, "\r\n");
    DIASET(_set_char_or_none, "quotechar", &self->quotechar, quotechar, '"');
    DIASET(_set_int, "quoting", &self->quoting, quoting, QUOTE_MINIMAL);
    DIASET(_set_bool, "skipinitialspace", &self->skipinitialspace, skipinitialspace, false);
    DIASET(_set_bool, "strict", &self->strict, strict, false);
#undef DIASET

    /* validate options */
    if (dialect_check_quoting(self->quoting))
        goto err;
    if (quotechar == Py_None && quoting == NULL)
        self->quoting = QUOTE_NONE;
    if (self->quoting != QUOTE_NONE && self->quotechar == NOT_SET) {
        PyErr_SetString(PyExc_TypeError,
                        "quotechar must be set if quoting enabled");
        goto err;
    }
    if (dialect_check_char("delimiter", self->delimiter, self, true) ||
        dialect_check_char("escapechar", self->escapechar, self,
                           !self->skipinitialspace) ||
        dialect_check_char("quotechar", self->quotechar, self,
                           !self->skipinitialspace) ||
        dialect_check_chars("delimiter", "escapechar",
                            self->delimiter, self->escapechar) ||
        dialect_check_chars("delimiter", "quotechar",
                            self->delimiter, self->quotechar) ||
        dialect_check_chars("escapechar", "quotechar",
                            self->escapechar, self->quotechar))
    {
        goto err;
    }

    ret = Py_NewRef(self);
err:
    Py_CLEAR(self);
    Py_CLEAR(dialect);
    Py_CLEAR(delimiter);
    Py_CLEAR(doublequote);
    Py_CLEAR(escapechar);
    Py_CLEAR(lineterminator);
    Py_CLEAR(quotechar);
    Py_CLEAR(quoting);
    Py_CLEAR(skipinitialspace);
    Py_CLEAR(strict);
    return ret;
}

/* Since dialect is now a heap type, it inherits pickling method for
 * protocol 0 and 1 from object, therefore it needs to be overridden */

PyDoc_STRVAR(dialect_reduce_doc, "raises an exception to avoid pickling");

static PyObject *
Dialect_reduce(PyObject *self, PyObject *args) {
    PyErr_Format(PyExc_TypeError,
        "cannot pickle '%.100s' instances", _PyType_Name(Py_TYPE(self)));
    return NULL;
}

static struct PyMethodDef dialect_methods[] = {
    {"__reduce__", Dialect_reduce, METH_VARARGS, dialect_reduce_doc},
    {"__reduce_ex__", Dialect_reduce, METH_VARARGS, dialect_reduce_doc},
    {NULL, NULL}
};

PyDoc_STRVAR(Dialect_Type_doc,
"CSV dialect\n"
"\n"
"The Dialect type records CSV parsing and generation options.\n");

static int
Dialect_clear(PyObject *op)
{
    DialectObj *self = _DialectObj_CAST(op);
    Py_CLEAR(self->lineterminator);
    return 0;
}

static int
Dialect_traverse(PyObject *op, visitproc visit, void *arg)
{
    DialectObj *self = _DialectObj_CAST(op);
    Py_VISIT(self->lineterminator);
    Py_VISIT(Py_TYPE(self));
    return 0;
}

static PyType_Slot Dialect_Type_slots[] = {
    {Py_tp_doc, (char*)Dialect_Type_doc},
    {Py_tp_members, Dialect_memberlist},
    {Py_tp_getset, Dialect_getsetlist},
    {Py_tp_new, dialect_new},
    {Py_tp_methods, dialect_methods},
    {Py_tp_dealloc, Dialect_dealloc},
    {Py_tp_clear, Dialect_clear},
    {Py_tp_traverse, Dialect_traverse},
    {0, NULL}
};

PyType_Spec Dialect_Type_spec = {
    .name = "_csv.Dialect",
    .basicsize = sizeof(DialectObj),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
              Py_TPFLAGS_IMMUTABLETYPE),
    .slots = Dialect_Type_slots,
};


/*
 * Return an instance of the dialect type, given a Python instance or kwarg
 * description of the dialect
 */
static PyObject *
_call_dialect(_csvstate *module_state, PyObject *dialect_inst, PyObject *kwargs)
{
    PyObject *type = (PyObject *)module_state->dialect_type;
    if (dialect_inst) {
        return PyObject_VectorcallDict(type, &dialect_inst, 1, kwargs);
    }
    else {
        return PyObject_VectorcallDict(type, NULL, 0, kwargs);
    }
}

/*
 * READER
 */
static int
parse_save_field(ReaderObj *self)
{
    int quoting = self->dialect->quoting;
    PyObject *field;

    if (self->unquoted_field &&
        self->field_len == 0 &&
        (quoting == QUOTE_NOTNULL || quoting == QUOTE_STRINGS))
    {
        field = Py_NewRef(Py_None);
    }
    else {
        field = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
                                        (void *) self->field, self->field_len);
        if (field == NULL) {
            return -1;
        }
        if (self->unquoted_field &&
            self->field_len != 0 &&
            (quoting == QUOTE_NONNUMERIC || quoting == QUOTE_STRINGS))
        {
            PyObject *tmp = PyNumber_Float(field);
            Py_DECREF(field);
            if (tmp == NULL) {
                return -1;
            }
            field = tmp;
        }
        self->field_len = 0;
    }
    if (PyList_Append(self->fields, field) < 0) {
        Py_DECREF(field);
        return -1;
    }
    Py_DECREF(field);
    return 0;
}

static int
parse_grow_buff(ReaderObj *self)
{
    assert((size_t)self->field_size <= PY_SSIZE_T_MAX / sizeof(Py_UCS4));

    Py_ssize_t field_size_new = self->field_size ? 2 * self->field_size : 4096;
    Py_UCS4 *field_new = self->field;
    PyMem_Resize(field_new, Py_UCS4, field_size_new);
    if (field_new == NULL) {
        PyErr_NoMemory();
        return 0;
    }
    self->field = field_new;
    self->field_size = field_size_new;
    return 1;
}

static int
parse_add_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c)
{
    Py_ssize_t field_limit = FT_ATOMIC_LOAD_SSIZE_RELAXED(module_state->field_limit);
    if (self->field_len >= field_limit) {
        PyErr_Format(module_state->error_obj,
                     "field larger than field limit (%zd)",
                     field_limit);
        return -1;
    }
    if (self->field_len == self->field_size && !parse_grow_buff(self))
        return -1;
    self->field[self->field_len++] = c;
    return 0;
}

static int
parse_process_char(ReaderObj *self, _csvstate *module_state, Py_UCS4 c)
{
    DialectObj *dialect = self->dialect;

    switch (self->state) {
    case START_RECORD:
        /* start of record */
        if (c == EOL)
            /* empty line - return [] */
            break;
        else if (c == '\n' || c == '\r') {
            self->state = EAT_CRNL;
            break;
        }
        /* normal character - handle as START_FIELD */
        self->state = START_FIELD;
        _Py_FALLTHROUGH;
    case START_FIELD:
        /* expecting field */
        self->unquoted_field = true;
        if (c == '\n' || c == '\r' || c == EOL) {
            /* save empty field - return [fields] */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = (c == EOL ? START_RECORD : EAT_CRNL);
        }
        else if (c == dialect->quotechar &&
                 dialect->quoting != QUOTE_NONE) {
            /* start quoted field */
            self->unquoted_field = false;
            self->state = IN_QUOTED_FIELD;
        }
        else if (c == dialect->escapechar) {
            /* possible escaped character */
            self->state = ESCAPED_CHAR;
        }
        else if (c == ' ' && dialect->skipinitialspace)
            /* ignore spaces at start of field */
            ;
        else if (c == dialect->delimiter) {
            /* save empty field */
            if (parse_save_field(self) < 0)
                return -1;
        }
        else {
            /* begin new unquoted field */
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
            self->state = IN_FIELD;
        }
        break;

    case ESCAPED_CHAR:
        if (c == '\n' || c=='\r') {
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
            self->state = AFTER_ESCAPED_CRNL;
            break;
        }
        if (c == EOL)
            c = '\n';
        if (parse_add_char(self, module_state, c) < 0)
            return -1;
        self->state = IN_FIELD;
        break;

    case AFTER_ESCAPED_CRNL:
        if (c == EOL)
            break;
        _Py_FALLTHROUGH;

    case IN_FIELD:
        /* in unquoted field */
        if (c == '\n' || c == '\r' || c == EOL) {
            /* end of line - return [fields] */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = (c == EOL ? START_RECORD : EAT_CRNL);
        }
        else if (c == dialect->escapechar) {
            /* possible escaped character */
            self->state = ESCAPED_CHAR;
        }
        else if (c == dialect->delimiter) {
            /* save field - wait for new field */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = START_FIELD;
        }
        else {
            /* normal character - save in field */
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
        }
        break;

    case IN_QUOTED_FIELD:
        /* in quoted field */
        if (c == EOL)
            ;
        else if (c == dialect->escapechar) {
            /* Possible escape character */
            self->state = ESCAPE_IN_QUOTED_FIELD;
        }
        else if (c == dialect->quotechar &&
                 dialect->quoting != QUOTE_NONE) {
            if (dialect->doublequote) {
                /* doublequote; " represented by "" */
                self->state = QUOTE_IN_QUOTED_FIELD;
            }
            else {
                /* end of quote part of field */
                self->state = IN_FIELD;
            }
        }
        else {
            /* normal character - save in field */
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
        }
        break;

    case ESCAPE_IN_QUOTED_FIELD:
        if (c == EOL)
            c = '\n';
        if (parse_add_char(self, module_state, c) < 0)
            return -1;
        self->state = IN_QUOTED_FIELD;
        break;

    case QUOTE_IN_QUOTED_FIELD:
        /* doublequote - seen a quote in a quoted field */
        if (dialect->quoting != QUOTE_NONE &&
            c == dialect->quotechar) {
            /* save "" as " */
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
            self->state = IN_QUOTED_FIELD;
        }
        else if (c == dialect->delimiter) {
            /* save field - wait for new field */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = START_FIELD;
        }
        else if (c == '\n' || c == '\r' || c == EOL) {
            /* end of line - return [fields] */
            if (parse_save_field(self) < 0)
                return -1;
            self->state = (c == EOL ? START_RECORD : EAT_CRNL);
        }
        else if (!dialect->strict) {
            if (parse_add_char(self, module_state, c) < 0)
                return -1;
            self->state = IN_FIELD;
        }
        else {
            /* illegal */
            PyErr_Format(module_state->error_obj, "'%c' expected after '%c'",
                            dialect->delimiter,
                            dialect->quotechar);
            return -1;
        }
        break;

    case EAT_CRNL:
        if (c == '\n' || c == '\r')
            ;
        else if (c == EOL)
            self->state = START_RECORD;
        else {
            PyErr_Format(module_state->error_obj,
                         "new-line character seen in unquoted field - "
                         "do you need to open the file with newline=''?");
            return -1;
        }
        break;

    }
    return 0;
}

static int
parse_reset(ReaderObj *self)
{
    Py_XSETREF(self->fields, PyList_New(0));
    if (self->fields == NULL)
        return -1;
    self->field_len = 0;
    self->state = START_RECORD;
    self->unquoted_field = false;
    return 0;
}

static PyObject *
Reader_iternext_lock_held(PyObject *op)
{
    ReaderObj *self = _ReaderObj_CAST(op);

    PyObject *fields = NULL;
    Py_UCS4 c;
    Py_ssize_t pos, linelen;
    int kind;
    const void *data;
    PyObject *lineobj;

    _csvstate *module_state = _csv_state_from_type(Py_TYPE(self),
                                                   "Reader.__next__");
    if (module_state == NULL) {
        return NULL;
    }

    if (parse_reset(self) < 0)
        return NULL;
    do {
        lineobj = PyIter_Next(self->input_iter);
        if (lineobj == NULL) {
            /* End of input OR exception */
            if (!PyErr_Occurred() && (self->field_len != 0 ||
                                      self->state == IN_QUOTED_FIELD)) {
                if (self->dialect->strict)
                    PyErr_SetString(module_state->error_obj,
                                    "unexpected end of data");
                else if (parse_save_field(self) >= 0)
                    break;
            }
            return NULL;
        }
        if (!PyUnicode_Check(lineobj)) {
            PyErr_Format(module_state->error_obj,
                         "iterator should return strings, "
                         "not %.200s "
                         "(the file should be opened in text mode)",
                         Py_TYPE(lineobj)->tp_name
                );
            Py_DECREF(lineobj);
            return NULL;
        }
        if (self->fields == NULL) {
            PyErr_SetString(module_state->error_obj,
                            "iterator has already advanced the reader");
            Py_DECREF(lineobj);
            return NULL;
        }
        ++self->line_num;
        kind = PyUnicode_KIND(lineobj);
        data = PyUnicode_DATA(lineobj);
        pos = 0;
        linelen = PyUnicode_GET_LENGTH(lineobj);
        while (linelen--) {
            c = PyUnicode_READ(kind, data, pos);
            if (parse_process_char(self, module_state, c) < 0) {
                Py_DECREF(lineobj);
                goto err;
            }
            pos++;
        }
        Py_DECREF(lineobj);
        if (parse_process_char(self, module_state, EOL) < 0)
            goto err;
    } while (self->state != START_RECORD);

    fields = self->fields;
    self->fields = NULL;
err:
    return fields;
}

static PyObject *
Reader_iternext(PyObject *op)
{
    PyObject *result;
    Py_BEGIN_CRITICAL_SECTION(op);
    result = Reader_iternext_lock_held(op);
    Py_END_CRITICAL_SECTION();
    return result;
}

static void
Reader_dealloc(PyObject *op)
{
    ReaderObj *self = _ReaderObj_CAST(op);
    PyTypeObject *tp = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    (void)tp->tp_clear(op);
    if (self->field != NULL) {
        PyMem_Free(self->field);
        self->field = NULL;
    }
    PyObject_GC_Del(self);
    Py_DECREF(tp);
}

static int
Reader_traverse(PyObject *op, visitproc visit, void *arg)
{
    ReaderObj *self = _ReaderObj_CAST(op);
    Py_VISIT(self->dialect);
    Py_VISIT(self->input_iter);
    Py_VISIT(self->fields);
    Py_VISIT(Py_TYPE(self));
    return 0;
}

static int
Reader_clear(PyObject *op)
{
    ReaderObj *self = _ReaderObj_CAST(op);
    Py_CLEAR(self->dialect);
    Py_CLEAR(self->input_iter);
    Py_CLEAR(self->fields);
    return 0;
}

PyDoc_STRVAR(Reader_Type_doc,
"CSV reader\n"
"\n"
"Reader objects are responsible for reading and parsing tabular data\n"
"in CSV format.\n"
);

static struct PyMethodDef Reader_methods[] = {
    { NULL, NULL }
};
#define R_OFF(x) offsetof(ReaderObj, x)

static struct PyMemberDef Reader_memberlist[] = {
    { "dialect", _Py_T_OBJECT, R_OFF(dialect), Py_READONLY },
    { "line_num", Py_T_ULONG, R_OFF(line_num), Py_READONLY },
    { NULL }
};

#undef R_OFF


static PyType_Slot Reader_Type_slots[] = {
    {Py_tp_doc, (char*)Reader_Type_doc},
    {Py_tp_traverse, Reader_traverse},
    {Py_tp_iter, PyObject_SelfIter},
    {Py_tp_iternext, Reader_iternext},
    {Py_tp_methods, Reader_methods},
    {Py_tp_members, Reader_memberlist},
    {Py_tp_clear, Reader_clear},
    {Py_tp_dealloc, Reader_dealloc},
    {0, NULL}
};

PyType_Spec Reader_Type_spec = {
    .name = "_csv.reader",
    .basicsize = sizeof(ReaderObj),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
              Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
    .slots = Reader_Type_slots
};


static PyObject *
csv_reader(PyObject *module, PyObject *args, PyObject *keyword_args)
{
    PyObject * iterator, * dialect = NULL;
    _csvstate *module_state = get_csv_state(module);
    ReaderObj * self = PyObject_GC_New(
        ReaderObj,
        module_state->reader_type);

    if (!self)
        return NULL;

    self->dialect = NULL;
    self->fields = NULL;
    self->input_iter = NULL;
    self->field = NULL;
    self->field_size = 0;
    self->line_num = 0;

    if (parse_reset(self) < 0) {
        Py_DECREF(self);
        return NULL;
    }

    if (!PyArg_UnpackTuple(args, "reader", 1, 2, &iterator, &dialect)) {
        Py_DECREF(self);
        return NULL;
    }
    self->input_iter = PyObject_GetIter(iterator);
    if (self->input_iter == NULL) {
        Py_DECREF(self);
        return NULL;
    }
    self->dialect = (DialectObj *)_call_dialect(module_state, dialect,
                                                keyword_args);
    if (self->dialect == NULL) {
        Py_DECREF(self);
        return NULL;
    }

    PyObject_GC_Track(self);
    return (PyObject *)self;
}

/*
 * WRITER
 */
/* ---------------------------------------------------------------- */
static void
join_reset(WriterObj *self)
{
    self->rec_len = 0;
    self->num_fields = 0;
}

#define MEM_INCR 32768

/* Calculate new record length or append field to record.  Return new
 * record length.
 */
static Py_ssize_t
join_append_data(WriterObj *self, int field_kind, const void *field_data,
                 Py_ssize_t field_len, int *quoted,
                 int copy_phase)
{
    DialectObj *dialect = self->dialect;
    Py_ssize_t i;
    Py_ssize_t rec_len;

#define INCLEN \
    do {\
        if (!copy_phase && rec_len == PY_SSIZE_T_MAX) {    \
            goto overflow; \
        } \
        rec_len++; \
    } while(0)

#define ADDCH(c)                                \
    do {\
        if (copy_phase) \
            self->rec[rec_len] = c;\
        INCLEN;\
    } while(0)

    rec_len = self->rec_len;

    /* If this is not the first field we need a field separator */
    if (self->num_fields > 0)
        ADDCH(dialect->delimiter);

    /* Handle preceding quote */
    if (copy_phase && *quoted)
        ADDCH(dialect->quotechar);

    /* Copy/count field data */
    /* If field is null just pass over */
    for (i = 0; field_data && (i < field_len); i++) {
        Py_UCS4 c = PyUnicode_READ(field_kind, field_data, i);
        int want_escape = 0;

        if (c == dialect->delimiter ||
            c == dialect->escapechar ||
            c == dialect->quotechar  ||
            c == '\n'  ||
            c == '\r'  ||
            PyUnicode_FindChar(
                dialect->lineterminator, c, 0,
                PyUnicode_GET_LENGTH(dialect->lineterminator), 1) >= 0) {
            if (dialect->quoting == QUOTE_NONE)
                want_escape = 1;
            else {
                if (c == dialect->quotechar) {
                    if (dialect->doublequote)
                        ADDCH(dialect->quotechar);
                    else
                        want_escape = 1;
                }
                else if (c == dialect->escapechar) {
                    want_escape = 1;
                }
                if (!want_escape)
                    *quoted = 1;
            }
            if (want_escape) {
                if (dialect->escapechar == NOT_SET) {
                    PyErr_Format(self->error_obj,
                                 "need to escape, but no escapechar set");
                    return -1;
                }
                ADDCH(dialect->escapechar);
            }
        }
        /* Copy field character into record buffer.
         */
        ADDCH(c);
    }

    if (*quoted) {
        if (copy_phase)
            ADDCH(dialect->quotechar);
        else {
            INCLEN; /* starting quote */
            INCLEN; /* ending quote */
        }
    }
    return rec_len;

  overflow:
    PyErr_NoMemory();
    return -1;
#undef ADDCH
#undef INCLEN
}

static int
join_check_rec_size(WriterObj *self, Py_ssize_t rec_len)
{
    assert(rec_len >= 0);

    if (rec_len > self->rec_size) {
        size_t rec_size_new = (size_t)(rec_len / MEM_INCR + 1) * MEM_INCR;
        Py_UCS4 *rec_new = self->rec;
        PyMem_Resize(rec_new, Py_UCS4, rec_size_new);
        if (rec_new == NULL) {
            PyErr_NoMemory();
            return 0;
        }
        self->rec = rec_new;
        self->rec_size = (Py_ssize_t)rec_size_new;
    }
    return 1;
}

static int
join_append(WriterObj *self, PyObject *field, int quoted)
{
    DialectObj *dialect = self->dialect;
    int field_kind = -1;
    const void *field_data = NULL;
    Py_ssize_t field_len = 0;
    Py_ssize_t rec_len;

    if (field != NULL) {
        field_kind = PyUnicode_KIND(field);
        field_data = PyUnicode_DATA(field);
        field_len = PyUnicode_GET_LENGTH(field);
    }
    if (!field_len && dialect->delimiter == ' ' && dialect->skipinitialspace) {
        if (dialect->quoting == QUOTE_NONE ||
            (field == NULL &&
             (dialect->quoting == QUOTE_STRINGS ||
              dialect->quoting == QUOTE_NOTNULL)))
        {
            PyErr_Format(self->error_obj,
                         "empty field must be quoted if delimiter is a space "
                         "and skipinitialspace is true");
            return 0;
        }
        quoted = 1;
    }
    rec_len = join_append_data(self, field_kind, field_data, field_len,
                               &quoted, 0);
    if (rec_len < 0)
        return 0;

    /* grow record buffer if necessary */
    if (!join_check_rec_size(self, rec_len))
        return 0;

    self->rec_len = join_append_data(self, field_kind, field_data, field_len,
                                     &quoted, 1);
    self->num_fields++;

    return 1;
}

static int
join_append_lineterminator(WriterObj *self)
{
    Py_ssize_t terminator_len, i;
    int term_kind;
    const void *term_data;

    terminator_len = PyUnicode_GET_LENGTH(self->dialect->lineterminator);
    if (terminator_len == -1)
        return 0;

    /* grow record buffer if necessary */
    if (!join_check_rec_size(self, self->rec_len + terminator_len))
        return 0;

    term_kind = PyUnicode_KIND(self->dialect->lineterminator);
    term_data = PyUnicode_DATA(self->dialect->lineterminator);
    for (i = 0; i < terminator_len; i++)
        self->rec[self->rec_len + i] = PyUnicode_READ(term_kind, term_data, i);
    self->rec_len += terminator_len;

    return 1;
}

static PyObject *
csv_writerow_lock_held(PyObject *op, PyObject *seq)
{
    WriterObj *self = _WriterObj_CAST(op);
    DialectObj *dialect = self->dialect;
    PyObject *iter, *field, *line, *result;
    bool null_field = false;

    iter = PyObject_GetIter(seq);
    if (iter == NULL) {
        if (PyErr_ExceptionMatches(PyExc_TypeError)) {
            PyErr_Format(self->error_obj,
                         "iterable expected, not %.200s",
                         Py_TYPE(seq)->tp_name);
        }
        return NULL;
    }

    /* Join all fields in internal buffer.
     */
    join_reset(self);
    while ((field = PyIter_Next(iter))) {
        int append_ok;
        int quoted;

        switch (dialect->quoting) {
        case QUOTE_NONNUMERIC:
            quoted = !PyNumber_Check(field);
            break;
        case QUOTE_ALL:
            quoted = 1;
            break;
        case QUOTE_STRINGS:
            quoted = PyUnicode_Check(field);
            break;
        case QUOTE_NOTNULL:
            quoted = field != Py_None;
            break;
        default:
            quoted = 0;
            break;
        }

        null_field = (field == Py_None);
        if (PyUnicode_Check(field)) {
            append_ok = join_append(self, field, quoted);
            Py_DECREF(field);
        }
        else if (null_field) {
            append_ok = join_append(self, NULL, quoted);
            Py_DECREF(field);
        }
        else {
            PyObject *str;

            str = PyObject_Str(field);
            Py_DECREF(field);
            if (str == NULL) {
                Py_DECREF(iter);
                return NULL;
            }
            append_ok = join_append(self, str, quoted);
            Py_DECREF(str);
        }
        if (!append_ok) {
            Py_DECREF(iter);
            return NULL;
        }
    }
    Py_DECREF(iter);
    if (PyErr_Occurred())
        return NULL;

    if (self->num_fields > 0 && self->rec_len == 0) {
        if (dialect->quoting == QUOTE_NONE ||
            (null_field &&
             (dialect->quoting == QUOTE_STRINGS ||
              dialect->quoting == QUOTE_NOTNULL)))
        {
            PyErr_Format(self->error_obj,
                "single empty field record must be quoted");
            return NULL;
        }
        self->num_fields--;
        if (!join_append(self, NULL, 1))
            return NULL;
    }

    /* Add line terminator.
     */
    if (!join_append_lineterminator(self)) {
        return NULL;
    }

    line = PyUnicode_FromKindAndData(PyUnicode_4BYTE_KIND,
                                     (void *) self->rec, self->rec_len);
    if (line == NULL) {
        return NULL;
    }
    result = PyObject_CallOneArg(self->write, line);
    Py_DECREF(line);
    return result;
}

PyDoc_STRVAR(csv_writerow_doc,
"writerow($self, row, /)\n"
"--\n\n"
"Construct and write a CSV record from an iterable of fields.\n"
"\n"
"Non-string elements will be converted to string.");

static PyObject *
csv_writerow(PyObject *op, PyObject *seq)
{
    PyObject *result;
    Py_BEGIN_CRITICAL_SECTION(op);
    result = csv_writerow_lock_held(op, seq);
    Py_END_CRITICAL_SECTION();
    return result;
}

PyDoc_STRVAR(csv_writerows_doc,
"writerows($self, rows, /)\n"
"--\n\n"
"Construct and write a series of iterables to a csv file.\n"
"\n"
"Non-string elements will be converted to string.");

static PyObject *
csv_writerows(PyObject *self, PyObject *seqseq)
{
    PyObject *row_iter, *row_obj, *result;

    row_iter = PyObject_GetIter(seqseq);
    if (row_iter == NULL) {
        return NULL;
    }
    while ((row_obj = PyIter_Next(row_iter))) {
        result = csv_writerow(self, row_obj);
        Py_DECREF(row_obj);
        if (!result) {
            Py_DECREF(row_iter);
            return NULL;
        }
        else
             Py_DECREF(result);
    }
    Py_DECREF(row_iter);
    if (PyErr_Occurred())
        return NULL;
    Py_RETURN_NONE;
}

static struct PyMethodDef Writer_methods[] = {
    {"writerow", csv_writerow, METH_O, csv_writerow_doc},
    {"writerows", csv_writerows, METH_O, csv_writerows_doc},
    {NULL, NULL, 0, NULL}  /* sentinel */
};

#define W_OFF(x) offsetof(WriterObj, x)

static struct PyMemberDef Writer_memberlist[] = {
    { "dialect", _Py_T_OBJECT, W_OFF(dialect), Py_READONLY },
    { NULL }
};

#undef W_OFF

static int
Writer_traverse(PyObject *op, visitproc visit, void *arg)
{
    WriterObj *self = _WriterObj_CAST(op);
    Py_VISIT(self->dialect);
    Py_VISIT(self->write);
    Py_VISIT(self->error_obj);
    Py_VISIT(Py_TYPE(self));
    return 0;
}

static int
Writer_clear(PyObject *op)
{
    WriterObj *self = _WriterObj_CAST(op);
    Py_CLEAR(self->dialect);
    Py_CLEAR(self->write);
    Py_CLEAR(self->error_obj);
    return 0;
}

static void
Writer_dealloc(PyObject *op)
{
    WriterObj *self = _WriterObj_CAST(op);
    PyTypeObject *tp = Py_TYPE(self);
    PyObject_GC_UnTrack(self);
    tp->tp_clear(op);
    if (self->rec != NULL) {
        PyMem_Free(self->rec);
    }
    PyObject_GC_Del(self);
    Py_DECREF(tp);
}

PyDoc_STRVAR(Writer_Type_doc,
"CSV writer\n"
"\n"
"Writer objects are responsible for generating tabular data\n"
"in CSV format from sequence input.\n"
);

static PyType_Slot Writer_Type_slots[] = {
    {Py_tp_doc, (char*)Writer_Type_doc},
    {Py_tp_traverse, Writer_traverse},
    {Py_tp_clear, Writer_clear},
    {Py_tp_dealloc, Writer_dealloc},
    {Py_tp_methods, Writer_methods},
    {Py_tp_members, Writer_memberlist},
    {0, NULL}
};

PyType_Spec Writer_Type_spec = {
    .name = "_csv.writer",
    .basicsize = sizeof(WriterObj),
    .flags = (Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_GC |
              Py_TPFLAGS_IMMUTABLETYPE | Py_TPFLAGS_DISALLOW_INSTANTIATION),
    .slots = Writer_Type_slots,
};


static PyObject *
csv_writer(PyObject *module, PyObject *args, PyObject *keyword_args)
{
    PyObject * output_file, * dialect = NULL;
    _csvstate *module_state = get_csv_state(module);
    WriterObj * self = PyObject_GC_New(WriterObj, module_state->writer_type);

    if (!self)
        return NULL;

    self->dialect = NULL;
    self->write = NULL;

    self->rec = NULL;
    self->rec_size = 0;
    self->rec_len = 0;
    self->num_fields = 0;

    self->error_obj = Py_NewRef(module_state->error_obj);

    if (!PyArg_UnpackTuple(args, "writer", 1, 2, &output_file, &dialect)) {
        Py_DECREF(self);
        return NULL;
    }
    if (PyObject_GetOptionalAttr(output_file,
                             module_state->str_write,
                             &self->write) < 0) {
        Py_DECREF(self);
        return NULL;
    }
    if (self->write == NULL || !PyCallable_Check(self->write)) {
        PyErr_SetString(PyExc_TypeError,
                        "argument 1 must have a \"write\" method");
        Py_DECREF(self);
        return NULL;
    }
    self->dialect = (DialectObj *)_call_dialect(module_state, dialect,
                                                keyword_args);
    if (self->dialect == NULL) {
        Py_DECREF(self);
        return NULL;
    }
    PyObject_GC_Track(self);
    return (PyObject *)self;
}

/*
 * DIALECT REGISTRY
 */

/*[clinic input]
_csv.list_dialects

Return a list of all known dialect names.
[clinic start generated code]*/

static PyObject *
_csv_list_dialects_impl(PyObject *module)
/*[clinic end generated code: output=a5b92b215b006a6d input=ec58040aafd6a20a]*/
{
    return PyDict_Keys(get_csv_state(module)->dialects);
}

static PyObject *
csv_register_dialect(PyObject *module, PyObject *args, PyObject *kwargs)
{
    PyObject *name_obj, *dialect_obj = NULL;
    _csvstate *module_state = get_csv_state(module);
    PyObject *dialect;

    if (!PyArg_UnpackTuple(args, "register_dialect", 1, 2, &name_obj, &dialect_obj))
        return NULL;
    if (!PyUnicode_Check(name_obj)) {
        PyErr_SetString(PyExc_TypeError,
                        "dialect name must be a string");
        return NULL;
    }
    dialect = _call_dialect(module_state, dialect_obj, kwargs);
    if (dialect == NULL)
        return NULL;
    if (PyDict_SetItem(module_state->dialects, name_obj, dialect) < 0) {
        Py_DECREF(dialect);
        return NULL;
    }
    Py_DECREF(dialect);
    Py_RETURN_NONE;
}


/*[clinic input]
_csv.unregister_dialect

    name: object

Delete the name/dialect mapping associated with a string name.
[clinic start generated code]*/

static PyObject *
_csv_unregister_dialect_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=0813ebca6c058df4 input=e1cf81bfe3ba0f62]*/
{
    _csvstate *module_state = get_csv_state(module);
    int rc = PyDict_Pop(module_state->dialects, name, NULL);
    if (rc < 0) {
        return NULL;
    }
    if (rc == 0) {
        PyErr_Format(module_state->error_obj, "unknown dialect");
        return NULL;
    }
    Py_RETURN_NONE;
}

/*[clinic input]
_csv.get_dialect

    name: object

Return the dialect instance associated with name.
[clinic start generated code]*/

static PyObject *
_csv_get_dialect_impl(PyObject *module, PyObject *name)
/*[clinic end generated code: output=aa988cd573bebebb input=74865c659dcb441f]*/
{
    return get_dialect_from_registry(name, get_csv_state(module));
}

/*[clinic input]
_csv.field_size_limit

    new_limit: object = NULL

Sets an upper limit on parsed fields.

Returns old limit. If limit is not given, no new limit is set and
the old limit is returned
[clinic start generated code]*/

static PyObject *
_csv_field_size_limit_impl(PyObject *module, PyObject *new_limit)
/*[clinic end generated code: output=f2799ecd908e250b input=77db7485ee3ae90a]*/
{
    _csvstate *module_state = get_csv_state(module);
    Py_ssize_t old_limit = FT_ATOMIC_LOAD_SSIZE_RELAXED(module_state->field_limit);
    if (new_limit != NULL) {
        if (!PyLong_CheckExact(new_limit)) {
            PyErr_Format(PyExc_TypeError,
                         "limit must be an integer");
            return NULL;
        }
        Py_ssize_t new_limit_value = PyLong_AsSsize_t(new_limit);
        if (new_limit_value == -1 && PyErr_Occurred()) {
            return NULL;
        }
        FT_ATOMIC_STORE_SSIZE_RELAXED(module_state->field_limit, new_limit_value);
    }
    return PyLong_FromSsize_t(old_limit);
}

static PyType_Slot error_slots[] = {
    {0, NULL},
};

PyType_Spec error_spec = {
    .name = "_csv.Error",
    .flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
    .slots = error_slots,
};

/*
 * MODULE
 */

PyDoc_STRVAR(csv_module_doc, "CSV parsing and writing.\n");

PyDoc_STRVAR(csv_reader_doc,
"reader($module, iterable, /, dialect='excel', **fmtparams)\n"
"--\n\n"
"Return a reader object that will process lines from the given iterable.\n"
"\n"
"The \"iterable\" argument can be any object that returns a line\n"
"of input for each iteration, such as a file object or a list.  The\n"
"optional \"dialect\" argument defines a CSV dialect.  The function\n"
"also accepts optional keyword arguments which override settings\n"
"provided by the dialect.\n"
"\n"
"The returned object is an iterator.  Each iteration returns a row\n"
"of the CSV file (which can span multiple input lines).\n");

PyDoc_STRVAR(csv_writer_doc,
"writer($module, fileobj, /, dialect='excel', **fmtparams)\n"
"--\n\n"
"Return a writer object that will write user data on the given file object.\n"
"\n"
"The \"fileobj\" argument can be any object that supports the file API.\n"
"The optional \"dialect\" argument defines a CSV dialect.  The function\n"
"also accepts optional keyword arguments which override settings\n"
"provided by the dialect.\n");

PyDoc_STRVAR(csv_register_dialect_doc,
"register_dialect($module, name, /, dialect='excel', **fmtparams)\n"
"--\n\n"
"Create a mapping from a string name to a CVS dialect.\n"
"\n"
"The optional \"dialect\" argument specifies the base dialect instance\n"
"or the name of the registered dialect.  The function also accepts\n"
"optional keyword arguments which override settings provided by the\n"
"dialect.\n");

static struct PyMethodDef csv_methods[] = {
    { "reader", _PyCFunction_CAST(csv_reader),
        METH_VARARGS | METH_KEYWORDS, csv_reader_doc},
    { "writer", _PyCFunction_CAST(csv_writer),
        METH_VARARGS | METH_KEYWORDS, csv_writer_doc},
    { "register_dialect", _PyCFunction_CAST(csv_register_dialect),
        METH_VARARGS | METH_KEYWORDS, csv_register_dialect_doc},
    _CSV_LIST_DIALECTS_METHODDEF
    _CSV_UNREGISTER_DIALECT_METHODDEF
    _CSV_GET_DIALECT_METHODDEF
    _CSV_FIELD_SIZE_LIMIT_METHODDEF
    { NULL, NULL }
};

static int
csv_exec(PyObject *module) {
    const StyleDesc *style;
    PyObject *temp;
    _csvstate *module_state = get_csv_state(module);

    temp = PyType_FromModuleAndSpec(module, &Dialect_Type_spec, NULL);
    module_state->dialect_type = (PyTypeObject *)temp;
    if (PyModule_AddObjectRef(module, "Dialect", temp) < 0) {
        return -1;
    }

    temp = PyType_FromModuleAndSpec(module, &Reader_Type_spec, NULL);
    module_state->reader_type = (PyTypeObject *)temp;
    if (PyModule_AddObjectRef(module, "Reader", temp) < 0) {
        return -1;
    }

    temp = PyType_FromModuleAndSpec(module, &Writer_Type_spec, NULL);
    module_state->writer_type = (PyTypeObject *)temp;
    if (PyModule_AddObjectRef(module, "Writer", temp) < 0) {
        return -1;
    }

    /* Set the field limit */
    module_state->field_limit = 128 * 1024;

    /* Add _dialects dictionary */
    module_state->dialects = PyDict_New();
    if (PyModule_AddObjectRef(module, "_dialects", module_state->dialects) < 0) {
        return -1;
    }

    /* Add quote styles into dictionary */
    for (style = quote_styles; style->name; style++) {
        if (PyModule_AddIntConstant(module, style->name,
                                    style->style) == -1)
            return -1;
    }

    /* Add the CSV exception object to the module. */
    PyObject *bases = PyTuple_Pack(1, PyExc_Exception);
    if (bases == NULL) {
        return -1;
    }
    module_state->error_obj = PyType_FromModuleAndSpec(module, &error_spec,
                                                       bases);
    Py_DECREF(bases);
    if (module_state->error_obj == NULL) {
        return -1;
    }
    if (PyModule_AddType(module, (PyTypeObject *)module_state->error_obj) != 0) {
        return -1;
    }

    module_state->str_write = PyUnicode_InternFromString("write");
    if (module_state->str_write == NULL) {
        return -1;
    }
    return 0;
}

static PyModuleDef_Slot csv_slots[] = {
    _Py_ABI_SLOT,
    {Py_mod_exec, csv_exec},
    {Py_mod_multiple_interpreters, Py_MOD_PER_INTERPRETER_GIL_SUPPORTED},
    {Py_mod_gil, Py_MOD_GIL_NOT_USED},
    {0, NULL}
};

static struct PyModuleDef _csvmodule = {
    PyModuleDef_HEAD_INIT,
    "_csv",
    csv_module_doc,
    sizeof(_csvstate),
    csv_methods,
    csv_slots,
    _csv_traverse,
    _csv_clear,
    _csv_free
};

PyMODINIT_FUNC
PyInit__csv(void)
{
    return PyModuleDef_Init(&_csvmodule);
}
