|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T l
Length: 9337 (0x2479) Types: TextFile Names: »lists.c«
└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki └─⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/lists.c«
/************************************************************************\ * * * lists.c * * * * Routines to maintain, scan and manipulate the generic list structures * * that permeate the program. Some of the most oft used routines: * * * * strlistadd() add to a list of strings * * genlistadd() add an abitrary object to a list * * strlistdel() delete a string from a list * * genlistdel() delete an abitrary object from a list * * search_list() search a list for a particular item * * tmplistadd() add a list pointer to the queue of string lists * * that is freed just before mcp prompt for another * * command * * freelist() free all memory associated with a list structure * * listpop() pop the first pointer from a list * * orstrlist() make the union of two string lists * * * \************************************************************************/ #include <stdio.h> #include <strings.h> #include <ctype.h> #include "sysdep.h" #include "macros.h" #include "mem.h" #include "gpa.h" #include "lists.h" #include "sort.h" extern struct list TempLists; char * skipspace(s) char *s; { while (*s && isspace(*s)) s++; return(s); } /* * Cuts a string of space separated words into a series of null separated * words. Spaces may be imbedded in words only when the word is surround * ed by double quotes [""]. Returns the number of words in the string. */ int cut(line) char *line; { int wc = 0; register char *cp; cp = line; if (*line == '\0') return(0); while ( *line != '\0' ) { if ( isspace(*line) ) { *cp++ = '\0'; line++; line = skipspace(line); } else { wc++; while ( *line ) { if (*line == '"') { *cp++ = *line++; while (*line && *line != '"') *cp++ = *line++; if (*line == '\0') break; } else if (isspace(*line)) break; *cp++ = *line++; } } } return(wc); } /* * Makes a vector of pointers to the null separated strings pointed * to by line. The number count is needed to keep the thing from * going on forever. Note the arg vector is in a static area, and * is overwritten by subsequent calls. */ addr * mkargv(line, n) char *line; int n; { static addr argv[G_P_A__SIZE]; int i; flexaddr p; i = 0; p.p_cp = line; while ( i < n && i < 128) { argv[i] = p.p_ap; p.p_cp += strlen(p.p_cp) + 1; i++; } argv[i] = NIL; return(argv); } /* * Globs the arguments of an argv-like vector into a single string. */ addr glob(v) addr *v; { static addr_t gob[LONG_BUF]; flexaddr p; p.p_ap = gob; p.p_cp[0] = '\0'; while ( *v ) { (void) strcat(p.p_cp, (char *)*v++); (void) strcat(p.p_cp, " "); } p.p_cp[strlen(p.p_cp)-1] = '\0'; /* remove trailing blank */ return(gob); } parse_line(line, cc, vv) char *line; int *cc; addr **vv; { *cc = cut(line); *vv = mkargv(line, *cc); return; } freeargv(v) addr *v; { critical(); while (*v) { FREEMEM((char *)*v); *v++ = NIL; } non_critical(); } int search_list(l, s, compfunc, found) struct list *l; char *s; int (*compfunc)(), *found; { int lo = 0, hi = l->l_count - 1, middle, compval; *found = 0; while (lo < hi) { middle = (lo + hi) / 2; if ((compval = (*compfunc)(s, l->l_list[middle])) == 0) { *found = 1; return middle; } else if (compval < 0) { decr(middle); hi = middle; } else lo = middle + 1; } if (l->l_count && ((*compfunc)(s, l->l_list[lo])) == 0) *found = 1; return lo; } freelist(l) struct list *l; { register int i; critical(); for (i=0; i<l->l_count; i++) FREEMEM((char *)l->l_list[i]); if (l->l_spacefor > 0) FREEMEM((char *)l->l_list); l->l_count = l->l_spacefor = 0; non_critical(); return; } strlistadd(l, s) struct list *l; char *s; { critical(); if (l->l_spacefor == 0) { l->l_list = (addr *) MEM(STARTSIZE * sizeof (addr)); l->l_spacefor = STARTSIZE; } else if (l->l_count == l->l_spacefor) { l->l_list = (addr *) DELTAMEM((addr)l->l_list, 2 * l->l_spacefor * sizeof(addr)); l->l_spacefor *= 2; } savestr((char **)&l->l_list[l->l_count], s); l->l_count++; non_critical(); return; } genlistadd(l, p, n) register struct list *l; register addr p; int n; { critical(); if (l->l_spacefor == 0) { l->l_list = (addr *) MEM(STARTSIZE * sizeof (addr)); l->l_spacefor = STARTSIZE; } else if (l->l_count == l->l_spacefor) { l->l_list = (addr *) DELTAMEM((addr)l->l_list, 2 * l->l_spacefor * sizeof (addr)); l->l_spacefor *= 2; } l->l_list[l->l_count] = MEM(n); bcopy(l->l_list[l->l_count], p, n); l->l_count++; non_critical(); return; } listadd(l, p) struct list *l; addr p; { critical(); if (l->l_spacefor == 0) { l->l_list = (addr *) MEM(STARTSIZE * sizeof (addr)); l->l_spacefor = STARTSIZE; } else if (l->l_count == l->l_spacefor) { l->l_list = (addr *) DELTAMEM((addr)l->l_list, 2 * l->l_spacefor * sizeof (addr)); l->l_spacefor *= 2; } l->l_list[l->l_count] = p; l->l_count++; non_critical(); return; } strlistdel(l, s) struct list *l; char *s; { register int i; int found, indx, halfavail; critical(); indx = search_list(l, s, strcmp, &found); if (found) { FREEMEM((char *)l->l_list[indx]); for (i=indx; i<l->l_count-1; i++) l->l_list[i] = l->l_list[i+1]; l->l_count--; halfavail = l->l_spacefor / 2; if (l->l_count < halfavail && l->l_spacefor > STARTSIZE) { l->l_list = (addr *) DELTAMEM((addr)l->l_list, halfavail * sizeof (addr)); l->l_spacefor = halfavail; } } non_critical(); return; } genlistdel(l, p, compfunc) struct list *l; addr p; int (*compfunc)(); { register int i; int found, indx, halfavail; critical(); indx = search_list(l, (char *)p, compfunc, &found); if (found) { FREEMEM((char *)l->l_list[indx]); for (i=indx; i<l->l_count-1; i++) l->l_list[i] = l->l_list[i+1]; l->l_count--; halfavail = l->l_spacefor / 2; if (l->l_count < halfavail && l->l_spacefor > STARTSIZE) { l->l_list = (addr *) DELTAMEM((addr)l->l_list, halfavail * sizeof (addr)); l->l_spacefor = halfavail; } } non_critical(); return; } int strlistchg(l, old, new) struct list *l; char *old, *new; { int found, indx; indx = search_list(l, old, strcmp, &found); if (!found) return 0; FREEMEM((char *)l->l_list[indx]); savestr((char **)&l->l_list[indx], new); sort_list(l, pstrcmp); return 1; } addr listpop(l) struct list *l; { register int i; addr first; int halfavail; critical(); first = l->l_list[0]; for (i=0; i<l->l_count-1; i++) l->l_list[i] = l->l_list[i+1]; l->l_count--; halfavail = l->l_spacefor / 2; if (l->l_count < halfavail && l->l_spacefor > STARTSIZE) { l->l_list = (addr *) DELTAMEM((addr)l->l_list, halfavail * sizeof (addr)); l->l_spacefor = halfavail; } non_critical(); return first; } int instrlist(l, s) struct list *l; char *s; { int found; (void) search_list(l, s, strcmp, &found); return found; } zerolist(l) struct list *l; { l->l_count = 0; l->l_spacefor = 0; } duplist(new, old) struct list *new, *old; { critical(); new->l_count = old->l_count; new->l_spacefor = old->l_spacefor; new->l_list = old->l_list; non_critical(); return; } /* **copylist(dest, src, objsize) **struct list *dest, *src; **int objsize; ** **{ ** register int i; ** ** zerolist(dest); ** for (i=0; i<src->l_count; i++) ** genlistadd(dest, src->l_list[i], objsize); ** return; **} */ int orstrlist(l, ll) struct list *l, *ll; { register int indx; int changed = 0; for (indx=0; indx<ll->l_count; indx++) { if (instrlist(l, (char *)ll->l_list[indx])) continue; changed++; strlistadd(l, (char *)ll->l_list[indx]); sort_list(l, pstrcmp); } return changed; } tmplistadd(l) struct list *l; { critical(); listadd(&TempLists, (addr)l); non_critical(); return; } freetmplists() { while (TempLists.l_count) freelist((struct list *) listpop(&TempLists)); return; } #define COLUMNS 80 #define SEPDIST 3 char *re_comp(); showlist(l, regexv) struct list *l; addr *regexv; { register int i, k; int tabs, h, j, longest, n; static struct list matches; char *errmsg; register char *cp; if (l->l_count == 0) return 0; longest = 0; zerolist(&matches); tmplistadd(&matches); for (h=0; regexv[h]; h++) { errmsg = re_comp((char *)regexv[h]); if (errmsg) { err(errmsg); continue; } for (i=0; i < l->l_count; i++) { cp = (char *)l->l_list[i]; if (re_exec(cp) == 0) continue; if (instrlist(&matches, cp)) continue; longest = max(longest, strlen(cp)); strlistadd(&matches, cp); } } n = matches.l_count; if (n == 0) return n; sort_list(&matches, pstrcmp); tabs = n / ((COLUMNS-1) / (longest + SEPDIST)); tabs += ( n % ((COLUMNS-1) / (longest + SEPDIST)) ? 1 : 0 ); for (j = 1; j <= tabs; j++) { for (k = j - 1; k < n; k += tabs) { (void) fputs((char *)matches.l_list[k], stdout); space(longest - strlen((char *)matches.l_list[k]) + SEPDIST); } puts(""); } return n; } listlist(l) struct list *l; { int indx; for (indx=0; indx < l->l_count; indx++) (void) printf("%s ", l->l_list[indx]); puts(""); } listout(l, fp) struct list *l; FILE *fp; { int i; for (i=0; i < l->l_count; i++) { if (i > 0) fputs(",", fp); fputs((char *)l->l_list[i], fp); } return; }