|
|
1.1 root 1: # include <stdio.h>
2: # include "constants.h"
3: # include "globals.h"
4: # include <sccs.h>
5:
6: SCCSID(@(#)retrieve.c 7.1 2/5/81)
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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.