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

Last change on this file since 1034 was 1034, checked in by gah, 16 years ago

added workaround for python 2.3

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