| /* |
| * 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); |
| } |