DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download
Index: ┃ T l

⟦dc82ac647⟧ TextFile

    Length: 9337 (0x2479)
    Types: TextFile
    Names: »lists.c«

Derivation

└─⟦a0efdde77⟧ Bits:30001252 EUUGD11 Tape, 1987 Spring Conference Helsinki
    └─ ⟦this⟧ »EUUGD11/euug-87hel/sec8/mcp/src/lists.c« 

TextFile

/************************************************************************\
* 									 *
* 	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;
}