|
|
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;
}