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
p_neo_error(NEOERR * err)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
p_hdf_dealloc(HDFObject * ho)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
p_hdf_to_object(HDF * data,int dealloc)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
p_object_to_hdf(PyObject * ho)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
p_hdf_init(PyObject * self,PyObject * args)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
p_hdf_get_int_value(PyObject * self,PyObject * args)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
p_hdf_get_value(PyObject * self,PyObject * args)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
p_hdf_get_obj(PyObject * self,PyObject * args)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
p_hdf_get_child(PyObject * self,PyObject * args)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
p_hdf_get_attr(PyObject * self,PyObject * args)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
p_hdf_obj_attr(PyObject * self,PyObject * args)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
p_hdf_obj_child(PyObject * self,PyObject * args)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
p_hdf_obj_next(PyObject * self,PyObject * args)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
p_hdf_obj_top(PyObject * self,PyObject * args)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
p_hdf_obj_name(PyObject * self,PyObject * args)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
p_hdf_obj_value(PyObject * self,PyObject * args)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
p_hdf_set_value(PyObject * self,PyObject * args)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
p_hdf_set_attr(PyObject * self,PyObject * args)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
p_hdf_read_file(PyObject * self,PyObject * args)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
p_hdf_write_file(PyObject * self,PyObject * args)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
p_hdf_write_file_atomic(PyObject * self,PyObject * args)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
p_hdf_remove_tree(PyObject * self,PyObject * args)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
p_hdf_dump(PyObject * self,PyObject * args)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
p_hdf_write_string(PyObject * self,PyObject * args)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
p_hdf_read_string(PyObject * self,PyObject * args)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
p_hdf_copy(PyObject * self,PyObject * args)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
p_hdf_set_symlink(PyObject * self,PyObject * args)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
p_hdf_search_path(PyObject * self,PyObject * args)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
p_escape(PyObject * self,PyObject * args)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
p_unescape(PyObject * self,PyObject * args)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 * */
p_time_expand(PyObject * self,PyObject * args)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
p_time_compact(PyObject * self,PyObject * args)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
p_hdf_value_get_attr(HDFObject * ho,char * name)691 PyObject *p_hdf_value_get_attr (HDFObject *ho, char *name)
692 {
693 return Py_FindMethod(HDFMethods, (PyObject *)ho, name);
694 }
695
initneo_util(void)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