00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 package require critcl
00015 package provide struct_treec 2.1.1
00016 package require Tcl 8.2
00017
00018 namespace ::struct {
00019
00020
00021 catch {
00022 critcl::cheaders -g
00023 critcl::debug memory symbols
00024 }
00025
00026 critcl::cheaders tree
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
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
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
00081 t_delete ((T*) clientData);
00082 }
00083 }
00084
00085 # Main command, tree creation.
00086
00087 critcl::ccommand tree_critcl {dummy interp objc objv} {
00088
00089
00090
00091
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
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
00208