1: # include <stdio.h> 2: # include "constants.h" 3: # include "globals.h" 4: # include <sccs.h> 5: 6: SCCSID(@(#)retrieve.c 8.1 12/31/84) 7: 8: 9: /* 10: ** RETRIEVE.C -- ret_list struct handlers 11: ** 12: ** The Ret_list is a structure where references to C variables, 13: ** and their types, used in a target list of a "tupret" are kept 14: ** for outputting in the while loop generated. 15: */ 16: 17: /* 18: ** ENTER_RET -- enter a variable in a ret_list 19: ** Concatenatest the strings in disp the calls add_ret 20: ** to add the new string to Ret_list. 21: ** 22: ** Parameters: 23: ** disp -- display containing the reference to the variable 24: ** type -- type of the variable 25: */ 26: 27: 28: enter_ret(disp, type) 29: struct display *disp; 30: int type; 31: { 32: char buf [MAXSTRING + 2]; /* &buf [1] is the start 33: * of the concatenated 34: * strings 35: */ 36: register char *srce, *dest; 37: struct disp_node *d; 38: register i; 39: 40: i = 0; 41: dest = buf; 42: for (d = disp->disp_first; d; d = d->d_next) 43: { 44: for (srce = d->d_elm; *srce; ) 45: { 46: if (i < MAXSTRING) 47: { 48: i += 1; 49: *++dest = *srce++; 50: } 51: else 52: break; 53: } 54: 55: if (i >= MAXSTRING) 56: { 57: yysemerr("reference to a variable too long, ']' probably missing from array subscription", 58: 0); 59: break; 60: } 61: } 62: *++dest = '\0'; 63: add_ret(salloc(&buf [1]), type); 64: } 65: /* 66: ** ADD_RET -- add a string (reference to a variable) to the Ret_list 67: ** 68: ** Parameters: 69: ** s -- string to add 70: ** type -- type of variable being added 71: */ 72: 73: 74: add_ret(s, type) 75: char *s; 76: int type; 77: { 78: register struct ret_list *list; 79: register struct ret_var *node; 80: 81: if (!s) 82: { 83: s = "ERROR_TOKEN"; 84: yysemerr("alloc error", s); 85: } 86: list = &Ret_list; 87: node = (struct ret_var *)nalloc(sizeof *node); 88: if (!node) 89: { 90: yysemerr("alloc error", s); 91: xfree(s); 92: return; 93: } 94: node->r_elm = s; 95: node->r_next = 0; 96: node->r_type = type; 97: if (list->ret_first == 0) 98: list->ret_first = list->ret_last = node; 99: else 100: { 101: list->ret_last->r_next = node; 102: list->ret_last = node; 103: } 104: } 105: /* 106: ** W_RET -- Generates the IIn_get() calls for the Ret_list 107: ** 108: ** Any variable whose type is not string gets an '&' 109: ** (adress of) operand prepended. 110: */ 111: 112: 113: w_ret() 114: { 115: register struct ret_var *node; 116: char type [3]; 117: 118: for (node = Ret_list.ret_first; node; node = node->r_next) 119: { 120: w_op("IIn_ret("); 121: if (node->r_type != opSTRING) 122: w_op("&"); 123: w_op(node->r_elm); 124: w_op(","); 125: itoa(node->r_type, type); 126: w_op(type); 127: w_op(");"); 128: } 129: } 130: /* 131: ** FRE_RET -- Free up the storage used by the Ret_list 132: */ 133: 134: free_ret() 135: { 136: register struct ret_list *list; 137: register struct ret_var *n, *f; 138: 139: list = &Ret_list; 140: for (f = list->ret_first; f; f = n) 141: { 142: n = f->r_next; 143: xfree(f->r_elm); 144: xfree(f); 145: } 146: list->ret_first = list->ret_last = 0; 147: }