[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Lua C-API - create two tables parallel
- From: Ervin Hegedüs <airween@...>
- Date: Sat, 7 Oct 2023 11:12:08 +0200
Hi there,
I made a library in C, which parses a special kind of logfile.
The logfile can contain errors (eg. truncated fields). The parser recognizes these errors and can show them. The errors are stored in a structure:
typedef struct mylogerr {
char *errmsg;
size_t *startpos;
size_t *endpos;
} mylogerr;
Each error uses a structure like this, the errors are in a list. The errmsg is a decription of the error, the startpos and endpos show where the error starts and ends.
The library provides a function which iterates over this list:
void read_mylog_err(mylogpool *pool, mylogerr *err);
The library has several bindings, eg. for Python, PHP, Ruby, ... and of cours for Lua.
The errors in the bindings are represented in two lists: first list contains the descriptions, the other contains the indexes, eg:
lineerrors: ['Truncated field', 'Missing field']
lineerrorpos: [[132,135], [212,512]]
Now in Lua binding I was able to make this only by this way:
lua_pushstring(L, "lineerrors");
lua_newtable(L);
int errorstable = lua_gettop(L);
if (l.lineerrcnt > 0) {
// reset errpool ptr
l.lineerrpool.currptr = l.lineerrpool.pool;
mylogerr logerr;
for (int c=0; c < l.lineerrcnt; c++) {
read_mylog_err(&l.lineerrpool, &logerr);
lua_pushinteger(L, c+1);
lua_pushstring(L, logerr.errmsg);
lua_settable(L, errorstable);
}
}
lua_settable(L, maintable);
lua_pushstring(L, "lineerrorspos");
lua_newtable(L);
int errorspostable = lua_gettop(L);
if (l.lineerrcnt > 0) {
// reset errpool ptr
l.lineerrpool.currptr = l.lineerrpool.pool;
mylogerr logerr;
for (int c=0; c < l.lineerrcnt; c++) {
read_mylog_err(&l.lineerrpool, &logerr);
lua_pushinteger(L, c+1);
lua_newtable(L);
subtable = lua_gettop(L);
lua_pushinteger(L, 1);
lua_pushinteger(L, *logerr.startpos);
lua_settable(L, subtable);
lua_pushinteger(L, 2);
lua_pushinteger(L, *logerr.endpos);
lua_settable(L, subtable);
lua_settable(L, errorspostable);
}
}
As you can see I iterate through the list twice, because I don't know how can I handle in two tables parallel.
(This is how this works in Python:
PyObject *errors = PyList_New(0);
PyObject *errorspos = PyList_New(0);
if (l.lineerrcnt > 0) {
// reset errpool ptr
l.lineerrpool.currptr = l.lineerrpool.pool;
mylogerr logerr;
for (int c=0; c < l.lineerrcnt; c++) {
read_mylog_err(&l.lineerrpool, &logerr);
PyList_Append(errors, Py_BuildValue("s", logerr.errmsg));
PyList_Append(errorspos, Py_BuildValue("[k,k]", *logerr.startpos, *logerr.endpos));
}
}
...
PyObject * rv = Py_BuildValue("{s:k,...,s:O,s:O}",
"linelen", l.linelen,
...
"lineerrors", errors,
"lineerrorspos", errorspos
);
)
Is there any more elegant way to handle this?
Thank you,
a.