131819Sdenise /*************************************************************************
231819Sdenise  *
3*31820Sdenise  * @(#)parse.c	1.2 (CWI) 87/07/10
4*31820Sdenise  *
531819Sdenise  * Code to parse the ditroff output language and take the appropriate
631819Sdenise  * action.
731819Sdenise  *
831819Sdenise  * For a description of the ditroff language, see the comment in main.c.
931819Sdenise  *
1031819Sdenise  ************************************************************************/
1131819Sdenise 
1231819Sdenise #include "the.h"
1331819Sdenise 
1431819Sdenise /* from dev.c  */
1531819Sdenise extern int	output;		/* do we output at all? */
1631819Sdenise extern int	hpos, vpos;	/* current position	*/
1731819Sdenise extern int	virtRES;	/* resolution of input		*/
1831819Sdenise 
1931819Sdenise /* from main.c */
2031819Sdenise extern int	debug, dbg;
21*31820Sdenise extern char	*devname;
2231819Sdenise 
2331819Sdenise 
conv(fp)2431819Sdenise conv(fp)
2531819Sdenise register FILE *fp;
2631819Sdenise {
2731819Sdenise 	register int c, k;
2831819Sdenise 	int m, n, n1, m1;
2931819Sdenise 	char str[100], buf[300];
3031819Sdenise 
3131819Sdenise 	while ((c = getc(fp)) != EOF) {
3231819Sdenise 		switch (c) {
3331819Sdenise 		case '\n':	/* when input is text */
3431819Sdenise 		case 0:		/* occasional noise creeps in */
3531819Sdenise 		case '\t':
3631819Sdenise 		case ' ':
3731819Sdenise 			break;
3831819Sdenise 		case '{':	/* push down current environment */
3931819Sdenise 			t_push();
4031819Sdenise 			break;
4131819Sdenise 		case '}':
4231819Sdenise 			t_pop();
4331819Sdenise 			break;
4431819Sdenise 		case '0': case '1': case '2': case '3': case '4':
4531819Sdenise 		case '5': case '6': case '7': case '8': case '9':
4631819Sdenise 			/* two motion digits plus a character */
4731819Sdenise 			k = (c-'0')*10 + getc(fp)-'0';
4831819Sdenise 			hmot(k);
4931819Sdenise 			put1(getc(fp));
5031819Sdenise 			break;
5131819Sdenise 		case 'c':	/* single ascii character */
5231819Sdenise 			put1(getc(fp));
5331819Sdenise 			break;
5431819Sdenise 		case 'C':
5531819Sdenise 			fscanf(fp, "%s", str);
5631819Sdenise 			put1s(str);
5731819Sdenise 			break;
5831819Sdenise 		case 't':	/* straight text */
5931819Sdenise 			if (fgets(buf, sizeof(buf), fp) == NULL)
6031819Sdenise 			    error(FATAL, "unexpected end of input");
6131819Sdenise 			t_text(buf);
6231819Sdenise 			break;
6331819Sdenise 		case 'D':	/* draw function */
6431819Sdenise 			if (fgets(buf, sizeof(buf), fp) == NULL)
6531819Sdenise 			    error(FATAL, "unexpected end of input");
6631819Sdenise 			switch (buf[0]) {
6731819Sdenise 			case 'l':	/* draw a line */
6831819Sdenise 			    sscanf(buf+1, "%d %d", &n, &m);
6931819Sdenise 			    drawline(n, m);
7031819Sdenise 			    break;
7131819Sdenise 			case 'c':	/* circle */
7231819Sdenise 			    sscanf(buf+1, "%d", &n);
7331819Sdenise 			    drawcirc(n);
7431819Sdenise 			    break;
7531819Sdenise 			case 'e':	/* ellipse */
7631819Sdenise 			    sscanf(buf+1, "%d %d", &m, &n);
7731819Sdenise 			    drawellip(m, n);
7831819Sdenise 			    break;
7931819Sdenise 			case 'a':	/* arc */
8031819Sdenise 			    sscanf(buf+1, "%d %d %d %d", &n, &m, &n1, &m1);
8131819Sdenise 			    drawarc(n, m, n1, m1);
8231819Sdenise 			    break;
8331819Sdenise 
8431819Sdenise 			case '~':	/* wiggly line */
8531819Sdenise 			    drawwig(buf+1, fp, buf[0] == '~');
8631819Sdenise 			    break;
8731819Sdenise 			default:
8831819Sdenise 			    error(FATAL, "unknown drawing function %s", buf);
8931819Sdenise 			    break;
9031819Sdenise 			}
9131819Sdenise 			break;
9231819Sdenise 		case 's':
9331819Sdenise 			fscanf(fp, "%d", &n);
9431819Sdenise 			setsize(t_size(n));
9531819Sdenise 			break;
9631819Sdenise 		case 'f':
9731819Sdenise 			fscanf(fp, "%s", str);
9831819Sdenise 			setfont(t_font(str));
9931819Sdenise 			break;
10031819Sdenise 		case 'H':	/* absolute horizontal motion */
10131819Sdenise 			while ((c = getc(fp)) == ' ')
10231819Sdenise 				;
10331819Sdenise 			k = 0;
10431819Sdenise 			do {
10531819Sdenise 				k = 10 * k + c - '0';
10631819Sdenise 			} while (isdigit(c = getc(fp)));
10731819Sdenise 			ungetc(c, fp);
10831819Sdenise 			hgoto(k);
10931819Sdenise 			break;
11031819Sdenise 		case 'h':	/* relative horizontal motion */
11131819Sdenise 			while ((c = getc(fp)) == ' ')
11231819Sdenise 				;
11331819Sdenise 			k = 0;
11431819Sdenise 			do {
11531819Sdenise 				k = 10 * k + c - '0';
11631819Sdenise 			} while (isdigit(c = getc(fp)));
11731819Sdenise 			ungetc(c, fp);
11831819Sdenise 			hmot(k);
11931819Sdenise 			break;
12031819Sdenise 		case 'w':	/* word space */
12131819Sdenise 			break;
12231819Sdenise 		case 'V':
12331819Sdenise 			fscanf(fp, "%d", &n);
12431819Sdenise 			vgoto(n);
12531819Sdenise 			break;
12631819Sdenise 		case 'v':
12731819Sdenise 			fscanf(fp, "%d", &n);
12831819Sdenise 			vmot(n);
12931819Sdenise 			break;
13031819Sdenise 		case 'P':	/* new spread */
13131819Sdenise 
13231819Sdenise 			DBGPRINT(0, ("output = %d\n", output));
13331819Sdenise 
13431819Sdenise 			if (output) outband(OVERBAND);
13531819Sdenise 			break;
13631819Sdenise 		case 'p':	/* new page */
13731819Sdenise 			fscanf(fp, "%d", &n);
13831819Sdenise 			t_page(n);
13931819Sdenise 			break;
14031819Sdenise 		case 'n':	/* end of line */
14131819Sdenise 			t_newline();
14231819Sdenise 
14331819Sdenise 		case '#':	/* comment */
14431819Sdenise 			do
14531819Sdenise 				c = getc(fp);
14631819Sdenise 			while (c != '\n' && c != EOF);
14731819Sdenise 			break;
14831819Sdenise 		case 'x':	/* device control */
14931819Sdenise 			if (devcntrl(fp)) return;
15031819Sdenise 			break;
15131819Sdenise 		default:
15231819Sdenise 			error(FATAL, "unknown input character %o %c", c, c);
15331819Sdenise 		}
15431819Sdenise 	}
15531819Sdenise }
15631819Sdenise 
15731819Sdenise int
devcntrl(fp)15831819Sdenise devcntrl(fp)		/* interpret device control functions */
15931819Sdenise FILE *fp;		/* returns -1 apon recieving "stop" command */
16031819Sdenise {
16131819Sdenise         char str[20], str1[50], buf[50];
16231819Sdenise 	int c, n;
16331819Sdenise 
16431819Sdenise 	fscanf(fp, "%s", str);
16531819Sdenise 	switch (str[0]) {	/* crude for now */
16631819Sdenise 	case 'i':			/* initialize */
16731819Sdenise 		fileinit();
16831819Sdenise 		t_init();
16931819Sdenise 		break;
17031819Sdenise 	case 't':			/* trailer */
17131819Sdenise 		break;
17231819Sdenise 	case 'p':			/* pause -- can restart */
17331819Sdenise 		t_reset('p');
17431819Sdenise 		break;
17531819Sdenise 	case 's':			/* stop */
17631819Sdenise 		t_reset('s');
17731819Sdenise 		return -1;
17831819Sdenise 	case 'r':			/* resolution assumed when prepared */
17931819Sdenise 		fscanf(fp, "%d", &virtRES);
18031819Sdenise 		initgraph(virtRES);		/* graph needs to know about this */
18131819Sdenise 		break;
18231819Sdenise 	case 'f':			/* font used */
18331819Sdenise 		fscanf(fp, "%d %s", &n, str);
18431819Sdenise 		(void) fgets(buf, sizeof buf, fp);   /* in case of filename */
18531819Sdenise 		ungetc('\n', fp);		/* fgets goes too far */
18631819Sdenise 		str1[0] = 0;			/* in case nothing comes in */
18731819Sdenise 		sscanf(buf, "%s", str1);
18831819Sdenise 		loadfont(n, str, str1);
18931819Sdenise 		break;
19031819Sdenise 	case 'H':			/* char height */
19131819Sdenise 		fscanf(fp, "%d", &n);
19231819Sdenise 		t_charht(n);
19331819Sdenise 		break;
19431819Sdenise 	case 'S':			/* slant */
19531819Sdenise 		fscanf(fp, "%d", &n);
19631819Sdenise 		t_slant(n);
19731819Sdenise 		break;
19831819Sdenise 	case 'T':			/* device name */
199*31820Sdenise 		fscanf(fp, "%s", str);
200*31820Sdenise 		if (strcmp(str,devname) != 0)
201*31820Sdenise 			exit(-1);	/* tell lpd to abort this file */
20231819Sdenise 		break;
20331819Sdenise 
20431819Sdenise 	}
20531819Sdenise 	while ((c = getc(fp)) != '\n')	/* skip rest of input line */
20631819Sdenise 		if (c == EOF)
20731819Sdenise 			return -1;
20831819Sdenise 	return 0;
20931819Sdenise }
210