ING_DB
This commit is contained in:
parent
eefa54f77f
commit
541d815424
|
|
@ -0,0 +1,306 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# 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);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,252 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# 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 "<filename.q.h>"',
|
||||||
|
** 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 "#<white>include<white>"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);
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,151 @@
|
||||||
|
# include <stdio.h>
|
||||||
|
# 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;
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue