source: trunk/python/Rappture/PyRpLibrary.cc @ 808

Last change on this file since 808 was 808, checked in by dkearney, 14 years ago

allow the user to create a new empty rappture library object in c++ and python bindings. this is useful when you want to create new xml files.

File size: 31.0 KB
Line 
1/*
2 * ======================================================================
3 *  AUTHOR:  Derrick S. Kearney, Purdue University
4 *  Copyright (c) 2004-2007  Purdue Research Foundation
5 *
6 *  See the file "license.terms" for information on usage and
7 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
8 * ======================================================================
9 */
10#include <Python.h>
11#include <RpLibrary.h>
12
13
14static PyObject *ErrorObject;
15RpLibrary* RpLibraryObject_AsLibrary(PyObject *lib);
16static PyObject* RpLibraryObject_FromLibrary(RpLibrary *lib);
17int boolAsInt(const char* inVal, int* outVal);
18int boolIntFromPyObject ( PyObject* inPyObj, const char* defaultVal,
19                            const char* argName, int* boolVal);
20int getArgCount ( PyObject* args, PyObject* keywds, int* argc);
21
22typedef struct {
23    PyObject_HEAD
24    RpLibrary* lib;
25} RpLibraryObject;
26
27/*
28 * Check to see if this object is a Rappture.library object.
29 * This does not check to see if the object is correctly
30 * initialized. To check for correct object type and
31 * correct initialization, use RpLibraryObject_IsValid.
32 */
33
34int
35RpLibraryObject_Check(PyObject *o)
36{
37    int retval = 0;
38
39    if (o != NULL) {
40        if (    (*(o->ob_type->tp_name) == 'R')
41             && (strcmp(o->ob_type->tp_name,"Rappture.library") == 0) ) {
42            retval = 1;
43        }
44    }
45
46    return retval;
47}
48
49/*
50 * Check to see if this object is a Rappture.library object
51 * and is correctly initialized
52 *
53 * This function calls RpLibraryObject_Check internally, and is used
54 * in most of the internal functions to check if an object being passed
55 * in by the user is a valid Rappture.library object
56 */
57
58int
59RpLibraryObject_IsValid(PyObject *o)
60{
61    int retval = 0;
62
63    if (o != NULL) {
64        if (RpLibraryObject_Check(o)) {
65            if ( ((RpLibraryObject *)o)->lib != NULL ) {
66                retval = 1;
67            }
68        }
69    }
70
71    return retval;
72}
73
74static PyObject*
75RpLibraryObject_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
76{
77    RpLibraryObject *self = NULL;
78
79    self = (RpLibraryObject *)type->tp_alloc(type,0);
80    if (self != NULL) {
81        self->lib = NULL;
82    }
83    else {
84        PyErr_SetString(PyExc_RuntimeError,"trouble creating new RpLibraryObject");
85    }
86
87    return (PyObject *)self;
88}
89
90static int
91RpLibraryObject_init(RpLibraryObject *self, PyObject *args, PyObject *kwds)
92{
93    PyObject *inObj = NULL;
94    char *filename = NULL;
95    int retVal = 1;
96
97    if (!PyArg_ParseTuple(args, "|O", &inObj)) {
98        PyErr_Format(PyExc_TypeError,
99            "library() takes at most 1 argument, a file name or a Rappture Library Object");
100        return -1;
101    }
102
103    if (inObj != NULL) {
104        if (PyString_Check(inObj)) {
105            filename = PyString_AsString(inObj);
106            if (filename == NULL) {
107                PyErr_Format(PyExc_ValueError,"a file name is required");
108            }
109            self->lib = new RpLibrary(std::string(filename));
110        }
111        else if (RpLibraryObject_IsValid(inObj)) {
112            self->lib = new RpLibrary( *(RpLibraryObject_AsLibrary(inObj)) );
113        }
114        else if (RpLibraryObject_Check(inObj)) {
115            self->lib = new RpLibrary();
116        }
117        else {
118            PyErr_Format(PyExc_TypeError,"unrecognized object type");
119            return -1;
120        }
121    }
122    else {
123        self->lib = new RpLibrary();
124    }
125
126    return retVal;
127}
128
129static void
130RpLibraryObject_dealloc(RpLibraryObject *self)
131{
132    if (self) {
133        if (self->lib){
134            delete(self->lib);
135        }
136        self->ob_type->tp_free((PyObject*) self);
137    }
138}
139
140PyDoc_STRVAR(RpLibraryObject_copy_doc,
141"copy (topath, frompath [, fromobj=$self]) -> None, copies data\n\
142\n\
143Copy an xml element to \'topath\' of the current this object\n\
144from \'frompath\' of the Rappture Library Object \'fromobj\'.\n\
145\n\
146\'topath\' is the path (in this object) where the data should\n\
147be copied to\n\
148\'frompath\' is an path (in fromobj) where the data should be\n\
149copied from\n\
150\'fromobj\' is the Rappture Library Object to copy the data from\n\
151if fromobj is not set, the data is copied from the same object\n\
152the data will be copied to (this object).\n\
153\n\
154");
155
156static PyObject*
157RpLibraryObject_copy(RpLibraryObject *self, PyObject *args, PyObject *keywds)
158{
159    char *topath = "";
160    char *frompath = "";
161    int argc = 0;
162    int status = 0;
163    PyObject *fromobj = (PyObject *) self;
164
165    static char *kwlist[] = {"topath","frompath","fromobj", NULL};
166
167    if (self->lib == NULL) {
168        PyErr_SetString(PyExc_RuntimeError,
169            "self is uninitialized Rappture Library Object");
170        return NULL;
171    }
172
173    status = getArgCount(args,keywds,&argc);
174    if (status != 0) {
175        // trouble ensues
176        // error message was set in getArgCount()
177        return NULL;
178    }
179
180    if (argc > 3) {
181        // tested with CopyTests.testArguments_TooManyArgs()
182        PyErr_Format(PyExc_TypeError,
183            "copy() takes at most 3 arguments (%i given)",argc);
184        return NULL;
185    }
186
187    if (argc < 2) {
188        // tested with CopyTests.testArguments_NotEnoughArgs()
189        PyErr_Format(PyExc_TypeError,
190            "copy() takes at least 2 arguments (%i given)",argc);
191        return NULL;
192    }
193
194    if (!PyArg_ParseTupleAndKeywords(args, keywds, "ss|O",
195            kwlist, &topath, &frompath, &fromobj)) {
196        // tested with CopyTests.testArguments_ArgsWrongType2()
197        PyErr_Format(PyExc_TypeError,
198            "copy() takes 2 sting and 1 Rappture Library Object as arguments");
199        return NULL;
200    }
201
202    if (!RpLibraryObject_IsValid(fromobj)) {
203        // tested with CopyTests.testArguments_ArgsWrongType3()
204        PyErr_SetString(PyExc_RuntimeError,
205            "incorrectly initialized Rappture Library Object");
206        return NULL;
207    }
208
209    self->lib->copy(std::string(topath),
210        RpLibraryObject_AsLibrary(fromobj),
211        std::string(frompath));
212
213    Py_RETURN_NONE;
214}
215
216PyDoc_STRVAR(RpLibraryObject_element_doc,
217"element ([path=\'\'][, as=\'object\']) -> returns string or Rappture Library Object\n\
218\n\
219Clients use this to query a particular element within the \n\
220entire data structure.  The path is a string of the form \n\
221\"structure.box(source).corner\".  This example represents \n\
222the tag <corner> within a tag <box id=\"source\"> within a \n\
223a tag <structure>, which must be found at the top level \n\
224within this document. \n\
225\n\
226By default, this method returns an object representing the \n\
227DOM node referenced by the path.  This is changed by setting \n\
228the \"as\" argument to \"id\" (for name of the tail element), \n\
229to \"type\" (for the type of the tail element), to \"component\" \n\
230(for the component name \"type(id)\"), or to \"object\" \n\
231for the default (an object representing the tail element).\n\
232");
233
234static PyObject*
235RpLibraryObject_element(RpLibraryObject *self, PyObject *args, PyObject *keywds)
236{
237    char* path = "";
238    char* as = "object";
239    RpLibrary* retlib = NULL;
240    PyObject* retVal = NULL;
241    int argc = 0;
242    int status = 0;
243
244    static char *kwlist[] = {"path", "as", NULL};
245
246    if (self->lib == NULL) {
247        PyErr_Format(PyExc_RuntimeError,
248            "self is uninitialized Rappture Library Object");
249        return retVal;
250    }
251
252    status = getArgCount(args,keywds,&argc);
253    if (status != 0) {
254        // trouble ensues
255        // error message was set in getArgCount()
256        return NULL;
257    }
258
259    if (argc > 2) {
260        // tested with ElementTests.testArguments_TooManyArgs()
261        PyErr_Format(PyExc_TypeError,
262            "element() takes at most 2 arguments (%i given)", argc);
263        return retVal;
264    }
265
266    if (!PyArg_ParseTupleAndKeywords(args, keywds, "|ss",
267                kwlist, &path, &as)) {
268        /* incorrect input values */
269        // tested with ElementTests.testArguments_ArgsWrongType2()
270        PyErr_Format(PyExc_TypeError,"element ([path=\'\'][, as=\'object\'])");
271        return retVal;
272    }
273
274    retlib = self->lib->element(std::string(path));
275
276    if (retlib != NULL) {
277        if (   (as == NULL)
278            || ((*as == 'o') && (strcmp("object",as) == 0)) ) {
279            // tested with ElementTests.testArguments_PathArg()
280            retVal = RpLibraryObject_FromLibrary(retlib);
281        }
282        else if ((*as == 'c') && (strcmp("component",as) == 0)) {
283            // tested with ElementTests.testArguments_TwoArgs()
284            retVal = PyString_FromString(retlib->nodeComp().c_str());
285        }
286        else if ((*as == 'i') && (strcmp("id",as) == 0)) {
287            // tested with ElementTests.testArguments_AsId()
288            retVal = PyString_FromString(retlib->nodeId().c_str());
289        }
290        else if ((*as == 't') && (strcmp("type",as) == 0)) {
291            // tested with ElementTests.testArguments_AsKeywordArgs()
292            retVal = PyString_FromString(retlib->nodeType().c_str());
293        }
294        else if ((*as == 'p') && (strcmp("path",as) == 0)) {
295            // tested with ElementTests.testArguments_TwoKeywordArgs()
296            retVal = PyString_FromString(retlib->nodePath().c_str());
297        }
298        else {
299            // tested with ElementTests.testArguments_UnrecognizedAs()
300            PyErr_Format(PyExc_ValueError,
301                "element() \'as\' arg must be \'object\' or \'component\' or \'id\' or \'type\' or \'path\'");
302        }
303    }
304
305    return (PyObject *)retVal;
306}
307
308
309PyDoc_STRVAR(RpLibraryObject_get_doc,
310"get ([path=\'\'][, decode=\'True\']) -> returns data at \'path\' as string\n\
311\n\
312Clients use this to query the value of a node.  If the path\n\
313is not specified, it returns the value associated with the\n\
314root node.  Otherwise, it returns the value for the element\n\
315specified by the path.\n\
316");
317
318static PyObject*
319RpLibraryObject_get(RpLibraryObject *self, PyObject *args, PyObject *keywds)
320{
321    char* path = "";
322
323    PyObject* decode = NULL;
324    int decodeVal = 0;
325
326    PyObject* retVal = NULL;
327    std::string retValStr = "";
328    Rappture::Buffer retValBuf;
329
330    int argc = 0;
331    int status = 0;
332
333    static char *kwlist[] = {"path","decode", NULL};
334
335    if (self->lib == NULL) {
336        PyErr_SetString(PyExc_RuntimeError,
337            "self uninitialized Rappture Library Object");
338        return NULL;
339    }
340
341    status = getArgCount(args,keywds,&argc);
342    if (status != 0) {
343        // trouble ensues
344        // error message was set in getArgCount()
345        return NULL;
346    }
347
348    if (argc > 2) {
349        // tested with GetTests.testArguments_TooManyArgs()
350        PyErr_Format(PyExc_TypeError,
351            "get() takes at most 2 arguments (%i given)",argc);
352        return NULL;
353    }
354
355    if (!PyArg_ParseTupleAndKeywords(args, keywds, "|sO",
356            kwlist, &path, &decode)) {
357        // tested with GetTests.testArguments_ArgsWrongType2()
358        PyErr_Format(PyExc_TypeError,"get ([path=\'\'][, decode=\'True\'])");
359        return NULL;
360    }
361
362    status = boolIntFromPyObject(decode,"yes","decode",&decodeVal);
363    if (status != 0) {
364        // tested with GetTests.testArgumentsDecodeError()
365        return NULL;
366    }
367
368    if (decodeVal == 1) {
369        // tested with GetTests.testArgumentsDecode()
370        // tested with GetTests.testArgumentsDecodeYes()
371        // tested with GetTests.testArgumentsDecodeTrue)
372        // tested with GetTests.testArgumentsDecodeOn()
373        // tested with GetTests.testArgumentsDecode1Str()
374        // tested with GetTests.testArgumentsDecode1Int()
375        retValStr = self->lib->get(std::string(path));
376        retVal = PyString_FromStringAndSize(retValStr.c_str(),retValStr.size());
377    }
378    else {
379        // tested with GetTests.testArgumentsNoDecodeNo()
380        // tested with GetTests.testArgumentsNoDecodeFalse()
381        // tested with GetTests.testArgumentsNoDecodeOff()
382        // tested with GetTests.testArgumentsNoDecode0Str()
383        // tested with GetTests.testArgumentsNoDecode0Int()
384        retValBuf = self->lib->getData(std::string(path));
385        retVal = PyString_FromStringAndSize(retValBuf.bytes(),retValBuf.size());
386    }
387
388    return (PyObject *)retVal;
389}
390
391PyDoc_STRVAR(RpLibraryObject_parent_doc,
392"parent ([path=\'\'][, as=\'object\']) -> returns string or Rappture Library Object\n\
393\n\
394Clients use this to query the parent of a particular element \n\
395This is just like the \'element()\' method, but it returns the parent \n\
396of the element instead of the element itself. \n\
397\n\
398By default, this method returns an object representing the \n\
399DOM node referenced by the path.  This is changed by setting \n\
400the \"as\" argument to \"id\" (for name of the tail element), \n\
401to \"type\" (for the type of the tail element), to \"component\" \n\
402(for the component name \"type(id)\"), or to \"object\" \n\
403for the default (an object representing the tail element).\n\
404");
405
406static PyObject*
407RpLibraryObject_parent(RpLibraryObject *self, PyObject *args, PyObject *keywds)
408{
409    char* path = "";
410    char* as = "object";
411    RpLibrary* retlib = NULL;
412    PyObject* retVal = NULL;
413    int argc = 0;
414    int status = 0;
415
416    static char *kwlist[] = {"path", "as", NULL};
417
418    status = getArgCount(args,keywds,&argc);
419    if (status != 0) {
420        // trouble ensues
421        // error message was set in getArgCount()
422        return NULL;
423    }
424
425    if (argc > 3) {
426        PyErr_SetString(PyExc_TypeError,"parent() takes at most 2 arguments");
427        return NULL;
428    }
429
430    if (!PyArg_ParseTupleAndKeywords(args, keywds, "|ss",
431            kwlist, &path, &as)) {
432        /* incorrect input values */
433        PyErr_SetString(PyExc_TypeError,"parent ([path=\'\'][, as=\'object\'])");
434        return NULL;
435    }
436
437    if (self->lib) {
438        retlib = self->lib->parent(std::string(path));
439    }
440    else {
441        PyErr_SetString(PyExc_RuntimeError,
442            "incorrectly initialized Rappture Library Object");
443        return NULL;
444    }
445
446    if (retlib != NULL) {
447        if (   (as == NULL)
448            || ((*as == 'o') && (strcmp("object",as) == 0))
449           ) {
450            retVal = RpLibraryObject_FromLibrary(retlib);
451        }
452        else if ((*as == 'c') && (strcmp("component",as) == 0)) {
453            retVal = PyString_FromString(retlib->nodeComp().c_str());
454        }
455        else if ((*as == 'i') && (strcmp("id",as) == 0)) {
456            retVal = PyString_FromString(retlib->nodeId().c_str());
457        }
458        else if ((*as == 't') && (strcmp("type",as) == 0)) {
459            retVal = PyString_FromString(retlib->nodeType().c_str());
460        }
461        else if ((*as == 'p') && (strcmp("path",as) == 0)) {
462            retVal = PyString_FromString(retlib->nodePath().c_str());
463        }
464        else {
465            PyErr_Format(PyExc_ValueError,
466                "parent() \'as\' arg must be \'object\' or \'component\' or \'id\' or \'type\' or \'path\'");
467        }
468    }
469
470    return (PyObject *)retVal;
471}
472
473PyDoc_STRVAR(RpLibraryObject_put_doc,
474"put (path=\'\', value=\'\'[,id=None][,append=False][,type=\'string\'][,compress=False]) -> None\n\
475\n\
476Clients use this to set the value of a node.  If the path\n\
477is not specified, it sets the value for the root node.\n\
478Otherwise, it sets the value for the element specified\n\
479by the path.  If the value is a string, then it is treated\n\
480as the text within the tag at the tail of the path.  If it\n\
481is a DOM node or a library, then it is inserted into the\n\
482tree at the specified path.\n\
483\n\
484The optional id input has no effect and is available for\n\
485backwards compatibility.\n\
486\n\
487If the optional append flag is specified, then the value\n\
488is appended to the current value. Otherwise, the value\n\
489replaces the current value.\n\
490\n\
491The optional type flag specifies whether the value should be\n\
492treated as string data (type=\"string\"), or the name of a\n\
493file (type=\"file\"). The default behavior is to treat the\n\
494value as string data.\n\
495\n\
496If the optional compress flag is specified, then the append\n\
497flag will be evaluated upon the data at path and the result\n\
498will be compressed.\n\
499");
500
501static PyObject*
502RpLibraryObject_put(RpLibraryObject *self, PyObject *args, PyObject *keywds)
503{
504    char *path = "";
505
506    PyObject *value = NULL;
507    PyObject *valueStrObj = NULL;
508    char *value_char = NULL;
509    int value_len = 0;
510
511    char *id = NULL;
512
513    PyObject* append = NULL;
514    int appendInt = 0;
515
516    char *type = "string";
517
518    PyObject* compress = NULL;
519    int compressInt = 0;
520
521    int argc = 0;
522    int status = 0;
523
524    static char *kwlist[] = {"path","value","id","append",
525                                "type","compress", NULL};
526
527    if (self->lib == NULL) {
528        PyErr_Format(PyExc_RuntimeError,
529            "self uninitialized Rappture Library Object");
530        return NULL;
531    }
532
533    status = getArgCount(args,keywds,&argc);
534    if (status != 0) {
535        // trouble ensues
536        // error message was set in getArgCount()
537        return NULL;
538    }
539
540    if (argc > 6) {
541        // tested with PutTests.testArguments_TooManyArgs()
542        PyErr_Format(PyExc_TypeError,
543            "put() takes at most 6 arguments (%i given)",argc);
544        return NULL;
545    }
546
547    if (argc < 2) {
548        // tested with PutTests.testArguments_NotEnoughArgs()
549        PyErr_Format(PyExc_TypeError,
550            "put() takes at least 2 arguments (%i given)",argc);
551        return NULL;
552    }
553
554    if (!PyArg_ParseTupleAndKeywords(args, keywds, "sO|sOsO",
555            kwlist, &path, &value, &id, &append, &type, &compress)) {
556        // tested with PutTests.testArguments_ArgsWrongType2()
557        PyErr_Format(PyExc_TypeError, "incorrect arguments: put(path=\'\',value=\'\'[,id=None][,append=False][,type=\'string\'][,compress=False])");
558        return NULL;
559    }
560
561    if (value == NULL) {
562        PyErr_Format(PyExc_ValueError, "put()'s \'value\' arg is required");
563        return NULL;
564    }
565
566    valueStrObj = PyObject_Str(value);
567
568    status = boolIntFromPyObject(append,"no","append",&appendInt);
569    if (status != 0) {
570        // error message set inside of boolIntFromPyObject
571        // tested with PutTests.testArguments_AppendValError()
572        return NULL;
573    }
574    status = boolIntFromPyObject(compress,"no","compress",&compressInt);
575    if (status != 0) {
576        // error message set inside of boolIntFromPyObject
577        // tested with PutTests.testArguments_CompressValError()
578        return NULL;
579    }
580
581    if (RpLibraryObject_IsValid(value)) {
582        // tested with PutTests.testPutObject()
583        self->lib->put( std::string(path),
584                        RpLibraryObject_AsLibrary(value), "", appendInt);
585    }
586    else if (valueStrObj != NULL) {
587
588        if (PyString_AsStringAndSize(valueStrObj, &value_char, &value_len) == -1) {
589            // user passed in an improper string
590            // exception raised within fxn
591            return NULL;
592        }
593
594        if (   ( type == NULL )
595            || ( (*type == 's') && (strcmp("string", type) == 0) ) ) {
596            if (compress == 0) {
597                // tested with PutTests.testArgumentsCheckAppend()
598                // tested with PutTests.testArgumentsCheckAppendYes()
599                self->lib->put( std::string(path),
600                                std::string(value_char), "", appendInt);
601            }
602            else {
603                // tested with PutTests.testArgumentsCheckTypeStringCompressYes()
604                self->lib->putData( std::string(path),
605                                    value_char, value_len, appendInt);
606            }
607        }
608        else if ( (*type == 'f') && (strcmp("file",type) == 0) ) {
609            // tested with PutTests.testArgumentsCheckTypeFile()
610            // tested with PutTests.testArgumentsCheckTypeFileCompressTrue()
611            // tested with PutTests.testArgumentsCheckTypeFileCompressTrueNoDecode()
612            self->lib->putFile( std::string(path),
613                                std::string(PyString_AsString(valueStrObj)),
614                                compressInt,appendInt);
615        }
616        else {
617            // tested with PutTests.testArgumentsCheckTypeError()
618            PyErr_Format(PyExc_ValueError,
619                "\'type\' arg must be \'string\' or \'file\'");
620            return NULL;
621        }
622    }
623    else {
624        PyErr_Format(PyExc_TypeError,
625            "put()'s \'value\' arg must be a string or Rappture Library Object");
626        return NULL;
627    }
628
629    Py_RETURN_NONE;
630}
631
632PyDoc_STRVAR(RpLibraryObject_xml_doc,
633"xml () -> returns xml string\n\
634\n\
635Clients use this to query the XML representation for this\n\
636object.\n\
637");
638
639static PyObject*
640RpLibraryObject_xml(RpLibraryObject *self)
641{
642    PyObject *retStr = NULL;
643
644    if (self->lib == NULL) {
645        PyErr_Format(PyExc_RuntimeError,
646            "self uninitialized Rappture Library Object");
647    }
648
649    retStr = PyString_FromString(self->lib->xml().c_str());
650
651    return (PyObject *)retStr;
652}
653
654PyDoc_STRVAR(RpLibraryObject_result_doc,
655"result ([status=0]) -> None, send results back to graphical user interface\n\
656\n\
657Use this function to report the result of a Rappture simulation.\n\
658Pass in the optional exit status. Default is 0\n\
659");
660
661static PyObject*
662RpLibraryObject_result(RpLibraryObject *self, PyObject *args, PyObject *keywds)
663{
664    int argc = 0;
665    int status = 0;
666
667    static char *kwlist[] = {"status", NULL};
668
669    if (self->lib == NULL) {
670        PyErr_Format(PyExc_RuntimeError,
671            "self uninitialized Rappture Library Object");
672        return NULL;
673    }
674
675    status = getArgCount(args,keywds,&argc);
676    if (status != 0) {
677        // trouble ensues
678        // error message was set in getArgCount()
679        return NULL;
680    }
681
682    if (argc > 2) {
683        PyErr_Format(PyExc_TypeError,
684            "result() takes at most 1 argument (%i given)",argc);
685        return NULL;
686    }
687
688    if (!PyArg_ParseTupleAndKeywords(args, keywds, "|i", kwlist, &status)) {
689        // tested with ResultTests.testArguments_InvalidStatusArg()
690        PyErr_Format(PyExc_TypeError, "an integer is required");
691        return NULL;
692    }
693
694    self->lib->put("tool.version.rappture.language","python");
695    self->lib->result(status);
696
697    Py_RETURN_NONE;
698}
699
700static PyMethodDef RpLibraryObject_methods[] = {
701
702    {"copy", (PyCFunction)RpLibraryObject_copy, METH_VARARGS|METH_KEYWORDS,
703        RpLibraryObject_copy_doc},
704
705/*
706    {"children", (PyCFunction)RpLibraryObject_children, METH_VARARGS|METH_KEYWORDS,
707        RpLibraryObject_children_doc},
708*/
709
710    {"element", (PyCFunction)RpLibraryObject_element, METH_VARARGS|METH_KEYWORDS,
711        RpLibraryObject_element_doc},
712
713    {"get", (PyCFunction)RpLibraryObject_get, METH_VARARGS|METH_KEYWORDS,
714        RpLibraryObject_get_doc},
715
716/*
717    {"parent", (PyCFunction)RpLibraryObject_parent, METH_VARARGS|METH_KEYWORDS,
718        RpLibraryObject_put_doc},
719*/
720
721    {"put", (PyCFunction)RpLibraryObject_put, METH_VARARGS|METH_KEYWORDS,
722        RpLibraryObject_put_doc},
723
724/*
725    {"remove", (PyCFunction)RpLibraryObject_remove, METH_VARARGS|METH_KEYWORDS,
726        RpLibraryObject_remove_doc},
727*/
728
729    {"xml", (PyCFunction)RpLibraryObject_xml, METH_NOARGS,
730        RpLibraryObject_xml_doc},
731
732    {"result", (PyCFunction)RpLibraryObject_result, METH_VARARGS|METH_KEYWORDS,
733        RpLibraryObject_result_doc},
734
735    {NULL,        NULL}        /* sentinel */
736};
737
738static PyTypeObject RpLibraryObjectType = {
739    /* The ob_type field must be initialized in the module init function
740     * to be portable to Windows without using C++. */
741    PyObject_HEAD_INIT(NULL)
742    0,                                    /*ob_size*/
743    "Rappture.library",                   /*tp_name*/
744    sizeof(RpLibraryObject),              /*tp_basicsize*/
745    0,                                    /*tp_itemsize*/
746    /* methods */
747    (destructor)RpLibraryObject_dealloc,  /*tp_dealloc*/
748    0,                                    /*tp_print*/
749    0,                                    /*tp_getattr*/
750    0,                                    /*tp_setattr*/
751    0,                                    /*tp_compare*/
752    0,                                    /*tp_repr*/
753    0,                                    /*tp_as_number*/
754    0,                                    /*tp_as_sequence*/
755    0,                                    /*tp_as_mapping*/
756    0,                                    /*tp_hash*/
757    0,                                    /*tp_call*/
758    0,                                    /*tp_str*/
759    0,                                    /*tp_getattro*/
760    0,                                    /*tp_setattro*/
761    0,                                    /*tp_as_buffer*/
762    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,   /*tp_flags*/
763    "Rappture.library Object",            /*tp_doc*/
764    0,                                    /*tp_traverse*/
765    0,                                    /*tp_clear*/
766    0,                                    /*tp_richcompare*/
767    0,                                    /*tp_weaklistoffset*/
768    0,                                    /*tp_iter*/
769    0,                                    /*tp_iternext*/
770    RpLibraryObject_methods,              /* tp_methods */
771    0,                                    /*tp_members*/
772    0,                                    /*tp_getset*/
773    0,                                    /*tp_base*/
774    0,                                    /*tp_dict*/
775    0,                                    /*tp_descr_get*/
776    0,                                    /*tp_descr_set*/
777    0,                                    /*tp_dictoffset*/
778    (initproc)RpLibraryObject_init,       /*tp_init*/
779    0,                                    /*tp_alloc*/
780    RpLibraryObject_new,                  /*tp_new*/
781    0,                                    /*tp_new*/
782};
783
784/*
785 * used to create a RpLibrary object from a PyObject
786 */
787RpLibrary*
788RpLibraryObject_AsLibrary(PyObject *lib)
789{
790    RpLibrary* retval = NULL;
791
792    if (lib != NULL) {
793        if (RpLibraryObject_IsValid(lib)) {
794            retval = ((RpLibraryObject *)lib)->lib;
795        }
796    }
797    return retval;
798}
799
800/*
801 * used to create a PyObject from a RpLibrary object
802 */
803PyObject*
804RpLibraryObject_FromLibrary(RpLibrary *lib)
805{
806    RpLibraryObject *self = NULL;
807
808    if (lib != NULL) {
809        self = PyObject_New(RpLibraryObject, &RpLibraryObjectType);
810        if (self != NULL) {
811            self->lib = lib;
812        }
813        else {
814            // raise error
815            PyErr_SetString(PyExc_RuntimeError,
816                            "trouble creating new RpLibraryObject");
817        }
818    }
819
820    return (PyObject *)self;
821}
822
823/*
824 *  int boolAsInt (inVal, outVal)
825 *
826 *  represent a boolean string as an integer.
827 *
828 *  outVal set to 1 if the boolean value inVal could
829 *  be associated with any of the following strings:
830 *  "yes", "on", "true", "1".
831 *
832 *  outVal set to 0 if the boolean value inVal could
833 *  be associated with any of the following strings:
834 *  "no", "off", "false", "0".
835 *
836 *  returns a status integer to tell if the operation
837 *  was successful (0) of if there was an error (!0)
838 *
839 *  note: string comparisons are case insensitive.
840 */
841
842int
843boolAsInt(const char* inVal, int* outVal)
844{
845    int len = 0;
846    int lcv = 0;
847    int status = 1;
848    char boolVal[7] = "\0\0\0\0\0\0";
849
850    if ( (inVal == NULL) || (outVal == NULL) ) {
851        PyErr_Format(PyExc_TypeError,"incorrect use of boolAsInt(inVal,outVal)");
852        return status;
853    }
854
855    len = strlen(inVal);
856
857    if (len > 5) {
858        PyErr_Format(PyExc_ValueError,
859            "unrecognized input: %s: should be one of: \'yes\',\'true\',\'on\',\'1\',1,True,\'no\',\'false\',\'off\',\'0\',0,False",boolVal);
860        return status;
861    }
862
863    for (lcv = 0; lcv < len; lcv++) {
864        boolVal[lcv] = tolower(inVal[lcv]);
865    }
866
867    if (
868        ((*boolVal == 'y') && (strcmp("yes",boolVal) == 0))  ||
869        ((*boolVal == 't') && (strcmp("true",boolVal) == 0)) ||
870        ((*boolVal == 'o') && (strcmp("on",boolVal) == 0)) ||
871        ((*boolVal == '1') && (strcmp("1",boolVal) == 0)) ) {
872
873        status = 0;
874        *outVal = 1;
875    }
876    else if (
877        ((*boolVal == 'n') && (strcmp("no",boolVal) == 0))  ||
878        ((*boolVal == 'f') && (strcmp("false",boolVal) == 0)) ||
879        ((*boolVal == 'o') && (strcmp("off",boolVal) == 0)) ||
880        ((*boolVal == '0') && (strcmp("0",boolVal) == 0)) ) {
881
882        status = 0;
883        *outVal = 0;
884    }
885    else {
886        PyErr_Format(PyExc_ValueError,
887            "unrecognized input: %s: should be one of: \'yes\',\'true\',\'on\',\'1\',1,True,\'no\',\'false\',\'off\',\'0\',0,False",boolVal);
888        status = 1;
889    }
890
891    return status;
892}
893
894int
895boolIntFromPyObject (
896    PyObject* inPyObj,
897    const char* defaultVal,
898    const char* argName,
899    int* boolVal
900    )
901{
902    int status = -1;
903    PyObject* inStrObj = NULL;
904    char* inStr = NULL;
905
906    if (    (defaultVal == NULL) ||
907            (argName == NULL) ||
908            (boolVal == NULL)
909        ) {
910        // incorrect use of function
911        PyErr_Format(PyExc_ValueError,
912            "boolIntFromPyObject(): defaultVal or argName or boolVal is NULL");
913        return status;
914    }
915
916    if (inPyObj != NULL) {
917        inStrObj = PyObject_Str(inPyObj);
918        if (inStrObj == NULL) {
919            PyErr_Format(PyExc_TypeError,
920                "bad value: %s: no string representation",argName);
921            return status;
922        }
923
924        inStr = PyString_AsString(inStrObj);
925        if (inStr == NULL) {
926            PyErr_Format(PyExc_TypeError,
927                "bad value: %s: cannot convert to string",argName);
928            return status;
929        }
930    }
931
932    if (inStr != NULL) {
933        status = boolAsInt(inStr,boolVal);
934    }
935    else {
936        status = boolAsInt(defaultVal,boolVal);
937    }
938
939    return status;
940}
941
942int getArgCount (
943    PyObject* args,
944    PyObject* keywds,
945    int* argc
946    )
947{
948    int status = 1;
949    int args_cnt = 0;
950    int keywds_cnt = 0;
951
952    if (argc == NULL) {
953        // incorrect use of function
954        // argc cannot be null
955        PyErr_Format(PyExc_ValueError,"getArgCount(): argc is NULL");
956        return status;
957    }
958
959    if (args != NULL) {
960        if (!PyTuple_Check(args)) {
961            PyErr_Format(PyExc_TypeError,
962                "getArgCount(): \'args\' should be a PyTuple");
963            return status;
964        }
965        args_cnt = PyTuple_Size(args);
966    }
967
968    if (keywds != NULL) {
969        if (!PyDict_Check(keywds)) {
970            PyErr_Format(PyExc_TypeError,
971                "getArgCount(): \'keywds\' should be a PyDict");
972            return status;
973        }
974        keywds_cnt = PyDict_Size(keywds);
975    }
976
977    *argc = args_cnt + keywds_cnt;
978    status = 0;
979
980    return status;
981}
982
983/* ---------- */
984
985/* List of functions defined in the module */
986
987static PyMethodDef Library_Methods[] = {
988    {NULL,        NULL}        /* sentinel */
989};
990
991PyDoc_STRVAR(module_doc, "Rappture Library Module for Python.");
992
993/* Initialization function for the module */
994
995PyMODINIT_FUNC
996initlibrary(void)
997{
998    PyObject *m;
999
1000    /* Finalize the type object including setting type of the new type
1001     * object; doing it here is required for portability to Windows
1002     * without requiring C++. */
1003    if (PyType_Ready(&RpLibraryObjectType) < 0)
1004        return;
1005
1006    /* Create the module and add the functions */
1007    m = Py_InitModule3("library", Library_Methods, module_doc);
1008
1009    /* Add some symbolic constants to the module */
1010    if (ErrorObject == NULL) {
1011        ErrorObject = PyErr_NewException("RpLibrary.error", NULL, NULL);
1012        if (ErrorObject == NULL)
1013            return;
1014    }
1015
1016    Py_INCREF(&RpLibraryObjectType);
1017    PyModule_AddObject(m, "library", (PyObject*) &RpLibraryObjectType);
1018
1019    Py_XINCREF(ErrorObject);
1020    PyModule_AddObject(m, "error", ErrorObject);
1021
1022}
Note: See TracBrowser for help on using the repository browser.