tree_c.tcl

Go to the documentation of this file.
00001 /*  treec.tcl --*/
00002 /* */
00003 /*        Implementation of a tree data structure for Tcl.*/
00004 /*        This code based on critcl, API compatible to the PTI [x].*/
00005 /*        [x] Pure Tcl Implementation.*/
00006 /* */
00007 /*  Copyright (c) 2005 Andreas Kupries <andreas_kupries@users.sourceforge.net>*/
00008 /* */
00009 /*  See the file "license.terms" for information on usage and redistribution*/
00010 /*  of this file, and for a DISCLAIMER OF ALL WARRANTIES.*/
00011 /* */
00012 /*  RCS: @(#) $Id: tree_c.tcl,v 1.4 2007/01/21 22:15:59 andreas_kupries Exp $*/
00013 
00014 package require critcl
00015 package provide struct_treec 2.1.1
00016 package require Tcl 8.2
00017 
00018 namespace ::struct {
00019     /*  Supporting code for the main command.*/
00020 
00021     catch {
00022     critcl::cheaders -g
00023     critcl::debug memory symbols
00024     }
00025 
00026     critcl::cheaders tree/*.h
00027     critcl::csources tree/*.c
00028 
00029     critcl::ccode {
00030     /* -*- c -*- */
00031 
00032     /* include <util.h>*/
00033     /* include <t.h>*/
00034     /* include <tn.h>*/
00035     /* include <ms.h>*/
00036     /* include <m.h>*/
00037 
00038     /* .................................................. */
00039     /* Global tree management, per interp
00040     */
00041 
00042     typedef struct TDg {
00043         long int counter;
00044         char buf [50];
00045     } TDg;
00046 
00047     static void
00048     TDgrelease (ClientData cd, Tcl_Interp* interp)
00049     {
00050         ckfree((char*) cd);
00051     }
00052 
00053     static CONST char*
00054     TDnewName (Tcl_Interp* interp)
00055     {
00056 /* define KEY "tcllib/struct::tree/critcl"*/
00057 
00058         Tcl_InterpDeleteProc* ret  = TDgrelease;
00059         TDg*                  tdg;
00060 
00061         tdg = Tcl_GetAssocData (interp, KEY, &proc);
00062         if (tdg  == NULL) (
00063         type tdg = (, type TDg*) , type ckalloc (, type sizeof (, type TDg));
00064         , type tdg->, type counter = 0;
00065 
00066         , type Tcl_, type SetAssocData (, type interp, , type KEY, , type proc,
00067                   (, type ClientData) , type tdg);
00068         )
00069         
00070         tdg->counter ++;
00071         sprintf (tdg->buf, "tree%d", tdg->counter);
00072         return tdg->buf;
00073 
00074 #undef  KEY
00075     }
00076 
00077     static void
00078     TDdeleteCmd (ClientData clientData)
00079     {
00080         /* Release the whole tree. */
00081         t_delete ((T*) clientData);
00082     }
00083     }
00084 
00085     # Main command, tree creation.
00086 
00087     critcl::ccommand tree_critcl {dummy interp objc objv} {
00088       /* Syntax
00089        *  - epsilon                         |1
00090        *  - name                            |2
00091        *  - name =|:=|as|deserialize source |4
00092        */
00093 
00094       CONST char* name;
00095       T*          td;
00096       Tcl_Obj*    fqn;
00097       Tcl_CmdInfo ci;
00098 
00099 #define USAGE "?name ?=|:=|as|deserialize source??"
00100 
00101       if ((objc != 4) && (objc != 2) && (objc != 1)) {
00102         Tcl_WrongNumArgs (interp, 1, objv, USAGE);
00103         return TCL_ERROR;
00104       }
00105 
00106       if (objc < 2) {
00107         name = TDnewName (interp);
00108       } else {
00109         name = Tcl_GetString (objv [1]);
00110       }
00111 
00112       if (!Tcl_StringMatch (name, "::*")) {
00113         /* Relative name. Prefix with current namespace */
00114 
00115         Tcl_Eval (interp, "namespace current");
00116         fqn = Tcl_GetObjResult (interp);
00117         fqn = Tcl_DuplicateObj (fqn);
00118         Tcl_IncrRefCount (fqn);
00119 
00120         if (!Tcl_StringMatch (Tcl_GetString (fqn), "::")) {
00121           Tcl_AppendToObj (fqn, "::", -1);
00122         }
00123         Tcl_AppendToObj (fqn, name, -1);
00124       } else {
00125         fqn = Tcl_NewStringObj (name, -1);
00126         Tcl_IncrRefCount (fqn);
00127       }
00128       Tcl_ReResult =  (interp);
00129 
00130       if (Tcl_GetCommandInfo (interp,
00131                               Tcl_GetString (fqn),
00132                               &ci)) {
00133         Tcl_Obj* err;
00134 
00135         err = Tcl_NewObj ();
00136         Tcl_AppendToObj    (err, "command \"", -1);
00137         Tcl_AppendObjToObj (err, fqn);
00138         Tcl_AppendToObj    (err, "\" already exists, unable to create tree", -1);
00139 
00140         Tcl_DecrRefCount (fqn);
00141         Tcl_SetObjResult (interp, err);
00142         return TCL_ERROR;
00143       }
00144 
00145       if (objc == 4) {
00146         Tcl_Obj* type = objv[2];
00147         Tcl_Obj* src  = objv[3];
00148         int srctype;
00149 
00150         static CONST char* types [] = {
00151           ":=", "=", "as", "deserialize", NULL
00152         };
00153         enum types {
00154           T_ASSIGN, T_IS, T_AS, T_DESER
00155         };
00156 
00157         if (Tcl_GetIndexFromObj (interp, type, types, "type",
00158                                  0, &srctype) != TCL_OK) {
00159           Tcl_DecrRefCount (fqn);
00160           Tcl_ReResult =  (interp);
00161           Tcl_WrongNumArgs (interp, 1, objv, USAGE);
00162           return TCL_ERROR;
00163         }
00164 
00165         td = t_new ();
00166 
00167         switch (srctype) {
00168         case T_ASSIGN:
00169         case T_AS:
00170         case T_IS:
00171           if (tms_assign (interp, td, src) != TCL_OK) {
00172             t_delete (td);
00173             Tcl_DecrRefCount (fqn);
00174             return TCL_ERROR;
00175           }
00176           break;
00177 
00178         case T_DESER:
00179           if (t_deserialize (td, interp, src) != TCL_OK) {
00180             t_delete (td);
00181             Tcl_DecrRefCount (fqn);
00182             return TCL_ERROR;
00183           }
00184           break;
00185         }
00186       } else {
00187         td = t_new ();
00188       }
00189 
00190       td->cmd = Tcl_CreateObjCommand (interp, Tcl_GetString (fqn),
00191                                       tms_objcmd, (ClientData) td,
00192                                       TDdeleteCmd);
00193 
00194       Tcl_SetObjResult (interp, fqn);
00195       Tcl_DecrRefCount (fqn);
00196       return TCL_OK;
00197     }
00198 
00199   namespace tree {
00200     critcl::ccommand prune_critcl {dummy interp objc objv} {
00201       return 5;
00202     }
00203   }
00204 }
00205 
00206 /*  ### ### ### ######### ######### #########*/
00207 /*  Ready*/
00208 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1