Implemented py_input using Python C API and fixed uninitialised value warning.

parent 45ab5b85
......@@ -25,15 +25,27 @@
*/
#include "Python.h"
#include "stdarg.h"
#include <stdarg.h>
#include <stdio.h>
#include <string.h>
#define likely(x) __builtin_expect((x),1)
#define unlikely(x) __builtin_expect((x),0)
static PyObject *py_callback_hook_handler_name;
static PyObject *py_callback_hook_read_after_name;
static PyObject *py_callback_hook_read_before_name;
static PyObject *py_callback_handle_name;
static PyObject *py_callback_hook_name;
static PyObject *py_callback_read_name;
// Construct attribute names (only the first time)
// TODO: where do we Py_DECREF(handle_name) ??
#define INIT_ATTR(variable, name) \
if (unlikely(!variable)) { \
variable = PyString_FromString(name); \
}
/*
* Callback function which is invoked by target handlers within the C yyparse()
......@@ -66,24 +78,16 @@ PyObject* py_callback(PyObject *parser, char *target, int option, int nargs,
va_end(ap);
// Construct attribute names (only the first time)
if (unlikely(!py_callback_handle_name)) {
py_callback_handle_name = PyString_FromString("_handle");
// TODO: where do we Py_DECREF(handle_name) ??
}
if (unlikely(!py_callback_hook_name)) {
py_callback_hook_name = PyString_FromString("hook_handler");
// TODO: where do we Py_DECREF(hook_name) ??
}
INIT_ATTR(py_callback_handle_name, "_handle");
INIT_ATTR(py_callback_hook_handler_name, "hook_handler");
// Call the handler with the arguments
PyObject *handle = PyObject_GetAttr(parser, py_callback_handle_name);
if (unlikely(!handle)) return res;
if (unlikely(!handle)) return NULL;
PyObject *arglist = Py_BuildValue("(siOO)", target, option, names, values);
if (unlikely(!arglist)) { Py_DECREF(handle); return res; }
if (unlikely(!arglist)) { Py_DECREF(handle); return NULL; }
res = PyObject_CallObject(handle, arglist);
......@@ -93,10 +97,10 @@ PyObject* py_callback(PyObject *parser, char *target, int option, int nargs,
if (unlikely(!res)) return res;
// Check if the "hook_handler" callback exists
if (unlikely(!PyObject_HasAttr(parser, py_callback_hook_name)))
if (unlikely(!PyObject_HasAttr(parser, py_callback_hook_handler_name)))
return res;
handle = PyObject_GetAttr(parser, py_callback_hook_name);
handle = PyObject_GetAttr(parser, py_callback_hook_handler_name);
if (unlikely(!handle)) {
Py_DECREF(res);
......@@ -114,3 +118,78 @@ PyObject* py_callback(PyObject *parser, char *target, int option, int nargs,
return res;
}
void py_input(PyObject *parser, char *buf, int *result, int max_size)
{
PyObject *handle, *arglist, *res;
char *bufstr;
INIT_ATTR(py_callback_hook_read_after_name, "hook_read_after");
INIT_ATTR(py_callback_hook_read_before_name, "hook_read_before");
INIT_ATTR(py_callback_read_name, "read");
// Check if the "hook_READ_BEFORE" callback exists
if (unlikely(!PyObject_HasAttr(parser, py_callback_hook_read_before_name)))
{
handle = PyObject_GetAttr(parser, py_callback_hook_read_before_name);
if (unlikely(!handle)) return;
// Call the "hook_READ_BEFORE" callback
arglist = PyTuple_New(0);
if (unlikely(!arglist)) { Py_DECREF(handle); return; }
res = PyObject_CallObject(handle, arglist);
Py_DECREF(handle);
Py_DECREF(arglist);
}
// Read the input string and catch keyboard interrupt exceptions.
handle = PyObject_GetAttr(parser, py_callback_read_name);
if (unlikely(!handle)) {
// TODO: set exception message for missing attribute error
return;
}
arglist = Py_BuildValue("(i)", max_size);
if (unlikely(!arglist)) { Py_DECREF(handle); return; }
res = PyObject_CallObject(handle, arglist);
Py_DECREF(handle);
Py_DECREF(arglist);
if (unlikely(!res)) { return; }
// Check if the "hook_read_after" callback exists
if (unlikely(!PyObject_HasAttr(parser, py_callback_hook_read_after_name)))
goto finish_input;
handle = PyObject_GetAttr(parser, py_callback_hook_read_after_name);
if (unlikely(!handle)) return;
// Call the "hook_READ_AFTER" callback
arglist = Py_BuildValue("(O)", res);
if (unlikely(!arglist)) { Py_DECREF(handle); return; }
res = PyObject_CallObject(handle, arglist);
Py_DECREF(handle);
Py_DECREF(arglist);
if (unlikely(!res)) return;
finish_input:
// Copy the read python input string to the buffer
bufstr = PyString_AsString(res);
*result = strlen(bufstr);
memcpy(buf, bufstr, *result);
// TODO: translate the following code snippet to the Python C aPI
//if buflen == 0 and parser.file:
// # Marks the Python file object as being closed from Python's point of
// # view. This does not close the associated C stream (which is not
// # necessary here, otherwise use "os.close(0)").
// parser.file.close()
}
#include "Python.h"
#include "stdarg.h"
PyObject* py_callback(PyObject *, char *, int option, int nargs,...);
PyObject* py_callback(PyObject *, char *, int, int,...);
void py_input(PyObject *, char *, int *, int);
......@@ -47,7 +47,8 @@ cdef extern from "string.h":
# Callback function which is invoked by target handlers
# within the C yyparse() function.
cdef extern from "../c/bison_callback.h":
object py_callback(object, char *, int option, int nargs,...)
object py_callback(object, char *, int, int,...)
void py_input(object, char *, int *, int)
cdef extern from "../c/bisondynlib.h":
void *bisondynlib_open(char *filename)
......@@ -59,37 +60,6 @@ cdef extern from "../c/bisondynlib.h":
#int bisondynlib_build(char *libName, char *includedir)
# callback routine for reading input
cdef public void py_input(object parser, char *buf, int *result, int max_size):
cdef int buflen
if parser.verbose:
print '\npy_input: want to read up to %s bytes' % max_size
if hasattr(parser, 'hook_read_before'):
parser.hook_read_before()
try:
raw = parser.read(max_size)
except KeyboardInterrupt:
raw = ''
if hasattr(parser, 'hook_read_after'):
raw = parser.hook_read_after(raw)
buflen = PyInt_AsLong(len(raw))
result[0] = buflen
memcpy(buf, PyString_AsString(raw), buflen)
if parser.verbose:
print '\npy_input: got %s bytes' % buflen
if buflen == 0 and parser.file:
# Marks the Python file object as being closed from Python's point of
# view. This does not close the associated C stream (which is not
# necessary here, otherwise use "os.close(0)").
parser.file.close()
import sys, os, sha, re, imp, traceback
import shutil
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment