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

Last change on this file since 1326 was 1326, checked in by gah, 15 years ago

Cast away warnings from usage of constant strings

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