/*
* 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 *NeoError;
static PyObject *NeoParseError;
PyObject * p_neo_error (NEOERR *err)
{
STRING str;
string_init (&str);
if (nerr_match(err, NERR_PARSE))
{
nerr_error_string (err, &str);
PyErr_SetString (NeoParseError, str.buf);
}
else
{
nerr_error_traceback (err, &str);
PyErr_SetString (NeoError, str.buf);
}
string_clear (&str);
return NULL;
}
#define HDFObjectCheck(a) (!(strcmp((a)->ob_type->tp_name, HDFObjectType.tp_name)))
typedef struct _HDFObject
{
PyObject_HEAD
HDF *data;
int dealloc;
} HDFObject;
static PyObject *p_hdf_value_get_attr (HDFObject *self, char *name);
static void p_hdf_dealloc (HDFObject *ho);
static PyTypeObject HDFObjectType = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"HDFObjectType", /*tp_name*/
sizeof(HDFObject), /*tp_size*/
0, /*tp_itemsize*/
/* methods */
(destructor)p_hdf_dealloc, /*tp_dealloc*/
0, /*tp_print*/
(getattrfunc)p_hdf_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_hdf_dealloc (HDFObject *ho)
{
/* ne_warn("deallocating hdf: %X", ho); */
if (ho->data && ho->dealloc)
{
hdf_destroy (&(ho->data));
}
PyObject_DEL(ho);
}
PyObject * p_hdf_to_object (HDF *data, int dealloc)
{
PyObject *rv;
if (data == NULL)
{
rv = Py_None;
Py_INCREF (rv);
}
else
{
HDFObject *ho = PyObject_NEW (HDFObject, &HDFObjectType);
if (ho == NULL) return NULL;
ho->data = data;
ho->dealloc = dealloc;
rv = (PyObject *) ho;
/* ne_warn("allocating hdf: %X", ho); */
}
return rv;
}
HDF * p_object_to_hdf (PyObject *ho)
{
if (HDFObjectCheck(ho))
{
return ((HDFObject *)ho)->data;
}
return NULL;
}
static PyObject * p_hdf_init (PyObject *self, PyObject *args)
{
HDF *hdf = NULL;
NEOERR *err;
err = hdf_init (&hdf);
if (err) return p_neo_error (err);
return p_hdf_to_object (hdf, 1);
}
static PyObject * p_hdf_get_int_value (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *name;
int r, d = 0;
if (!PyArg_ParseTuple(args, "si:getIntValue(name, default)", &name, &d))
return NULL;
r = hdf_get_int_value (ho->data, name, d);
rv = Py_BuildValue ("i", r);
return rv;
}
static PyObject * p_hdf_get_value (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *name;
char *r, *d = NULL;
if (!PyArg_ParseTuple(args, "ss:getValue(name, default)", &name, &d))
return NULL;
r = hdf_get_value (ho->data, name, d);
rv = Py_BuildValue ("s", r);
return rv;
}
static PyObject * p_hdf_get_obj (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *name;
HDF *r;
if (!PyArg_ParseTuple(args, "s:getObj(name)", &name))
return NULL;
r = hdf_get_obj (ho->data, name);
if (r == NULL)
{
rv = Py_None;
Py_INCREF(rv);
return rv;
}
rv = p_hdf_to_object (r, 0);
return rv;
}
static PyObject * p_hdf_get_child (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *name;
HDF *r;
if (!PyArg_ParseTuple(args, "s:getChild(name)", &name))
return NULL;
r = hdf_get_child (ho->data, name);
if (r == NULL)
{
rv = Py_None;
Py_INCREF(rv);
return rv;
}
rv = p_hdf_to_object (r, 0);
return rv;
}
static PyObject * p_hdf_get_attr (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv, *item;
char *name;
HDF_ATTR *attr;
if (!PyArg_ParseTuple(args, "s:getAttrs(name)", &name))
return NULL;
rv = PyList_New(0);
if (rv == NULL) return NULL;
Py_INCREF(rv);
attr = hdf_get_attr (ho->data, name);
while (attr != NULL)
{
item = Py_BuildValue("(s,s)", attr->key, attr->value);
if (item == NULL)
{
Py_DECREF(rv);
return NULL;
}
if (PyList_Append(rv, item) == -1)
{
Py_DECREF(rv);
return NULL;
}
attr = attr->next;
}
return rv;
}
static PyObject * p_hdf_obj_attr (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv, *item;
HDF_ATTR *attr;
rv = PyList_New(0);
if (rv == NULL) return NULL;
Py_INCREF(rv);
attr = hdf_obj_attr (ho->data);
while (attr != NULL)
{
item = Py_BuildValue("(s,s)", attr->key, attr->value);
if (item == NULL)
{
Py_DECREF(rv);
return NULL;
}
if (PyList_Append(rv, item) == -1)
{
Py_DECREF(rv);
return NULL;
}
attr = attr->next;
}
return rv;
}
static PyObject * p_hdf_obj_child (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
HDF *r;
r = hdf_obj_child (ho->data);
if (r == NULL)
{
rv = Py_None;
Py_INCREF(rv);
return rv;
}
rv = p_hdf_to_object (r, 0);
return rv;
}
static PyObject * p_hdf_obj_next (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
HDF *r;
r = hdf_obj_next (ho->data);
if (r == NULL)
{
rv = Py_None;
Py_INCREF(rv);
return rv;
}
rv = p_hdf_to_object (r, 0);
return rv;
}
static PyObject * p_hdf_obj_top (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
HDF *r;
r = hdf_obj_top (ho->data);
if (r == NULL)
{
rv = Py_None;
Py_INCREF(rv);
return rv;
}
rv = p_hdf_to_object (r, 0);
return rv;
}
static PyObject * p_hdf_obj_name (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *r;
r = hdf_obj_name (ho->data);
if (r == NULL)
{
rv = Py_None;
Py_INCREF(rv);
return rv;
}
rv = Py_BuildValue ("s", r);
return rv;
}
static PyObject * p_hdf_obj_value (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *r;
r = hdf_obj_value (ho->data);
if (r == NULL)
{
rv = Py_None;
Py_INCREF(rv);
return rv;
}
rv = Py_BuildValue ("s", r);
return rv;
}
static PyObject * p_hdf_set_value (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *name, *value;
NEOERR *err;
int nlen = 0;
int vlen = 0;
if (!PyArg_ParseTuple(args, "s#s#:setValue(name, value)", &name, &nlen, &value, &vlen))
return NULL;
err = hdf_set_value (ho->data, name, value);
if (err) return p_neo_error(err);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_hdf_set_attr (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *name, *value, *key;
NEOERR *err;
if (!PyArg_ParseTuple(args, "ssO:setAttr(name, key, value)", &name, &key, &rv))
return NULL;
if (PyString_Check(rv))
{
value = PyString_AsString(rv);
}
else if (rv == Py_None)
{
value = NULL;
}
else
{
return PyErr_Format(PyExc_TypeError, "Invalid type for value, expected None or string");
}
err = hdf_set_attr (ho->data, name, key, value);
if (err) return p_neo_error(err);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_hdf_read_file (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *path;
NEOERR *err;
if (!PyArg_ParseTuple(args, "s:readFile(path)", &path))
return NULL;
err = hdf_read_file (ho->data, path);
if (err) return p_neo_error(err);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_hdf_write_file (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *path;
NEOERR *err;
if (!PyArg_ParseTuple(args, "s:writeFile(path)", &path))
return NULL;
err = hdf_write_file (ho->data, path);
if (err) return p_neo_error(err);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_hdf_write_file_atomic (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *path;
NEOERR *err;
if (!PyArg_ParseTuple(args, "s:writeFile(path)", &path))
return NULL;
err = hdf_write_file_atomic (ho->data, path);
if (err) return p_neo_error(err);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_hdf_remove_tree (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *name;
NEOERR *err;
if (!PyArg_ParseTuple(args, "s:removeTree(name)", &name))
return NULL;
err = hdf_remove_tree (ho->data, name);
if (err) return p_neo_error(err);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_hdf_dump (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
NEOERR *err;
STRING str;
string_init (&str);
err = hdf_dump_str (ho->data, NULL, 0, &str);
if (err) return p_neo_error(err);
rv = Py_BuildValue ("s", str.buf);
string_clear (&str);
return rv;
}
static PyObject * p_hdf_write_string (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
NEOERR *err;
char *s = NULL;
err = hdf_write_string (ho->data, &s);
if (err) return p_neo_error(err);
rv = Py_BuildValue ("s", s);
if (s) free(s);
return rv;
}
static PyObject * p_hdf_read_string (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
NEOERR *err;
char *s = NULL;
int ignore = 0;
if (!PyArg_ParseTuple(args, "s|i:readString(string)", &s, &ignore))
return NULL;
err = hdf_read_string_ignore (ho->data, s, ignore);
if (err) return p_neo_error(err);
Py_INCREF (Py_None);
return Py_None;
}
static PyObject * p_hdf_copy (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
HDF *src = NULL;
PyObject *rv, *o = NULL;
char *name;
NEOERR *err;
if (!PyArg_ParseTuple(args, "sO:copy(name, src_hdf)", &name, &o))
return NULL;
src = p_object_to_hdf (o);
if (src == NULL)
{
PyErr_Format(PyExc_TypeError, "second argument must be an HDFObject");
return NULL;
}
err = hdf_copy (ho->data, name, src);
if (err) return p_neo_error(err);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_hdf_set_symlink (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *src;
char *dest;
NEOERR *err;
if (!PyArg_ParseTuple(args, "ss:setSymLink(src, dest)", &src, &dest))
return NULL;
err = hdf_set_symlink (ho->data, src, dest);
if (err) return p_neo_error(err);
rv = Py_None;
Py_INCREF(rv);
return rv;
}
static PyObject * p_hdf_search_path (PyObject *self, PyObject *args)
{
HDFObject *ho = (HDFObject *)self;
PyObject *rv;
char *path;
char full[_POSIX_PATH_MAX];
NEOERR *err;
if (!PyArg_ParseTuple(args, "s:searchPath(path)", &path))
return NULL;
err = hdf_search_path (ho->data, path, full);
if (err) return p_neo_error(err);
rv = PyString_FromString(full);
return rv;
}
static PyMethodDef HDFMethods[] =
{
{"getIntValue", p_hdf_get_int_value, METH_VARARGS, NULL},
{"getValue", p_hdf_get_value, METH_VARARGS, NULL},
{"getObj", p_hdf_get_obj, METH_VARARGS, NULL},
{"getChild", p_hdf_get_child, METH_VARARGS, NULL},
{"getAttrs", p_hdf_get_attr, METH_VARARGS, NULL},
{"child", p_hdf_obj_child, METH_VARARGS, NULL},
{"next", p_hdf_obj_next, METH_VARARGS, NULL},
{"name", p_hdf_obj_name, METH_VARARGS, NULL},
{"value", p_hdf_obj_value, METH_VARARGS, NULL},
{"top", p_hdf_obj_top, METH_VARARGS, NULL},
{"attrs", p_hdf_obj_attr, METH_VARARGS, NULL},
{"setValue", p_hdf_set_value, METH_VARARGS, NULL},
{"setAttr", p_hdf_set_attr, METH_VARARGS, NULL},
{"readFile", p_hdf_read_file, METH_VARARGS, NULL},
{"writeFile", p_hdf_write_file, METH_VARARGS, NULL},
{"writeFileAtomic", p_hdf_write_file_atomic, METH_VARARGS, NULL},
{"readString", p_hdf_read_string, METH_VARARGS, NULL},
{"writeString", p_hdf_write_string, METH_VARARGS, NULL},
{"removeTree", p_hdf_remove_tree, METH_VARARGS, NULL},
{"dump", p_hdf_dump, METH_VARARGS, NULL},
{"copy", p_hdf_copy, METH_VARARGS, NULL},
{"setSymLink", p_hdf_set_symlink, METH_VARARGS, NULL},
{"searchPath", p_hdf_search_path, METH_VARARGS, NULL},
{NULL, NULL}
};
static PyObject * p_escape (PyObject *self, PyObject *args)
{
PyObject *rv;
char *s;
char *escape;
char *esc_char;
int buflen;
char *ret = NULL;
NEOERR *err;
if (!PyArg_ParseTuple(args, "s#ss:escape(str, char, escape)", &s, &buflen, &esc_char, &escape))
return NULL;
err = neos_escape(s, buflen, esc_char[0], escape, &ret);
if (err) return p_neo_error(err);
rv = Py_BuildValue("s", ret);
free(ret);
return rv;
}
static PyObject * p_unescape (PyObject *self, PyObject *args)
{
PyObject *rv;
char *s;
char *copy;
char *esc_char;
int buflen;
if (!PyArg_ParseTuple(args, "s#s:unescape(str, char)", &s, &buflen, &esc_char))
return NULL;
copy = strdup(s);
if (copy == NULL) return PyErr_NoMemory();
neos_unescape(copy, buflen, esc_char[0]);
rv = Py_BuildValue("s", copy);
free(copy);
return rv;
}
/* This returns the expanded version in the standard python time tuple
* */
static PyObject * p_time_expand (PyObject *self, PyObject *args)
{
PyObject *rv;
int tt;
struct tm ttm;
char *tz;
if (!PyArg_ParseTuple(args, "is:time_expand(time_t, timezone string)", &tt, &tz))
return NULL;
neo_time_expand(tt, tz, &ttm);
rv = Py_BuildValue("(i,i,i,i,i,i,i,i,i)", ttm.tm_year + 1900, ttm.tm_mon + 1,
ttm.tm_mday, ttm.tm_hour, ttm.tm_min, ttm.tm_sec, ttm.tm_wday, 0, ttm.tm_isdst);
return rv;
}
static PyObject * p_time_compact (PyObject *self, PyObject *args)
{
PyObject *rv;
int tt;
struct tm ttm;
int junk;
char *tz;
memset(&ttm, 0, sizeof(struct tm));
if (!PyArg_ParseTuple(args, "(i,i,i,i,i,i,i,i,i)s:time_compact(time tuple, timezone string)", &ttm.tm_year, &ttm.tm_mon, &ttm.tm_mday, &ttm.tm_hour, &ttm.tm_min, &ttm.tm_sec, &ttm.tm_wday, &junk, &ttm.tm_isdst, &tz))
return NULL;
/* fix up difference between ttm and python tup */
ttm.tm_year -= 1900;
ttm.tm_mon -= 1;
tt = neo_time_compact (&ttm, tz);
rv = Py_BuildValue("i", tt);
return rv;
}
static PyMethodDef UtilMethods[] =
{
{"HDF", p_hdf_init, METH_VARARGS, NULL},
{"escape", p_escape, METH_VARARGS, NULL},
{"unescape", p_unescape, METH_VARARGS, NULL},
{"time_expand", p_time_expand, METH_VARARGS, NULL},
{"time_compact", p_time_compact, METH_VARARGS, NULL},
{NULL, NULL}
};
PyObject *p_hdf_value_get_attr (HDFObject *ho, char *name)
{
return Py_FindMethod(HDFMethods, (PyObject *)ho, name);
}
DL_EXPORT(void) initneo_util(void)
{
PyObject *m, *d;
HDFObjectType.ob_type = &PyType_Type;
m = Py_InitModule("neo_util", UtilMethods);
d = PyModule_GetDict(m);
NeoError = PyErr_NewException("neo_util.Error", NULL, NULL);
NeoParseError = PyErr_NewException("neo_util.ParseError", NULL, NULL);
PyDict_SetItemString(d, "Error", NeoError);
PyDict_SetItemString(d, "ParseError", NeoParseError);
}