~ubuntu-branches/ubuntu/oneiric/postgresql-9.1/oneiric-security

« back to all changes in this revision

Viewing changes to src/interfaces/ecpg/preproc/ecpg.header

  • Committer: Bazaar Package Importer
  • Author(s): Martin Pitt
  • Date: 2011-05-11 10:41:53 UTC
  • Revision ID: james.westby@ubuntu.com-20110511104153-psbh2o58553fv1m0
Tags: upstream-9.1~beta1
ImportĀ upstreamĀ versionĀ 9.1~beta1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* src/interfaces/ecpg/preproc/ecpg.header */
 
2
 
 
3
/* Copyright comment */
 
4
%{
 
5
#include "postgres_fe.h"
 
6
 
 
7
#include "extern.h"
 
8
#include "ecpg_config.h"
 
9
#include <unistd.h>
 
10
 
 
11
/* Location tracking support --- simpler than bison's default */
 
12
#define YYLLOC_DEFAULT(Current, Rhs, N) \
 
13
        do { \
 
14
                if (N) \
 
15
                        (Current) = (Rhs)[1]; \
 
16
                else \
 
17
                        (Current) = (Rhs)[0]; \
 
18
        } while (0)
 
19
 
 
20
/*
 
21
 * The %name-prefix option below will make bison call base_yylex, but we
 
22
 * really want it to call filtered_base_yylex (see parser.c).
 
23
 */
 
24
#define base_yylex filtered_base_yylex
 
25
 
 
26
/*
 
27
 * This is only here so the string gets into the POT.  Bison uses it
 
28
 * internally.
 
29
 */
 
30
#define bison_gettext_dummy gettext_noop("syntax error")
 
31
 
 
32
/*
 
33
 * Variables containing simple states.
 
34
 */
 
35
int struct_level = 0;
 
36
int braces_open; /* brace level counter */
 
37
char *current_function;
 
38
int ecpg_internal_var = 0;
 
39
char    *connection = NULL;
 
40
char    *input_filename = NULL;
 
41
 
 
42
static int      FoundInto = 0;
 
43
static int      initializer = 0;
 
44
static int      pacounter = 1;
 
45
static char     pacounter_buffer[sizeof(int) * CHAR_BIT * 10 / 3]; /* a rough guess at the size we need */
 
46
static struct this_type actual_type[STRUCT_DEPTH];
 
47
static char *actual_startline[STRUCT_DEPTH];
 
48
static int      varchar_counter = 1;
 
49
 
 
50
/* temporarily store struct members while creating the data structure */
 
51
struct ECPGstruct_member *struct_member_list[STRUCT_DEPTH] = { NULL };
 
52
 
 
53
/* also store struct type so we can do a sizeof() later */
 
54
static char *ECPGstruct_sizeof = NULL;
 
55
 
 
56
/* for forward declarations we have to store some data as well */
 
57
static char *forward_name = NULL;
 
58
 
 
59
struct ECPGtype ecpg_no_indicator = {ECPGt_NO_INDICATOR, NULL, NULL, NULL, {NULL}, 0};
 
60
struct variable no_indicator = {"no_indicator", &ecpg_no_indicator, 0, NULL};
 
61
 
 
62
struct ECPGtype ecpg_query = {ECPGt_char_variable, NULL, NULL, NULL, {NULL}, 0};
 
63
 
 
64
/*
 
65
 * Handle parsing errors and warnings
 
66
 */
 
67
void
 
68
mmerror(int error_code, enum errortype type, const char *error, ...)
 
69
{
 
70
        va_list ap;
 
71
 
 
72
        /* internationalize the error message string */
 
73
        error = _(error);
 
74
 
 
75
        fprintf(stderr, "%s:%d: ", input_filename, yylineno);
 
76
 
 
77
        switch(type)
 
78
        {
 
79
                case ET_WARNING:
 
80
                        fprintf(stderr, _("WARNING: "));
 
81
                        break;
 
82
                case ET_ERROR:
 
83
                case ET_FATAL:
 
84
                        fprintf(stderr, _("ERROR: "));
 
85
                        break;
 
86
        }
 
87
 
 
88
        va_start(ap, error);
 
89
        vfprintf(stderr, error, ap);
 
90
        va_end(ap);
 
91
 
 
92
        fprintf(stderr, "\n");
 
93
 
 
94
        switch(type)
 
95
        {
 
96
                case ET_WARNING:
 
97
                        break;
 
98
                case ET_ERROR:
 
99
                        ret_value = error_code;
 
100
                        break;
 
101
                case ET_FATAL:
 
102
                        if (yyin)
 
103
                                fclose(yyin);
 
104
                        if (yyout)
 
105
                                fclose(yyout);
 
106
 
 
107
                        if (strcmp(output_filename, "-") != 0 && unlink(output_filename) != 0)
 
108
                                fprintf(stderr, _("could not remove output file \"%s\"\n"), output_filename);
 
109
                        exit(error_code);
 
110
        }
 
111
}
 
112
 
 
113
/*
 
114
 * string concatenation
 
115
 */
 
116
 
 
117
static char *
 
118
cat2_str(char *str1, char *str2)
 
119
{
 
120
        char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + 2);
 
121
 
 
122
        strcpy(res_str, str1);
 
123
        if (strlen(str1) != 0 && strlen(str2) != 0)
 
124
                strcat(res_str, " ");
 
125
        strcat(res_str, str2);
 
126
        free(str1);
 
127
        free(str2);
 
128
        return(res_str);
 
129
}
 
130
 
 
131
static char *
 
132
cat_str(int count, ...)
 
133
{
 
134
        va_list         args;
 
135
        int                     i;
 
136
        char            *res_str;
 
137
 
 
138
        va_start(args, count);
 
139
 
 
140
        res_str = va_arg(args, char *);
 
141
 
 
142
        /* now add all other strings */
 
143
        for (i = 1; i < count; i++)
 
144
                res_str = cat2_str(res_str, va_arg(args, char *));
 
145
 
 
146
        va_end(args);
 
147
 
 
148
        return(res_str);
 
149
}
 
150
 
 
151
static char *
 
152
make2_str(char *str1, char *str2)
 
153
{
 
154
        char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) + 1);
 
155
 
 
156
        strcpy(res_str, str1);
 
157
        strcat(res_str, str2);
 
158
        free(str1);
 
159
        free(str2);
 
160
        return(res_str);
 
161
}
 
162
 
 
163
static char *
 
164
make3_str(char *str1, char *str2, char *str3)
 
165
{
 
166
        char * res_str  = (char *)mm_alloc(strlen(str1) + strlen(str2) +strlen(str3) + 1);
 
167
 
 
168
        strcpy(res_str, str1);
 
169
        strcat(res_str, str2);
 
170
        strcat(res_str, str3);
 
171
        free(str1);
 
172
        free(str2);
 
173
        free(str3);
 
174
        return(res_str);
 
175
}
 
176
 
 
177
/* and the rest */
 
178
static char *
 
179
make_name(void)
 
180
{
 
181
        return mm_strdup(yytext);
 
182
}
 
183
 
 
184
static char *
 
185
create_questionmarks(char *name, bool array)
 
186
{
 
187
        struct variable *p = find_variable(name);
 
188
        int count;
 
189
        char *result = EMPTY;
 
190
 
 
191
        /* In case we have a struct, we have to print as many "?" as there are attributes in the struct
 
192
         * An array is only allowed together with an element argument
 
193
         * This is essantially only used for inserts, but using a struct as input parameter is an error anywhere else
 
194
         * so we don't have to worry here. */
 
195
 
 
196
        if (p->type->type == ECPGt_struct || (array && p->type->type == ECPGt_array && p->type->u.element->type == ECPGt_struct))
 
197
        {
 
198
                struct ECPGstruct_member *m;
 
199
 
 
200
                if (p->type->type == ECPGt_struct)
 
201
                        m = p->type->u.members;
 
202
                else
 
203
                        m = p->type->u.element->u.members;
 
204
 
 
205
                for (count = 0; m != NULL; m=m->next, count++);
 
206
        }
 
207
        else
 
208
                count = 1;
 
209
 
 
210
        for (; count > 0; count --)
 
211
        {
 
212
                sprintf(pacounter_buffer, "$%d", pacounter++);
 
213
                result = cat_str(3, result, mm_strdup(pacounter_buffer), mm_strdup(" , "));
 
214
        }
 
215
 
 
216
        /* removed the trailing " ," */
 
217
 
 
218
        result[strlen(result)-3] = '\0';
 
219
        return(result);
 
220
}
 
221
 
 
222
static char *
 
223
adjust_outofscope_cursor_vars(struct cursor *cur)
 
224
{
 
225
        /* Informix accepts DECLARE with variables that are out of scope when OPEN is called.
 
226
         * For instance you can DECLARE a cursor in one function, and OPEN/FETCH/CLOSE
 
227
         * it in other functions. This is very useful for e.g. event-driver programming,
 
228
         * but may also lead to dangerous programming. The limitation when this is allowed
 
229
         * and doesn's cause problems have to be documented, like the allocated variables
 
230
         * must not be realloc()'ed.
 
231
         *
 
232
         * We have to change the variables to our own struct and just store the pointer
 
233
         * instead of the variable. Do it only for local variables, not for globals.
 
234
         */
 
235
 
 
236
        char *result = mm_strdup("");
 
237
        int insert;
 
238
 
 
239
        for (insert = 1; insert >= 0; insert--)
 
240
        {
 
241
                struct arguments *list;
 
242
                struct arguments *ptr;
 
243
                struct arguments *newlist = NULL;
 
244
                struct variable *newvar, *newind;
 
245
 
 
246
                list = (insert ? cur->argsinsert : cur->argsresult);
 
247
 
 
248
                for (ptr = list; ptr != NULL; ptr = ptr->next)
 
249
                {
 
250
                        char temp[20];
 
251
                        char *original_var;
 
252
                        bool skip_set_var = false;
 
253
 
 
254
                        /* change variable name to "ECPGget_var(<counter>)" */
 
255
                        original_var = ptr->variable->name;
 
256
                        sprintf(temp, "%d))", ecpg_internal_var);
 
257
 
 
258
                        /* Don't emit ECPGset_var() calls for global variables */
 
259
                        if (ptr->variable->brace_level == 0)
 
260
                        {
 
261
                                newvar = ptr->variable;
 
262
                                skip_set_var = true;
 
263
                        }
 
264
                        else if ((ptr->variable->type->type == ECPGt_char_variable) && (!strncmp(ptr->variable->name, "ECPGprepared_statement", strlen("ECPGprepared_statement"))))
 
265
                        {
 
266
                                newvar = ptr->variable;
 
267
                                skip_set_var = true;
 
268
                        }
 
269
                        else if ((ptr->variable->type->type != ECPGt_varchar && ptr->variable->type->type != ECPGt_char && ptr->variable->type->type != ECPGt_unsigned_char && ptr->variable->type->type != ECPGt_string) && atoi(ptr->variable->type->size) > 1)
 
270
                        {
 
271
                                newvar = new_variable(cat_str(4, mm_strdup("("), mm_strdup(ecpg_type_name(ptr->variable->type->u.element->type)), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, mm_strdup("1"), ptr->variable->type->u.element->counter), ptr->variable->type->size), 0);
 
272
                                sprintf(temp, "%d, (", ecpg_internal_var++);
 
273
                        }
 
274
                        else if ((ptr->variable->type->type == ECPGt_varchar || ptr->variable->type->type == ECPGt_char || ptr->variable->type->type == ECPGt_unsigned_char || ptr->variable->type->type == ECPGt_string) && atoi(ptr->variable->type->size) > 1)
 
275
                        {
 
276
                                newvar = new_variable(cat_str(4, mm_strdup("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->counter), 0);
 
277
                                if (ptr->variable->type->type == ECPGt_varchar)
 
278
                                        sprintf(temp, "%d, &(", ecpg_internal_var++);
 
279
                                else
 
280
                                        sprintf(temp, "%d, (", ecpg_internal_var++);
 
281
                        }
 
282
                        else if (ptr->variable->type->type == ECPGt_struct || ptr->variable->type->type == ECPGt_union)
 
283
                        {
 
284
                                sprintf(temp, "%d)))", ecpg_internal_var);
 
285
                                newvar = new_variable(cat_str(4, mm_strdup("(*("), mm_strdup(ptr->variable->type->type_name), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->variable->type->u.members, ptr->variable->type->type, ptr->variable->type->type_name, ptr->variable->type->struct_sizeof), 0);
 
286
                                sprintf(temp, "%d, &(", ecpg_internal_var++);
 
287
                        }
 
288
                        else if (ptr->variable->type->type == ECPGt_array)
 
289
                        {
 
290
                                if (ptr->variable->type->u.element->type == ECPGt_struct || ptr->variable->type->u.element->type == ECPGt_union)
 
291
                                {
 
292
                                        sprintf(temp, "%d)))", ecpg_internal_var);
 
293
                                        newvar = new_variable(cat_str(4, mm_strdup("(*("), mm_strdup(ptr->variable->type->u.element->type_name), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->variable->type->u.element->u.members, ptr->variable->type->u.element->type, ptr->variable->type->u.element->type_name, ptr->variable->type->u.element->struct_sizeof), 0);
 
294
                                        sprintf(temp, "%d, (", ecpg_internal_var++);
 
295
                                }
 
296
                                else
 
297
                                {
 
298
                                        newvar = new_variable(cat_str(4, mm_strdup("("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->variable->type->u.element->type, ptr->variable->type->u.element->size, ptr->variable->type->u.element->counter), ptr->variable->type->size), 0);
 
299
                                        sprintf(temp, "%d, &(", ecpg_internal_var++);
 
300
                                }
 
301
                        }
 
302
                        else
 
303
                        {
 
304
                                newvar = new_variable(cat_str(4, mm_strdup("*("), mm_strdup(ecpg_type_name(ptr->variable->type->type)), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->variable->type->type, ptr->variable->type->size, ptr->variable->type->counter), 0);
 
305
                                sprintf(temp, "%d, &(", ecpg_internal_var++);
 
306
                        }
 
307
 
 
308
                        /* create call to "ECPGset_var(<counter>, <pointer>. <line number>)" */
 
309
                        if (!skip_set_var)
 
310
                                result = cat_str(5, result, mm_strdup("ECPGset_var("), mm_strdup(temp), mm_strdup(original_var), mm_strdup("), __LINE__);\n"));
 
311
 
 
312
                        /* now the indicator if there is one and it's not a global variable */
 
313
                        if ((ptr->indicator->type->type == ECPGt_NO_INDICATOR) || (ptr->indicator->brace_level == 0))
 
314
                        {
 
315
                                newind = ptr->indicator;
 
316
                        }
 
317
                        else
 
318
                        {
 
319
                                /* change variable name to "ECPGget_var(<counter>)" */
 
320
                                original_var = ptr->indicator->name;
 
321
                                sprintf(temp, "%d))", ecpg_internal_var);
 
322
 
 
323
                                if (ptr->indicator->type->type == ECPGt_struct || ptr->indicator->type->type == ECPGt_union)
 
324
                                {
 
325
                                        sprintf(temp, "%d)))", ecpg_internal_var);
 
326
                                        newind = new_variable(cat_str(4, mm_strdup("(*("), mm_strdup(ptr->indicator->type->type_name), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->indicator->type->u.members, ptr->indicator->type->type, ptr->indicator->type->type_name, ptr->indicator->type->struct_sizeof), 0);
 
327
                                        sprintf(temp, "%d, &(", ecpg_internal_var++);
 
328
                                }
 
329
                                else if (ptr->indicator->type->type == ECPGt_array)
 
330
                                {
 
331
                                        if (ptr->indicator->type->u.element->type == ECPGt_struct || ptr->indicator->type->u.element->type == ECPGt_union)
 
332
                                        {
 
333
                                                sprintf(temp, "%d)))", ecpg_internal_var);
 
334
                                                newind = new_variable(cat_str(4, mm_strdup("(*("), mm_strdup(ptr->indicator->type->u.element->type_name), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_struct_type(ptr->indicator->type->u.element->u.members, ptr->indicator->type->u.element->type, ptr->indicator->type->u.element->type_name, ptr->indicator->type->u.element->struct_sizeof), 0);
 
335
                                                sprintf(temp, "%d, (", ecpg_internal_var++);
 
336
                                        }
 
337
                                        else
 
338
                                        {
 
339
                                                newind = new_variable(cat_str(4, mm_strdup("("), mm_strdup(ecpg_type_name(ptr->indicator->type->u.element->type)), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_array_type(ECPGmake_simple_type(ptr->indicator->type->u.element->type, ptr->indicator->type->u.element->size, ptr->indicator->type->u.element->counter), ptr->indicator->type->size), 0);
 
340
                                                sprintf(temp, "%d, &(", ecpg_internal_var++);
 
341
                                        }
 
342
                                }
 
343
                                else if (atoi(ptr->indicator->type->size) > 1)
 
344
                                {
 
345
                                        newind = new_variable(cat_str(4, mm_strdup("("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->counter), 0);
 
346
                                        sprintf(temp, "%d, (", ecpg_internal_var++);
 
347
                                }
 
348
                                else
 
349
                                {
 
350
                                        newind = new_variable(cat_str(4, mm_strdup("*("), mm_strdup(ecpg_type_name(ptr->indicator->type->type)), mm_strdup(" *)(ECPGget_var("), mm_strdup(temp)), ECPGmake_simple_type(ptr->indicator->type->type, ptr->indicator->type->size, ptr->variable->type->counter), 0);
 
351
                                        sprintf(temp, "%d, &(", ecpg_internal_var++);
 
352
                                }
 
353
 
 
354
                                /* create call to "ECPGset_var(<counter>, <pointer>. <line number>)" */
 
355
                                result = cat_str(5, result, mm_strdup("ECPGset_var("), mm_strdup(temp), mm_strdup(original_var), mm_strdup("), __LINE__);\n"));
 
356
                        }
 
357
 
 
358
                        add_variable_to_tail(&newlist, newvar, newind);
 
359
                }
 
360
 
 
361
                if (insert)
 
362
                        cur->argsinsert_oos = newlist;
 
363
                else
 
364
                        cur->argsresult_oos = newlist;
 
365
        }
 
366
 
 
367
        return result;
 
368
}
 
369
 
 
370
/* This tests whether the cursor was declared and opened in the same function. */
 
371
#define SAMEFUNC(cur)   \
 
372
        ((cur->function == NULL) ||             \
 
373
         (cur->function != NULL && !strcmp(cur->function, current_function)))
 
374
 
 
375
static struct cursor *
 
376
add_additional_variables(char *name, bool insert)
 
377
{
 
378
        struct cursor *ptr;
 
379
        struct arguments *p;
 
380
        int (* strcmp_fn)(const char *, const char *) = (name[0] == ':' ? strcmp : pg_strcasecmp);
 
381
 
 
382
        for (ptr = cur; ptr != NULL; ptr=ptr->next)
 
383
        {
 
384
                if (strcmp_fn(ptr->name, name) == 0)
 
385
                        break;
 
386
        }
 
387
 
 
388
        if (ptr == NULL)
 
389
        {
 
390
                mmerror(PARSE_ERROR, ET_ERROR, "cursor \"%s\" does not exist", name);
 
391
                return NULL;
 
392
        }
 
393
 
 
394
        if (insert)
 
395
        {
 
396
                /* add all those input variables that were given earlier
 
397
                 * note that we have to append here but have to keep the existing order */
 
398
                for (p = (SAMEFUNC(ptr) ? ptr->argsinsert : ptr->argsinsert_oos); p; p = p->next)
 
399
                        add_variable_to_tail(&argsinsert, p->variable, p->indicator);
 
400
        }
 
401
 
 
402
        /* add all those output variables that were given earlier */
 
403
        for (p = (SAMEFUNC(ptr) ? ptr->argsresult : ptr->argsresult_oos); p; p = p->next)
 
404
                add_variable_to_tail(&argsresult, p->variable, p->indicator);
 
405
 
 
406
        return ptr;
 
407
}
 
408
 
 
409
static void
 
410
add_typedef(char *name, char * dimension, char * length, enum ECPGttype type_enum, char *type_dimension, char *type_index, int initializer, int array)
 
411
{
 
412
        /* add entry to list */
 
413
        struct typedefs *ptr, *this;
 
414
 
 
415
        if ((type_enum == ECPGt_struct ||
 
416
             type_enum == ECPGt_union) &&
 
417
            initializer == 1)
 
418
                mmerror(PARSE_ERROR, ET_ERROR, "initializer not allowed in type definition");
 
419
        else if (INFORMIX_MODE && strcmp(name, "string") == 0)
 
420
                mmerror(PARSE_ERROR, ET_ERROR, "type name \"string\" is reserved in Informix mode");
 
421
        else
 
422
        {
 
423
                for (ptr = types; ptr != NULL; ptr = ptr->next)
 
424
                {
 
425
                        if (strcmp(name, ptr->name) == 0)
 
426
                                /* re-definition is a bug */
 
427
                                mmerror(PARSE_ERROR, ET_ERROR, "type \"%s\" is already defined", name);
 
428
                }
 
429
                adjust_array(type_enum, &dimension, &length, type_dimension, type_index, array, true);
 
430
 
 
431
                this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
 
432
 
 
433
                /* initial definition */
 
434
                this->next = types;
 
435
                this->name = name;
 
436
                this->brace_level = braces_open;
 
437
                this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
 
438
                this->type->type_enum = type_enum;
 
439
                this->type->type_str = mm_strdup(name);
 
440
                this->type->type_dimension = dimension; /* dimension of array */
 
441
                this->type->type_index = length;        /* length of string */
 
442
                this->type->type_sizeof = ECPGstruct_sizeof;
 
443
                this->struct_member_list = (type_enum == ECPGt_struct || type_enum == ECPGt_union) ?
 
444
                ECPGstruct_member_dup(struct_member_list[struct_level]) : NULL;
 
445
 
 
446
                if (type_enum != ECPGt_varchar &&
 
447
                        type_enum != ECPGt_char &&
 
448
                        type_enum != ECPGt_unsigned_char &&
 
449
                        type_enum != ECPGt_string &&
 
450
                        atoi(this->type->type_index) >= 0)
 
451
                        mmerror(PARSE_ERROR, ET_ERROR, "multidimensional arrays for simple data types are not supported");
 
452
 
 
453
                types = this;
 
454
        }
 
455
}
 
456
%}
 
457
 
 
458
%expect 0
 
459
%name-prefix="base_yy"
 
460
%locations
 
461
 
 
462
%union {
 
463
        double  dval;
 
464
        char    *str;
 
465
        int     ival;
 
466
        struct  when            action;
 
467
        struct  index           index;
 
468
        int             tagname;
 
469
        struct  this_type       type;
 
470
        enum    ECPGttype       type_enum;
 
471
        enum    ECPGdtype       dtype_enum;
 
472
        struct  fetch_desc      descriptor;
 
473
        struct  su_symbol       struct_union;
 
474
        struct  prep            prep;
 
475
}