1/* struct::tree - critcl - layer 1 declarations 2 * (b) Arc operations. 3 */ 4 5#include <arc.h> 6#include <attr.h> 7#include <graph.h> 8#include <util.h> 9 10/* .................................................. */ 11 12static GL* gla_link (GA* a, GL* i, GN* n, GLA* na); 13static void gla_unlink (GL* i, GLA* na); 14 15/* .................................................. */ 16 17GA* 18ga_new (G* g, const char* name, GN* src, GN* dst) 19{ 20 GA* a; 21 22 if (Tcl_FindHashEntry (g->arcs.map, name) != NULL) { 23 Tcl_Panic ("struct::graph(c) ga_new - tried to use duplicate name for new arc"); 24 } 25 26 a = ALLOC (GA); 27 28 gc_setup ((GC*) a, &g->arcs, name, g); 29 gc_add ((GC*) a, &g->arcs); 30 31 ga_shimmer_self (a); 32 33 /* node / arc linkage */ 34 35 a->start = gla_link (a, ALLOC (GL), src, &src->out); 36 a->end = gla_link (a, ALLOC (GL), dst, &dst->in); 37 a->weight = NULL; /* New arcs have no weight */ 38 39 return a; 40} 41 42/* .................................................. */ 43 44void 45ga_delete (GA* a) 46{ 47 gc_remove ((GC*) a, &a->base.graph->arcs); 48 gc_delete ((GC*) a); 49 50 /* interlink removal */ 51 52 gla_unlink (a->start, &a->start->n->out); 53 gla_unlink (a->end, &a->end->n->in); 54 55 ckfree ((char*) a->start); a->start = NULL; 56 ckfree ((char*) a->end); a->end = NULL; 57 58 if (a->weight) { 59 Tcl_DecrRefCount (a->weight); 60 a->weight = NULL; 61 } 62 63 ckfree ((char*) a); 64} 65 66/* .................................................. */ 67 68void 69ga_mv_src (GA* a, GN* nsrc) 70{ 71 GN* src = a->start->n; 72 73 if (src == nsrc) return; 74 75 gla_unlink (a->start, &src->out); 76 gla_link (a, a->start, nsrc, &nsrc->out); 77} 78 79/* .................................................. */ 80 81void 82ga_mv_dst (GA* a, GN* ndst) 83{ 84 GN* dst = a->end->n; 85 86 if (dst == ndst) return; 87 88 gla_unlink (a->end, &dst->in); 89 gla_link (a, a->end, ndst, &ndst->in); 90} 91 92/* .................................................. */ 93 94Tcl_Obj* 95ga_serial (GA* a, Tcl_Obj* empty, int nodeId) 96{ 97 Tcl_Obj* lv [4]; 98 99 lv [0] = a->base.name; 100 lv [1] = Tcl_NewIntObj (nodeId); 101 lv [2] = g_attr_serial (a->base.attr, empty); 102 103 if (a->weight) { 104 lv [3] = a->weight; 105 return Tcl_NewListObj (4, lv); 106 } else { 107 return Tcl_NewListObj (3, lv); 108 } 109} 110 111/* .................................................. */ 112 113void 114ga_err_duplicate (Tcl_Interp* interp, Tcl_Obj* a, Tcl_Obj* g) 115{ 116 Tcl_Obj* err = Tcl_NewObj (); 117 118 Tcl_AppendToObj (err, "arc \"", -1); 119 Tcl_AppendObjToObj (err, a); 120 Tcl_AppendToObj (err, "\" already exists in graph \"", -1); 121 Tcl_AppendObjToObj (err, g); 122 Tcl_AppendToObj (err, "\"", -1); 123 124 Tcl_SetObjResult (interp, err); 125} 126 127/* .................................................. */ 128 129void 130ga_err_missing (Tcl_Interp* interp, Tcl_Obj* a, Tcl_Obj* g) 131{ 132 Tcl_Obj* err = Tcl_NewObj (); 133 134 /* Keep any prefix ... */ 135 Tcl_AppendObjToObj (err, Tcl_GetObjResult (interp)); 136 Tcl_AppendToObj (err, "arc \"", -1); 137 Tcl_AppendObjToObj (err, a); 138 Tcl_AppendToObj (err, "\" does not exist in graph \"", -1); 139 Tcl_AppendObjToObj (err, g); 140 Tcl_AppendToObj (err, "\"", -1); 141 142 Tcl_SetObjResult (interp, err); 143} 144 145/* .................................................. */ 146 147static GL* 148gla_link (GA* a, GL* il, GN* n, GLA* na) 149{ 150 il->n = n; 151 il->a = a; 152 153 if (na->first) { 154 na->first->prev = il; 155 } 156 157 il->prev = NULL; 158 il->next = na->first; 159 160 na->first = il; 161 na->n ++; 162 163 return il; 164} 165 166/* .................................................. */ 167 168static void 169gla_unlink (GL* il, GLA* na) 170{ 171 if (na->first == il) { 172 na->first = il->next; 173 } 174 if (il->next) { 175 il->next->prev = il->prev; 176 } 177 if (il->prev) { 178 il->prev->next = il->next; 179 } 180 181 il->n = NULL; 182 il->a = NULL; 183 il->prev = NULL; 184 il->next = NULL; 185 186 na->n --; 187} 188 189/* .................................................. */ 190 191/* 192 * Local Variables: 193 * mode: c 194 * c-basic-offset: 4 195 * fill-column: 78 196 * End: 197 */ 198