source: trunk/lang/python/Rappture/PyRpLibrary.cc @ 1039

Last change on this file since 1039 was 1039, checked in by dkearney, 16 years ago

updated python bindings library module to compile with python2.4 as advised by PEP353

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