~vcs-imports/mammoth-replicator/trunk

« back to all changes in this revision

Viewing changes to src/interfaces/ecpg/preproc/descriptor.c

  • Committer: alvherre
  • Date: 2005-12-16 21:24:52 UTC
  • Revision ID: svn-v4:db760fc0-0f08-0410-9d63-cc6633f64896:trunk:1
Initial import of the REL8_0_3 sources from the Pgsql CVS repository.

Show diffs side-by-side

added added

removed removed

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