TLA Line data Source code
1 : /*
2 : * functions needed for descriptor handling
3 : *
4 : * src/interfaces/ecpg/preproc/descriptor.c
5 : *
6 : * since descriptor might be either a string constant or a string var
7 : * we need to check for a constant if we expect a constant
8 : */
9 :
10 : #include "postgres_fe.h"
11 :
12 : #include "preproc_extern.h"
13 :
14 : /*
15 : * assignment handling function (descriptor)
16 : */
17 :
18 : static struct assignment *assignments;
19 :
20 : void
21 CBC 78 : push_assignment(char *var, enum ECPGdtype value)
22 : {
23 78 : struct assignment *new = (struct assignment *) mm_alloc(sizeof(struct assignment));
24 :
25 78 : new->next = assignments;
26 78 : new->variable = mm_alloc(strlen(var) + 1);
27 78 : strcpy(new->variable, var);
28 78 : new->value = value;
29 78 : assignments = new;
30 78 : }
31 :
32 : static void
33 54 : drop_assignments(void)
34 : {
35 132 : while (assignments)
36 : {
37 78 : struct assignment *old_head = assignments;
38 :
39 78 : assignments = old_head->next;
40 78 : free(old_head->variable);
41 78 : free(old_head);
42 : }
43 54 : }
44 :
45 : static void
46 12 : ECPGnumeric_lvalue(char *name)
47 : {
48 12 : const struct variable *v = find_variable(name);
49 :
50 12 : switch (v->type->type)
51 : {
52 12 : case ECPGt_short:
53 : case ECPGt_int:
54 : case ECPGt_long:
55 : case ECPGt_long_long:
56 : case ECPGt_unsigned_short:
57 : case ECPGt_unsigned_int:
58 : case ECPGt_unsigned_long:
59 : case ECPGt_unsigned_long_long:
60 : case ECPGt_const:
61 12 : fputs(name, base_yyout);
62 12 : break;
63 UBC 0 : default:
64 0 : mmerror(PARSE_ERROR, ET_ERROR, "variable \"%s\" must have a numeric type", name);
65 0 : break;
66 : }
67 CBC 12 : }
68 :
69 : /*
70 : * descriptor name lookup
71 : */
72 :
73 : static struct descriptor *descriptors;
74 :
75 : void
76 18 : add_descriptor(char *name, char *connection)
77 : {
78 : struct descriptor *new;
79 :
80 18 : if (name[0] != '"')
81 1 : return;
82 :
83 17 : new = (struct descriptor *) mm_alloc(sizeof(struct descriptor));
84 :
85 17 : new->next = descriptors;
86 17 : new->name = mm_alloc(strlen(name) + 1);
87 17 : strcpy(new->name, name);
88 17 : if (connection)
89 : {
90 2 : new->connection = mm_alloc(strlen(connection) + 1);
91 2 : strcpy(new->connection, connection);
92 : }
93 : else
94 15 : new->connection = connection;
95 17 : descriptors = new;
96 : }
97 :
98 : void
99 16 : drop_descriptor(char *name, char *connection)
100 : {
101 : struct descriptor *i;
102 16 : struct descriptor **lastptr = &descriptors;
103 :
104 16 : if (name[0] != '"')
105 1 : return;
106 :
107 19 : for (i = descriptors; i; lastptr = &i->next, i = i->next)
108 : {
109 19 : if (strcmp(name, i->name) == 0)
110 : {
111 15 : if ((!connection && !i->connection)
112 2 : || (connection && i->connection
113 2 : && strcmp(connection, i->connection) == 0))
114 : {
115 15 : *lastptr = i->next;
116 GNC 15 : free(i->connection);
117 CBC 15 : free(i->name);
118 15 : free(i);
119 GIC 15 : return;
120 : }
121 : }
122 EUB : }
123 UBC 0 : if (connection)
124 UIC 0 : mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to connection %s does not exist", name, connection);
125 EUB : else
126 UIC 0 : mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to the default connection does not exist", name);
127 : }
128 :
129 : struct descriptor
130 ECB : *
131 GIC 54 : lookup_descriptor(char *name, char *connection)
132 : {
133 : struct descriptor *i;
134 ECB :
135 CBC 54 : if (name[0] != '"')
136 GIC 1 : return NULL;
137 ECB :
138 GIC 67 : for (i = descriptors; i; i = i->next)
139 ECB : {
140 GIC 67 : if (strcmp(name, i->name) == 0)
141 ECB : {
142 CBC 53 : if ((!connection && !i->connection)
143 3 : || (connection && i->connection
144 3 : && strcmp(connection, i->connection) == 0))
145 GBC 53 : return i;
146 UIC 0 : if (connection && !i->connection)
147 : {
148 EUB : /* overwrite descriptor's connection */
149 UBC 0 : i->connection = mm_strdup(connection);
150 UIC 0 : return i;
151 : }
152 : }
153 EUB : }
154 UBC 0 : if (connection)
155 UIC 0 : mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to connection %s does not exist", name, connection);
156 EUB : else
157 UBC 0 : mmerror(PARSE_ERROR, ET_WARNING, "descriptor %s bound to the default connection does not exist", name);
158 UIC 0 : return NULL;
159 : }
160 :
161 ECB : void
162 GIC 11 : output_get_descr_header(char *desc_name)
163 : {
164 : struct assignment *results;
165 ECB :
166 CBC 11 : fprintf(base_yyout, "{ ECPGget_desc_header(__LINE__, %s, &(", desc_name);
167 GIC 22 : for (results = assignments; results != NULL; results = results->next)
168 ECB : {
169 CBC 11 : if (results->value == ECPGd_count)
170 GIC 11 : ECPGnumeric_lvalue(results->variable);
171 EUB : else
172 UIC 0 : mmerror(PARSE_ERROR, ET_WARNING, "descriptor header item \"%d\" does not exist", results->value);
173 : }
174 ECB :
175 CBC 11 : drop_assignments();
176 11 : fprintf(base_yyout, "));\n");
177 11 : whenever_action(3);
178 GIC 11 : }
179 :
180 ECB : void
181 GIC 31 : output_get_descr(char *desc_name, char *index)
182 : {
183 : struct assignment *results;
184 ECB :
185 CBC 31 : fprintf(base_yyout, "{ ECPGget_desc(__LINE__, %s, %s,", desc_name, index);
186 GIC 82 : for (results = assignments; results != NULL; results = results->next)
187 ECB : {
188 CBC 51 : const struct variable *v = find_variable(results->variable);
189 GIC 51 : char *str_zero = mm_strdup("0");
190 ECB :
191 GIC 51 : switch (results->value)
192 EUB : {
193 UBC 0 : case ECPGd_nullable:
194 0 : mmerror(PARSE_ERROR, ET_WARNING, "nullable is always 1");
195 0 : break;
196 0 : case ECPGd_key_member:
197 0 : mmerror(PARSE_ERROR, ET_WARNING, "key_member is always 0");
198 LBC 0 : break;
199 CBC 51 : default:
200 GIC 51 : break;
201 ECB : }
202 CBC 51 : fprintf(base_yyout, "%s,", get_dtype(results->value));
203 GIC 51 : ECPGdump_a_type(base_yyout, v->name, v->type, v->brace_level,
204 ECB : NULL, NULL, -1, NULL, NULL, str_zero, NULL, NULL);
205 GIC 51 : free(str_zero);
206 ECB : }
207 CBC 31 : drop_assignments();
208 GIC 31 : fputs("ECPGd_EODT);\n", base_yyout);
209 ECB :
210 CBC 31 : whenever_action(2 | 1);
211 GIC 31 : }
212 :
213 ECB : void
214 GIC 1 : output_set_descr_header(char *desc_name)
215 : {
216 : struct assignment *results;
217 ECB :
218 CBC 1 : fprintf(base_yyout, "{ ECPGset_desc_header(__LINE__, %s, (int)(", desc_name);
219 GIC 2 : for (results = assignments; results != NULL; results = results->next)
220 ECB : {
221 CBC 1 : if (results->value == ECPGd_count)
222 GIC 1 : ECPGnumeric_lvalue(results->variable);
223 EUB : else
224 UIC 0 : mmerror(PARSE_ERROR, ET_WARNING, "descriptor header item \"%d\" does not exist", results->value);
225 : }
226 ECB :
227 CBC 1 : drop_assignments();
228 1 : fprintf(base_yyout, "));\n");
229 1 : whenever_action(3);
230 GIC 1 : }
231 :
232 EUB : static const char *
233 UIC 0 : descriptor_item_name(enum ECPGdtype itemcode)
234 EUB : {
235 UIC 0 : switch (itemcode)
236 EUB : {
237 UBC 0 : case ECPGd_cardinality:
238 0 : return "CARDINALITY";
239 0 : case ECPGd_count:
240 0 : return "COUNT";
241 0 : case ECPGd_data:
242 0 : return "DATA";
243 0 : case ECPGd_di_code:
244 0 : return "DATETIME_INTERVAL_CODE";
245 0 : case ECPGd_di_precision:
246 0 : return "DATETIME_INTERVAL_PRECISION";
247 0 : case ECPGd_indicator:
248 0 : return "INDICATOR";
249 0 : case ECPGd_key_member:
250 0 : return "KEY_MEMBER";
251 0 : case ECPGd_length:
252 0 : return "LENGTH";
253 0 : case ECPGd_name:
254 0 : return "NAME";
255 0 : case ECPGd_nullable:
256 0 : return "NULLABLE";
257 0 : case ECPGd_octet:
258 0 : return "OCTET_LENGTH";
259 0 : case ECPGd_precision:
260 0 : return "PRECISION";
261 0 : case ECPGd_ret_length:
262 0 : return "RETURNED_LENGTH";
263 0 : case ECPGd_ret_octet:
264 0 : return "RETURNED_OCTET_LENGTH";
265 0 : case ECPGd_scale:
266 0 : return "SCALE";
267 0 : case ECPGd_type:
268 0 : return "TYPE";
269 0 : default:
270 UIC 0 : return NULL;
271 : }
272 : }
273 :
274 ECB : void
275 GIC 11 : output_set_descr(char *desc_name, char *index)
276 : {
277 : struct assignment *results;
278 ECB :
279 CBC 11 : fprintf(base_yyout, "{ ECPGset_desc(__LINE__, %s, %s,", desc_name, index);
280 GIC 26 : for (results = assignments; results != NULL; results = results->next)
281 ECB : {
282 GIC 15 : const struct variable *v = find_variable(results->variable);
283 ECB :
284 GIC 15 : switch (results->value)
285 EUB : {
286 UIC 0 : case ECPGd_cardinality:
287 : case ECPGd_di_code:
288 : case ECPGd_di_precision:
289 : case ECPGd_precision:
290 EUB : case ECPGd_scale:
291 UIC 0 : mmfatal(PARSE_ERROR, "descriptor item \"%s\" is not implemented",
292 : descriptor_item_name(results->value));
293 : break;
294 EUB :
295 UIC 0 : case ECPGd_key_member:
296 : case ECPGd_name:
297 : case ECPGd_nullable:
298 : case ECPGd_octet:
299 : case ECPGd_ret_length:
300 EUB : case ECPGd_ret_octet:
301 UIC 0 : mmfatal(PARSE_ERROR, "descriptor item \"%s\" cannot be set",
302 : descriptor_item_name(results->value));
303 : break;
304 ECB :
305 GIC 15 : case ECPGd_data:
306 : case ECPGd_indicator:
307 : case ECPGd_length:
308 : case ECPGd_type:
309 ECB : {
310 GIC 15 : char *str_zero = mm_strdup("0");
311 ECB :
312 CBC 15 : fprintf(base_yyout, "%s,", get_dtype(results->value));
313 GIC 15 : ECPGdump_a_type(base_yyout, v->name, v->type, v->brace_level,
314 ECB : NULL, NULL, -1, NULL, NULL, str_zero, NULL, NULL);
315 GIC 15 : free(str_zero);
316 ECB : }
317 GIC 15 : break;
318 ECB :
319 GIC 15 : default:
320 : ;
321 : }
322 ECB : }
323 CBC 11 : drop_assignments();
324 GIC 11 : fputs("ECPGd_EODT);\n", base_yyout);
325 ECB :
326 CBC 11 : whenever_action(2 | 1);
327 GIC 11 : }
328 :
329 : /* I consider dynamic allocation overkill since at most two descriptor
330 : variables are possible per statement. (input and output descriptor)
331 : And descriptors are no normal variables, so they don't belong into
332 : the variable list.
333 : */
334 :
335 : #define MAX_DESCRIPTOR_NAMELEN 128
336 ECB : struct variable *
337 GIC 22 : descriptor_variable(const char *name, int input)
338 : {
339 : static char descriptor_names[2][MAX_DESCRIPTOR_NAMELEN];
340 : static struct ECPGtype descriptor_type = {ECPGt_descriptor, NULL, NULL, NULL, {NULL}, 0};
341 : static struct variable varspace[2] = {
342 : {descriptor_names[0], &descriptor_type, 0, NULL},
343 : {descriptor_names[1], &descriptor_type, 0, NULL}
344 : };
345 ECB :
346 CBC 22 : strlcpy(descriptor_names[input], name, sizeof(descriptor_names[input]));
347 GIC 22 : return &varspace[input];
348 : }
349 :
350 ECB : struct variable *
351 GIC 24 : sqlda_variable(const char *name)
352 ECB : {
353 GIC 24 : struct variable *p = (struct variable *) mm_alloc(sizeof(struct variable));
354 ECB :
355 CBC 24 : p->name = mm_strdup(name);
356 24 : p->type = (struct ECPGtype *) mm_alloc(sizeof(struct ECPGtype));
357 24 : p->type->type = ECPGt_sqlda;
358 24 : p->type->size = NULL;
359 24 : p->type->struct_sizeof = NULL;
360 24 : p->type->u.element = NULL;
361 24 : p->type->counter = 0;
362 24 : p->brace_level = 0;
363 GIC 24 : p->next = NULL;
364 ECB :
365 GIC 24 : return p;
366 : }
|