Home | History | Annotate | Download | only in python
      1 /*
      2  * Copyright 2001-2004 Brandon Long
      3  * All Rights Reserved.
      4  *
      5  * ClearSilver Templating System
      6  *
      7  * This code is made available under the terms of the ClearSilver License.
      8  * http://www.clearsilver.net/license.hdf
      9  *
     10  */
     11 
     12 #include <Python.h>
     13 #include "ClearSilver.h"
     14 
     15 #define NEO_CGI_MODULE
     16 #include "p_neo_util.h"
     17 
     18 static PyObject *NeoError;
     19 static PyObject *NeoParseError;
     20 
     21 PyObject * p_neo_error (NEOERR *err)
     22 {
     23   STRING str;
     24 
     25   string_init (&str);
     26   if (nerr_match(err, NERR_PARSE))
     27   {
     28     nerr_error_string (err, &str);
     29     PyErr_SetString (NeoParseError, str.buf);
     30   }
     31   else
     32   {
     33     nerr_error_traceback (err, &str);
     34     PyErr_SetString (NeoError, str.buf);
     35   }
     36   string_clear (&str);
     37   return NULL;
     38 }
     39 
     40 #define HDFObjectCheck(a) (!(strcmp((a)->ob_type->tp_name, HDFObjectType.tp_name)))
     41 
     42 typedef struct _HDFObject
     43 {
     44    PyObject_HEAD
     45    HDF *data;
     46    int dealloc;
     47 } HDFObject;
     48 
     49 static PyObject *p_hdf_value_get_attr (HDFObject *self, char *name);
     50 static void p_hdf_dealloc (HDFObject *ho);
     51 
     52 static PyTypeObject HDFObjectType = {
     53   PyObject_HEAD_INIT(NULL)
     54     0,			             /*ob_size*/
     55   "HDFObjectType",	             /*tp_name*/
     56   sizeof(HDFObject),	     /*tp_size*/
     57   0,			             /*tp_itemsize*/
     58   /* methods */
     59   (destructor)p_hdf_dealloc,	     /*tp_dealloc*/
     60   0,			             /*tp_print*/
     61   (getattrfunc)p_hdf_value_get_attr,     /*tp_getattr*/
     62   0,			             /*tp_setattr*/
     63   0,			             /*tp_compare*/
     64   (reprfunc)0,                       /*tp_repr*/
     65   0,                                 /* tp_as_number */
     66   0,                                 /* tp_as_sequence */
     67   0,                                 /* tp_as_mapping */
     68   0,                                 /* tp_as_hash */
     69 };
     70 
     71 
     72 static void p_hdf_dealloc (HDFObject *ho)
     73 {
     74   /* ne_warn("deallocating hdf: %X", ho); */
     75   if (ho->data && ho->dealloc)
     76   {
     77     hdf_destroy (&(ho->data));
     78   }
     79   PyObject_DEL(ho);
     80 }
     81 
     82 PyObject * p_hdf_to_object (HDF *data, int dealloc)
     83 {
     84   PyObject *rv;
     85 
     86   if (data == NULL)
     87   {
     88     rv = Py_None;
     89     Py_INCREF (rv);
     90   }
     91   else
     92   {
     93     HDFObject *ho = PyObject_NEW (HDFObject, &HDFObjectType);
     94     if (ho == NULL) return NULL;
     95     ho->data = data;
     96     ho->dealloc = dealloc;
     97     rv = (PyObject *) ho;
     98     /* ne_warn("allocating hdf: %X", ho); */
     99   }
    100   return rv;
    101 }
    102 
    103 HDF * p_object_to_hdf (PyObject *ho)
    104 {
    105   if (HDFObjectCheck(ho))
    106   {
    107     return ((HDFObject *)ho)->data;
    108   }
    109   return NULL;
    110 }
    111 
    112 static PyObject * p_hdf_init (PyObject *self, PyObject *args)
    113 {
    114   HDF *hdf = NULL;
    115   NEOERR *err;
    116 
    117   err = hdf_init (&hdf);
    118   if (err) return p_neo_error (err);
    119   return p_hdf_to_object (hdf, 1);
    120 }
    121 
    122 static PyObject * p_hdf_get_int_value (PyObject *self, PyObject *args)
    123 {
    124   HDFObject *ho = (HDFObject *)self;
    125   PyObject *rv;
    126   char *name;
    127   int r, d = 0;
    128 
    129   if (!PyArg_ParseTuple(args, "si:getIntValue(name, default)", &name, &d))
    130     return NULL;
    131 
    132   r = hdf_get_int_value (ho->data, name, d);
    133   rv = Py_BuildValue ("i", r);
    134   return rv;
    135 }
    136 
    137 static PyObject * p_hdf_get_value (PyObject *self, PyObject *args)
    138 {
    139   HDFObject *ho = (HDFObject *)self;
    140   PyObject *rv;
    141   char *name;
    142   char *r, *d = NULL;
    143 
    144   if (!PyArg_ParseTuple(args, "ss:getValue(name, default)", &name, &d))
    145     return NULL;
    146 
    147   r = hdf_get_value (ho->data, name, d);
    148   rv = Py_BuildValue ("s", r);
    149   return rv;
    150 }
    151 
    152 static PyObject * p_hdf_get_obj (PyObject *self, PyObject *args)
    153 {
    154   HDFObject *ho = (HDFObject *)self;
    155   PyObject *rv;
    156   char *name;
    157   HDF *r;
    158 
    159   if (!PyArg_ParseTuple(args, "s:getObj(name)", &name))
    160     return NULL;
    161 
    162   r = hdf_get_obj (ho->data, name);
    163   if (r == NULL)
    164   {
    165     rv = Py_None;
    166     Py_INCREF(rv);
    167     return rv;
    168   }
    169   rv = p_hdf_to_object (r, 0);
    170   return rv;
    171 }
    172 
    173 static PyObject * p_hdf_get_child (PyObject *self, PyObject *args)
    174 {
    175   HDFObject *ho = (HDFObject *)self;
    176   PyObject *rv;
    177   char *name;
    178   HDF *r;
    179 
    180   if (!PyArg_ParseTuple(args, "s:getChild(name)", &name))
    181     return NULL;
    182 
    183   r = hdf_get_child (ho->data, name);
    184   if (r == NULL)
    185   {
    186     rv = Py_None;
    187     Py_INCREF(rv);
    188     return rv;
    189   }
    190   rv = p_hdf_to_object (r, 0);
    191   return rv;
    192 }
    193 
    194 static PyObject * p_hdf_get_attr (PyObject *self, PyObject *args)
    195 {
    196   HDFObject *ho = (HDFObject *)self;
    197   PyObject *rv, *item;
    198   char *name;
    199   HDF_ATTR *attr;
    200 
    201   if (!PyArg_ParseTuple(args, "s:getAttrs(name)", &name))
    202     return NULL;
    203 
    204   rv = PyList_New(0);
    205   if (rv == NULL) return NULL;
    206   Py_INCREF(rv);
    207   attr = hdf_get_attr (ho->data, name);
    208   while (attr != NULL)
    209   {
    210     item = Py_BuildValue("(s,s)", attr->key, attr->value);
    211     if (item == NULL)
    212     {
    213       Py_DECREF(rv);
    214       return NULL;
    215     }
    216     if (PyList_Append(rv, item) == -1)
    217     {
    218       Py_DECREF(rv);
    219       return NULL;
    220     }
    221     attr = attr->next;
    222   }
    223   return rv;
    224 }
    225 
    226 static PyObject * p_hdf_obj_attr (PyObject *self, PyObject *args)
    227 {
    228   HDFObject *ho = (HDFObject *)self;
    229   PyObject *rv, *item;
    230   HDF_ATTR *attr;
    231 
    232   rv = PyList_New(0);
    233   if (rv == NULL) return NULL;
    234   Py_INCREF(rv);
    235   attr = hdf_obj_attr (ho->data);
    236   while (attr != NULL)
    237   {
    238     item = Py_BuildValue("(s,s)", attr->key, attr->value);
    239     if (item == NULL)
    240     {
    241       Py_DECREF(rv);
    242       return NULL;
    243     }
    244     if (PyList_Append(rv, item) == -1)
    245     {
    246       Py_DECREF(rv);
    247       return NULL;
    248     }
    249     attr = attr->next;
    250   }
    251   return rv;
    252 }
    253 
    254 static PyObject * p_hdf_obj_child (PyObject *self, PyObject *args)
    255 {
    256   HDFObject *ho = (HDFObject *)self;
    257   PyObject *rv;
    258   HDF *r;
    259 
    260   r = hdf_obj_child (ho->data);
    261   if (r == NULL)
    262   {
    263     rv = Py_None;
    264     Py_INCREF(rv);
    265     return rv;
    266   }
    267   rv = p_hdf_to_object (r, 0);
    268   return rv;
    269 }
    270 
    271 static PyObject * p_hdf_obj_next (PyObject *self, PyObject *args)
    272 {
    273   HDFObject *ho = (HDFObject *)self;
    274   PyObject *rv;
    275   HDF *r;
    276 
    277   r = hdf_obj_next (ho->data);
    278   if (r == NULL)
    279   {
    280     rv = Py_None;
    281     Py_INCREF(rv);
    282     return rv;
    283   }
    284   rv = p_hdf_to_object (r, 0);
    285   return rv;
    286 }
    287 
    288 static PyObject * p_hdf_obj_top (PyObject *self, PyObject *args)
    289 {
    290   HDFObject *ho = (HDFObject *)self;
    291   PyObject *rv;
    292   HDF *r;
    293 
    294   r = hdf_obj_top (ho->data);
    295   if (r == NULL)
    296   {
    297     rv = Py_None;
    298     Py_INCREF(rv);
    299     return rv;
    300   }
    301   rv = p_hdf_to_object (r, 0);
    302   return rv;
    303 }
    304 
    305 static PyObject * p_hdf_obj_name (PyObject *self, PyObject *args)
    306 {
    307   HDFObject *ho = (HDFObject *)self;
    308   PyObject *rv;
    309   char *r;
    310 
    311   r = hdf_obj_name (ho->data);
    312   if (r == NULL)
    313   {
    314     rv = Py_None;
    315     Py_INCREF(rv);
    316     return rv;
    317   }
    318   rv = Py_BuildValue ("s", r);
    319   return rv;
    320 }
    321 
    322 static PyObject * p_hdf_obj_value (PyObject *self, PyObject *args)
    323 {
    324   HDFObject *ho = (HDFObject *)self;
    325   PyObject *rv;
    326   char *r;
    327 
    328   r = hdf_obj_value (ho->data);
    329   if (r == NULL)
    330   {
    331     rv = Py_None;
    332     Py_INCREF(rv);
    333     return rv;
    334   }
    335   rv = Py_BuildValue ("s", r);
    336   return rv;
    337 }
    338 
    339 static PyObject * p_hdf_set_value (PyObject *self, PyObject *args)
    340 {
    341   HDFObject *ho = (HDFObject *)self;
    342   PyObject *rv;
    343   char *name, *value;
    344   NEOERR *err;
    345   int nlen = 0;
    346   int vlen = 0;
    347 
    348   if (!PyArg_ParseTuple(args, "s#s#:setValue(name, value)", &name, &nlen, &value, &vlen))
    349     return NULL;
    350 
    351   err = hdf_set_value (ho->data, name, value);
    352   if (err) return p_neo_error(err);
    353 
    354   rv = Py_None;
    355   Py_INCREF(rv);
    356   return rv;
    357 }
    358 
    359 static PyObject * p_hdf_set_attr (PyObject *self, PyObject *args)
    360 {
    361   HDFObject *ho = (HDFObject *)self;
    362   PyObject *rv;
    363   char *name, *value, *key;
    364   NEOERR *err;
    365 
    366   if (!PyArg_ParseTuple(args, "ssO:setAttr(name, key, value)", &name, &key, &rv))
    367     return NULL;
    368 
    369   if (PyString_Check(rv))
    370   {
    371     value = PyString_AsString(rv);
    372   }
    373   else if (rv == Py_None)
    374   {
    375     value = NULL;
    376   }
    377   else
    378   {
    379     return PyErr_Format(PyExc_TypeError, "Invalid type for value, expected None or string");
    380   }
    381   err = hdf_set_attr (ho->data, name, key, value);
    382   if (err) return p_neo_error(err);
    383 
    384   rv = Py_None;
    385   Py_INCREF(rv);
    386   return rv;
    387 }
    388 
    389 static PyObject * p_hdf_read_file (PyObject *self, PyObject *args)
    390 {
    391   HDFObject *ho = (HDFObject *)self;
    392   PyObject *rv;
    393   char *path;
    394   NEOERR *err;
    395 
    396   if (!PyArg_ParseTuple(args, "s:readFile(path)", &path))
    397     return NULL;
    398 
    399   err = hdf_read_file (ho->data, path);
    400   if (err) return p_neo_error(err);
    401 
    402   rv = Py_None;
    403   Py_INCREF(rv);
    404   return rv;
    405 }
    406 
    407 static PyObject * p_hdf_write_file (PyObject *self, PyObject *args)
    408 {
    409   HDFObject *ho = (HDFObject *)self;
    410   PyObject *rv;
    411   char *path;
    412   NEOERR *err;
    413 
    414   if (!PyArg_ParseTuple(args, "s:writeFile(path)", &path))
    415     return NULL;
    416 
    417   err = hdf_write_file (ho->data, path);
    418   if (err) return p_neo_error(err);
    419 
    420   rv = Py_None;
    421   Py_INCREF(rv);
    422   return rv;
    423 }
    424 
    425 static PyObject * p_hdf_write_file_atomic (PyObject *self, PyObject *args)
    426 {
    427   HDFObject *ho = (HDFObject *)self;
    428   PyObject *rv;
    429   char *path;
    430   NEOERR *err;
    431 
    432   if (!PyArg_ParseTuple(args, "s:writeFile(path)", &path))
    433     return NULL;
    434 
    435   err = hdf_write_file_atomic (ho->data, path);
    436   if (err) return p_neo_error(err);
    437 
    438   rv = Py_None;
    439   Py_INCREF(rv);
    440   return rv;
    441 }
    442 
    443 static PyObject * p_hdf_remove_tree (PyObject *self, PyObject *args)
    444 {
    445   HDFObject *ho = (HDFObject *)self;
    446   PyObject *rv;
    447   char *name;
    448   NEOERR *err;
    449 
    450   if (!PyArg_ParseTuple(args, "s:removeTree(name)", &name))
    451     return NULL;
    452 
    453   err = hdf_remove_tree (ho->data, name);
    454   if (err) return p_neo_error(err);
    455 
    456   rv = Py_None;
    457   Py_INCREF(rv);
    458   return rv;
    459 }
    460 
    461 static PyObject * p_hdf_dump (PyObject *self, PyObject *args)
    462 {
    463   HDFObject *ho = (HDFObject *)self;
    464   PyObject *rv;
    465   NEOERR *err;
    466   STRING str;
    467 
    468   string_init (&str);
    469 
    470   err = hdf_dump_str (ho->data, NULL, 0, &str);
    471   if (err) return p_neo_error(err);
    472   rv = Py_BuildValue ("s", str.buf);
    473   string_clear (&str);
    474   return rv;
    475 }
    476 
    477 static PyObject * p_hdf_write_string (PyObject *self, PyObject *args)
    478 {
    479   HDFObject *ho = (HDFObject *)self;
    480   PyObject *rv;
    481   NEOERR *err;
    482   char *s = NULL;
    483 
    484   err = hdf_write_string (ho->data, &s);
    485   if (err) return p_neo_error(err);
    486   rv = Py_BuildValue ("s", s);
    487   if (s) free(s);
    488   return rv;
    489 }
    490 
    491 static PyObject * p_hdf_read_string (PyObject *self, PyObject *args)
    492 {
    493   HDFObject *ho = (HDFObject *)self;
    494   NEOERR *err;
    495   char *s = NULL;
    496   int ignore = 0;
    497 
    498   if (!PyArg_ParseTuple(args, "s|i:readString(string)", &s, &ignore))
    499     return NULL;
    500 
    501   err = hdf_read_string_ignore (ho->data, s, ignore);
    502   if (err) return p_neo_error(err);
    503   Py_INCREF (Py_None);
    504   return Py_None;
    505 }
    506 
    507 static PyObject * p_hdf_copy (PyObject *self, PyObject *args)
    508 {
    509   HDFObject *ho = (HDFObject *)self;
    510   HDF *src = NULL;
    511   PyObject *rv, *o = NULL;
    512   char *name;
    513   NEOERR *err;
    514 
    515   if (!PyArg_ParseTuple(args, "sO:copy(name, src_hdf)", &name, &o))
    516     return NULL;
    517 
    518   src = p_object_to_hdf (o);
    519   if (src == NULL)
    520   {
    521     PyErr_Format(PyExc_TypeError, "second argument must be an HDFObject");
    522     return NULL;
    523   }
    524 
    525   err = hdf_copy (ho->data, name, src);
    526   if (err) return p_neo_error(err);
    527 
    528   rv = Py_None;
    529   Py_INCREF(rv);
    530   return rv;
    531 }
    532 
    533 static PyObject * p_hdf_set_symlink (PyObject *self, PyObject *args)
    534 {
    535   HDFObject *ho = (HDFObject *)self;
    536   PyObject *rv;
    537   char *src;
    538   char *dest;
    539   NEOERR *err;
    540 
    541   if (!PyArg_ParseTuple(args, "ss:setSymLink(src, dest)", &src, &dest))
    542     return NULL;
    543 
    544   err = hdf_set_symlink (ho->data, src, dest);
    545   if (err) return p_neo_error(err);
    546 
    547   rv = Py_None;
    548   Py_INCREF(rv);
    549   return rv;
    550 }
    551 
    552 static PyObject * p_hdf_search_path (PyObject *self, PyObject *args)
    553 {
    554   HDFObject *ho = (HDFObject *)self;
    555   PyObject *rv;
    556   char *path;
    557   char full[_POSIX_PATH_MAX];
    558   NEOERR *err;
    559 
    560   if (!PyArg_ParseTuple(args, "s:searchPath(path)", &path))
    561     return NULL;
    562 
    563   err = hdf_search_path (ho->data, path, full);
    564   if (err) return p_neo_error(err);
    565 
    566   rv = PyString_FromString(full);
    567   return rv;
    568 }
    569 
    570 static PyMethodDef HDFMethods[] =
    571 {
    572   {"getIntValue", p_hdf_get_int_value, METH_VARARGS, NULL},
    573   {"getValue", p_hdf_get_value, METH_VARARGS, NULL},
    574   {"getObj", p_hdf_get_obj, METH_VARARGS, NULL},
    575   {"getChild", p_hdf_get_child, METH_VARARGS, NULL},
    576   {"getAttrs", p_hdf_get_attr, METH_VARARGS, NULL},
    577   {"child", p_hdf_obj_child, METH_VARARGS, NULL},
    578   {"next", p_hdf_obj_next, METH_VARARGS, NULL},
    579   {"name", p_hdf_obj_name, METH_VARARGS, NULL},
    580   {"value", p_hdf_obj_value, METH_VARARGS, NULL},
    581   {"top", p_hdf_obj_top, METH_VARARGS, NULL},
    582   {"attrs", p_hdf_obj_attr, METH_VARARGS, NULL},
    583   {"setValue", p_hdf_set_value, METH_VARARGS, NULL},
    584   {"setAttr", p_hdf_set_attr, METH_VARARGS, NULL},
    585   {"readFile", p_hdf_read_file, METH_VARARGS, NULL},
    586   {"writeFile", p_hdf_write_file, METH_VARARGS, NULL},
    587   {"writeFileAtomic", p_hdf_write_file_atomic, METH_VARARGS, NULL},
    588   {"readString", p_hdf_read_string, METH_VARARGS, NULL},
    589   {"writeString", p_hdf_write_string, METH_VARARGS, NULL},
    590   {"removeTree", p_hdf_remove_tree, METH_VARARGS, NULL},
    591   {"dump", p_hdf_dump, METH_VARARGS, NULL},
    592   {"copy", p_hdf_copy, METH_VARARGS, NULL},
    593   {"setSymLink", p_hdf_set_symlink, METH_VARARGS, NULL},
    594   {"searchPath", p_hdf_search_path, METH_VARARGS, NULL},
    595   {NULL, NULL}
    596 };
    597 
    598 static PyObject * p_escape (PyObject *self, PyObject *args)
    599 {
    600   PyObject *rv;
    601   char *s;
    602   char *escape;
    603   char *esc_char;
    604   int buflen;
    605   char *ret = NULL;
    606   NEOERR *err;
    607 
    608   if (!PyArg_ParseTuple(args, "s#ss:escape(str, char, escape)", &s, &buflen, &esc_char, &escape))
    609     return NULL;
    610 
    611   err = neos_escape(s, buflen, esc_char[0], escape, &ret);
    612   if (err) return p_neo_error(err);
    613 
    614   rv = Py_BuildValue("s", ret);
    615   free(ret);
    616   return rv;
    617 }
    618 
    619 static PyObject * p_unescape (PyObject *self, PyObject *args)
    620 {
    621   PyObject *rv;
    622   char *s;
    623   char *copy;
    624   char *esc_char;
    625   int buflen;
    626 
    627   if (!PyArg_ParseTuple(args, "s#s:unescape(str, char)", &s, &buflen, &esc_char))
    628     return NULL;
    629 
    630   copy = strdup(s);
    631   if (copy == NULL) return PyErr_NoMemory();
    632   neos_unescape(copy, buflen, esc_char[0]);
    633 
    634   rv = Py_BuildValue("s", copy);
    635   free(copy);
    636   return rv;
    637 }
    638 
    639 /* This returns the expanded version in the standard python time tuple
    640  * */
    641 static PyObject * p_time_expand (PyObject *self, PyObject *args)
    642 {
    643   PyObject *rv;
    644   int tt;
    645   struct tm ttm;
    646   char *tz;
    647 
    648   if (!PyArg_ParseTuple(args, "is:time_expand(time_t, timezone string)", &tt, &tz))
    649     return NULL;
    650 
    651   neo_time_expand(tt, tz, &ttm);
    652 
    653   rv = Py_BuildValue("(i,i,i,i,i,i,i,i,i)", ttm.tm_year + 1900, ttm.tm_mon + 1,
    654       ttm.tm_mday, ttm.tm_hour, ttm.tm_min, ttm.tm_sec, ttm.tm_wday, 0, ttm.tm_isdst);
    655   return rv;
    656 }
    657 
    658 static PyObject * p_time_compact (PyObject *self, PyObject *args)
    659 {
    660   PyObject *rv;
    661   int tt;
    662   struct tm ttm;
    663   int junk;
    664   char *tz;
    665 
    666   memset(&ttm, 0, sizeof(struct tm));
    667 
    668   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))
    669     return NULL;
    670 
    671   /* fix up difference between ttm and python tup */
    672   ttm.tm_year -= 1900;
    673   ttm.tm_mon -= 1;
    674 
    675   tt = neo_time_compact (&ttm, tz);
    676 
    677   rv = Py_BuildValue("i", tt);
    678   return rv;
    679 }
    680 
    681 static PyMethodDef UtilMethods[] =
    682 {
    683   {"HDF", p_hdf_init, METH_VARARGS, NULL},
    684   {"escape", p_escape, METH_VARARGS, NULL},
    685   {"unescape", p_unescape, METH_VARARGS, NULL},
    686   {"time_expand", p_time_expand, METH_VARARGS, NULL},
    687   {"time_compact", p_time_compact, METH_VARARGS, NULL},
    688   {NULL, NULL}
    689 };
    690 
    691 PyObject *p_hdf_value_get_attr (HDFObject *ho, char *name)
    692 {
    693   return Py_FindMethod(HDFMethods, (PyObject *)ho, name);
    694 }
    695 
    696 DL_EXPORT(void) initneo_util(void)
    697 {
    698   PyObject *m, *d;
    699 
    700   HDFObjectType.ob_type = &PyType_Type;
    701 
    702   m = Py_InitModule("neo_util", UtilMethods);
    703   d = PyModule_GetDict(m);
    704   NeoError = PyErr_NewException("neo_util.Error", NULL, NULL);
    705   NeoParseError = PyErr_NewException("neo_util.ParseError", NULL, NULL);
    706   PyDict_SetItemString(d, "Error", NeoError);
    707   PyDict_SetItemString(d, "ParseError", NeoParseError);
    708 }
    709