Created
February 8, 2019 23:51
-
-
Save VehpuS/76e5d6edb3acbd3976daac53c0340dcc to your computer and use it in GitHub Desktop.
A CSV parser in C using the Python csv standard module
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <Python.h> | |
#include <string.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#define bail_null(obj) \ | |
if (NULL == obj) { err = 1; goto bail; } | |
#define bail_require(cond) \ | |
if (!(cond)) { err = 1; goto bail; } | |
static int try_python(const char* dbPath); | |
static int try_python(const char* dbPath) { | |
int err = 0; | |
PyObject *csvModule, *getReader, *dbFile, *reader; | |
PyObject *pArgs, *iterator, *item; | |
char fileName[1000] = {'\0'}; | |
char mode[] = "rbZ"; | |
strncpy(fileName, dbPath, sizeof(fileName)); | |
Py_Initialize(); | |
// https://docs.python.org/2.7/library/csv.html | |
csvModule = PyImport_ImportModule("csv"); | |
bail_null_msg(csvModule, "Failed to import CSV parser modules"); | |
getReader = PyObject_GetAttrString(csvModule, "reader"); | |
bail_null(getReader); | |
bail_require(PyCallable_Check(getReader)); | |
/* getReader is a new reference */ | |
dbFile = PyFile_FromString(fileName, mode); | |
bail_null(dbFile); | |
pArgs = PyTuple_New(1); | |
bail_null(pArgs); | |
PyTuple_SetItem(pArgs, 0, dbFile); | |
reader = PyObject_CallObject(getReader, pArgs); | |
bail_null(reader); | |
bail_require(PyIter_Check(reader)); | |
iterator = PyObject_GetIter(reader); | |
bail_null(iterator); | |
while ((item = PyIter_Next(iterator))) { | |
PyObject* iteratorString = PyObject_Str(item); | |
const char* s = PyString_AsString(iteratorString); | |
printf("%s\n", s); | |
Py_DECREF(iteratorString); | |
Py_DECREF(item); | |
} | |
bail: | |
if (reader) { | |
Py_DECREF(reader); | |
} | |
if (dbFile) { | |
Py_DECREF(dbFile); | |
} | |
if (getReader) { | |
Py_XDECREF(reader); | |
} | |
if (csvModule) { | |
Py_DECREF(csvModule); | |
} | |
if (err) { | |
PyErr_Print(); | |
} | |
Py_Finalize(); | |
return err; | |
} | |
int main(int argc, char *argv[]) { | |
int err = 0; | |
printf("test python CSV parser from C.\n"); | |
if (argc < 2 || NULL == argv[1]) { | |
printf("You need to call this binary with a path to a CSV file.\n\n"); | |
err = 1; | |
} else { | |
err = try_python(argv[1]); | |
} | |
return err; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment