1 /* Copyright comment */
10 static void yyerror(char *);
13 * Variables containing simple states.
16 static int struct_level = 0;
18 /* temporarily store record members while creating the data structure */
19 struct ECPGrecord_member *record_member_list[128] = { NULL };
22 * Handle the filename and line numbering.
24 char * input_filename = NULL;
30 fprintf(yyout, "\n#line %d \"%s\"\n", yylineno, input_filename);
34 * Handling of the variables.
42 /* This is a linked list of the variable names and types. */
46 struct ECPGtype * type;
48 struct variable * next;
51 static struct variable * allvariables = NULL;
53 static struct variable *
54 find_variable(char * name)
58 for (p = allvariables; p; p = p->next)
60 if (strcmp(p->name, name) == 0)
65 char * errorstring = (char *) malloc(strlen(name) + 100);
67 sprintf(errorstring, "The variable :%s is not declared.", name);
76 new_variable(const char * name, struct ECPGtype * type)
78 struct variable * p = (struct variable*) malloc(sizeof(struct variable));
80 p->name = strdup(name);
82 p->brace_level = braces_open;
84 p->next = allvariables;
89 remove_variables(int brace_level)
91 struct variable * p, *prev;
93 for (p = prev = allvariables; p; p = p ? p->next : NULL)
95 if (p->brace_level >= brace_level)
98 if (p == allvariables)
99 prev = allvariables = p->next;
101 prev->next = p->next;
103 ECPGfree_type(p->type);
115 * Here are the variables that need to be handled on every request.
116 * These are of two kinds: input and output.
117 * I will make two lists for them.
120 struct variable * variable;
121 struct arguments * next;
125 static struct arguments * argsinsert = NULL;
126 static struct arguments * argsresult = NULL;
136 /* Add a variable to a request. */
138 add_variable(struct arguments ** list, struct variable * var)
140 struct arguments * p = (struct arguments *)malloc(sizeof(struct arguments));
147 /* Dump out a list of all the variable on this list.
148 This is a recursive function that works from the end of the list and
149 deletes the list as we go on.
152 dump_variables(struct arguments * list)
159 /* The list is build up from the beginning so lets first dump the
163 dump_variables(list->next);
165 /* Then the current element. */
166 ECPGdump_a_type(yyout, list->variable->name, list->variable->type, NULL);
168 /* Then release the list element. */
175 struct ECPGtemp_type type;
178 enum ECPGttype type_enum;
181 %token <tagname> SQL_START SQL_SEMI SQL_STRING SQL_INTO
182 %token <tagname> SQL_BEGIN SQL_END SQL_DECLARE SQL_SECTION SQL_INCLUDE
183 %token <tagname> SQL_CONNECT SQL_OPEN SQL_EXECUTE SQL_IMMEDIATE
184 %token <tagname> SQL_COMMIT SQL_ROLLBACK SQL_RELEASE SQL_WORK
186 %token <tagname> S_SYMBOL S_LENGTH S_ANYTHING
187 %token <tagname> S_VARCHAR S_VARCHAR2
188 %token <tagname> S_EXTERN S_STATIC S_AUTO S_CONST S_REGISTER S_STRUCT
189 %token <tagname> S_UNSIGNED S_SIGNED
190 %token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL
191 %token <tagname> '[' ']' ';' ',' '{' '}' '=' '*'
193 %type <type> type type_detailed varchar_type simple_type array_type struct_type
194 %type <symbolname> symbol
195 %type <tagname> maybe_storage_clause varchar_tag db_name
196 %type <type_enum> simple_tag
197 %type <indexsize> index length
198 %type <tagname> canything sqlanything both_anything vartext commit_release
204 statements : /* empty */
205 | statements statement;
207 statement : sqldeclaration
219 sqldeclaration : sql_startdeclare
220 variable_declarations
223 sql_startdeclare : SQL_START SQL_BEGIN SQL_DECLARE SQL_SECTION SQL_SEMI {
224 fprintf(yyout, "/* exec sql begin declare section */\n");
225 output_line_number();
228 sql_enddeclare : SQL_START SQL_END SQL_DECLARE SQL_SECTION SQL_SEMI {
229 fprintf(yyout,"/* exec sql end declare section */\n");
230 output_line_number();
233 variable_declarations : /* empty */
234 | variable_declarations variable_declaration;
236 /* Here is where we can enter support for typedef. */
237 variable_declaration : type initializer ';' {
238 /* don't worry about our list when we're working on a struct */
239 if (struct_level == 0)
241 new_variable($<type>1.name, $<type>1.typ);
247 initializer : /*empty */
248 | '=' {fwrite(yytext, yyleng, 1, yyout);} vartext;
250 vartext : both_anything {fwrite(yytext, yyleng, 1, yyout);}
251 | vartext both_anything {fwrite(yytext, yyleng, 1, yyout);}
254 char * name = (char *)malloc(yyleng + 1);
256 strncpy(name, yytext, yyleng);
259 $<symbolname>$ = name;
262 type : maybe_storage_clause type_detailed { $<type>$ = $<type>2; };
263 type_detailed : varchar_type { $<type>$ = $<type>1; }
264 | simple_type { $<type>$ = $<type>1; }
265 | array_type {$<type>$ = $<type>1; }
266 | pointer_type {$<type>$ = $<type>1; }
267 | struct_type {$<type>$ = $<type>1; };
269 varchar_type : varchar_tag symbol index {
270 if ($<indexsize>3 > 0)
271 fprintf(yyout, "struct varchar_%s { int len; char arr[%d]; } %s", $<symbolname>2, $<indexsize>3, $<symbolname>2);
273 fprintf(yyout, "struct varchar_%s { int len; char arr[%d]; } %s", $<symbolname>2, $<indexsize>3, $<symbolname>2);
274 if (struct_level == 0)
276 $<type>$.name = $<symbolname>2;
277 $<type>$.typ = ECPGmake_varchar_type(ECPGt_varchar, $<indexsize>3);
280 ECPGmake_record_member($<symbolname>2, ECPGmake_varchar_type(ECPGt_varchar, $<indexsize>3), &(record_member_list[struct_level-1]));
283 varchar_tag : S_VARCHAR { $<tagname>$ = $<tagname>1; }
284 | S_VARCHAR2 { $<tagname>$ = $<tagname>1; };
286 simple_type : simple_tag symbol {
287 fprintf(yyout, "%s %s", ECPGtype_name($<type_enum>1), $<symbolname>2);
288 if (struct_level == 0)
290 $<type>$.name = $<symbolname>2;
291 $<type>$.typ = ECPGmake_simple_type($<type_enum>1);
294 ECPGmake_record_member($<symbolname>2, ECPGmake_simple_type($<type_enum>1), &(record_member_list[struct_level-1]));
297 array_type : simple_tag symbol index {
298 if ($<indexsize>3 > 0)
299 fprintf(yyout, "%s %s [%d]", ECPGtype_name($<type_enum>1), $<symbolname>2, $<indexsize>3);
301 fprintf(yyout, "%s %s []", ECPGtype_name($<type_enum>1), $<symbolname>2);
302 if (struct_level == 0)
304 $<type>$.name = $<symbolname>2;
305 $<type>$.typ = ECPGmake_array_type(ECPGmake_simple_type($<type_enum>1), $<indexsize>3);
308 ECPGmake_record_member($<symbolname>2, ECPGmake_array_type(ECPGmake_simple_type($<type_enum>1), $<indexsize>3), &(record_member_list[struct_level-1]));
311 pointer_type : simple_tag '*' symbol {
312 fprintf(yyout, "%s * %s", ECPGtype_name($<type_enum>1), $<symbolname>3);
313 if (struct_level == 0)
315 $<type>$.name = $<symbolname>3;
316 $<type>$.typ = ECPGmake_array_type(ECPGmake_simple_type($<type_enum>1), 0);
319 ECPGmake_record_member($<symbolname>3, ECPGmake_array_type(ECPGmake_simple_type($<type_enum>1), 0), &(record_member_list[struct_level-1]));
322 s_struct : S_STRUCT symbol {
324 fprintf(yyout, "struct %s {", $<symbolname>2);
327 struct_type : s_struct '{' variable_declarations '}' symbol {
329 if (struct_level == 0)
331 $<type>$.name = $<symbolname>5;
332 $<type>$.typ = ECPGmake_record_type(record_member_list[struct_level]);
335 ECPGmake_record_member($<symbolname>5, ECPGmake_record_type(record_member_list[struct_level]), &(record_member_list[struct_level-1]));
336 fprintf(yyout, "} %s", $<symbolname>5);
337 record_member_list[struct_level] = NULL;
340 simple_tag : S_CHAR { $<type_enum>$ = ECPGt_char; }
341 | S_UNSIGNED S_CHAR { $<type_enum>$ = ECPGt_unsigned_char; }
342 | S_SHORT { $<type_enum>$ = ECPGt_short; }
343 | S_UNSIGNED S_SHORT { $<type_enum>$ = ECPGt_unsigned_short; }
344 | S_INT { $<type_enum>$ = ECPGt_int; }
345 | S_UNSIGNED S_INT { $<type_enum>$ = ECPGt_unsigned_int; }
346 | S_LONG { $<type_enum>$ = ECPGt_long; }
347 | S_UNSIGNED S_LONG { $<type_enum>$ = ECPGt_unsigned_long; }
348 | S_FLOAT { $<type_enum>$ = ECPGt_float; }
349 | S_DOUBLE { $<type_enum>$ = ECPGt_double; }
350 | S_BOOL { $<type_enum>$ = ECPGt_bool; };
352 maybe_storage_clause : S_EXTERN { fwrite(yytext, yyleng, 1, yyout); }
353 | S_STATIC { fwrite(yytext, yyleng, 1, yyout); }
354 | S_CONST { fwrite(yytext, yyleng, 1, yyout); }
355 | S_REGISTER { fwrite(yytext, yyleng, 1, yyout); }
356 | S_AUTO { fwrite(yytext, yyleng, 1, yyout); }
359 index : '[' length ']' { $<indexsize>$ = $<indexsize>2; }
360 | '[' ']' { $<indexsize>$ = 0; }
362 length : S_LENGTH { $<indexsize>$ = atoi(yytext); }
364 sqlinclude : SQL_START SQL_INCLUDE { fprintf(yyout, "#include \""); }
365 filename SQL_SEMI { fprintf(yyout, ".h\""); output_line_number(); };
370 sqlconnect : SQL_START SQL_CONNECT { fprintf(yyout, "ECPGconnect("); }
372 SQL_SEMI { fprintf(yyout, ");"); output_line_number();}
374 db_name : SQL_STRING { fprintf(yyout, "\""); fwrite(yytext + 1, yyleng - 2, 1, yyout); fprintf(yyout, "\""); }
375 | ':' symbol { /* check if we have a char variabnle */
376 struct variable *p = find_variable($<symbolname>2);
377 enum ECPGttype typ = p->type->typ;
379 /* if array see what's inside */
380 if (typ == ECPGt_array)
381 typ = p->type->u.element->typ;
383 if (typ != ECPGt_char && typ != ECPGt_unsigned_char)
384 yyerror("invalid datatype");
386 fprintf(yyout, "%s", $<symbolname>2);
389 /* Open is an open cursor. Removed. */
390 sqlopen : SQL_START SQL_OPEN sqlgarbage SQL_SEMI { output_line_number(); };
392 sqlgarbage : /* Empty */
393 | sqlgarbage sqlanything;
396 sqlcommit : SQL_START commit_release SQL_SEMI {
397 fprintf(yyout, "ECPGcommit(__LINE__);");
398 output_line_number();
401 commit_release : SQL_COMMIT
402 | SQL_COMMIT SQL_RELEASE
403 | SQL_COMMIT SQL_WORK SQL_RELEASE;
405 sqlrollback : SQL_START SQL_ROLLBACK SQL_SEMI {
406 fprintf(yyout, "ECPGrollback(__LINE__);");
407 output_line_number();
410 sqlexecute : SQL_START { /* Reset stack */
412 fprintf(yyout, "ECPGdo(__LINE__, \"");
413 } SQL_EXECUTE SQL_IMMEDIATE sqlstatement_words SQL_SEMI {
415 fprintf(yyout, "\", ");
416 dump_variables(argsinsert);
417 fprintf(yyout, "ECPGt_EOIT, ");
418 dump_variables(argsresult);
419 fprintf(yyout, "ECPGt_EORT );");
420 output_line_number();
423 sqlstatement : SQL_START { /* Reset stack */
425 fprintf(yyout, "ECPGdo(__LINE__, \"");
426 } sqlstatement_words SQL_SEMI {
428 fprintf(yyout, "\", ");
429 dump_variables(argsinsert);
430 fprintf(yyout, "ECPGt_EOIT, ");
431 dump_variables(argsresult);
432 fprintf(yyout, "ECPGt_EORT );");
433 output_line_number();
436 sqlstatement_words : sqlstatement_word
437 | sqlstatement_words sqlstatement_word;
439 sqlstatement_word : ':' symbol
441 add_variable(&argsinsert, find_variable($2));
442 fprintf(yyout, " ;; ");
444 | SQL_INTO into_list { }
447 fwrite(yytext, yyleng, 1, yyout);
448 fwrite(" ", 1, 1, yyout);
450 | SQL_INTO sqlanything
452 fprintf(yyout, " into ");
453 fwrite(yytext, yyleng, 1, yyout);
454 fwrite(" ", 1, 1, yyout);
457 into_list : ':' symbol {
458 add_variable(&argsresult, find_variable($2));
460 | into_list ',' ':' symbol{
461 add_variable(&argsresult, find_variable($4));
465 fwrite(yytext, yyleng, 1, yyout);
468 canything : both_anything
472 sqlanything : both_anything;
474 both_anything : S_LENGTH | S_VARCHAR | S_VARCHAR2
475 | S_LONG | S_SHORT | S_INT | S_CHAR | S_FLOAT | S_DOUBLE | S_BOOL
476 | SQL_OPEN | SQL_CONNECT
478 | SQL_BEGIN | SQL_END
479 | SQL_DECLARE | SQL_SECTION
482 | S_STATIC | S_EXTERN | S_AUTO | S_CONST | S_REGISTER | S_STRUCT
483 | '[' | ']' | ',' | '=' | '*'
488 fwrite(yytext, yyleng, 1, yyout);
492 remove_variables(braces_open--);
493 fwrite(yytext, yyleng, 1, yyout);
496 static void yyerror(char * error)
498 fprintf(stderr, "%s\n", error);