1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
|
/* struct::graph - critcl - layer 1 definitions.
* (b) Node operations.
* Tcl_ObjType for nodes, and shimmering to it.
*/
#include <string.h>
#include <node.h>
/* .................................................. */
static void free_rep (Tcl_Obj* obj);
static void dup_rep (Tcl_Obj* obj, Tcl_Obj* dup);
static void string_rep (Tcl_Obj* obj);
static int from_any (Tcl_Interp* ip, Tcl_Obj* obj);
static
Tcl_ObjType gn_type = {
"tcllib::struct::graph/critcl::node",
free_rep,
dup_rep,
string_rep,
from_any
};
/* .................................................. */
static void
free_rep (Tcl_Obj* obj)
{
/* Nothing to do. The rep is the GN in the G. */
}
static void
dup_rep (Tcl_Obj* obj, Tcl_Obj* dup)
{
GN* n = (GN*) obj->internalRep.otherValuePtr;
dup->internalRep.otherValuePtr = n;
dup->typePtr = &gn_type;
}
static void
string_rep (Tcl_Obj* obj)
{
Tcl_Obj* temp;
char* str;
GN* n = (GN*) obj->internalRep.otherValuePtr;
obj->length = n->base.name->length;
obj->bytes = ckalloc (obj->length + 1);
memcpy (obj->bytes, n->base.name->bytes, obj->length + 1);
}
static int
from_any (Tcl_Interp* ip, Tcl_Obj* obj)
{
Tcl_Panic ("Cannot create GDN structure via regular shimmering.");
return TCL_ERROR;
}
/* .................................................. */
void
gn_shimmer (Tcl_Obj* o, GN* n)
{
/* Release an existing representation */
if (o->typePtr && o->typePtr->freeIntRepProc) {
o->typePtr->freeIntRepProc (o);
}
o->typePtr = &gn_type;
o->internalRep.otherValuePtr = n;
}
/* .................................................. */
GN*
gn_get_node (G* g, Tcl_Obj* node, Tcl_Interp* interp, Tcl_Obj* graph)
{
GN* n = NULL;
Tcl_HashEntry* he;
/* Check if we have a valid cached int.rep. */
#if 0
/* [x] TODO */
/* Caching of handles implies that the graphs have to */
/* keep track of the tcl_obj pointing to them. So that */
/* the int.rep can be invalidated upon graph deletion */
if (node->typePtr == &gn_type) {
n = (GN*) node->internalRep.otherValuePtr;
if (n->graph == g) {
#if 0
fprintf (stderr, "cached: %p (%p - %p)\n", n, t, n->graph);
fflush(stderr);
#endif
return n;
}
}
#endif
/* Incompatible int.rep, or refering to a different
* graph. We go through the hash table.
*/
he = Tcl_FindHashEntry (g->nodes.map, Tcl_GetString (node));
if (he != NULL) {
n = (GN*) Tcl_GetHashValue (he);
/* Shimmer the object, cache the node information.
*/
gn_shimmer (node, n);
return n;
}
/* Node handle not found. Leave an error message,
* if possible.
*/
if (interp != NULL) {
gn_err_missing (interp, node, graph);
}
return NULL;
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|