From 3a9aa90773f334d735570772ba490d4fff3bfefa Mon Sep 17 00:00:00 2001 From: CSRG Date: Fri, 5 Nov 1982 07:11:02 -0800 Subject: [PATCH] BSD 4_1c_2 development Work on file usr/src/ucb/ingres/source/equel/display.c Synthesized-from: CSRG/cd1/4.1c.2 --- usr/src/ucb/ingres/source/equel/display.c | 333 ++++++++++++++++++++++ 1 file changed, 333 insertions(+) create mode 100644 usr/src/ucb/ingres/source/equel/display.c diff --git a/usr/src/ucb/ingres/source/equel/display.c b/usr/src/ucb/ingres/source/equel/display.c new file mode 100644 index 0000000000..92fdc36e8e --- /dev/null +++ b/usr/src/ucb/ingres/source/equel/display.c @@ -0,0 +1,333 @@ +# include +# include "constants.h" +# include "globals.h" +# include + +SCCSID(@(#)display.c 7.2 10/27/81) + +/* +** DISPLAY.C -- display manipulation routines +** +** a display is a list of strings, the symbol +** space Symsp is impemented by means of displays. +** +** Required By: +** Lexical analysis routines to add to the symbol space +** semantic productions to manipulate input +*/ + + + + + /* this avoids having to specify &Cv_display in the semantic + * routines, by making Cv_display a pointer to the pertinent + * display structure. + */ +struct display *Cv_display = &Displays [0]; + + /* +** ENTER_DISPLAY -- enter a new string into a display +** +** Parameters: +** disp -- display to be added to +** string -- string to add +** +** Returns: +** pointer to new disp_node structure. +** +** Side Effects: +** allocates a new disp_node structispl +** Expects a dynamic "string", i.e. one that it can +** dispose of as it wishes, so it is the users responsability +** to allocate space for this string. +** If the string passed is 0, the string +** "ERROR_TOKEN" is substituted, and a message is printed, +** so a caller may call enter_display with the return of an +** salloc() directly. +** If no space is available for the allocation of the +** new node, an error message is given, and a reset(III) +** is performed (this should goto equel()[main.c]) +** +** Called By: +** add_sym() -- to add a token to the Symsp +** the semantic productions -- for manipulating usages +** of C variables. +*/ + + +struct disp_node *enter_display(disp, string) +struct display *disp; +char *string; +{ + register struct display *d; + register struct disp_node *node; + + node = (struct disp_node *)nalloc(sizeof *node); + if (node == 0) + { + yysemerr("symbol space overflow", string); + reset(1); + } + d = disp; + if (!d->disp_first) + d->disp_first = d->disp_last = node; + else + { + d->disp_last->d_next = node; + d->disp_last = node; + } + node->d_next = 0; + if (!(node->d_elm = string)) + { + yysemerr("alloc error in display", 0); + node->d_elm = "ERROR_TOKEN"; + } + return (node); +} + + /* +** ADDSYM -- add a token to the symbol space +** +** The node's .d_line field is set to the value of yyline, +** which, if this routine is called from a lexical routine +** taking lexemes that can't include newlines (and back them up), +** is the line the lexeme was read from. This fact is used +** be yyserror() [yyerror.c] to report accurate line numbers +** for errors. +** +** Parameters: +** s -- string to add +** +** Returns: +** pointer to node added +*/ + + + +struct disp_node *addsym(s) +char *s; +{ + register struct disp_node *d; + + d = enter_display(&Symsp, s); + d->d_line = yyline; + return (d); +} + + /* +** FREE_DISPLAY -- frees all elements of a display +** +** Parameters: +** disp -- the display to free +*/ + + + + + +free_display(disp) +struct display *disp; +{ + register struct display *d; + register struct disp_node *f, *n; + + d = disp; + for (f = d->disp_first; f; f = n) + { + n = f->d_next; + xfree(f->d_elm); + xfree(f); + } + d->disp_first = d->disp_last = 0; +} + + /* +** SYSMSPFREE -- Frees symbol space +** Symspfree frees all the symbol table, EXCEPT +** for the last element in it, as this is the lookahead +** element. That is to say, the element which forced reduction +** to the non-terminal program, which called on symspfree() +** +** Requires: +** Symsp -- to free it +** +** Called By: +** argproc() +** semantic routines (nonterminal "program") +*/ + + + +symspfree() +{ + register struct display *d; + register struct disp_node *f, *n; + + d = &Symsp; + for (f = d->disp_first; f && f->d_next; f = n) + { + n = f->d_next; + xfree(f->d_elm); + xfree(f); + } + d->disp_first = d->disp_last; +} + + /* +** W_DISPLAY -- write out the contents of a display +** +** Parameters: +** disp -- display to take write out +** +** Side Effects: +** Writes onto Out_file +** the contents of the display, +** each string is comsidered a separate +** word to be written out(so w_raw may +** break a line between words). +** Calls are made to w_op() and w_key() so as +** to have the minimum number of spaces in the text. +** +** Requires: +** w_op() -- to write out operator terminated +** strings +** w_key() -- to write out KEYCHAR terminated +** strings +** +** Called By: +** semantic productions dealing with usage of +** C variables. +*/ + + + +w_display(disp) +struct display *disp; +{ + register struct disp_node *n; + + for (n = disp->disp_first; n; n = n->d_next) + { + switch (Cmap [n->d_elm [length(n->d_elm) - 1]]) + { + + case OPATR : + case PUNCT : + w_op(n->d_elm); + break; + + default : + w_key(n->d_elm); + break; + } + } +} + /* +** EAT_DISPLAY -- enter text from In_file into a display +** Enters all text gotten through getch() [getch.c] +** lying between one character delimiters, which may +** be nested, into a display or w_op()'s it. +** eat_display() assumes that when it is called a +** "left_ch" has just been seen. It will "eat" up to +** MAXSTRING characters. +** Newline is played with because : +** a) a newline may have been read by eat_display +** instead of yylex(), therefore if eat_display +** stops there, yylex() must know that a newline +** has just been seen and it must test for C_CODE. +** b) Newline may have to be set to 0 if an include() +** was done which sets it to 1, and no yylex() was +** done afterwards to reset it. +** +** NOTE : This playing with Newline is needed because +** yylex() and not getch() maintains Newline. If getch() +** maintained Newline then it would be automatically right. +** +** Parameters: +** disp -- display to add elements to if != 0 else +** characters are written out. +** left_ch -- left delimiter character +** right_ch -- right delimiter character +** +** Side Effects: +** advances input to after the close of the +** left_ch, right_ch pair. +** may back up 2 characters. +** +** Called By: +** semantic routines dealing with array subscription +** +** Bugs: +** #include's encountered, are treated wrongly +** because the "#include ...c.h" is put out immediately, +** while the display is put out only later. +*/ + + +eat_display(disp, left_ch, right_ch) +struct display *disp; +char left_ch; +char right_ch; +{ + char buf [MAXSTRING + 1]; + register char *cp; + register level; + register i; + char pk; + char r_c [2]; + + cp = buf; + level = i = 1; + *cp = left_ch; + do + { + i++; + if (i >= sizeof buf) + { + yysemerr("display too long", 0); + break; + } + if ((*++cp = getch()) == left_ch) + level++; + else if (*cp == right_ch) + level -= 1; + else if (*cp == EOF_TOK) + { + backup(*cp); +missing : + r_c [1] = '\0'; + r_c [0] = right_ch; + yysemerr("missing closing character", r_c); + *cp = right_ch; + /* make next line be read as possible + * C_CODE by yylex() [yylex.c] + */ + Newline = 1; + break; + } + else if (*cp == '\n') + { + /* test that next line is valid equel line, + * and strip "##" + */ + if ((pk = getch()) != '#') + { + backup(pk); + goto missing; + } + if ((pk = getch()) != '#') + { + backup(pk); + backup('#'); + goto missing; + } + } + } while (*cp != right_ch || level > 0); + if (level == 0) + Newline = 0; + *++cp = '\0'; + if (disp) + enter_display(disp, salloc(buf)); + else + w_op(buf); +} -- 2.20.1