Plan 9 from Bell Labs’s /usr/web/sources/contrib/steve/root/sys/src/cmd/refer/refer2.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


# include "refer.h"

#ifndef D1
#define	D1 0
#endif

extern FILE *in;
# define NFLD 200

# define TLEN 4096
char	one[ANSLEN];
int	onelen = ANSLEN;
static char	dr [100] = "";
char	*maynard;

static int newline(char *);
static void choices(char *);
static void dirfix(char *);
static void clean(char *[], int, int);

/* refer2.c */
//void doref(char *);
//int newline(const char *);
int control(int);

void doref(char *firline)
{
	char buff[QLEN], dbuff[3*QLEN], answer[ANSLEN], temp[TLEN];
	char line[LLINE];
	char *p, **sr, *flds[NFLD], *r;
	int nf, nr, alph, query = 0, chp, digs, i;

	/* get query */
   again:
	buff[0] = dbuff[0] = 0;
	if (nobracket) {
	if (biblio && Iline == 1 && firline[0] == '%')
		strcpy( control(firline[0]) ? dbuff : buff , firline);
		if (control(firline[0])) 
			query = 1;
		firline = "  ";
	}
	while (input(line)) {	/* get query */
		Iline++;
		if (prefix(".]", line)) {
			trailspace(Iline, line);
			break;
		}
		if (biblio && line[0] == '\n')
			break;
		if (biblio && line[0] == '%' && line[1] == *convert)
			break;
		if (nobracket) {
			int	i, allblank = 1;
			for (i = 0; allblank && line[i] != '\0'; i++)
				if (!isspace(line[i]))
					allblank = 0;
			if (allblank)
				break;
		}
		if (control(line[0])) 
			query = 1;
		strcat (query  ? dbuff : buff, line);
		if (strlen(buff) >= QLEN)
			errline("query too big (%d char limit)", Iline, QLEN);
		if (strlen(dbuff) >= 3 * QLEN)
			errline("direct query too long (%d char limit)", Iline, 3 * QLEN);
	}
	if (biblio && line[0] == '\n' && feof(in))
		return;
	if (!query && !nobracket && buff[0] == 0)
		errline("empty query", Iline, "");
	if (strcmp (buff, "$LIST$\n") == 0) {
#if D1
		fprintf(stderr, "dump sorted list\n");
#endif
		assert ( dbuff[0] == 0);
		dumpold();
		return;
	}
	answer[0] = 0;
#if D1
	fprintf(stderr, "query is %s\n", buff);
#endif
	for ( p = buff; *p; p++) {
		if (isupper(*p)) 
			*p |= 040;
	}
	alph = digs = 0;
	for (p = buff; *p; p++) {
		if (isalpha(chp = *p)) 
			alph++;
		else if (isdigit(*p)) 
			digs++;
		else {
			*p = 0;
			if ( (alph + digs < 3) || common(p - alph)) {
				r = p - alph;
				while (r < p)
					*r++ = ' ';
			}
			if ( alph == 0 && digs > 0) {
				r = p - digs;
#if D1
				fprintf(stderr, "number, %d long, text is %s\n", digs, r);
#endif
				if (digs != 4 || (atoi(r) / 100 != 19)) {
					while (r < p)
						*r++ = ' ';
				}
			}
			if (chp == '\\')
				*p++ = ' ';
			*p = ' ';
			alph = digs = 0;
		}
	}
#if D1
	fprintf(stderr, "query translated to %s\n", buff);
#endif
	one[0] = 0;
	if (buff[0]) /* do not search if no query */
		for ( sr = rdata; sr < search; sr++) {
#if D1
			fprintf(stderr, "now searching %s\n", *sr);
#endif
			temp[0] = 0;
			corout (buff, temp, "hunt", *sr, TLEN);
			strcpy(dr, *sr);
			dirfix(dr);
			if (strlen(temp) >= TLEN)
				err("Accumulated answers too large %d >= TLEN", strlen(temp));
			if (strlen(temp) + strlen(answer) >= ANSLEN)
				err("Accumulated answers too large %d >= ANSLEN", strlen(temp) + strlen(answer));
			strcat(answer, temp);
			if (strlen(answer) >= LLINE)
				err("answer too long (%d)", strlen(answer));
			if (newline(answer) > 0) 
				break;
		}
#if D1
	fprintf(stderr, "answer:\n%s****\n", answer);
#endif
	assert (strlen(one) < ANSLEN);
	assert (strlen(answer) < ANSLEN);
	if (buff[0])
		switch (newline(answer)) {
		case 0:
			warn(Iline, "no such paper %s", (trimnl(buff),buff));
			return;
		default:
			warn(Iline, "too many hits for '%s'", (trimnl(buff),buff));
			choices(answer);
			p = buff;
			while (*p != '\n') 
				p++;
			*++p = 0;
		case 1:
#if D1
			fprintf(stderr, "found one\n");
#endif
{maynard=(trimnl(buff),buff);}
			if (endpush)
				if (nr = chkdup(answer)) {
					if (bare < 2)
						putsig (0, flds, nr, firline, line);
					return;
				}
#if D1
			fprintf(stderr, "one[0] was %o\n", one[0]);
#endif
			if (one[0] == 0)
				corout (answer, one, "deliv", dr, QLEN);
#if D1
			fprintf(stderr, "one now %o\n", one[0]);
#endif
			break;
		}
	assert (strlen(buff) < QLEN);
	assert (strlen(one) < ANSLEN);
	nf = tabs(flds, one, NFLD);
	if (nf < 0)
		errline("more than %d words in a reference", Iline, NFLD);
	i = tabs(flds + nf, dbuff, NFLD - nf);
	if (i < 0)
		errline("more than %d words in a reference", Iline, NFLD);
	nf += i;
	clean(flds, nf, 'L');
#if D1
	fprintf(stderr, "one %.20s dbuff %.20s nf %d\n", one, dbuff, nf);
#endif
	assert (nf < NFLD);
	refnum++;
	if (sort) 
		putkey (nf, flds, refnum, keystr);
#if D1
	fprintf(stderr, "past putkey, bare %d\n", bare);
#endif
	if (bare < 2)
		putsig (nf, flds, refnum, firline, line);
	else
		flout();
#if D1
	fprintf(stderr, "put signal\n");
#endif
	putref (nf, flds);
#if D1
	fprintf(stderr, "put ref\n");
#endif
	if (biblio && line[0] == '\n')
		goto again;
	if (biblio && line[0] == '%' && line[1] == *convert)
		fprintf(fo, "%s%c%s", convert+1, sep, line+3);

}

static int newline(char *s)
{
	int k;

	for (k=0; (s = strchr(s, '\n')) != 0; s++)
		k++;
	return k;
}

static void choices(char *buff)
{
	char	ob[LLINE], *p, *r, *q, *t;
	int	nl;
	for (r = p = buff; *p; p++) {
		if (*p == '\n') {
			*p++ = 0;
			 {
				corout (r, ob, "deliv", dr, LLINE);
				nl = 1;
				for ( q = ob; *q; q++) {
					if (nl && (q[0] == '.' || q[0] == '%') && q[1] == 'T') {
						q += 3;
						for (t = q; *t && *t != '\n'; t++)
							;
						*t = 0;
						fprintf(stderr, "%.70s\n", q);
						q = 0; 
						break;
					}
					nl = *q == '\n';
				}
				if (q)
					fprintf(stderr, "??? at %s\n", r);
			}
			r = p;
		}
		if (*p == 0) 
			break; /* the p++ might go past the end */
	}
}

int control(int c)
{
	return c == '.' || c == '%';
}

static void dirfix(char *s)
{
	char *t;

	if ((t = strrchr(s, '/')) != 0)
		*t = 0;
	else
		strcpy(s, ".");
}

static void clean(char *xf[], int nf, int c)
{
	int	i, j;
	for (i = nf - 1; i >= 0; i--) {
		if (control(xf[i][0]) && xf[i][1] == c)
			break;
	}
	if (i < 0) 
		return;
	for (j = i - 1; j >= 0; j--) {
		if (control(xf[j][0]) && xf[j][1] == c)
			xf[j][1] = '~'; /* cancel */
	}
}


Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.