source: trunk/src/tcl/src/RpLibraryTclInterface.cc @ 365

Last change on this file since 365 was 365, checked in by dkearney, 18 years ago

fixes for tcl bindings.

File size: 33.7 KB
Line 
1/*
2 * ----------------------------------------------------------------------
3 *  Rappture::library
4 *
5 *  This is an interface to the rappture library module.
6 *  It allows you to create rappture library objects.
7 * ======================================================================
8 *  AUTHOR:  Derrick Kearney, Purdue University
9 *  Copyright (c) 2004-2006  Purdue Research Foundation
10 *
11 *  See the file "license.terms" for information on usage and
12 *  redistribution of this file, and for a DISCLAIMER OF ALL WARRANTIES.
13 * ======================================================================
14 */
15#include <tcl.h>
16#include <sstream>
17#include "core/RpLibrary.h"
18#include "RpLibraryTclInterface.h"
19
20#ifdef __cplusplus
21extern "C" {
22#endif
23
24#include "bltInt.h"
25
26
27static int RpLibraryCmd   _ANSI_ARGS_((   ClientData cdata, Tcl_Interp *interp,
28                                        int argc, const char *argv[]    ));
29static int RpLibCallCmd   _ANSI_ARGS_(( ClientData cData, Tcl_Interp *interp,
30                                        int argc, const char* argv[]    ));
31
32static int RpTclLibChild  _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
33                                        int argc, const char *argv[]    ));
34static int RpTclLibCopy   _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
35                                        int argc, const char *argv[]    ));
36static int RpTclLibDiff   _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
37                                        int argc, const char *argv[]    ));
38static int RpTclLibElem   _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
39                                        int argc, const char *argv[]    ));
40static int RpTclLibGet    _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
41                                        int argc, const char *argv[]    ));
42static int RpTclLibIsa    _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
43                                        int argc, const char *argv[]    ));
44static int RpTclLibParent _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
45                                        int argc, const char *argv[]    ));
46static int RpTclLibPut    _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
47                                        int argc, const char *argv[]    ));
48static int RpTclLibRemove _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
49                                        int argc, const char *argv[]    ));
50static int RpTclLibResult _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
51                                        int argc, const char *argv[]    ));
52static int RpTclLibValue  _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
53                                        int argc, const char *argv[]    ));
54static int RpTclLibXml    _ANSI_ARGS_(( ClientData cdata, Tcl_Interp *interp,
55                                        int argc, const char *argv[]    ));
56
57static int RpTclResult   _ANSI_ARGS_((    ClientData cdata,
58                                       Tcl_Interp *interp,
59                                       int argc,
60                                       const char *argv[]    ));
61
62
63static std::string rpLib2command _ANSI_ARGS_(( Tcl_Interp *interp,
64                                               RpLibrary* newRpLibObj   ));
65
66// member function, function pointer mainly used in 'element' implementation
67typedef std::string (RpLibrary::*rpMbrFxnPtr) _ANSI_ARGS_(());
68
69static Blt_OpSpec rpLibOps[] = {
70    {"children", 2, (Blt_Op)RpTclLibChild, 2, 7,
71        "?-as <fval>? ?-type <name>? ?<path>?",},
72    {"copy", 2, (Blt_Op)RpTclLibCopy, 5, 6,
73        "<path> from ?<xmlobj>? <path>",},
74    {"diff", 1, (Blt_Op)RpTclLibDiff, 3, 3, "<xmlobj>",},
75    {"element", 1, (Blt_Op)RpTclLibElem, 2, 5, "?-as <fval>? ?<path>?",},
76    {"get", 1, (Blt_Op)RpTclLibGet, 2, 3, "?<path>?",},
77    {"isa", 1, (Blt_Op)RpTclLibIsa, 3, 3, "<objType>",},
78    {"parent", 2, (Blt_Op)RpTclLibParent, 2, 5, "?-as <fval>? ?<path>?",},
79    {"put", 2, (Blt_Op)RpTclLibPut, 2, 8,
80        "?-append yes? ?-id num? ?<path>? <string>",},
81    {"remove", 3, (Blt_Op)RpTclLibRemove, 2, 3, "?<path>?",},
82    {"result", 3, (Blt_Op)RpTclLibResult, 2, 2, "",},
83    {"xml", 1, (Blt_Op)RpTclLibXml, 2, 2, "",},
84};
85
86static int nRpLibOps = sizeof(rpLibOps) / sizeof(Blt_OpSpec);
87
88#ifdef __cplusplus
89}
90#endif
91
92/*
93 * ------------------------------------------------------------------------
94 *  Rappturelibrary_Init()
95 *
96 *  Called in Rappture_Init() to initialize the commands defined
97 *  in this file.
98 * ------------------------------------------------------------------------
99 */
100
101int
102Rappturelibrary_Init(Tcl_Interp *interp)
103{
104
105    Tcl_CreateCommand(interp, "::Rappture::library",
106        RpLibraryCmd, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
107
108    Tcl_CreateCommand(interp, "::Rappture::result",
109        RpTclResult, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
110
111    Tcl_CreateCommand(interp, "::Rappture::LibraryObj::value",
112        RpTclLibValue, (ClientData)NULL, (Tcl_CmdDeleteProc*)NULL);
113
114    return TCL_OK;
115}
116
117/*
118 *
119 * USAGE: library <file>
120 * USAGE: library standard
121 * USAGE: library isvalid <object>
122 *
123 */
124
125int
126RpLibraryCmd (  ClientData cData,
127                Tcl_Interp *interp,
128                int argc,
129                const char* argv[]  )
130{
131    RpLibrary *rpptr = NULL;
132    std::string libName = "";
133    int noerr = 0;
134    std::stringstream result;
135    Tcl_CmdInfo info;  // pointer to the command info
136
137
138    if ( (argc > 2) && (strncmp(argv[1],"isvalid",7) == 0) ) {
139        result.str("0");
140        if (argc != 3) {
141            Tcl_AppendResult(interp, "wrong # args: should be \"", argv[0],
142                "\": isvalid object",
143                (char*)NULL);
144            return TCL_ERROR;
145        }
146
147        noerr = Tcl_GetCommandInfo(interp, argv[2], &info);
148        if (noerr == 1) {
149            if (info.proc == &RpLibCallCmd) {
150                result.clear();
151                result.str("1");
152            }
153        }
154
155        Tcl_ResetResult(interp);
156        Tcl_AppendResult(interp, result.str().c_str(), (char*)NULL);
157        return TCL_OK;
158    }
159
160    if (argc != 2) {
161        Tcl_AppendResult(interp, "usage: ", argv[0], " <xmlfile>",(char*)NULL);
162        return TCL_ERROR;
163    }
164
165    // create a new command
166    rpptr = new RpLibrary(argv[1]);
167
168    libName = rpLib2command(interp,rpptr);
169
170    Tcl_AppendResult(interp, libName.c_str(), (char*)NULL);
171    return TCL_OK;
172}
173
174std::string
175rpLib2command (Tcl_Interp *interp, RpLibrary* newRpLibObj)
176{
177    static int libCount = 0;
178    std::stringstream libName;
179
180    libName << "::libraryObj" << libCount++;
181
182    Tcl_CreateCommand(interp, libName.str().c_str(),
183        RpLibCallCmd, (ClientData)newRpLibObj, (Tcl_CmdDeleteProc*)NULL);
184
185    return libName.str();
186}
187
188int
189RpLibCallCmd (  ClientData cData,
190                Tcl_Interp *interp,
191                int argc,
192                const char* argv[]  )
193{
194    Blt_Op proc;
195
196    if (argc < 2) {
197        Tcl_AppendResult(interp, "usage: \"", argv[0],
198            "\": <command> <arg-list>",
199            (char*)NULL);
200        return TCL_ERROR;
201    }
202
203    proc = Blt_GetOp(interp, nRpLibOps, rpLibOps, BLT_OP_ARG1,
204                    argc, (char**)argv, 0);
205
206    if (proc == NULL) {
207        return TCL_ERROR;
208                                }
209    return (*proc)(cData, interp, argc, argv);
210
211}
212
213int
214RpTclLibChild   (   ClientData cdata,
215                    Tcl_Interp *interp,
216                    int argc,
217                    const char *argv[]  )
218{
219    std::string path   = "";    // path of where to place data inside xml tree
220    std::string type   = "";    // type of nodes to be returned
221    std::string retStr = "";    // path of where to place data inside xml tree
222    int nextarg        = 2;     // start parsing using the '2'th argument
223    int opt_argc       = 2;     // max number of optional parameters
224    int argsLeft       = 0;     // temp variable for calculation
225
226    RpLibrary* node    = NULL;
227    rpMbrFxnPtr asProc = &RpLibrary::nodeComp;
228
229    // parse through -'d arguments
230    while (opt_argc--) {
231        if (nextarg < argc && *argv[nextarg] == '-') {
232            if (strncmp(argv[nextarg],"-as",3) == 0) {
233                nextarg++;
234                if (nextarg < argc) {
235                    if (    (*argv[nextarg] == 'c') &&
236                            (strncmp(argv[nextarg],"component",9) == 0) ) {
237                        asProc = &RpLibrary::nodeComp;
238                        nextarg++;
239                    }
240                    else if ((*argv[nextarg] == 'i') &&
241                             (strncmp(argv[nextarg],"id",2) == 0 ) ) {
242                        asProc = &RpLibrary::nodeId;
243                        nextarg++;
244                    }
245                    else if ((*argv[nextarg] == 't') &&
246                             (strncmp(argv[nextarg],"type",4) == 0 ) ) {
247                        asProc = &RpLibrary::nodeType;
248                        nextarg++;
249                    }
250                    else if ((*argv[nextarg] == 'p') &&
251                             (strncmp(argv[nextarg],"path",4) == 0 ) ) {
252                        asProc = &RpLibrary::nodePath;
253                        nextarg++;
254                    }
255                    else if ((*argv[nextarg] == 'o') &&
256                             (strncmp(argv[nextarg],"object",6) == 0 ) ) {
257                        asProc = NULL;
258                        nextarg++;
259                    }
260                    else {
261                        Tcl_AppendResult(interp, "bad flavor \"", argv[nextarg],
262                            "\": should be component, id, type, path, object",
263                            (char*)NULL);
264                        return TCL_ERROR;
265                    }
266                }
267                else {
268                    Tcl_AppendResult(interp, "bad flavor \"", argv[nextarg],
269                        "\": should be component, id, type, path, object",
270                        (char*)NULL);
271                    return TCL_ERROR;
272                }
273            }
274            else if (strncmp(argv[nextarg],"-type",5) == 0) {
275                nextarg++;
276                if (argc > nextarg) {
277                    type = std::string(argv[nextarg]);
278                    nextarg++;
279                }
280                else {
281                    Tcl_AppendResult(interp, "bad flavor \"empty type\"",
282                        "\": should be a type of node within the xml",
283                        (char*)NULL);
284                    return TCL_ERROR;
285                }
286            }
287            else {
288                Tcl_AppendResult(interp, "bad option \"", argv[nextarg],
289                    "\": should be -as or -type", (char*)NULL);
290                return TCL_ERROR;
291            }
292        }
293    }
294
295    argsLeft = (argc-nextarg);
296    if (argsLeft == 1) {
297        path = std::string(argv[nextarg++]);
298    }
299    else {
300        path = "";
301    }
302
303    // call the rappture library children function
304    while ( (node = ((RpLibrary*) cdata)->children(path,node,type)) ) {
305        if (node) {
306
307            // clear any previous result in the interpreter
308            // Tcl_ResetResult(interp);
309
310            if (asProc) {
311                // evaluate the "-as" flag on the returned node
312                retStr = (node->*asProc)();
313            }
314            else {
315                // create a new command for the new rappture object
316                retStr = rpLib2command(interp, node);
317            }
318
319            // store the new result string in the interpreter
320            Tcl_AppendElement(interp,retStr.c_str());
321        }
322    }
323
324    return TCL_OK;
325}
326
327int
328RpTclLibCopy    (   ClientData cdata,
329                    Tcl_Interp *interp,
330                    int argc,
331                    const char *argv[]  )
332{
333    std::string fromPath = "";    // path of where to copy data from
334    std::string toPath   = "";    // path of where to copy data to
335    std::string from     = "";    // string that should == "from"
336    std::string fromObjStr = "";  // string that represents the
337                                  // string name of the object
338    RpLibrary* fromObj   = NULL;
339    int nextarg          = 2;     // start parsing using the '2'th argument
340    int argsLeft         = 0;     // temp variable for calculation
341    int noerr              = 0;     // err flag for Tcl_GetCommandInfo
342    Tcl_CmdInfo info;  // pointer to the command info
343
344    toPath = std::string(argv[nextarg++]);
345    from = std::string(argv[nextarg++]);
346
347    argsLeft = (argc-nextarg);
348    if (argsLeft == 2) {
349        fromObjStr = std::string(argv[nextarg++]);
350        noerr = Tcl_GetCommandInfo(interp, fromObjStr.c_str(), &info);
351        if (noerr == 1) {
352            if (info.proc == RpLibCallCmd) {
353                fromObj = (RpLibrary*) (info.clientData);
354            }
355            else {
356                Tcl_ResetResult(interp);
357                Tcl_AppendResult(interp,
358                    "wrong arg type: xmlobj should be a Rappture Library\"",
359                    (char*)NULL);
360                return TCL_ERROR;
361            }
362        }
363        fromPath = std::string(argv[nextarg++]);
364    }
365    else if (argsLeft == 1) {
366        fromPath = std::string(argv[nextarg++]);
367    }
368    else {
369        Tcl_ResetResult(interp);
370        Tcl_AppendResult(interp,
371            "wrong # args: should be \"copy path from ?xmlobj? path\"",
372            (char*)NULL);
373        return TCL_ERROR;
374    }
375
376    if (from != "from") {
377        Tcl_ResetResult(interp);
378        Tcl_AppendResult(interp,
379            "bad syntax: should be \"copy path from ?xmlobj? path\"",
380            (char*)NULL);
381        return TCL_ERROR;
382    }
383
384    // call the rappture library copy function
385    ((RpLibrary*) cdata)->copy(toPath, fromPath, fromObj);
386
387    // clear any previous result in the interpreter
388    // store the new result in the interpreter
389    Tcl_ResetResult(interp);
390    Tcl_AppendResult(interp, "", (char*)NULL);
391
392    return TCL_OK;
393}
394
395int
396RpTclLibDiff     (   ClientData cdata,
397                    Tcl_Interp *interp,
398                    int argc,
399                    const char *argv[]  )
400{
401
402    Tcl_CmdInfo info;                // pointer to the command info
403    std::string otherLibStr = "";
404    RpLibrary* otherLib     = NULL;
405    int nextarg             = 2;     // start parsing using the '2'th argument
406    int argsLeft            = 0;     // temp variable for calculation
407    int noerr               = 0;     // err flag for Tcl_GetCommandInfo
408
409    std::list<std::string> diffList; // list to store the return value
410                                     // from diff command
411    std::list<std::string>::iterator diffListIter;
412
413    // parse input arguments
414    argsLeft = (argc-nextarg);
415    if (argsLeft == 1) {
416        otherLibStr = std::string(argv[nextarg++]);
417        noerr = Tcl_GetCommandInfo(interp, otherLibStr.c_str(), &info);
418        if (noerr == 1) {
419            if (info.proc == RpLibCallCmd) {
420                otherLib = (RpLibrary*) (info.clientData);
421            }
422            else {
423                Tcl_ResetResult(interp);
424                Tcl_AppendResult(interp,
425                    "wrong arg type: xmlobj should be a Rappture Library",
426                    (char*)NULL);
427                return TCL_ERROR;
428            }
429        }
430        else {
431            // there was an error getting the command info
432            Tcl_AppendResult(interp,
433                "There was an error getting the command info for "
434                "the provided library \"", otherLibStr.c_str(), "\'",
435                "\nAre you sure its a Rappture Library Object?",
436                (char*)NULL);
437            return TCL_ERROR;
438        }
439    }
440    else {
441        Tcl_ResetResult(interp);
442        Tcl_AppendResult(interp,
443            "wrong # args: should be \"diff <xmlobj>\"",
444            (char*)NULL);
445        return TCL_ERROR;
446    }
447
448    // perform the diff command
449    diffList = ((RpLibrary*) (cdata))->diff(otherLib,"input");
450    diffListIter = diffList.begin();
451
452    Tcl_ResetResult(interp);
453
454    // parse through the output of the diff command
455    // put it into the return result
456    while (diffListIter != diffList.end()) {
457        Tcl_AppendElement(interp,(*diffListIter).c_str());
458
459        // increment the iterator
460        diffListIter++;
461    }
462
463
464    // Tcl_AppendResult(interp, retStr.c_str(), (char*)NULL);
465    return TCL_OK;
466}
467
468int
469RpTclLibElem    (   ClientData cdata,
470                    Tcl_Interp *interp,
471                    int argc,
472                    const char *argv[]  )
473{
474    std::string path   = "";    // path of where to place data inside xml tree
475    std::string retStr = "";    // path of where to place data inside xml tree
476    int nextarg        = 2;     // start parsing using the '2'th argument
477    int opt_argc       = 1;     // max number of optional parameters
478    int argsLeft       = 0;     // temp variable for calculation
479
480    RpLibrary* node    = NULL;
481    rpMbrFxnPtr asProc = &RpLibrary::nodeComp;
482
483    // parse through -'d arguments
484    while (opt_argc--) {
485        if (nextarg < argc && *argv[nextarg] == '-') {
486            if (strncmp(argv[nextarg],"-as",3) == 0) {
487                nextarg++;
488                if (nextarg < argc) {
489                    if (    (*argv[nextarg] == 'c') &&
490                            (strncmp(argv[nextarg],"component",9) == 0) ) {
491                        asProc = &RpLibrary::nodeComp;
492                        nextarg++;
493                    }
494                    else if ((*argv[nextarg] == 'i') &&
495                             (strncmp(argv[nextarg],"id",2) == 0 ) ) {
496                        asProc = &RpLibrary::nodeId;
497                        nextarg++;
498                    }
499                    else if ((*argv[nextarg] == 't') &&
500                             (strncmp(argv[nextarg],"type",4) == 0 ) ) {
501                        asProc = &RpLibrary::nodeType;
502                        nextarg++;
503                    }
504                    else if ((*argv[nextarg] == 'p') &&
505                             (strncmp(argv[nextarg],"path",4) == 0 ) ) {
506                        asProc = &RpLibrary::nodePath;
507                        nextarg++;
508                    }
509                    else if ((*argv[nextarg] == 'o') &&
510                             (strncmp(argv[nextarg],"object",6) == 0 ) ) {
511                        asProc = NULL;
512                        nextarg++;
513                    }
514                    else {
515                        Tcl_AppendResult(interp, "bad flavor \"", argv[nextarg],
516                            "\" for -as: should be component, id, type, path, object",
517                            (char*)NULL);
518                        return TCL_ERROR;
519                    }
520                }
521                else {
522                    Tcl_AppendResult(interp, "bad flavor \"\" for -as:",
523                           " should be component, id, type, path, object",
524                            (char*)NULL);
525                    return TCL_ERROR;
526                }
527            }
528            else {
529                Tcl_AppendResult(interp, "bad option \"", argv[nextarg],
530                    "\": should be -as", (char*)NULL);
531                return TCL_ERROR;
532            }
533        }
534    }
535
536    argsLeft = (argc-nextarg);
537    if (argsLeft > 1) {
538        Tcl_AppendResult(interp,
539            "wrong # args: should be \"element ?-as <fval>? ?<path>?\"",
540            (char*)NULL);
541        return TCL_ERROR;
542    }
543    else if (argsLeft == 1) {
544        path = std::string(argv[nextarg++]);
545    }
546    else {
547        path = "";
548    }
549
550    // call the rappture library element function
551    node = ((RpLibrary*) cdata)->element(path);
552    if (node) {
553
554        // clear any previous result in the interpreter
555        Tcl_ResetResult(interp);
556
557        if (asProc) {
558            // evaluate the "-as" flag on the returned node
559            retStr = (node->*asProc)();
560        }
561        else {
562            // create a new command for the new rappture object
563            retStr = rpLib2command(interp, node);
564        }
565        // store the new result string in the interpreter
566        Tcl_AppendResult(interp, retStr.c_str(), (char*)NULL);
567    }
568
569
570    return TCL_OK;
571}
572
573int
574RpTclLibGet     (   ClientData cdata,
575                    Tcl_Interp *interp,
576                    int argc,
577                    const char *argv[]  )
578{
579
580    std::string retStr = ""; // return value of rappture get fxn
581    std::string path = "";
582
583    if (argc == 3) {
584        path = std::string(argv[2]);
585    }
586    else if (argc != 2) {
587        Tcl_ResetResult(interp);
588        Tcl_AppendResult(interp,
589            "wrong # args: should be \"get ?path?\"",
590            "\":", (char*)NULL);
591        return TCL_ERROR;
592    }
593
594    // call the Rappture Library Get Function
595    retStr = ((RpLibrary*) cdata)->getString(path);
596
597    // clear any previous result in the interpreter
598    // store the new result in the interpreter
599    Tcl_ResetResult(interp);
600    Tcl_AppendResult(interp, retStr.c_str(), (char*)NULL);
601
602    return TCL_OK;
603}
604
605int
606RpTclLibIsa     (   ClientData cdata,
607                    Tcl_Interp *interp,
608                    int argc,
609                    const char *argv[]  )
610{
611
612    std::string compVal = ""; // string value of object being compared to
613    std::string retStr  = ""; // return value of rappture get fxn
614
615    if (argc == 3) {
616        compVal = std::string(argv[2]);
617    }
618    else {
619        Tcl_ResetResult(interp);
620        Tcl_AppendResult(interp,
621            "wrong # args: should be \"isa <objType>\"",
622            (char*)NULL);
623        return TCL_ERROR;
624    }
625
626    if (compVal == RAPPTURE_OBJ_TYPE) {
627        retStr = "1";
628    }
629    else {
630        retStr = "0";
631    }
632
633    // clear any previous result in the interpreter
634    // store the new result in the interpreter
635    Tcl_ResetResult(interp);
636    Tcl_AppendResult(interp, retStr.c_str(), (char*)NULL);
637
638    return TCL_OK;
639}
640
641int
642RpTclLibParent  (   ClientData cdata,
643                    Tcl_Interp *interp,
644                    int argc,
645                    const char *argv[]  )
646{
647
648    std::string path   = "";    // path of where to place data inside xml tree
649    std::string retStr = "";    // path of where to place data inside xml tree
650    int nextarg        = 2;     // start parsing using the '2'th argument
651    int opt_argc       = 1;     // max number of optional parameters
652    int argsLeft       = 0;     // temp variable for calculation
653
654    RpLibrary* node    = NULL;
655    rpMbrFxnPtr asProc = &RpLibrary::nodeComp;
656
657    // parse through -'d arguments
658    while (opt_argc--) {
659        if (nextarg < argc && *argv[nextarg] == '-') {
660            if (strncmp(argv[nextarg],"-as",3) == 0) {
661                nextarg++;
662                if (nextarg < argc) {
663                    if (    (*argv[nextarg] == 'c') &&
664                            (strncmp(argv[nextarg],"component",9) == 0) ) {
665                        asProc = &RpLibrary::nodeComp;
666                        nextarg++;
667                    }
668                    else if ((*argv[nextarg] == 'i') &&
669                             (strncmp(argv[nextarg],"id",2) == 0 ) ) {
670                        asProc = &RpLibrary::nodeId;
671                        nextarg++;
672                    }
673                    else if ((*argv[nextarg] == 't') &&
674                             (strncmp(argv[nextarg],"type",4) == 0 ) ) {
675                        asProc = &RpLibrary::nodeType;
676                        nextarg++;
677                    }
678                    else if ((*argv[nextarg] == 'p') &&
679                             (strncmp(argv[nextarg],"path",4) == 0 ) ) {
680                        asProc = &RpLibrary::nodePath;
681                        nextarg++;
682                    }
683                    else if ((*argv[nextarg] == 'o') &&
684                             (strncmp(argv[nextarg],"object",6) == 0 ) ) {
685                        asProc = NULL;
686                        nextarg++;
687                    }
688                    else {
689                        Tcl_AppendResult(interp, "bad flavor \"", argv[nextarg],
690                            "\": should be component, id, type, path, object",
691                            (char*)NULL);
692                        return TCL_ERROR;
693                    }
694                }
695                else {
696                    Tcl_AppendResult(interp, "bad flavor \"", argv[nextarg],
697                        "\": should be component, id, type, path, object",
698                        (char*)NULL);
699                    return TCL_ERROR;
700                }
701            }
702            else {
703                Tcl_AppendResult(interp, "bad option \"", argv[nextarg],
704                    "\": should be -as", (char*)NULL);
705                return TCL_ERROR;
706            }
707        }
708    }
709
710    argsLeft = (argc-nextarg);
711    if (argsLeft == 1) {
712        path = std::string(argv[nextarg++]);
713    }
714    else {
715        Tcl_AppendResult(interp,
716            "wrong # args: should be \"parent ?-as <fval>? ?<path>?\"",
717            (char*)NULL);
718        return TCL_ERROR;
719    }
720
721    // call the rappture library parent function
722    node = ((RpLibrary*) cdata)->parent(path);
723    if (node) {
724
725        // clear any previous result in the interpreter
726        Tcl_ResetResult(interp);
727
728        if (asProc) {
729            // evaluate the "-as" flag on the returned node
730            retStr = (node->*asProc)();
731        }
732        else {
733            // create a new command for the new rappture object
734            retStr = rpLib2command(interp, node);
735        }
736        // store the new result string in the interpreter
737        Tcl_AppendResult(interp, retStr.c_str(), (char*)NULL);
738
739    }
740
741
742    return TCL_OK;
743}
744
745int
746RpTclLibPut     (   ClientData cdata,
747                    Tcl_Interp *interp,
748                    int argc,
749                    const char *argv[]  )
750{
751
752    std::string id     = "";    // id tag for the given path
753    std::string path   = "";    // path of where to place data inside xml tree
754    std::string addStr = "";    // string to be added to data inside xml tree
755    int nextarg        = 2;     // start parsing using the '2'th argument
756    int append         = 0;     // append flag - 0 means no, 1 means yes
757    int opt_argc       = 2;     // max number of optional parameters
758    int argsLeft       = 0;     // temp variable for calculation
759
760    while (opt_argc--) {
761        if (nextarg < argc && *argv[nextarg] == '-') {
762            if (strncmp(argv[nextarg],"-append",7) == 0) {
763                ++nextarg;
764                if (nextarg < argc) {
765                    if (strncmp(argv[nextarg],"yes",3) == 0 ) {
766                        append = 1;
767                        nextarg++;
768                    }
769                    else if (strncmp(argv[nextarg],"no",2) == 0 ) {
770                        append = 0;
771                        nextarg++;
772                    }
773                    else {
774                        Tcl_AppendResult(interp, "expected boolean value but got \"",
775                            argv[nextarg], "\"", (char*)NULL);
776                        return TCL_ERROR;
777                    }
778                }
779                else {
780                    Tcl_AppendResult(interp, "expected boolean value but got \"",
781                        argv[nextarg], "\"", (char*)NULL);
782                    return TCL_ERROR;
783                }
784            }
785            else if (strncmp(argv[nextarg],"-id",3) == 0) {
786                id = std::string(argv[++nextarg]);
787                nextarg++;
788            }
789            else {
790                Tcl_AppendResult(interp, "bad option \"", argv[nextarg],
791                    "\": should be -append or -id", (char*)NULL);
792                return TCL_ERROR;
793            }
794        }
795    }
796
797    argsLeft = (argc-nextarg);
798    if (argsLeft == 2) {
799        path = std::string(argv[nextarg++]);
800        addStr = std::string(argv[nextarg++]);
801    }
802    else if (argsLeft == 1) {
803        path = "";
804        addStr = std::string(argv[nextarg++]);
805    }
806    else {
807        Tcl_AppendResult(interp, "wrong # args: should be ",
808            "\"put ?-append yes? ?-id num? ?<path>? <string>\"",
809            (char*)NULL);
810        return TCL_ERROR;
811    }
812
813    // call the rappture library put function
814    ((RpLibrary*) cdata)->put(path, addStr, id, append);
815
816    // clear any previous result in the interpreter
817    // store the new result in the interpreter
818    Tcl_ResetResult(interp);
819    Tcl_AppendResult(interp, "", (char*)NULL);
820
821    return TCL_OK;
822}
823
824int
825RpTclLibRemove  (   ClientData cdata,
826                    Tcl_Interp *interp,
827                    int argc,
828                    const char *argv[]  )
829{
830
831    std::string path = std::string("");    // path of where to remove data from
832    int nextarg = 2;
833
834
835    if (argc == 2) {
836        path = std::string("");
837    }
838    else if (argc == 3) {
839        path = std::string(argv[nextarg]);
840    }
841    else {
842        Tcl_AppendResult(interp,
843            "wrong # args: should be \"remove ?path?\"",
844            (char*)NULL);
845        return TCL_ERROR;
846    }
847
848    // call the rappture library remove function
849    ((RpLibrary*) cdata)->remove(path);
850
851    // clear any previous result in the interpreter
852    // store the new result in the interpreter
853    Tcl_ResetResult(interp);
854    Tcl_AppendResult(interp, "", (char*)NULL);
855
856    return TCL_OK;
857}
858
859int
860RpTclLibResult  (   ClientData cdata,
861                    Tcl_Interp *interp,
862                    int argc,
863                    const char *argv[]  )
864{
865    if (argc == 2) {
866        // call the rappture library result function
867        ((RpLibrary*) cdata)->result();
868    }
869    else {
870        Tcl_AppendResult(interp,
871            "wrong # args: should be \"result \"",
872            (char*)NULL);
873        return TCL_ERROR;
874    }
875
876
877    // clear any previous result in the interpreter
878    // store the new result in the interpreter
879    Tcl_ResetResult(interp);
880    Tcl_AppendResult(interp, "", (char*)NULL);
881
882    return TCL_OK;
883}
884
885int
886RpTclLibValue   (   ClientData cdata,
887                    Tcl_Interp *interp,
888                    int argc,
889                    const char *argv[]  )
890{
891
892    Tcl_CmdInfo info;                // pointer to the command info
893    std::string path        = "";
894    std::string libStr      = "";
895    RpLibrary* lib          = NULL;
896    int nextarg             = 1;     // start parsing using the '1'th argument
897    int argsLeft            = 0;     // temp variable for calculation
898    int noerr               = 0;     // err flag for Tcl_GetCommandInfo
899
900    std::list<std::string> valList; // list to store the return value
901                                     // from diff command
902    std::list<std::string>::iterator valListIter;
903
904    if ( argc != 3 ) {
905        Tcl_AppendResult(interp,
906            "wrong # args: should be \"value <xmlobj> <path>\"",
907            (char*)NULL);
908        return TCL_ERROR;
909    }
910
911    // parse input arguments
912    argsLeft = (argc-nextarg);
913    if (argsLeft == 2) {
914        libStr = std::string(argv[nextarg++]);
915        noerr = Tcl_GetCommandInfo(interp, libStr.c_str(), &info);
916        if (noerr == 1) {
917            if (info.proc == RpLibCallCmd) {
918                lib = (RpLibrary*) (info.clientData);
919            }
920            else {
921                Tcl_AppendResult(interp,
922                    "wrong arg type: xmlobj should be a Rappture Library",
923                    (char*)NULL);
924                return TCL_ERROR;
925            }
926        }
927        else {
928            // there was an error getting the command info
929            Tcl_AppendResult(interp,
930                "There was an error getting the command info for "
931                "the provided library \"", libStr.c_str(), "\'",
932                "\nAre you sure its a Rappture Library Object?",
933                (char*)NULL);
934            return TCL_ERROR;
935        }
936        path = std::string(argv[nextarg++]);
937    }
938    else {
939        Tcl_ResetResult(interp);
940        Tcl_AppendResult(interp,
941            "wrong # args: should be \"", argv[0], " <xmlobj> <path>\"",
942            (char*)NULL);
943        return TCL_ERROR;
944    }
945
946    // perform the value command
947    valList = lib->value(path);
948    valListIter = valList.begin();
949
950    // parse through the output of the diff command
951    // put it into the return result
952    while (valListIter != valList.end()) {
953        Tcl_AppendElement(interp,(*valListIter).c_str());
954
955        // increment the iterator
956        valListIter++;
957    }
958
959    return TCL_OK;
960}
961
962int
963RpTclLibXml     (   ClientData cdata,
964                    Tcl_Interp *interp,
965                    int argc,
966                    const char *argv[]  )
967{
968
969    std::string retStr = ""; // return value of rappture get fxn
970
971    if ( argc != 2 ) {
972        Tcl_AppendResult(interp, "wrong # args: should be \"",
973                argv[0], " xml\"", (char*)NULL);
974        return TCL_ERROR;
975    }
976
977    // call the Rappture Library xml Function
978    retStr = ((RpLibrary*) cdata)->xml();
979
980    // clear any previous result in the interpreter
981    // store the new result in the interpreter
982    Tcl_ResetResult(interp);
983    Tcl_AppendResult(interp, retStr.c_str(), (char*)NULL);
984
985    return TCL_OK;
986}
987
988int
989RpTclResult   (   ClientData cdata,
990                   Tcl_Interp *interp,
991                   int argc,
992                   const char *argv[]  )
993{
994    Tcl_CmdInfo info;            // pointer to the command info
995    int noerr            = 0;    // err flag for Tcl_GetCommandInfo
996    std::string libName  = "";
997    RpLibrary* lib       = NULL;
998
999    // parse through command line options
1000    if (argc != 2) {
1001        Tcl_AppendResult(interp, "wrong # args: should be \"",
1002                argv[0], " <xmlobj>\"", (char*)NULL);
1003        return TCL_ERROR;
1004    }
1005
1006    libName = std::string(argv[1]);
1007
1008    noerr = Tcl_GetCommandInfo(interp, libName.c_str(), &info);
1009    if (noerr == 1) {
1010        if (info.proc == RpLibCallCmd) {
1011            lib = (RpLibrary*) (info.clientData);
1012        }
1013        else {
1014            Tcl_AppendResult(interp,
1015                "wrong arg type: xmlobj should be a Rappture Library\"",
1016                (char*)NULL);
1017            return TCL_ERROR;
1018        }
1019    }
1020    else {
1021        // there was an error getting the command info
1022        Tcl_AppendResult(interp,
1023            "There was an error getting the command info for ",
1024            "the provided library \"", libName.c_str(), "\'",
1025            "\nAre you sure its a Rappture Library Object?",
1026            (char*)NULL);
1027        return TCL_ERROR;
1028    }
1029
1030    lib->result();
1031    Tcl_AppendResult(interp,"",(char*)NULL);
1032    return TCL_OK;
1033}
Note: See TracBrowser for help on using the repository browser.