graph_c.tcl

Go to the documentation of this file.
00001 /*  graphc.tcl --*/
00002 /* */
00003 /*        Implementation of a graph 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) 2006 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: graph_c.tcl,v 1.1 2006/11/16 06:33:12 andreas_kupries Exp $*/
00013 
00014 package require critcl
00015 package provide struct_graphc 2.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 graph/*.h
00027     critcl::csources graph/*.c
00028 
00029     critcl::ccode {
00030     /* -*- c -*- */
00031 
00032     /* include <global.h>*/
00033     /* include <objcmd.h>*/
00034     /* include <graph.h>*/
00035 
00036     /* define USAGE "?name ?=|:=|as|deserialize source??"*/
00037 
00038     static void gg_delete (ClientData clientData)
00039     {
00040         /* Release the whole graph. */
00041         g_delete ((G*) clientData);
00042     }
00043     }
00044 
00045     /*  Main command, graph creation.*/
00046 
00047     critcl::ccommand graph_critcl {dummy interp objc objv} {
00048     /* Syntax */
00049     /*  - epsilon                         |1 */
00050     /*  - name                            |2 */
00051     /*  - name =|:=|as|deserialize source |4 */
00052 
00053     CONST char* name;
00054     G*          g;
00055     Tcl_Obj*    fqn;
00056     Tcl_CmdInfo ci;
00057 
00058     if ((objc != 4) && (objc != 2) && (objc != 1)) {
00059         Tcl_WrongNumArgs (interp, 1, objv, USAGE);
00060         return TCL_ERROR;
00061     }
00062 
00063     if (objc < 2) {
00064         name = gg_new (interp);
00065     } else {
00066         name = Tcl_GetString (objv [1]);
00067     }
00068 
00069     if (!Tcl_StringMatch (name, "::*")) {
00070         /* Relative name. Prefix with current namespace */
00071 
00072         Tcl_Eval (interp, "namespace current");
00073         fqn = Tcl_GetObjResult (interp);
00074         fqn = Tcl_DuplicateObj (fqn);
00075         Tcl_IncrRefCount (fqn);
00076 
00077         if (!Tcl_StringMatch (Tcl_GetString (fqn), "::")) {
00078         Tcl_AppendToObj (fqn, "::", -1);
00079         }
00080         Tcl_AppendToObj (fqn, name, -1);
00081     } else {
00082         fqn = Tcl_NewStringObj (name, -1);
00083         Tcl_IncrRefCount (fqn);
00084     }
00085 
00086     Tcl_ReResult =  (interp);
00087 
00088     if (Tcl_GetCommandInfo (interp, Tcl_GetString (fqn), &ci)) {
00089         Tcl_Obj* err;
00090 
00091         err = Tcl_NewObj ();
00092         Tcl_AppendToObj    (err, "command \"", -1);
00093         Tcl_AppendObjToObj (err, fqn);
00094         Tcl_AppendToObj    (err, "\" already exists, unable to create graph", -1);
00095 
00096         Tcl_DecrRefCount (fqn);
00097         Tcl_SetObjResult (interp, err);
00098         return TCL_ERROR;
00099     }
00100 
00101     if (objc == 4) {
00102         /* Construction with immediate initialization */
00103         /* through deserialization */
00104 
00105         Tcl_Obj* type = objv[2];
00106         Tcl_Obj* src  = objv[3];
00107         int      srctype;
00108 
00109         static CONST char* types [] = {
00110         ":=", "=", "as", "deserialize", NULL
00111         };
00112         enum types {
00113         G_ASSIGN, G_IS, G_AS, G_DESER
00114         };
00115 
00116         if (Tcl_GetIndexFromObj (interp, type, types, "type", 0, &srctype) != TCL_OK) {
00117         Tcl_DecrRefCount (fqn);
00118         Tcl_ReResult =   (interp);
00119         Tcl_WrongNumArgs (interp, 1, objv, USAGE);
00120         return TCL_ERROR;
00121         }
00122 
00123         g = g_new ();
00124 
00125         switch (srctype) {
00126         case G_ASSIGN:
00127         case G_AS:
00128         case G_IS:
00129         if (g_ms_assign (interp, g, src) != TCL_OK) {
00130             g_delete (g);
00131             Tcl_DecrRefCount (fqn);
00132             return TCL_ERROR;
00133         }
00134         break;
00135 
00136         case G_DESER:
00137         if (g_deserialize (g, interp, src) != TCL_OK) {
00138             g_delete (g);
00139             Tcl_DecrRefCount (fqn);
00140             return TCL_ERROR;
00141         }
00142         break;
00143         }
00144     } else {
00145         g = g_new ();
00146     }
00147 
00148     g->cmd = Tcl_CreateObjCommand (interp, Tcl_GetString (fqn),
00149                                        g_objcmd, (ClientData) g,
00150                                        gg_delete);
00151 
00152     Tcl_SetObjResult (interp, fqn);
00153     Tcl_DecrRefCount (fqn);
00154     return TCL_OK;
00155     }
00156 }
00157 
00158 /*  ### ### ### ######### ######### #########*/
00159 /*  Ready*/
00160 

Generated on 21 Sep 2010 for Gui by  doxygen 1.6.1