/*
* Copyright 2001-2004 Brandon Long
* All Rights Reserved.
*
* ClearSilver Templating System
*
* This code is made available under the terms of the ClearSilver License.
* http://www.clearsilver.net/license.hdf
*
*/
#include <Python.h>
#include "ClearSilver.h"
#define NEO_CGI_MODULE
#include "p_neo_util.h"
static PyObject *CGIFinishedException;
#define CGIObjectCheck(a) (!(strcmp((a)->ob_type->tp_name, CGIObjectType.tp_name)))
typedef struct _CGIObject
{
PyObject_HEAD
CGI *cgi;
PyObject *hdf;
PyObject *upload_cb;
PyObject *upload_rock;
int upload_error;
} CGIObject;
static PyObject *p_cgi_value_get_attr (CGIObject *self, char *name);
static void p_cgi_dealloc (CGIObject *ho);
PyTypeObject CGIObjectType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"CGIObjectType", /*tp_name*/
sizeof(CGIObject), /*tp_size*/
0, /*tp_itemsize*/
/* methods */
(destructor)p_cgi_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)p_cgi_value_get_attr, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
(reprfunc)0, /*tp_repr*/
0, /* tp_as_number */
0, /* tp_as_sequence */
0, /* tp_as_mapping */
0, /* tp_as_hash */
};
static void p_cgi_dealloc (CGIObject *ho)
{
if (ho->cgi)
{
cgi_destroy (&(ho->cgi));
}
PyObject_DEL(ho);
}
PyObject * p_cgi_to_object (CGI *data)
{
PyObject *rv;
if (data == NULL)
{
rv = Py_None;
Py_INCREF (rv);
}
else
{
CGIObject *ho = PyObject_NEW (CGIObject, &CGIObjectType);
if (ho == NULL) return NULL;
ho->cgi = data;
ho->hdf = p_hdf_to_object (data->hdf, 0);
Py_INCREF(ho->hdf);
rv = (PyObject *) ho;
}
return rv;
}
static PyObject * p_cgi_init (PyObject *self, PyObject *args)
{
CGI *cgi = NULL;
NEOERR *err;
err = cgi_init (&cgi, NULL);
if (err) return p_neo_error (err);
return p_cgi_to_object (cgi);
}
static PyObject * p_cgi_parse (PyObject *self, PyObject *args)
{
CGI *cgi = ((CGIObject *) self)->cgi;
CGIObject *p_cgi = (CGIObject *) self;
PyObject *rv;
NEOERR *err;
p_cgi->upload_error = 0;
err = cgi_parse (cgi);
if (err) return p_neo_error (err);
if (p_cgi->upload_error)
{
p_cgi->upload_error = 0;
return NULL;
}
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static int python_upload_cb (CGI *cgi, int nread, int expected)
{
CGIObject *self = (CGIObject *)(cgi->data);
PyObject *cb, *rock;
PyObject *args, *result;
int r;
/* fprintf(stderr, "upload_cb: %d/%d\n", nread, expected); */
cb = self->upload_cb;
rock = self->upload_rock;
if (cb == NULL) return 0;
args = Py_BuildValue("(Oii)", rock, nread, expected);
if (args == NULL) {
self->upload_error = 1;
return 1;
}
result = PyEval_CallObject(cb, args);
Py_DECREF(args);
if (result != NULL && !PyInt_Check(result)) {
Py_DECREF(result);
result = NULL;
PyErr_SetString(PyExc_TypeError,
"upload_cb () returned non-integer");
self->upload_error = 1;
return 1;
}
r = PyInt_AsLong(result);
Py_DECREF(result);
result = NULL;
return r;
}
static PyObject * p_cgi_set_upload_cb (PyObject *self, PyObject *args)
{
CGI *cgi = ((CGIObject *) self)->cgi;
CGIObject *p_cgi = (CGIObject *) self;
PyObject *rock, *cb;
if (!PyArg_ParseTuple(args, "OO:setUploadCB(rock, func)", &rock, &cb))
return NULL;
cgi->data = self;
cgi->upload_cb = python_upload_cb;
p_cgi->upload_cb = cb;
p_cgi->upload_rock = rock;
p_cgi->upload_error = 0;
Py_INCREF(cb);
Py_INCREF(rock);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject * p_cgi_error (PyObject *self, PyObject *args)
{
CGI *cgi = ((CGIObject *) self)->cgi;
char *s;
PyObject *rv;
if (!PyArg_ParseTuple(args, "s:error(str)", &s))
return NULL;
cgi_error (cgi, s);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_cgi_display (PyObject *self, PyObject *args)
{
CGI *cgi = ((CGIObject *) self)->cgi;
char *file;
PyObject *rv;
NEOERR *err;
if (!PyArg_ParseTuple(args, "s:display(file)", &file))
return NULL;
err = cgi_display (cgi, file);
if (err) return p_neo_error (err);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_cgi_redirect (PyObject *self, PyObject *args)
{
CGI *cgi = ((CGIObject *) self)->cgi;
char *s;
PyObject *rv;
if (!PyArg_ParseTuple(args, "s:redirect(str)", &s))
return NULL;
cgi_redirect (cgi, "%s", s);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_cgi_redirect_uri (PyObject *self, PyObject *args)
{
CGI *cgi = ((CGIObject *) self)->cgi;
char *s;
PyObject *rv;
if (!PyArg_ParseTuple(args, "s:redirectUri(str)", &s))
return NULL;
cgi_redirect_uri (cgi, "%s", s);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_cgi_cookie_authority (PyObject *self, PyObject *args)
{
CGI *cgi = ((CGIObject *) self)->cgi;
char *s, *host;
PyObject *rv;
if (!PyArg_ParseTuple(args, "s:cookieAuthority(host)", &host))
return NULL;
s = cgi_cookie_authority (cgi, host);
if (s == NULL)
{
rv = Py_None;
Py_INCREF(rv);
}
else
{
rv = Py_BuildValue ("s", s);
}
return rv;
}
static PyObject * p_cgi_cookie_set (PyObject *self, PyObject *args,
PyObject *keywds)
{
CGI *cgi = ((CGIObject *) self)->cgi;
char *name, *value, *path = NULL, *domain = NULL, *time_str = NULL;
int persist = 0;
int secure = 0;
NEOERR *err;
static char *kwlist[] = {"name", "value", "path", "domain", "time_str", "persist", "secure", NULL};
if (!PyArg_ParseTupleAndKeywords(args, keywds, "ss|sssii:cookieSet()", kwlist, &name, &value, &path, &domain, &time_str, &persist, &secure))
return NULL;
err = cgi_cookie_set (cgi, name, value, path, domain, time_str, persist, secure);
if (err) return p_neo_error (err);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject * p_cgi_cookie_clear (PyObject *self, PyObject *args)
{
CGI *cgi = ((CGIObject *) self)->cgi;
char *name, *domain = NULL, *path = NULL;
NEOERR *err;
if (!PyArg_ParseTuple(args, "s|ss:cookieClear(name, domain, path)", &name, &domain, &path))
return NULL;
err = cgi_cookie_clear (cgi, name, domain, path);
if (err) return p_neo_error (err);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject * p_cgi_filehandle (PyObject *self, PyObject *args)
{
CGI *cgi = ((CGIObject *) self)->cgi;
char *name;
FILE *fp;
if (!PyArg_ParseTuple(args, "s:filehandle(form_name)", &name))
return NULL;
fp = cgi_filehandle (cgi, name);
if (fp == NULL)
{
Py_INCREF(Py_None);
return Py_None;
}
return PyFile_FromFile (fp, name, "w+", NULL);
}
static PyObject * p_cgi_cs_init (PyObject *self, PyObject *args)
{
CGI *cgi = ((CGIObject *) self)->cgi;
NEOERR *err;
CSPARSE *cs;
if (!PyArg_ParseTuple(args, ":cs()"))
return NULL;
err = cgi_cs_init(cgi, &cs);
if (err) return p_neo_error (err);
return p_cs_to_object(cs);
}
static PyMethodDef CGIMethods[] =
{
#if 0
{"debugInit", p_cgi_debug_init, METH_VARARGS, NULL},
{"wrapInit", p_cgi_wrap_init, METH_VARARGS, NULL},
#endif
{"parse", p_cgi_parse, METH_VARARGS, NULL},
{"setUploadCB", p_cgi_set_upload_cb, METH_VARARGS, NULL},
{"error", p_cgi_error, METH_VARARGS, NULL},
{"display", p_cgi_display, METH_VARARGS, NULL},
{"redirect", p_cgi_redirect, METH_VARARGS, NULL},
{"redirectUri", p_cgi_redirect_uri, METH_VARARGS, NULL},
{"cookieAuthority", p_cgi_cookie_authority, METH_VARARGS, NULL},
{"cookieSet", (PyCFunction)p_cgi_cookie_set, METH_VARARGS|METH_KEYWORDS, NULL},
{"cookieClear", p_cgi_cookie_clear, METH_VARARGS, NULL},
{"filehandle", p_cgi_filehandle, METH_VARARGS, NULL},
{"cs", p_cgi_cs_init, METH_VARARGS, NULL},
{NULL, NULL}
};
static PyObject * p_cgi_url_escape (PyObject *self, PyObject *args)
{
char *s, *esc, *o = NULL;
NEOERR *err;
PyObject *rv;
if (!PyArg_ParseTuple(args, "s|s:urlEscape(str, other=None)", &s, &o))
return NULL;
err = cgi_url_escape_more (s, &esc, o);
if (err) return p_neo_error (err);
rv = Py_BuildValue ("s", esc);
free (esc);
return rv;
}
static PyObject * p_cgi_url_unescape (PyObject *self, PyObject *args)
{
char *s;
PyObject *rv;
char *r;
if (!PyArg_ParseTuple(args, "s:urlUnescape(str)", &s))
return NULL;
r = strdup(s);
if (r == NULL) return PyErr_NoMemory();
cgi_url_unescape (r);
rv = Py_BuildValue ("s", r);
free (r);
return rv;
}
static PyObject * p_html_escape (PyObject *self, PyObject *args)
{
char *s, *esc;
NEOERR *err;
PyObject *rv;
int len;
if (!PyArg_ParseTuple(args, "s#:htmlEscape(str)", &s, &len))
return NULL;
err = html_escape_alloc (s, len, &esc);
if (err) return p_neo_error (err);
rv = Py_BuildValue ("s", esc);
free (esc);
return rv;
}
static PyObject * p_html_strip (PyObject *self, PyObject *args)
{
char *s, *esc;
NEOERR *err;
PyObject *rv;
int len;
if (!PyArg_ParseTuple(args, "s#:htmlStrip(str)", &s, &len))
return NULL;
err = html_strip_alloc (s, len, &esc);
if (err) return p_neo_error (err);
rv = Py_BuildValue ("s", esc);
free (esc);
return rv;
}
static PyObject * p_text_html (PyObject *self, PyObject *args, PyObject *keywds)
{
char *s, *esc;
NEOERR *err;
PyObject *rv;
int len;
HTML_CONVERT_OPTS opts;
static char *kwlist[] = {"text", "bounce_url", "url_class", "url_target", "mailto_class", "long_lines", "space_convert", "newlines_convert", "longline_width", "check_ascii_art", "link_name", NULL};
/* These defaults all come from the old version */
opts.bounce_url = NULL;
opts.url_class = NULL;
opts.url_target = "_blank";
opts.mailto_class = NULL;
opts.long_lines = 0;
opts.space_convert = 0;
opts.newlines_convert = 1;
opts.longline_width = 75; /* This hasn't been used in a while, actually */
opts.check_ascii_art = 1;
opts.link_name = NULL;
if (!PyArg_ParseTupleAndKeywords(args, keywds, "s#|ssssiiiiis:text2html(text)",
kwlist,
&s, &len, &(opts.bounce_url), &(opts.url_class), &(opts.url_target),
&(opts.mailto_class), &(opts.long_lines), &(opts.space_convert),
&(opts.newlines_convert), &(opts.longline_width), &(opts.check_ascii_art), &(opts.link_name)))
return NULL;
err = convert_text_html_alloc_options (s, len, &esc, &opts);
if (err) return p_neo_error (err);
rv = Py_BuildValue ("s", esc);
free (esc);
return rv;
}
PyObject *p_cgi_value_get_attr (CGIObject *ho, char *name)
{
if (!strcmp(name, "hdf"))
{
Py_INCREF(ho->hdf);
return ho->hdf;
}
return Py_FindMethod(CGIMethods, (PyObject *)ho, name);
}
/* Enable wrapping of newlib stdin/stdout output to go through python */
typedef struct wrapper_data
{
PyObject *p_stdin;
PyObject *p_stdout;
PyObject *p_env;
} WRAPPER_DATA;
static WRAPPER_DATA Wrapper = {NULL, NULL, NULL};
static char cgiwrap_doc[] = "cgiwrap(stdin, stdout, env)\nMethod that will cause all cgiwrapped stdin/stdout functions to be redirected to the python stdin/stdout file objects specified. Also redirect getenv/putenv calls (env should be either a python dictionary or os.environ)";
static PyObject * cgiwrap (PyObject *self, PyObject *args)
{
PyObject *p_stdin;
PyObject *p_stdout;
PyObject *p_env;
if (!PyArg_ParseTuple(args, "OOO:cgiwrap(stdin, stdout, env)", &p_stdin, &p_stdout, &p_env))
return NULL;
if (p_stdin != Py_None)
{
if (Wrapper.p_stdin != NULL)
{
Py_DECREF (Wrapper.p_stdin);
}
Wrapper.p_stdin = p_stdin;
Py_INCREF (Wrapper.p_stdin);
}
if (p_stdout != Py_None)
{
if (Wrapper.p_stdout != NULL)
{
Py_DECREF (Wrapper.p_stdout);
}
Wrapper.p_stdout = p_stdout;
Py_INCREF (Wrapper.p_stdout);
}
if (p_env != Py_None)
{
if (Wrapper.p_env != NULL)
{
Py_DECREF (Wrapper.p_env);
}
Wrapper.p_env = p_env;
Py_INCREF (Wrapper.p_env);
}
Py_INCREF(Py_None);
return Py_None;
}
static int p_writef (void *data, const char *fmt, va_list ap)
{
WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
PyObject *str;
char *buf;
int len;
int err;
buf = vsprintf_alloc(fmt, ap);
len = visprintf_alloc(&buf, fmt, ap);
if (buf == NULL)
return 0;
str = PyString_FromStringAndSize (buf, len);
free(buf);
err = PyFile_WriteObject(str, wrap->p_stdout, Py_PRINT_RAW);
Py_DECREF(str);
if (err == 0)
{
PyErr_Clear();
return len;
}
PyErr_Clear();
return err;
}
static int p_write (void *data, const char *buf, int len)
{
WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
PyObject *s;
int err;
s = PyString_FromStringAndSize (buf, len);
err = PyFile_WriteObject(s, wrap->p_stdout, Py_PRINT_RAW);
Py_DECREF(s);
if (err == 0)
{
PyErr_Clear();
return len;
}
PyErr_Clear();
return err;
}
/* Similar to the PyFile_GetLine function, this one invokes read on the
* file object */
static PyObject *PyFile_Read (PyObject *f, int n)
{
if (f == NULL)
{
PyErr_BadInternalCall();
return NULL;
}
/* If this was in the python fileobject code, we could handle this
* directly for builtin file objects. Oh well. */
/* if (!PyFile_Check(f))*/
else
{
PyObject *reader;
PyObject *args;
PyObject *result;
reader = PyObject_GetAttrString(f, "read");
if (reader == NULL)
return NULL;
if (n <= 0)
args = Py_BuildValue("()");
else
args = Py_BuildValue("(i)", n);
if (args == NULL) {
Py_DECREF(reader);
return NULL;
}
result = PyEval_CallObject(reader, args);
Py_DECREF(reader);
Py_DECREF(args);
if (result != NULL && !PyString_Check(result)) {
Py_DECREF(result);
result = NULL;
PyErr_SetString(PyExc_TypeError,
"object.read() returned non-string");
}
return result;
}
}
static int p_read (void *data, char *ptr, int len)
{
WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
PyObject *buf;
char *s;
buf = PyFile_Read (wrap->p_stdin, len);
if (buf == NULL)
{
PyErr_Clear();
return -1;
}
len = PyString_Size(buf);
s = PyString_AsString(buf);
memcpy (ptr, s, len);
Py_DECREF(buf);
PyErr_Clear();
return len;
}
/* We can't really have an error return from this (and the other
* cgiwrap) function, because the API doesn't have an error return,
* and if we get back to python, the error will occur at the next random
* place that python actually checks for errors independent of an error
* return. Not the best way to do things, but its what we've got. Some
* of these we can check for in cgiWrap() */
static char *p_getenv (void *data, const char *s)
{
WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
PyObject *get;
PyObject *args = NULL;
PyObject *result;
char *ret = NULL;
get = PyObject_GetAttrString(wrap->p_env, "__getitem__");
if (get != NULL)
{
args = Py_BuildValue("(s)", s);
if (args == NULL) {
Py_DECREF(get);
PyErr_Clear();
return NULL;
}
}
else
{
/* Python 1.5.2 and earlier don't have __getitem__ on the standard
* dict object, so we'll just use get for them */
get = PyObject_GetAttrString(wrap->p_env, "get");
if (get != NULL)
{
args = Py_BuildValue("(s,O)", s, Py_None);
if (args == NULL)
{
Py_DECREF(get);
PyErr_Clear();
return NULL;
}
}
}
if (get == NULL)
{
ne_warn("Unable to get __getitem__ from env");
PyErr_Clear();
return NULL;
}
result = PyEval_CallObject(get, args);
Py_DECREF(get);
Py_DECREF(args);
if (result != NULL && !PyString_Check(result) && (result != Py_None))
{
Py_DECREF(result);
result = NULL;
PyErr_SetString(PyExc_TypeError,
"env.get() returned non-string");
}
if (result != NULL && result != Py_None)
{
ret = strdup (PyString_AsString(result));
Py_DECREF (result);
}
PyErr_Clear();
return ret;
}
static int p_iterenv (void *data, int x, char **rk, char **rv)
{
WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
PyObject *items;
PyObject *env_list;
PyObject *result;
PyObject *k, *v;
items = PyObject_GetAttrString(wrap->p_env, "items");
if (items == NULL)
{
ne_warn ("p_iterenv: Unable to get items method");
PyErr_Clear();
return -1;
}
env_list = PyEval_CallObject(items, NULL);
Py_DECREF(items);
if (env_list == NULL)
{
ne_warn ("p_iterenv: Unable to call items method");
PyErr_Clear();
return -1;
}
if (x >= PyList_Size(env_list))
{
*rk = NULL;
*rv = NULL;
Py_DECREF(env_list);
return 0;
}
result = PyList_GetItem (env_list, x);
if (result == NULL)
{
ne_warn ("p_iterenv: Unable to get env %d", x);
Py_DECREF(env_list);
PyErr_Clear();
return -1;
}
k = PyTuple_GetItem (result, 0);
v = PyTuple_GetItem (result, 1);
if (k == NULL || v == NULL)
{
ne_warn ("p_iterenv: Unable to get k,v %p,%p", k, v);
Py_DECREF(env_list);
PyErr_Clear();
return -1;
}
*rk = strdup(PyString_AsString(k));
*rv = strdup(PyString_AsString(v));
if (*rk == NULL || *rv == NULL)
{
if (*rk) free (*rk);
if (*rv) free (*rv);
Py_DECREF(env_list);
PyErr_Clear();
return -1;
}
Py_DECREF(env_list);
PyErr_Clear();
return 0;
}
static int p_putenv (void *data, const char *k, const char *v)
{
WRAPPER_DATA *wrap = (WRAPPER_DATA *)data;
PyObject *set;
PyObject *args;
PyObject *result;
if (k == NULL || v == NULL) return -1;
set = PyObject_GetAttrString(wrap->p_env, "__setitem__");
if (set == NULL)
{
PyErr_Clear();
return -1;
}
args = Py_BuildValue("(s,s)", k, v);
if (args == NULL) {
Py_DECREF(set);
PyErr_Clear();
return -1;
}
result = PyEval_CallObject(set, args);
Py_DECREF(set);
Py_DECREF(args);
if (result == NULL)
{
PyErr_Clear();
return -1;
}
Py_DECREF(result);
PyErr_Clear();
return 0;
}
static void p_cgiwrap_init(PyObject *m)
{
PyObject *sys, *os, *p_stdin, *p_stdout, *args, *p_env;
#if 0
PyObject *argv;
int x;
#endif
/* Set up the python wrapper
* This might not be enough to actually continue to point to
* sys.stdin/sys.stdout, we'd probably have to actually do the lookup
* every time... if we need that functionality
*/
sys = PyImport_ImportModule("sys");
os = PyImport_ImportModule("os");
if (sys)
{
p_stdin = PyObject_GetAttrString(sys, "stdin");
p_stdout = PyObject_GetAttrString(sys, "stdout");
#if 0
argv = PyObject_GetAttrString(sys, "argv");
if (argv)
{
Argc = PyList_Size (argv);
if (Argc != -1)
{
Argv = (char **) malloc (sizeof (char *) * (Argc+1));
for (x = 0; x < Argc; x++)
{
PyObject *a;
char *b;
a = PyList_GetItem (argv, x);
if (a == NULL)
break;
b = PyString_AsString(a);
if (b == NULL)
break;
Argv[x] = b;
}
Argv[x] = NULL;
}
}
#endif
if (os)
{
p_env = PyObject_GetAttrString(os, "environ");
}
else
{
Py_INCREF(Py_None);
p_env = Py_None;
}
args = Py_BuildValue("(O,O,O)", p_stdin, p_stdout, p_env);
if (args)
{
cgiwrap_init_emu (&Wrapper, p_read, p_writef, p_write, p_getenv, p_putenv, p_iterenv);
cgiwrap (m, args);
Py_DECREF(args);
}
}
}
static PyObject * p_ignore (PyObject *self, PyObject *args)
{
int i = 0;
if (!PyArg_ParseTuple(args, "i:IgnoreEmptyFormVars(bool)", &i))
return NULL;
IgnoreEmptyFormVars = i;
Py_INCREF(Py_None);
return Py_None;
}
static PyObject * p_export_date (PyObject *self, PyObject *args)
{
NEOERR *err;
PyObject *ho;
int i = 0;
char *prefix;
char *timezone;
HDF *hdf;
if (!PyArg_ParseTuple(args, "Ossi:exportDate(hdf, prefix, timezone, time_t)", &ho, &prefix, &timezone, &i))
return NULL;
hdf = p_object_to_hdf (ho);
if (hdf == NULL)
{
PyErr_SetString(PyExc_TypeError, "First argument must be an HDF Object");
return NULL;
}
err = export_date_time_t (hdf, prefix, timezone, i);
if (err) return p_neo_error (err);
Py_INCREF(Py_None);
return Py_None;
}
static PyObject * p_update (PyObject *self, PyObject *args)
{
if (_PyImport_FindExtension("neo_util","neo_util") == NULL)
initneo_util();
if (_PyImport_FindExtension("neo_cs","neo_cs") == NULL)
initneo_cs();
Py_INCREF(Py_None);
return Py_None;
}
static PyMethodDef ModuleMethods[] =
{
{"CGI", p_cgi_init, METH_VARARGS, NULL},
{"urlEscape", p_cgi_url_escape, METH_VARARGS, NULL},
{"urlUnescape", p_cgi_url_unescape, METH_VARARGS, NULL},
{"htmlEscape", p_html_escape, METH_VARARGS, NULL},
{"htmlStrip", p_html_strip, METH_VARARGS, NULL},
{"text2html", (PyCFunction)p_text_html, METH_VARARGS|METH_KEYWORDS, NULL},
{"cgiWrap", cgiwrap, METH_VARARGS, cgiwrap_doc},
{"IgnoreEmptyFormVars", p_ignore, METH_VARARGS, NULL},
{"exportDate", p_export_date, METH_VARARGS, NULL},
{"update", p_update, METH_VARARGS, NULL},
{NULL, NULL}
};
DL_EXPORT(void) initneo_cgi(void)
{
PyObject *m, *d;
static void *NEO_PYTHON_API[P_NEO_CGI_POINTERS];
PyObject *c_api_object;
CGIObjectType.ob_type = &PyType_Type;
initneo_util();
_PyImport_FixupExtension("neo_util", "neo_util");
initneo_cs();
_PyImport_FixupExtension("neo_cs", "neo_cs");
m = Py_InitModule("neo_cgi", ModuleMethods);
p_cgiwrap_init (m);
d = PyModule_GetDict(m);
CGIFinishedException = PyErr_NewException("neo_cgi.CGIFinished", NULL, NULL);
PyDict_SetItemString(d, "CGIFinished", CGIFinishedException);
/* Initialize the C API Pointer array */
NEO_PYTHON_API[P_HDF_TO_OBJECT_NUM] = (void *)p_hdf_to_object;
NEO_PYTHON_API[P_OBJECT_TO_HDF_NUM] = (void *)p_object_to_hdf;
NEO_PYTHON_API[P_NEO_ERROR_NUM] = (void *)p_neo_error;
/* create a CObject containing the API pointer array's address */
c_api_object = PyCObject_FromVoidPtr((void *)NEO_PYTHON_API, NULL);
if (c_api_object != NULL) {
/* create a name for this object in the module's namespace */
PyDict_SetItemString(d, "_C_API", c_api_object);
Py_DECREF(c_api_object);
PyDict_SetItemString(d, "_C_API_NUM", PyInt_FromLong(P_NEO_CGI_POINTERS));
}
}