From 541d8154246fcfa5251f76f6fd6f04aea86709c1 Mon Sep 17 00:00:00 2001 From: Oliver Lehmann Date: Thu, 25 Jan 1990 05:41:31 +0000 Subject: [PATCH] ING_DB --- WEGA/contrib/ingres/dbs/src/eql/display.c | 306 +++++++++++++++++++++ WEGA/contrib/ingres/dbs/src/eql/include.c | 252 +++++++++++++++++ WEGA/contrib/ingres/dbs/src/eql/retrieve.c | 151 ++++++++++ 3 files changed, 709 insertions(+) create mode 100644 WEGA/contrib/ingres/dbs/src/eql/display.c create mode 100644 WEGA/contrib/ingres/dbs/src/eql/include.c create mode 100644 WEGA/contrib/ingres/dbs/src/eql/retrieve.c diff --git a/WEGA/contrib/ingres/dbs/src/eql/display.c b/WEGA/contrib/ingres/dbs/src/eql/display.c new file mode 100644 index 0000000..aeffac8 --- /dev/null +++ b/WEGA/contrib/ingres/dbs/src/eql/display.c @@ -0,0 +1,306 @@ +# include +# include "gen.h" +# include "../h/bs.h" +# include "constants.h" +# include "globals.h" + +static struct display Symsp; /* storage for symbols read by */ + /* yylex() */ +static struct display Displays[1]; /* Cv_display is set to point at */ + /* this, so that Cv_display may be */ + /* passed a parameter instead of */ + /* &Cv_display */ +struct display *Cv_display = &Displays[0]; + +/* +** DISPLAY.C -- display manipulation routines +** +** a display is a list of strings, the symbol +** space Symsp is impemented by means of displays. +** +** Defines: +** enter_display() +** addsym() +** free_display() +** symspfree() +** w_display() +** eat_display() +** +** +** +** this avoids having to specify &Cv_display in the semantic +** routines, by making Cv_display a pointer to the pertinent +** display structure. +*/ + +/* +** 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 structure. +** 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 longjump(3) +** is performed (this should goto eql()[main.c]) +*/ +struct disp_node *enter_display(disp, string) +register struct display *disp; +register char *string; +{ + register struct disp_node *node; + extern char *nalloc(); + + node = (struct disp_node *) nalloc(sizeof *node); + if (!node) + { + yysemerr("symbol space overflow", string); + reset(); + } + if (!disp->disp_first) + disp->disp_first = disp->disp_last = node; + else + { + disp->disp_last->d_next = node; + disp->disp_last = node; + } + node->d_next = 0; + if (!(node->d_elm = string)) + { + printf("alloc error in display\n"); + 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) +register 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) +register struct display *disp; +{ + register struct disp_node *f; + register struct disp_node *n; + + for (f = disp->disp_first; f; f = n) + { + n = f->d_next; + xfree(f->d_elm); + xfree(f); + } + disp->disp_first = disp->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() +*/ +symspfree() +{ + register struct display *d; + register struct disp_node *f; + register struct disp_node *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_raw() and w_key() so as +** to have the minimum number of spaces in the text. +*/ +w_display(disp) +register struct display *disp; +{ + register struct disp_node *n; + register int i; + + for (n = disp->disp_first; n; n = n->d_next) + { + i = AAlength(n->d_elm); + i = n->d_elm[i - 1]; + switch (CMAP(i)) + { + case OPATR : + case PUNCT : + w_raw(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_raw()'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. +** +** 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; +{ + register char *cp; + register int level; + register int i; + register int pk; + char r_c[2]; + char buf[MAXSTRING + 1]; + extern char *salloc(); + + cp = buf; + level = i = 1; + *cp = left_ch; + do + { + i++; + if (i >= sizeof buf) + { + yysemerr("display too long", (char *) 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 EQL 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) + Newline = 0; + *++cp = '\0'; + if (disp) + enter_display(disp, salloc(buf)); + else + w_raw(buf); +} diff --git a/WEGA/contrib/ingres/dbs/src/eql/include.c b/WEGA/contrib/ingres/dbs/src/eql/include.c new file mode 100644 index 0000000..c45a294 --- /dev/null +++ b/WEGA/contrib/ingres/dbs/src/eql/include.c @@ -0,0 +1,252 @@ +# include +# include "gen.h" +# include "constants.h" +# include "globals.h" + +struct inc_file *Inc_file; /* file stack pushed by #includes */ + +/* +** INLUDE.C -- Routine to process "#include" lines +** +** Defines: +** tst_include() +** include() +** restoref() +** +** +** +** TST_INCLUDE -- Test and process a "#include" line +** +** Checks that a line is of the form '# include ""', +** and calls include to change i/o files if so. +** +** Returns: +** 1 -- if change of file was done +** 0 -- otherwise +*/ +tst_include() +{ + register char *lp; + register char *tp; + register char *chp; + char temp[MAXSTRING + 1]; + + /* copy line read into temp ( because temp is same + * size as Linebuf, no overflow check is needed + */ + for (tp = temp, lp = Line_buf; (*tp++ = *lp++) != '\n'; ) + continue; + /* skip white space between "#" and "include" */ + for (tp = &temp[1]; *tp == ' ' || *tp == '\t'; tp++) + continue; + if (AAscompare("include", 7, tp, 7)) + return (0); + /* skip "include", the white space till '"' */ + for (tp = &tp[7]; *tp == ' ' || *tp == '\t'; tp++) + continue; + if (*tp++ != '"') + return (0); + + /* {tp points to X in a line "#include"X..." } + * make "lp" point at right end '"' (filename must not have + * escaped '"' in it + */ + for (lp = tp; *lp != '"' && *lp != '\n'; lp++) + continue; + + if (*lp != '"') + return (0); + /* make sure filename is long enough to have the EQL "include" + * suffix ".q.h" + */ + if (lp - tp < 4) + return (0); + if (AAscompare(".q.h", 4, &lp[-4], 4)) + return (0); /* other include (non-EQL) */ + + /* "chp" points at 'q' in '.q.h' which will be changed to 'c' */ + chp = &lp[-3]; + + /* check that rest of the line is white space */ + for (lp++; *lp == ' ' || *lp == '\t'; lp++) + continue; + if (*lp != '\n') + { + *lp = '\0'; + yysemerr("garbage after valid \"#include\"", temp); + return (0); + } + *++lp = '\0'; + return (include(temp, tp, chp, &chp[3])); +} + +/* +** INCLUDE -- Change i/o files for a file inclusion +** Saves status of current i/o files, puts out +** '#include"___.c.h"', and opens appropriate files. +** Makes both files legal C files, closing quotes, +** and reopeneing them in the new file, if necessary. +** Reuses Out_buf. +** +** Parameters: +** buf -- "#include..." line +** start -- start of filename +** chp -- *chp is 'q' in ".q.h" of filename +** end -- ptr to last '"' after filename +** +** Returns: +** 1 -- if i/o files changed +** 0 -- otherwise +*/ +include(buf, start, chp, end) +char *buf; +char *start; +char *chp; +char *end; +{ + register struct inc_file *i_f; + register int in_q_flag; +# ifdef SETBUF + register char *ibuf; +# endif + extern char *nalloc(); + extern char *salloc(); + + in_q_flag = In_quote; + if (in_q_flag) + { + end_quote(); + equate_lines(); + } + + if (!(i_f = (struct inc_file *) nalloc(sizeof *i_f))) + { +err1 : + *++end = '\0'; /* overwrite before new-line at end */ + yysemerr("alloc error in #include processing", buf); + if (in_q_flag) + begin_quote(); + *end = '\n'; + return (0); + } +# ifdef SETBUF + if (!(ibuf = nalloc(BUFSIZ))) + goto err2; +# endif + i_f->inc_yyline = yyline + 1; /* next line that will be read is + * yyline + 1 because getch does not + * see the '\n' at the end of the + * "#include" line + */ + i_f->inc_lineout = Lineout + 1; /* because the write of the "#include + * "... .c.h" file is done after the + * fixation of the value of Lineout. + */ + i_f->inc_fid = Input_file_name; + i_f->inc_outfile = Out_file; + i_f->inc_infile = In_file; +# ifdef SETBUF + i_f->inc_ibuf = Ibuf; +# endif + i_f->inc_next = 0; + + *end = '\0'; + if (!(Input_file_name = salloc(start))) + { +# ifdef SETBUF + xfree(ibuf); +# endif +err2 : + xfree(i_f); + goto err1; + } + + if (!(In_file = fopen(Input_file_name, "r"))) + { + printf("can't read included file \"%s\"\n", Input_file_name); +err3 : + xfree(Input_file_name); + Input_file_name = i_f->inc_fid; + In_file = i_f->inc_infile; +# ifdef SETBUF + xfree(ibuf); +# endif + xfree(i_f); + return (0); + } +# ifdef SETBUF + setbuf(In_file, ibuf); +# endif + *end = '"'; + *chp = 'c'; + + /* write out "#include..c.h" line (make sure it's at beginning + * of line. + */ + equate_lines(); + if (Charcnt) + w_raw("\n"); + w_raw(buf); + fflush(Out_file); + *end = '\0'; + if (!(Out_file = fopen(start, "w"))) + { + printf("can't write file \"%s\"\n", start); + fclose(In_file); + Out_file = i_f->inc_outfile; + goto err3; + } +# ifdef SETBUF + setbuf(Out_file, Out_buf); + Ibuf = ibuf; +# endif + /* go to it !!! */ + Lineout = yyline = Newline = 1; + Pre_proc_flag = 0; + Line_pos = (char *) 0; + if (in_q_flag) + begin_quote(); + Inc_file = i_f; + return (1); +} + + +/* +** RESTOREF -- Restore previous file environment +** Closes current files, and restores global variable +** values for old files. +** +** Returns: +** 0 -- if no old files (top level, no "#include"s) +** 1 -- otherwise +*/ +restoref() +{ + register struct inc_file *i_f; + + if (Inc_file) + { + fclose(Out_file); + fclose(In_file); +# ifdef SETBUF + xfree(Ibuf); +# endif + xfree(Input_file_name); + + /* restore previous environment */ + i_f = Inc_file; + yyline = i_f->inc_yyline; + Lineout = i_f->inc_lineout; +# ifdef SETBUF + Ibuf = i_f->inc_ibuf; +# endif + Input_file_name = i_f->inc_fid; + Out_file = i_f->inc_outfile; + In_file = i_f->inc_infile; + Line_pos = (char *) 0; + Inc_file = i_f->inc_next; + xfree(i_f); + return (1); + } + return (0); +} diff --git a/WEGA/contrib/ingres/dbs/src/eql/retrieve.c b/WEGA/contrib/ingres/dbs/src/eql/retrieve.c new file mode 100644 index 0000000..fbd4ff2 --- /dev/null +++ b/WEGA/contrib/ingres/dbs/src/eql/retrieve.c @@ -0,0 +1,151 @@ +# include +# include "gen.h" +# include "constants.h" +# include "globals.h" + +static struct ret_list Ret_list; /* list of variables in a "ctlelm" */ + +/* +** RETRIEVE.C -- ret_list struct handlers +** +** The Ret_list is a structure where references to C variables, +** and their types, used in a target list of a "tupret" are kept +** for outputting in the while loop generated. +** +** Defines: +** enter_ret() +** add_ret() +** w_ret() +** free_ret() +** +** +** +** ENTER_RET -- enter a variable in a ret_list +** Concatenatest the strings in disp the calls add_ret +** to add the new string to Ret_list. +** +** Parameters: +** disp -- display containing the reference to the variable +** type -- type of the variable +*/ +enter_ret(disp, type) +struct display *disp; +int type; +{ + register char *srce; + register char *dest; + register struct disp_node *d; + register int i; + char buf[MAXSTRING + 2]; + extern char *salloc(); + + i = 0; + dest = buf; + for (d = disp->disp_first; d; d = d->d_next) + { + for (srce = d->d_elm; *srce; ) + { + if (i < MAXSTRING) + { + i += 1; + *++dest = *srce++; + } + else + break; + } + + if (i >= MAXSTRING) + { + yysemerr("reference to a variable too long, ']' probably missing from array subscription", (char *) 0); + break; + } + } + *++dest = '\0'; + add_ret(salloc(&buf[1]), type); +} + + +/* +** ADD_RET -- add a string (reference to a variable) to the Ret_list +** +** Parameters: +** s -- string to add +** type -- type of variable being added +*/ +add_ret(s, type) +char *s; +int type; +{ + register struct ret_list *list; + register struct ret_var *node; + extern char *nalloc(); + + if (!s) + { + s = "ERROR_TOKEN"; + yysemerr("alloc error", s); + } + list = &Ret_list; + node = (struct ret_var *) nalloc(sizeof *node); + if (!node) + { + yysemerr("alloc error", s); + xfree(s); + return; + } + node->r_elm = s; + node->r_next = 0; + node->r_type = type; + if (!list->ret_first) + list->ret_first = list->ret_last = node; + else + { + list->ret_last->r_next = node; + list->ret_last = node; + } +} + + +/* +** W_RET -- Generates the IIn_get() calls for the Ret_list +** +** Any variable whose type is not string gets an '&' +** (adress of) operand prepended. +*/ +w_ret() +{ + register struct ret_var *node; + char type[3]; + + for (node = Ret_list.ret_first; node; node = node->r_next) + { + w_raw("IIn_ret("); + if (node->r_type != opSTRING) + w_raw("&"); + w_raw(node->r_elm); + w_raw(", "); + AA_itoa(node->r_type, type); + w_raw(type); + w_raw(");"); + } +} + + +/* +** FRE_RET -- Free up the storage used by the Ret_list +*/ +free_ret() +{ + register struct ret_list *list; + register struct ret_var *n; + register struct ret_var *f; + + list = &Ret_list; + for (f = list->ret_first; f; f = n) + { + n = f->r_next; + xfree(f->r_elm); + xfree(f); + } + list->ret_first = list->ret_last = 0; +}