/*=================================================== * convert_proplist_to_proparray -- * Convert a list of property tables to an array of same * Consumes the list (actually removes it at end) * Output array is one larger than list, and last entry is NULL * Created: 2002/10/19, Perry Rapp *=================================================*/ TABLE * convert_proplist_to_proparray (LIST list) { TABLE * props; INT i; props = (TABLE *)malloc((length_list(list)+1)*sizeof(props[0])); i = 0; FORLIST(list, el) props[i++] = (TABLE)el; ENDLIST props[i] = NULL; /* null marker at end of array */ destroy_list(list); return props; }
void list_sort (void *list, NODE_COMPARE comp) { int jump_size, i; LIST *base, *swap, *temp; Bool swapped; jump_size = 0; FORLIST (base, * (LIST *) list) jump_size++; swapped = TRUE; while ((jump_size > 1) || swapped) { jump_size = (10 * jump_size + 3) / 13; base = ((LIST *) list)-> next; swap = base; for (i = 0; i < jump_size; i++) swap = swap-> next; swapped = FALSE; while (swap != (LIST *) list) { if ((*comp) (base, swap)) { temp = base-> prev; list_unlink (base); list_relink_after (base, swap); list_unlink (swap); list_relink_after (swap, temp); temp = base; base = swap; swap = temp; swapped = TRUE; } base = base-> next; swap = swap-> next; } } }
/*================================================================= * expand_tree -- Create copy of node tree with additional link info *===============================================================*/ static NODE expand_tree (NODE root0) { NODE copy, node, sub; STRING key; static NODE root; /* root of record being edited */ LIST subs; /* list of contained records */ NODE expd; /* expanded main record - copy - our retval */ root = root0; expd = copy_nodes(root, TRUE, TRUE); subs = create_list(); traverse_nodes(expd, advedit_expand_traverse, subs); /* expand the list of records into the copied record */ FORLIST(subs, el) node = (NODE) el; #ifdef DEBUG llwprintf("in list: %s %s\n", ntag(node), nval(node)); #endif key = rmvat(nval(node)); if ((sub = nztop(key_possible_to_record(key, *key)))) { copy = copy_node_subtree(sub); nxref(node) = nxref(copy); ntag(node) = ntag(copy); nchild(node) = nchild(copy); nparent(node) = nparent(copy); /*MEMORY LEAK; MEMORY LEAK; MEMORY LEAK: node not removed (because its value and possibly xref [probably not] are still being referred to */ } ENDLIST /* Shouldn't we free subs now ? Perry 2001/06/22 */ #ifdef DEBUG show_node(expd); #endif return expd; }
/*================================================================= * advedit_expand_traverse -- Traverse routine called when expanding record *===============================================================*/ static BOOLEAN advedit_expand_traverse (NODE node, VPTR param) { LIST subs = (LIST)param; STRING key = value_to_xref(nval(node)); if (!key) return TRUE; key = strsave(key); #ifdef DEBUG llwprintf("expand_traverse: %s %s\n", ntag(node), nval(node)); #endif /* DEBUG */ FORLIST(subs, el) #ifdef DEBUG llwprintf("expand_traverse: %s %s\n", key, rmvat(nval((NODE) el))); #endif /* DEBUG */ if (eqstr(key, rmvat(nval((NODE) el)))) { STOPLIST stdfree(key); return TRUE; } ENDLIST enqueue_list(subs, node); stdfree(key); return TRUE; }
/*================================================= * add_dnodes -- add dnodes to dnode tree * recursively, traversing NODE tree & building corresponding * dnode tree * if a line overflows, give it succeeding sibling dnodes * also, check for subordinate CONT & CONC dnodes to be assimilated *===============================================*/ static DISPNODE add_dnodes (NODE node, INT gen, INT indent, INT maxgen, INT * count, CANVASDATA canvas) { DISPNODE tn; DISPNODE tn0, tn1, tn2; NODE child, anode; INT width = (canvas->rect->right - canvas->rect->left) - 2 - gen*indent; static char line[MAXLINELEN], output[MAXLINELEN]; /* must be same size */ STRING ptr=output; INT leader; LIST list=NULL; INT mylen=sizeof(output), mylenorig; if (mylen>width) mylen = width; mylenorig = mylen; /* build xref & tag into line */ line[0] = 0; ptr = line; mylen = sizeof(line); if (nxref(node)) { llstrcatn(&ptr, nxref(node), &mylen); llstrcatn(&ptr, " ", &mylen); } if (ntag(node)) { llstrcatn(&ptr, ntag(node), &mylen); llstrcatn(&ptr, " ", &mylen); } leader = ptr-line; width -= leader; if (width < 10) { /* insufficient space */ return NULL; } /* output is available as scratch */ list = text_to_list("", width, LISTDOFREE); if (nval(node)) { STRING valtxt = nval(node); append_to_text_list(list, valtxt, width, FALSE); } /* anode is first child */ anode = nchild(node); /* check for text continuation nodes to assimilate */ if (nchild(node)) { for ( ; anode && !nchild(anode); anode = nsibling(anode)) { BOOLEAN newline=FALSE; STRING valtxt=NULL; if (eqstr(ntag(anode), "CONC")) { append_to_text_list(list, " ", width, FALSE); newline = FALSE; } else if (eqstr(ntag(anode), "CONT")) { newline = TRUE; } else { break; } valtxt = nval(anode); append_to_text_list(list, valtxt, width, newline); } } /* anode is now first non-assimilated child */ /* now add all list elements to tree as siblings first one will be tn, which we return as our result tn0 refers to previous one, for the nsibling links */ tn = tn0 = tn1 = 0; FORLIST(list, el) tn1 = alloc_displaynode(); if (!tn) { INT i; tn = tn1; /* ptr & mylen still point after leader */ llstrcatn(&ptr, el, &mylen); /* put original line */ tn1->str = strsave(line); /* now build leader we will keep reusing */ for (i=0; i<leader; i++) line[i] = '.'; line[leader-1] = ' '; } else { llstrcatn(&ptr, el, &mylen); tn1->str = strsave(line); } /* now we keep resetting ptr & mylen to after blank leader */ /* so we keep reusing that leader we built in line earlier */ ptr=line+leader; mylen=mylenorig-leader; tn1->firstchild = 0; tn1->nextsib = 0; if (tn0) tn0->nextsib = tn1; tn0 = tn1; (*count)++; ENDLIST /* special handling for empty list, which didn't get its leader */ if (is_empty_list(list)) { tn1 = alloc_displaynode(); tn = tn1; tn1->str = strsave(line); tn1->firstchild = 0; tn1->nextsib = 0; tn0 = tn1; (*count)++; } destroy_list(list); list=0; if (gen < maxgen) { /* our children hang off of tn2, which is last node of our sibling tree; tn0 is previously added child */ tn2 = tn1; tn0 = 0; /* anode was last unassimilated child */ for (child = anode; child; child = nsibling(child)) { tn1 = add_dnodes(child, gen+1, indent, maxgen, count, canvas); if (!tn1) continue; /* child was skipped */ /* link new displaynode into tree we're building */ if (tn0) tn0 = tn0->nextsib = tn1; else /* first child - first time thru loop */ tn0 = tn2->firstchild = tn1; /* child displaynode might have (overflow or assimilated) siblings */ while (tn0->nextsib) tn0 = tn0->nextsib; } } return tn; }