1: #
   2: # include   "../unix.h"
   3: 
   4: extern jmp_buf      Env;
   5: 
   6: /*
   7: **  DISPLAY.C -- display manipulation routines
   8: **
   9: **	a display is a list of strings, the symbol
  10: **	space Symsp is impemented by means of displays.
  11: **
  12: **	Defines:
  13: **		enter_display()
  14: **		addsym()
  15: **		free_display()
  16: **		symspfree()
  17: **		w_display()
  18: **		eat_display()
  19: **
  20: **	Required By:
  21: **		Lexical analysis routines to add to the symbol space
  22: **		semantic productions to manipulate input
  23: **
  24: **	Files:
  25: **		constants.h
  26: **		globals.h
  27: **
  28: **	History:
  29: **		6/1/78 -- (marc) written
  30: **
  31: */
  32: 
  33: 
  34: # include   <stdio.h>
  35: 
  36: # include   "constants.h"
  37: # include   "globals.h"
  38: 
  39: 
  40:     /* this avoids having to specify &Cv_display in the semantic
  41: 	 * routines, by making Cv_display a pointer to the pertinent
  42: 	 * display structure.
  43: 	 */
  44: extern struct display   *Cv_display = &Displays [0];
  45: 
  46: /*
  47: **  ENTER_DISPLAY -- enter a new string into a display
  48: **
  49: **	Parameters:
  50: **		disp -- display to be added to
  51: **		string -- string to add
  52: **
  53: **	Returns:
  54: **		pointer to new disp_node structure.
  55: **
  56: **	Side Effects:
  57: **		allocates a new disp_node structure.
  58: **		Expects a dynamic "string", i.e. one that it can
  59: **		dispose of as it wishes, so it is the users responsability
  60: **		to allocate space for this string.
  61: **		If the string passed is 0, the string
  62: **		"ERROR_TOKEN" is substituted, and a message is printed,
  63: **		so a caller may call enter_display with the return of an
  64: **		salloc() directly.
  65: **		If no space is available for the allocation of the
  66: **		new node, an error message is given, and a longjump(3)
  67: **		is performed (this should goto equel()[main.c])
  68: **
  69: **	Called By:
  70: **		add_sym() -- to add a token to the Symsp
  71: **		the semantic productions -- for manipulating usages
  72: **			of C variables.
  73: **
  74: **	Diagnostics:
  75: **		"symbol space overflow" -- total reset to after
  76: **			current top level file (not #included)
  77: **		"alloc error in display" -- someone called enter_display
  78: **			with a string == 0
  79: **
  80: **	History:
  81: **		6/1/78 -- (marc) written
  82: **
  83: */
  84: 
  85: 
  86: struct disp_node *enter_display(disp, string)
  87: struct display  *disp;
  88: char        *string;
  89: {
  90:     register struct display     *d;
  91:     register struct disp_node   *node;
  92:     extern char         *nalloc();
  93: 
  94:     node = (struct disp_node *) nalloc(sizeof *node);
  95:     if (node == 0)
  96:     {
  97:         yysemerr("symbol space overflow", string);
  98:         reset(Env, 1);
  99:     }
 100:     d = disp;
 101:     if (!d->disp_first)
 102:         d->disp_first = d->disp_last = node;
 103:     else
 104:     {
 105:         d->disp_last->d_next = node;
 106:         d->disp_last = node;
 107:     }
 108:     node->d_next = 0;
 109:     if (!(node->d_elm = string))
 110:     {
 111:         printf("alloc error in display\n");
 112:         node->d_elm = "ERROR_TOKEN";
 113:     }
 114:     return (node);
 115: }
 116: 
 117: /*
 118: **  ADDSYM -- add a token to the symbol space
 119: **
 120: **	The node's .d_line field is set to the value of yyline,
 121: **	which, if this routine is called from a lexical routine
 122: **	taking lexemes that can't include newlines (and back them up),
 123: **	is the line the lexeme was read from. This fact is used
 124: **	be yyserror() [yyerror.c] to report accurate line numbers
 125: **	for errors.
 126: **
 127: **	Parameters:
 128: **		s -- string to add
 129: **
 130: **	Returns:
 131: **		pointer to node added
 132: **
 133: **	Requires:
 134: **		enter_display() -- to enter the string
 135: 
 136: **		Symsp -- display in which to enter it
 137: **
 138: **	Called By:
 139: **		All lexical routines
 140: **
 141: **	History:
 142: **		6/1/78 -- (marc) written
 143: **
 144: */
 145: 
 146: 
 147: 
 148: struct disp_node *addsym(s)
 149: char        *s;
 150: {
 151:     register struct disp_node   *d;
 152: 
 153:     d = enter_display(&Symsp, s);
 154:     d->d_line = yyline;
 155:     return (d);
 156: }
 157: 
 158: /*
 159: **  FREE_DISPLAY -- frees all elements of a display
 160: **
 161: **	Parameters:
 162: **		disp -- the display to free
 163: **
 164: **	Called By:
 165: **		The semantic produtions dealing with
 166: **		usage of C variables.
 167: **
 168: **	History:
 169: **		6/1/78 -- (marc) written
 170: **
 171: */
 172: 
 173: 
 174: 
 175: 
 176: 
 177: free_display(disp)
 178: struct display  *disp;
 179: {
 180:     register struct display     *d;
 181:     register struct disp_node   *f, *n;
 182: 
 183:     d = disp;
 184:     for (f = d->disp_first; f; f = n)
 185:     {
 186:         n = f->d_next;
 187:         xfree(f->d_elm);
 188:         xfree(f);
 189:     }
 190:     d->disp_first = d->disp_last = 0;
 191: }
 192: 
 193: /*
 194: **  SYSMSPFREE -- Frees symbol space
 195: **	Symspfree frees all the symbol table, EXCEPT
 196: **	for the last element in it, as this is the lookahead
 197: **	element. That is to say, the element which forced reduction
 198: **	to the non-terminal program, which called on symspfree()
 199: **
 200: **	Requires:
 201: **		Symsp -- to free it
 202: **
 203: **	Called By:
 204: **		argproc()
 205: **		semantic routines (nonterminal "program")
 206: **
 207: **	History:
 208: **		6/1/78 -- (marc) written
 209: **
 210: */
 211: 
 212: 
 213: 
 214: symspfree()
 215: {
 216:     register struct display     *d;
 217:     register struct disp_node   *f, *n;
 218: 
 219:     d = &Symsp;
 220:     for (f = d->disp_first; f && f->d_next; f = n)
 221:     {
 222:         n = f->d_next;
 223:         xfree(f->d_elm);
 224:         xfree(f);
 225:     }
 226:     d->disp_first = d->disp_last;
 227: }
 228: 
 229: /*
 230: **  W_DISPLAY -- write out the contents of a display
 231: **
 232: **	Parameters:
 233: **		disp -- display to take write out
 234: **
 235: **	Side Effects:
 236: **		Writes onto Out_file
 237: **		the contents of the display,
 238: **		each string is comsidered a separate
 239: **		word to be written out(so w_raw may
 240: **		break a line between words).
 241: **		Calls are made to w_op() and w_key() so as
 242: **		to have the minimum number of spaces in the text.
 243: **
 244: **	Requires:
 245: **		w_op() -- to write out operator terminated
 246: **			strings
 247: **		w_key() -- to write out KEYCHAR terminated
 248: **			strings
 249: **
 250: **	Called By:
 251: **		semantic productions dealing with usage of
 252: **		C variables.
 253: **
 254: **	History:
 255: **		6/1/78 -- (marc) written
 256: **
 257: */
 258: 
 259: 
 260: 
 261: w_display(disp)
 262: struct display      *disp;
 263: {
 264:     register struct disp_node   *n;
 265: 
 266:     for (n = disp->disp_first; n; n = n->d_next)
 267:     {
 268:         switch (Cmap [n->d_elm [length(n->d_elm) - 1]])
 269:         {
 270: 
 271:           case OPATR :
 272:           case PUNCT :
 273:             w_op(n->d_elm);
 274:             break;
 275: 
 276:           default :
 277:             w_key(n->d_elm);
 278:             break;
 279:         }
 280:     }
 281: }
 282: /*
 283: **  EAT_DISPLAY -- enter text from In_file into a display
 284: **	Enters all text gotten through getch() [getch.c]
 285: **	lying between one character delimiters, which may
 286: **	be nested, into a display or w_op()'s it.
 287: **	eat_display() assumes that when it is called a
 288: **	"left_ch" has just been seen. It will "eat" up to
 289: **	MAXSTRING characters.
 290: **	Newline is played with because :
 291: **		a) a newline may have been read by eat_display
 292: **		   instead of yylex(), therefore if eat_display
 293: **		   stops there, yylex() must know that a newline
 294: **		   has just been seen and it must test for C_CODE.
 295: **		b) Newline may have to be set to 0 if an include()
 296: **		   was done which sets it to 1, and no yylex() was
 297: **		   done afterwards to reset it.
 298: **
 299: **		NOTE : This playing with Newline is needed because
 300: **		yylex() and not getch() maintains Newline. If getch()
 301: **		maintained Newline then it would be automatically right.
 302: **
 303: **	Parameters:
 304: **		disp -- display to add elements to if != 0 else
 305: **			characters are written out.
 306: **		left_ch -- left delimiter character
 307: **		right_ch -- right delimiter character
 308: **
 309: **	Side Effects:
 310: **		advances input to after the close of the
 311: **		left_ch, right_ch pair.
 312: **		may back up 2 characters.
 313: **
 314: **	Called By:
 315: **		semantic routines dealing with array subscription
 316: **
 317: **	Diagnostics:
 318: **		"missing closing character" -- if end-of-file
 319: **			encountered in the stream.
 320: **		"display too long" -- if more than MAXSTRING
 321: **			chars between delimiters.
 322: **
 323: **	History:
 324: **		6/1/78 -- (marc) written
 325: **
 326: **	Bugs:
 327: **		#include's encountered, are treated wrongly
 328: **		because the "#include ...c.h" is put out immediately,
 329: **		while the display is put out only later.
 330: **
 331: **
 332: */
 333: 
 334: 
 335: eat_display(disp, left_ch, right_ch)
 336: struct display  *disp;
 337: char        left_ch;
 338: char        right_ch;
 339: {
 340:     char        buf [MAXSTRING + 1];
 341:     register char   *cp;
 342:     register    level;
 343:     register    i;
 344:     char        pk;
 345:     char        r_c [2];
 346: 
 347:     cp = buf;
 348:     level = i = 1;
 349:     *cp = left_ch;
 350:     do
 351:     {
 352:         i++;
 353:         if (i >= sizeof buf)
 354:         {
 355:             yysemerr("display too long", 0);
 356:             break;
 357:         }
 358:         if ((*++cp = getch()) == left_ch)
 359:             level++;
 360:         else if (*cp == right_ch)
 361:             level -= 1;
 362:         else if (*cp == EOF_TOK)
 363:         {
 364:             backup(*cp);
 365: missing :
 366:             r_c [1] = '\0';
 367:             r_c [0] = right_ch;
 368:             yysemerr("missing closing character", r_c);
 369:             *cp = right_ch;
 370:             /* make next line be read as possible
 371: 			 * C_CODE by yylex() [yylex.c]
 372: 			 */
 373:             Newline = 1;
 374:             break;
 375:         }
 376:         else if (*cp == '\n')
 377:         {
 378:             /* test that next line is valid equel line,
 379: 			 * and strip "##"
 380: 			 */
 381:             if ((pk = getch()) != '#')
 382:             {
 383:                 backup(pk);
 384:                 goto missing;
 385:             }
 386:             if ((pk = getch()) != '#')
 387:             {
 388:                 backup(pk);
 389:                 backup('#');
 390:                 goto missing;
 391:             }
 392:         }
 393:     }  while (*cp != right_ch || level > 0);
 394:     if (level == 0)
 395:         Newline = 0;
 396:     *++cp = '\0';
 397:     if (disp)
 398:         enter_display(disp, salloc(buf));
 399:     else
 400:         w_op(buf);
 401: }

Defined functions

eat_display defined in line 335; used 3 times
enter_display defined in line 86; used 10 times
free_display defined in line 177; used 7 times
Last modified: 1995-04-14
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3585
Valid CSS Valid XHTML 1.0 Strict