home *** CD-ROM | disk | FTP | other *** search
- /* (C) C.D.F. Miller, Heriot-Watt University, March 1984
- *
- * Permission is hereby given to reproduce or modify this
- * software freely, provided that this notice be retained,
- * and that no use be made of the software for commercial
- * purposes without the express written permission of the
- * author.
- */
-
- /* scan.c:
- * scan an input file, recording label-definitions, etc.
- * All special actions are introduced by a line starting
- * .<macro>
- * where <macro> is "L=" unless redefined in the command-line.
- * Actions are
- * .L= <type> <level> <label>
- * define <label> by incrementing the <level>th
- * index of label-type <type>, e.g.
- * .L= table 1 profits_1983
- * .L= delimiter <char>
- * redefines the delimiter for the subsequent text.
- * .L= format <type> <string>
- * defines a format for displaying the given label <type>;
- * the latest definition in the input will be used for
- * ALL occurrences, including preceding ones.
- * e.g.
- * .L= format appendix %A-%1
- * .L= next <type> <value> <value> ...
- * set the value of the next label generated for <type>;
- * the <value>s give successive levels, with omitted
- * trailing values defaulting to 0.
- */
-
- #include <lbl.h>
- #include <ctype.h>
-
- extern char macroname[];
- extern char *filename;
- extern int sflag;
- extern FILE *tempfile;
- extern long fileline;
-
- scan(fname, f)
- rg char *fname;
- rg FILE *f;
- {
- char line[BUFSIZ];
- rg int line_complete = 1;
-
- /* Mark start of file in temp file */
- if (!sflag)
- fprintf(tempfile, "%c%c%c%s\n", MAGIC1, MAGIC2, M_FILE, fname);
- filename = fname;
- fileline = 0L;
-
- while (fgets(line, BUFSIZ, f) != NULL)
- {
- if (!sflag)
- fputs(line, tempfile);
- if (line_complete)
- {
- fileline++;
- line_complete = line[strlen(line)-1] == '\n';
- if (line[0]=='.' && line[1]==macroname[0] &&
- line[2]==macroname[1])
- {
- if (line_complete)
- process(line+3);
- else
- error(".%s line too long", macroname);
- }
- }
- else
- line_complete = line[strlen(line)-1] == '\n';
- }
- }
-
- process(line)
- char *line;
- {
- us int split();
- keyword *findkeyword();
- us int nargs;
- char *argvec[NLEVELS+2];
- keyword *key;
-
- if ((nargs = split(line, argvec)) == 0)
- {
- error("empty .%s line", macroname);
- return;
- }
-
- /* Check for and act upon reserved words */
- if ((key = findkeyword(argvec[0])) != NULL)
- {
- if (nargs < key->k_minargs)
- {
- error("%s - too few arguments", key->k_name);
- return;
- }
- if (nargs > key->k_maxargs)
- {
- error("%s - too many arguments", key->k_name);
- return;
- }
- (*(key->k_action))(nargs, argvec);
- return;
- }
-
- /* Process a label definition */
- if (nargs != 3)
- {
- error("too %s arguments in label definition",
- nargs < 3 ? "few" : "many");
- return;
- }
- addlbl(argvec[0], argvec[1], argvec[2]);
- }
-
- /* split - split a line into arguments
- * N.B. successive calls of this invalidate earlier calls;
- * argvec is set to point to strings within the
- * static local buffer "copybuf" which is overwritten on
- * each call.
- */
- us int
- split(line, argvec)
- char *line;
- char *argvec[];
- {
- us int nargs = 0;
- static char copybuf[BUFSIZ];
- char *ln = copybuf;
-
- strcpy(ln, line);
- while (*ln)
- {
- while (isspace(*ln))
- ln++;
- if (*ln)
- {
- if (nargs > 2+NLEVELS)
- {
- error("surplus arguments to .%s ignored",
- macroname);
- break;
- }
- argvec[nargs++] = ln;
- while (*ln && !isspace(*ln))
- ln++;
- if (*ln)
- *ln++ = '\0';
- }
- }
- if (nargs > 2+NLEVELS)
- nargs = 2+NLEVELS;
- return nargs;
- }
-