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