1: # include   <stdio.h>
   2: # include   "constants.h"
   3: # include   "globals.h"
   4: # include   <sccs.h>
   5: 
   6: SCCSID(@(#)cvar.c	8.1	12/31/84)
   7: 
   8: /*
   9: **  CVAR -- routines to manipulate the c variable trees
  10: **
  11: **	C variable trees are binary trees of cvar structs,
  12: **	with the c_left < c_right with respect to c_id.
  13: */
  14: /*
  15: **  DECL_CVAR -- Declare a C variable
  16: **
  17: **	Parameters:
  18: **		name -- identifier string (makes its own copy for the tree)
  19: **		type
  20: **		indir_level -- level of indirection of declaration
  21: **			(- 1 if string)
  22: **		block_level -- 0 - global, else local var
  23: **
  24: **	Returns:
  25: **		none
  26: **
  27: **	Side Effects:
  28: **		allocates a cvar node, and a copy of name, may put a node
  29: **		in a cvar tree (if not previously declared).
  30: **
  31: **	Called By:
  32: **		the c_variable productions of the parser [grammar.y]
  33: */
  34: 
  35: 
  36: decl_cvar(name, type, indir_level, block_level)
  37: char        *name;
  38: int     type;
  39: int     indir_level;
  40: int     block_level;
  41: {
  42:     register struct cvar        *bad_node;
  43:     struct cvar         *dec_var();
  44: 
  45:     if (bad_node = dec_var(name, type, indir_level, block_level,
  46:                 &C_locals, &C_globals))
  47:     {
  48:         yysemerr("re-declared identifier", bad_node->c_id);
  49:         xfree(bad_node->c_id);
  50:         xfree(bad_node);
  51:     }
  52: }
  53: 
  54: /*
  55: **  DECL_FIELD -- Declare a structures field
  56: **
  57: **	Same as decl_cvar() for fields within C records (structs).
  58: **	NOTE : if a !0 is returned from dec_var() (i.e. the field
  59: **	was already declared) the storage for that node is freed
  60: **	but no error has been comitted, as fields may be re-declared.
  61: */
  62: 
  63: decl_field(name, type, indir_level, block_level)
  64: char        *name;
  65: int     type;
  66: int     indir_level;
  67: int     block_level;
  68: {
  69:     register struct cvar        *bad_node;
  70:     struct cvar         *dec_var();
  71: 
  72:     if (bad_node = dec_var(name, type, indir_level, block_level,
  73:                 &F_locals, &F_globals))
  74:     {
  75:         xfree(bad_node->c_id);
  76:         xfree(bad_node);
  77:     }
  78: }
  79: /*
  80: **  DEC_VAR -- declare a C var or field.
  81: **
  82: **	Parameters:
  83: **		same as decl_cvar() & decl_field plus
  84: **		the local and global tree variables.
  85: **
  86: **	Returns:
  87: **		0 -- successful
  88: **		other -- cvar node pointer that couldn't be entered
  89: **			to tree
  90: */
  91: 
  92: struct cvar *
  93: dec_var(name, type, indir_level, block_level, local_tree, global_tree)
  94: char        *name;
  95: int     type, indir_level, block_level;
  96: struct cvar **local_tree, **global_tree;
  97: {
  98:     register struct cvar        *cvarp;
  99:     register            i;
 100:     char                *salloc();
 101: 
 102:     cvarp = (struct cvar *)nalloc(sizeof *cvarp);
 103:     if (!cvarp)
 104:     {
 105:         yysemerr("unable to allocate space for a variable", name);
 106:         return (0);
 107:     }
 108:     if (!(cvarp->c_id = salloc(name)))
 109:     {
 110:         yysemerr("no space for variable name", name);
 111:         xfree(cvarp);
 112:         return (0);
 113:     }
 114:     cvarp->c_type = type;
 115:     cvarp->c_indir = indir_level;
 116:     cvarp->c_left = cvarp->c_right = 0;
 117:     i = c_enter(cvarp, block_level > 0 ? local_tree : global_tree);
 118:     return (i ? 0 : cvarp);
 119: }
 120: /*
 121: **   C_ENTER -- Enter a cvar node in a cvar tree
 122: **
 123: **	Parameters:
 124: **		node -- the cvar node to insert
 125: **		root -- a pointer to the root pointer
 126: **
 127: **	Returns:
 128: **		1 -- if successful
 129: **		0 -- otherwise (node of same name existed
 130: **
 131: **	Side Effects:
 132: **		If a node of that name didn't exist one is inserted
 133: **
 134: **	Called By:
 135: **		dec_var()
 136: */
 137: 
 138: c_enter(node, root)
 139: struct cvar *node;
 140: struct cvar **root;
 141: {
 142:     register char       *name;
 143:     register struct cvar    *n, *r;
 144: 
 145:     r = *root;
 146:     n = node;
 147:     name = n->c_id;
 148:     if (!r)
 149:     {
 150:         *root = n;
 151:         return (1);
 152:     }
 153:     for (;;)
 154:     {
 155:         switch (scompare(name, 0, r->c_id, 0))
 156:         {
 157: 
 158:           case -1 :
 159:             if (!r->c_left)
 160:             {
 161:                 r->c_left = n;
 162:                 return (1);
 163:             }
 164:             r = r->c_left;
 165:             break;
 166: 
 167:           case 0 :
 168:             yysemerr("identifier re-declared", name);
 169:             xfree(name);
 170:             xfree(n);
 171:             return (0);
 172: 
 173:           case 1 :
 174:             if (!r->c_right)
 175:             {
 176:                 r->c_right = n;
 177:                 return (1);
 178:             }
 179:             r = r->c_right;
 180:             break;
 181:         }
 182:     }
 183: }
 184: 
 185: 
 186: /*
 187: **  GET_VAR -- get a cvar node from a local_tree, global_tree pair
 188: **	searching first through the local then the global.
 189: **
 190: **	Parameters:
 191: **		id -- c_id key
 192: **		local_tree -- first tree
 193: **		global_tree -- secomd tree to search
 194: **
 195: **	Returns:
 196: **		0 -- if no node by that name
 197: **		otherwise -- pointer to the node
 198: */
 199: 
 200: 
 201: struct cvar *get_var(id, local_tree, global_tree)
 202: char        *id;
 203: struct cvar *local_tree, *global_tree;
 204: {
 205:     register char       *name;
 206:     register struct cvar    *tree, *node;
 207:     char            flag;
 208: 
 209:     flag = 0;
 210:     name = id;
 211:     tree = local_tree;
 212:     for ( ; ; )
 213:     {
 214:         for (node = tree; node; )
 215:         {
 216:             switch (scompare(name, 0, node->c_id, 0))
 217:             {
 218: 
 219:               case -1 :
 220:                 if (!node->c_left)
 221:                     break;
 222:                 else
 223:                     node = node->c_left;
 224:                 continue;
 225: 
 226:               case 0 :
 227:                 return (node);
 228: 
 229:               case 1 :
 230:                 if (!node->c_right)
 231:                     break;
 232:                 else
 233:                     node = node->c_right;
 234:                 continue;
 235:             }
 236:             break;
 237:         }
 238:         if (!flag)
 239:         {
 240:             flag += 1;
 241:             tree = global_tree;
 242:         }
 243:         else
 244:             return (0);
 245:     }
 246: }
 247: /*
 248: **  GETCVAR -- get the cvar node for a given identifier
 249: **	Looks first in C_locals, then in C_globals.
 250: **
 251: **	Parameters:
 252: **		id -- name of cvar to look for
 253: **
 254: **	Returns:
 255: **		adress of cvar node if found
 256: **		0 -- otherwise
 257: **
 258: **	Requires:
 259: **		C_locals & C_globals -- to search them
 260: */
 261: 
 262: struct cvar *
 263: getcvar(id)
 264: char        *id;
 265: {
 266:     return (get_var(id, C_locals, C_globals));
 267: }
 268: 
 269: /*
 270: **  GETFIELD -- Same as getcvar() for structure fields
 271: */
 272: 
 273: struct cvar *
 274: getfield(id)
 275: char        *id;
 276: {
 277:     return (get_var(id, F_locals, F_globals));
 278: }
 279: 
 280: 
 281: /*
 282: **  FREECVAR & F_CVAR -- Free up storage in a cvar tree
 283: **
 284: **	Freecvar calls f_cvar to free storage for a tree, then
 285: **	0's out the root pointer passed it.
 286: */
 287: 
 288: freecvar(rootp)
 289: struct cvar **rootp;
 290: {
 291:     f_cvar(*rootp);
 292:     *rootp = 0;
 293: }
 294: 
 295: f_cvar(root)
 296: struct cvar *root;
 297: {
 298:     if (root)
 299:     {
 300:         f_cvar(root->c_left);
 301:         f_cvar(root->c_right);
 302:         xfree(root->c_id);
 303:         xfree(root);
 304:     }
 305: }

Defined functions

c_enter defined in line 138; used 1 times
dec_var defined in line 92; used 4 times
decl_cvar defined in line 6; used 1 times
decl_field defined in line 63; used 1 times
f_cvar defined in line 295; used 3 times
freecvar defined in line 288; used 6 times
get_var defined in line 201; used 2 times
Last modified: 1986-04-17
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 1328
Valid CSS Valid XHTML 1.0 Strict