BSD 4_1c_2 development
authorCSRG <csrg@ucbvax.Berkeley.EDU>
Fri, 5 Nov 1982 15:11:02 +0000 (07:11 -0800)
committerCSRG <csrg@ucbvax.Berkeley.EDU>
Fri, 5 Nov 1982 15:11:02 +0000 (07:11 -0800)
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 [new file with mode: 0644]

diff --git a/usr/src/ucb/ingres/source/equel/display.c b/usr/src/ucb/ingres/source/equel/display.c
new file mode 100644 (file)
index 0000000..92fdc36
--- /dev/null
@@ -0,0 +1,333 @@
+# include      <stdio.h>
+# include      "constants.h"
+# include      "globals.h"
+# include      <sccs.h>
+
+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];
+
+\f/*
+**  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);
+}
+
+\f/*
+**  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);
+}
+
+\f/*
+**  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;
+}
+
+\f/*
+**  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;
+}
+
+\f/*
+**  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;
+               }
+       }
+}
+\f/*
+**  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);
+}