@@ -12,7 +12,11 @@ static void yyerror(char *);
12
12
/*
13
13
* Variables containing simple states.
14
14
*/
15
- int debugging =0 ;
15
+ int debugging =0 ;
16
+ static int struct_level =0 ;
17
+
18
+ /* temporarily store record members while creating the data structure*/
19
+ struct ECPGrecord_member *record_member_list[128 ] = {NULL };
16
20
17
21
/*
18
22
* Handle the filename and line numbering.
@@ -86,7 +90,7 @@ remove_variables(int brace_level)
86
90
{
87
91
struct variable * p, *prev;
88
92
89
- for (p = prev = allvariables; p; p = p->next )
93
+ for (p = prev = allvariables; p; p = p ? p ->next : NULL )
90
94
{
91
95
if (p->brace_level >= brace_level)
92
96
{
@@ -96,6 +100,8 @@ remove_variables(int brace_level)
96
100
else
97
101
prev->next = p->next ;
98
102
103
+ ECPGfree_type (p->type );
104
+ free (p->name );
99
105
free (p);
100
106
p = prev;
101
107
}
@@ -157,7 +163,7 @@ dump_variables(struct arguments * list)
157
163
dump_variables (list->next );
158
164
159
165
/* Then the current element.*/
160
- ECPGdump_a_type (yyout, list->variable ->name , list->variable ->type );
166
+ ECPGdump_a_type (yyout, list->variable ->name , list->variable ->type , NULL );
161
167
162
168
/* Then release the list element.*/
163
169
free (list);
@@ -179,12 +185,12 @@ dump_variables(struct arguments * list)
179
185
180
186
%token <tagname> S_SYMBOL S_LENGTH S_ANYTHING
181
187
%token <tagname> S_VARCHAR S_VARCHAR2
182
- %token <tagname> S_EXTERN S_STATIC
188
+ %token <tagname> S_EXTERN S_STATIC S_AUTO S_CONST S_REGISTER S_STRUCT
183
189
%token <tagname> S_UNSIGNED S_SIGNED
184
190
%token <tagname> S_LONG S_SHORT S_INT S_CHAR S_FLOAT S_DOUBLE S_BOOL
185
191
%token <tagname> ' [' ' ]' ' ;' ' ,' ' {' ' }'
186
192
187
- %type <type> type type_detailed varchar_type simple_type array_type
193
+ %type <type> type type_detailed varchar_type simple_type array_type struct_type
188
194
%type <symbolname> symbol
189
195
%type <tagname> maybe_storage_clause varchar_tag
190
196
%type <type_enum> simple_tag
@@ -227,8 +233,12 @@ variable_declarations : /* empty */
227
233
228
234
/* Here is where we can enter support for typedef.*/
229
235
variable_declaration :type ' ;' {
230
- new_variable ($<type>1 .name, $<type>1 .typ);
231
- free ($<type>1 .name);
236
+ /* don't worry about our list when we're working on a struct*/
237
+ if (struct_level ==0 )
238
+ {
239
+ new_variable ($<type>1 .name, $<type>1 .typ);
240
+ free ($<type>1 .name);
241
+ }
232
242
fprintf (yyout," ;" );
233
243
}
234
244
@@ -244,27 +254,61 @@ symbol : S_SYMBOL {
244
254
type :maybe_storage_clause type_detailed { $<type>$ = $<type>2 ; };
245
255
type_detailed :varchar_type { $<type>$ = $<type>1 ; }
246
256
| simple_type { $<type>$ = $<type>1 ; }
247
- | array_type {$<type>$ = $<type>1 ; };
257
+ | array_type {$<type>$ = $<type>1 ; }
258
+ | struct_type {$<type>$ = $<type>1 ; };
248
259
249
260
varchar_type :varchar_tag symbol index {
250
261
fprintf (yyout," struct varchar_%s { int len; char arr[%d]; } %s" , $<symbolname>2 , $<indexsize>3 , $<symbolname>2 );
251
- $<type>$.name = $<symbolname>2 ;
252
- $<type>$.typ = ECPGmake_varchar_type(ECPGt_varchar, $<indexsize>3 );
262
+ if (struct_level ==0 )
263
+ {
264
+ $<type>$.name = $<symbolname>2 ;
265
+ $<type>$.typ = ECPGmake_varchar_type(ECPGt_varchar, $<indexsize>3 );
266
+ }
267
+ else
268
+ ECPGmake_record_member ($<symbolname>2 , ECPGmake_varchar_type(ECPGt_varchar, $<indexsize>3 ), &(record_member_list[struct_level-1 ]));
253
269
}
254
270
255
271
varchar_tag :S_VARCHAR { $<tagname>$ = $<tagname>1 ; }
256
272
| S_VARCHAR2 { $<tagname>$ = $<tagname>1 ; };
257
273
258
274
simple_type :simple_tag symbol {
259
275
fprintf (yyout," %s %s" , ECPGtype_name($<type_enum>1 ), $<symbolname>2);
260
- $<type>$.name = $<symbolname>2 ;
261
- $<type>$.typ = ECPGmake_simple_type($<type_enum>1 );
276
+ if (struct_level ==0 )
277
+ {
278
+ $<type>$.name = $<symbolname>2 ;
279
+ $<type>$.typ = ECPGmake_simple_type($<type_enum>1 );
280
+ }
281
+ else
282
+ ECPGmake_record_member ($<symbolname>2 , ECPGmake_simple_type($<type_enum>1 ), &(record_member_list[struct_level-1 ]));
262
283
}
263
284
264
285
array_type :simple_tag symbol index {
265
286
fprintf (yyout," %s %s [%d]" , ECPGtype_name($<type_enum>1 ), $<symbolname>2, $<indexsize>3);
266
- $<type>$.name = $<symbolname>2 ;
267
- $<type>$.typ = ECPGmake_array_type(ECPGmake_simple_type($<type_enum>1 ), $<indexsize>3 );
287
+ if (struct_level ==0 )
288
+ {
289
+ $<type>$.name = $<symbolname>2 ;
290
+ $<type>$.typ = ECPGmake_array_type(ECPGmake_simple_type($<type_enum>1 ), $<indexsize>3 );
291
+ }
292
+ else
293
+ ECPGmake_record_member ($<symbolname>2 , ECPGmake_array_type(ECPGmake_simple_type($<type_enum>1 ), $<indexsize>3), &(record_member_list[struct_level-1 ]));
294
+ }
295
+
296
+ s_struct :S_STRUCT symbol {
297
+ struct_level++;
298
+ fprintf (yyout," struct %s {" , $<symbolname>2 );
299
+ }
300
+
301
+ struct_type :s_struct ' {' variable_declarations ' }' symbol {
302
+ struct_level--;
303
+ if (struct_level ==0 )
304
+ {
305
+ $<type>$.name = $<symbolname>5 ;
306
+ $<type>$.typ = ECPGmake_record_type(record_member_list[struct_level]);
307
+ }
308
+ else
309
+ ECPGmake_record_member ($<symbolname>5 , ECPGmake_record_type(record_member_list[struct_level]), &(record_member_list[struct_level-1 ]));
310
+ fprintf (yyout," } %s" , $<symbolname>5 );
311
+ record_member_list[struct_level] =NULL ;
268
312
}
269
313
270
314
simple_tag :S_CHAR { $<type_enum>$ = ECPGt_char; }
@@ -281,6 +325,9 @@ simple_tag : S_CHAR { $<type_enum>$ = ECPGt_char; }
281
325
282
326
maybe_storage_clause :S_EXTERN { fwrite(yytext, yyleng,1 , yyout); }
283
327
| S_STATIC { fwrite(yytext, yyleng,1 , yyout); }
328
+ | S_CONST { fwrite(yytext, yyleng,1 , yyout); }
329
+ | S_REGISTER { fwrite(yytext, yyleng,1 , yyout); }
330
+ | S_AUTO { fwrite(yytext, yyleng,1 , yyout); }
284
331
| /* empty*/ { };
285
332
286
333
index :' [' length ' ]' {
@@ -369,13 +416,14 @@ canything : both_anything
369
416
sqlanything :both_anything ;
370
417
371
418
both_anything :S_LENGTH | S_VARCHAR | S_VARCHAR2
372
- | S_LONG | S_SHORT | S_INT | S_CHAR | S_FLOAT | S_DOUBLE
419
+ | S_LONG | S_SHORT | S_INT | S_CHAR | S_FLOAT | S_DOUBLE | S_BOOL
373
420
| SQL_OPEN | SQL_CONNECT
374
421
| SQL_STRING
375
422
| SQL_BEGIN | SQL_END
376
423
| SQL_DECLARE | SQL_SECTION
377
424
| SQL_INCLUDE
378
425
| S_SYMBOL
426
+ | S_STATIC | S_EXTERN | S_AUTO | S_CONST | S_REGISTER | S_STRUCT
379
427
| ' [' | ' ]' | ' ,'
380
428
| S_ANYTHING ;
381
429