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

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


#include "signal.h"
#include "refer.h"
#include "error.h"
#undef KERNEL
#include <sys/types.h>
#include <sys/stat.h>

static void signals(void);
static void cleanup(void);

void
main(int argc, char **argv)
{
	char	line[LLINE], *s;
	int	brack;

	progname = mkprogname(argv[0]);
	signals();
	while (argc > 1 && argv[1][0] == '-') {
		switch (argv[1][1]) {
		case 'e':
			endpush++; 
			break;
		case 'l':
			labels++;
			s = argv[1] + 2;
			if (!isdigit(*s)) 
				nmlen = INF_LENGTH;
			else 
				nmlen = atoi(s);
			for ( ; *s; s++)
				if (*s == ',' || *s == '_' || *s == '"')
					break;
			if (*s == '\0') {
				dtlen = INF_LENGTH;
				break;
			}
			if (*s == 0) 
				break;
			switch (*s++) {
			case ',': 
				labblkflg = 0; 
				break;
			case '_': 
				labblkflg = " "; 
				break;
			case '"':
				labblkflg = s;
				while (*s && *s != '"')
					s++;
				*s++ = 0; 
				break;
			}
			if (*s == '\0') 
				dtlen = INF_LENGTH;
			else 
				dtlen = atoi(s);
			break;
		case 'k':
			keywant = (argv[1][2] ? argv[1][2] : 'L');
			labels++;
			break;
		case 's':
			sort++;
			if (argv[1][2])
				keystr = argv[1] + 2;
			break;
		case 'p': 
			 {
				struct stat buf;
				argc--; 
				argv++;
				/* The below is not quite comprehensive; it
			 	 * will complain if the reference source file
			 	 * named exists but is not a regular file, but
			 	 * not if the source is missing and the .i? files
			 	 * do not exist or are not regular.
			 	 */
				if (argc < 2 ||
				    (stat(argv[1], &buf)>=0 && !S_ISREG(buf.st_mode)))
					err("-p requires the name of a file");
				*search++ = argv[1];
				if (search - rdata > NSEARCH)
					err("too many -p options (limit %d)", NSEARCH);
				break; 
			}
		case 'n':
			/* obsolete */
			break;
		case 'B':
			nobracket++; /* falls through */
			biblio++;
			bare = 2;
			if (argv[1][2])
				convert = argv[1]+2;
		case 'b':
			bare = (argv[1][2] == '1') ? 1 : 2;
			break;
		case 'c':
			smallcaps = argv[1] + 2;
			break;
		case 'a':
			authrev = atoi (argv[1] + 2);
			if (authrev <= 0)
				authrev = 1000;
			for (s = argv[1] + 2; isdigit(*s); s++)
				;
			if (*s == ',') 
				nocomma++;
			break;
		case 'd': /* reduce date to year only */
			yearonly = 1;
			break;
		case 'A': /* these fields get appended */
			appfld = argv[1] + 2;
			break;
		case 'I': /* these fields get ignored */
			ignfld = argv[1] + 2;
			break;
		case 'P': /* preserve original: no .ds's */
			preserve = 1;
			break;
		case 'L':
			labsepstr = argv[1] + 2; 
			break;
		case 'H': /* headers when sort key changes */
			headers = 1;
			break;
		case 'R': /* references in appearance order, list in -s order */
			order++;
			labels++;
			break;
		case 'f': /* use square brackets instead the troff default superscripts */
			sqbrack++;
			break;
		}
		if (order && !sort)
			err("-R without -s illegal");
		argc--; 
		argv++;
	}

	if (sort)
		endpush = 1;


	if (endpush)
		sprintf(tfile, "/tmp/rj%da", getpid());
	if (sort) {
		sprintf(ofile, "/tmp/rj%db", getpid());
		sprintf(tdfile, "/tmp/rj%de", getpid());
		ftemp = efopen(ofile, "w");
	}

	do {
		if (argc > 1) {
			if (in != stdin)
				fclose(in);
			Iline = 0;
			if (strcmp(argv[1], "-") == SAME)
				in = stdin;
			else
				in = efopen(Ifile = argv[1], "r");
			argc--; 
			argv++;
		}
		if (sqbrack) {
			/* These follow definitions in the macros, and therefore
			 * override them.
			 */
			printf(".ds [. [\n");
			printf(".ds .] ]\n");
			printf(".ds <. \"\n");
			printf(".ds >. .\n");
		}
		while (input(line)) {
			Iline++;
			if (biblio && *line == '\n')
				doref(line);
			else if (biblio && Iline == 1 && *line == '%')
				doref(line);

#if D1
			fprintf(stderr, "line %.20s\n", line);
#endif
			if ((brack = prefix(".[", line)) || (nobracket && line[0] != '\n')) {
				if (brack) 
					trailspace(Iline, line);
				if (endpush && (fo == NULL || fo == stdout)) {
					fo = efopen(tfile, "w");
# if D1
					fprintf(stderr, "opened %s as %o\n", tfile, fo);
#endif
					sep = 002; /* separate records without confusing sort..*/
				}
				doref(line);
			} else
				output(line);
# if D1
			fprintf(stderr, "past output/doref\n");
#endif
		}
	} while (argc > 1);
# if D1
	fprintf(stderr, "before dumpold, endpush %d fo %o\n", endpush, fo);
#endif
	widelab();
	if (endpush && (fo != NULL && fo != stdout))
		dumpold();
	output("");
	fflush (ftemp);
	if (sort)
		recopy(ofile);
# ifndef D1
	cleanup();
#endif
	exit(0);
}

void trailspace(int lineno, char *s)
{
	int i;

	for (i = 0; s[i] != '\0' && s[i] != '\n'; i++)
		;
	if (i != 0 && s[i - 1] == ' ')
		warn(lineno, "space(s) at end of line");
}

static void intr(int x)
{
	USED(x);
	signal(SIGINT, SIG_IGN);
	cleanup();
	exit(1);
}

static void signals(void)
{
	if (signal(SIGINT, SIG_IGN) != SIG_IGN)
		signal(SIGINT, intr);
	if (signal(SIGHUP, SIG_IGN) != SIG_IGN)
		signal (SIGHUP, intr);
	signal(SIGPIPE, intr);
	if (signal(SIGTERM, SIG_IGN) != SIG_IGN)
		signal(SIGTERM, intr);
}

static void cleanup(void)
{
	if (tfile[0]) 
		remove(tfile);
	if (gfile[0]) 
		remove(gfile);
	if (ofile[0]) 
		remove(ofile);
	if (hidenam[0]) 
		remove(hidenam);
}

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.