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) Arc operations.
* Tcl_ObjType for arcs, and shimmering to it.
*/
#include <string.h>
#include <arc.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 ga_type = {
"tcllib::struct::graph/critcl::arc",
free_rep,
dup_rep,
string_rep,
from_any
};
/* .................................................. */
static void
free_rep (Tcl_Obj* obj)
{
/* Nothing to do. The rep is the GA in the G. */
}
static void
dup_rep (Tcl_Obj* obj, Tcl_Obj* dup)
{
GA* a = (GA*) obj->internalRep.otherValuePtr;
dup->internalRep.otherValuePtr = a;
dup->typePtr = &ga_type;
}
static void
string_rep (Tcl_Obj* obj)
{
Tcl_Obj* temp;
char* str;
GA* a = (GA*) obj->internalRep.otherValuePtr;
obj->length = a->base.name->length;
obj->bytes = ckalloc (obj->length + 1);
memcpy (obj->bytes, a->base.name->bytes, obj->length + 1);
}
static int
from_any (Tcl_Interp* ip, Tcl_Obj* obj)
{
Tcl_Panic ("Cannot create GA structure via regular shimmering.");
return TCL_ERROR;
}
/* .................................................. */
void
ga_shimmer (Tcl_Obj* o, GA* a)
{
/* Release an existing representation */
if (o->typePtr && o->typePtr->freeIntRepProc) {
o->typePtr->freeIntRepProc (o);
}
o->typePtr = &ga_type;
o->internalRep.otherValuePtr = a;
}
/* .................................................. */
GA*
ga_get_arc (G* g, Tcl_Obj* arc, Tcl_Interp* interp, Tcl_Obj* graph)
{
GA* a = 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 (arc->typePtr == &ga_type) {
a = (GA*) arc->internalRep.otherValuePtr;
if (a->graph == g) {
#if 0
fprintf (stderr, "cached: %p (%p - %p)\n", a, t, a->graph);
fflush(stderr);
#endif
return a;
}
}
#endif
/* Incompatible int.rep, or refering to a different
* graph. We go through the hash table.
*/
he = Tcl_FindHashEntry (g->arcs.map, Tcl_GetString (arc));
if (he) {
a = (GA*) Tcl_GetHashValue (he);
/* Shimmer the object, cache the arc information.
*/
ga_shimmer (arc, a);
return a;
}
/* Arc handle not found. Leave an error message,
* if possible.
*/
if (interp != NULL) {
ga_err_missing (interp, arc, graph);
}
return NULL;
}
/*
* Local Variables:
* mode: c
* c-basic-offset: 4
* fill-column: 78
* End:
*/
|