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

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

updated python bindings to not complain about giving an empty value sting to the put() fxn.
removing the old python version of simsim.

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