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