@@ -17,8 +17,8 @@ static int QueryIsRule = 0;
17
17
static enum ECPGttype actual_type[128 ];
18
18
static char *actual_storage[128 ];
19
19
20
- /* temporarily store record members while creating the data structure */
21
- struct ECPGrecord_member *record_member_list [128 ] = { NULL };
20
+ /* temporarily store struct members while creating the data structure */
21
+ struct ECPGstruct_member *struct_member_list [128 ] = { NULL };
22
22
23
23
/* keep a list of cursors */
24
24
struct cursor *cur = NULL ;
@@ -89,36 +89,107 @@ int braces_open;
89
89
static struct variable * allvariables = NULL ;
90
90
91
91
static struct variable *
92
- find_variable (char * name)
92
+ new_variable (const char * name, struct ECPGtype * type)
93
+ {
94
+ struct variable * p = (struct variable *) mm_alloc (sizeof (struct variable ));
95
+
96
+ p->name = strdup (name);
97
+ p->type = type;
98
+ p->brace_level = braces_open;
99
+
100
+ p->next = allvariables;
101
+ allvariables = p;
102
+
103
+ return (p);
104
+ }
105
+
106
+ static struct variable * find_variable (char * name);
107
+
108
+ static struct variable *
109
+ find_struct_member (char *name, char *str, struct ECPGstruct_member *members)
110
+ {
111
+ char *next = strpbrk (++str, " .-" ), c = ' \0 ' ;
112
+
113
+ if (next != NULL )
114
+ {
115
+ c = *next;
116
+ *next = ' \0 ' ;
117
+ }
118
+
119
+ for (; members; members = members->next )
120
+ {
121
+ if (strcmp (members->name , str) == 0 )
122
+ {
123
+ if (c == ' \0 ' )
124
+ {
125
+ /* found the end */
126
+ switch (members->typ ->typ )
127
+ {
128
+ case ECPGt_struct:
129
+ return (new_variable (name, ECPGmake_struct_type (members->typ ->u .members )));
130
+ case ECPGt_varchar:
131
+ return (new_variable (name, ECPGmake_varchar_type (members->typ ->typ , members->typ ->size )));
132
+ default :
133
+ return (new_variable (name, ECPGmake_simple_type (members->typ ->typ , members->typ ->size )));
134
+ }
135
+ }
136
+ else
137
+ {
138
+ *next = c;
139
+ if (c == ' -' ) next++;
140
+ return (find_struct_member (name, next, members->typ ->u .members ));
141
+ }
142
+ }
143
+ }
144
+
145
+ return (NULL );
146
+ }
147
+
148
+ static struct variable *
149
+ find_struct (char * name, char *next)
150
+ {
151
+ struct variable * p;
152
+ char c = *next;
153
+
154
+ /* first get the mother structure entry */
155
+ *next = ' \0 ' ;
156
+ p = find_variable (name);
157
+
158
+ /* restore the name, we will need it later on */
159
+ *next = c;
160
+ if (*next == ' -' ) next++;
161
+
162
+ return (find_struct_member (name, next, p->type ->u .members ));
163
+ }
164
+
165
+ static struct variable *
166
+ find_simple (char * name)
93
167
{
94
168
struct variable * p;
95
- char * errorstring = (char *) mm_alloc (strlen (name) + 100 );
96
169
97
170
for (p = allvariables; p; p = p->next )
98
171
{
99
172
if (strcmp (p->name , name) == 0 )
100
173
return p;
101
174
}
102
175
103
- sprintf (errorstring, " The variable %s is not declared" , name);
104
- yyerror (errorstring);
105
- free (errorstring);
106
-
107
- return NULL ;
176
+ return (NULL );
108
177
}
109
178
110
-
111
- static void
112
- new_variable (const char * name, struct ECPGtype * type)
179
+ static struct variable *
180
+ find_variable (char * name)
113
181
{
114
- struct variable * p = (struct variable *) mm_alloc (sizeof (struct variable ));
182
+ char * next;
183
+ struct variable * p =
184
+ ((next = strpbrk (name, " .-" )) != NULL ) ? find_struct (name, next) : find_simple (name);
115
185
116
- p->name = strdup (name);
117
- p->type = type;
118
- p->brace_level = braces_open;
186
+ if (p == NULL )
187
+ {
188
+ sprintf (errortext, " The variable %s is not declared" , name);
189
+ yyerror (errortext);
190
+ }
119
191
120
- p->next = allvariables;
121
- allvariables = p;
192
+ return (p);
122
193
}
123
194
124
195
static void
@@ -215,7 +286,7 @@ check_indicator(struct ECPGtype *var)
215
286
/* make sure this is a valid indicator variable */
216
287
switch (var->typ )
217
288
{
218
- struct ECPGrecord_member *p;
289
+ struct ECPGstruct_member *p;
219
290
220
291
case ECPGt_short:
221
292
case ECPGt_int:
@@ -225,7 +296,7 @@ check_indicator(struct ECPGtype *var)
225
296
case ECPGt_unsigned_long:
226
297
break ;
227
298
228
- case ECPGt_record :
299
+ case ECPGt_struct :
229
300
for (p = var->u .members ; p; p = p->next )
230
301
check_indicator (p->typ );
231
302
break ;
@@ -392,8 +463,8 @@ output_statement(const char * stmt)
392
463
/* C token */
393
464
%token S_ANYTHING S_AUTO S_BOOL S_CHAR S_CONST S_DOUBLE S_EXTERN
394
465
%token S_FLOAT S_INT
395
- %token S_LONG S_REGISTER S_SHORT S_SIGNED S_STATIC S_STRUCT S_UNSIGNED
396
- %token S_VARCHAR
466
+ %token S_LONG S_REGISTER S_SHORT S_SIGNED S_STATIC S_STRUCT
467
+ %token S_STRUCTPOINTER S_UNSIGNED S_VARCHAR
397
468
398
469
/* I need this and don't know where it is defined inside the backend */
399
470
%token TYPECAST
@@ -3704,7 +3775,7 @@ declaration: storage_clause type
3704
3775
{
3705
3776
actual_storage[struct_level] = $1 ;
3706
3777
actual_type[struct_level] = $2 ;
3707
- if ($2 != ECPGt_varchar && $2 != ECPGt_record )
3778
+ if ($2 != ECPGt_varchar && $2 != ECPGt_struct )
3708
3779
fprintf (yyout, " %s %s" , $1 , ECPGtype_name($2 ));
3709
3780
}
3710
3781
variable_list ' ;' { fputc(' ;' , yyout); }
@@ -3723,11 +3794,13 @@ type: simple_type
3723
3794
struct_type : s_struct ' {' variable_declarations ' }'
3724
3795
{
3725
3796
struct_level--;
3726
- $$ = actual_type[struct_level] = ECPGt_record;
3797
+ fputs (" } " , yyout);
3798
+ $$ = ECPGt_struct;
3727
3799
}
3728
3800
3729
3801
s_struct : S_STRUCT symbol
3730
3802
{
3803
+ struct_member_list[struct_level] = NULL ;
3731
3804
struct_level++;
3732
3805
fprintf (yyout, " struct %s {" , $2 );
3733
3806
}
@@ -3764,14 +3837,13 @@ variable: opt_pointer symbol opt_index opt_initializer
3764
3837
3765
3838
switch (actual_type[struct_level])
3766
3839
{
3767
- case ECPGt_record :
3840
+ case ECPGt_struct :
3768
3841
if (struct_level == 0 )
3769
- new_variable ($2 , ECPGmake_record_type(record_member_list [struct_level]));
3842
+ new_variable ($2 , ECPGmake_struct_type(struct_member_list [struct_level]));
3770
3843
else
3771
- ECPGmake_record_member ($2 , ECPGmake_record_type(record_member_list [struct_level]), &(record_member_list [struct_level-1 ]));
3844
+ ECPGmake_struct_member ($2 , ECPGmake_struct_type(struct_member_list [struct_level]), &(struct_member_list [struct_level-1 ]));
3772
3845
3773
- record_member_list[struct_level] = NULL ;
3774
- fprintf (yyout, " } %s%s%s%s" , $1 , $2 , $3 .str, $4 );
3846
+ fprintf (yyout, " %s%s%s%s" , $1 , $2 , $3 .str, $4 );
3775
3847
3776
3848
break ;
3777
3849
case ECPGt_varchar:
@@ -3781,7 +3853,7 @@ variable: opt_pointer symbol opt_index opt_initializer
3781
3853
if (struct_level == 0 )
3782
3854
new_variable ($2 , ECPGmake_varchar_type(actual_type[struct_level], length));
3783
3855
else
3784
- ECPGmake_record_member ($2 , ECPGmake_varchar_type(actual_type[struct_level], length), &(record_member_list [struct_level-1 ]));
3856
+ ECPGmake_struct_member ($2 , ECPGmake_varchar_type(actual_type[struct_level], length), &(struct_member_list [struct_level-1 ]));
3785
3857
3786
3858
if (length > 0 )
3787
3859
fprintf (yyout, " %s struct varchar_%s { int len; char arr[%d]; } %s" , actual_storage[struct_level], $2 , length, $2 );
@@ -3794,7 +3866,7 @@ variable: opt_pointer symbol opt_index opt_initializer
3794
3866
if (struct_level == 0 )
3795
3867
new_variable ($2 , ECPGmake_simple_type(actual_type[struct_level], length));
3796
3868
else
3797
- ECPGmake_record_member ($2 , ECPGmake_simple_type(actual_type[struct_level], length), &(record_member_list [struct_level-1 ]));
3869
+ ECPGmake_struct_member ($2 , ECPGmake_simple_type(actual_type[struct_level], length), &(struct_member_list [struct_level-1 ]));
3798
3870
3799
3871
fprintf (yyout, " %s%s%s%s" , $1 , $2 , $3 .str, $4 );
3800
3872
@@ -4230,15 +4302,15 @@ civariableonly : cvariable name {
4230
4302
}
4231
4303
4232
4304
cvariable : CVARIABLE { $$ = $1 ; }
4233
- | CVARIABLE ' .' identlist { $$ = $1 ; }
4234
- | CVARIABLE ' - ' ' > ' identlist { $$ = $1 ; }
4305
+ | CVARIABLE ' .' identlist { $$ = cat3_str( $1 , " . " , $3 ) ; }
4306
+ | CVARIABLE S_STRUCTPOINTER identlist { $$ = cat3_str( $1 , " -> " , $3 ) ; }
4235
4307
4236
4308
identlist : IDENT { $$ = $1 ; }
4237
- | IDENT ' .' identlist { $$ = $1 ; }
4238
- | IDENT ' - ' ' > ' identlist { $$ = $1 ; }
4309
+ | IDENT ' .' identlist { $$ = cat3_str( $1 , " . " , $3 ) ; }
4310
+ | IDENT S_STRUCTPOINTER identlist { $$ = cat3_str( $1 , " -> " , $3 ) ; }
4239
4311
4240
4312
indicator : /* empty */ { $$ = NULL ; }
4241
- | cvariable { check_indicator((find_variable($1 ))->type); $$ = $1 ; }
4313
+ | cvariable { printf( " ## %s \n " , $1 ); check_indicator((find_variable($1 ))->type); $$ = $1 ; }
4242
4314
| SQL_INDICATOR cvariable { check_indicator((find_variable($2 ))->type); $$ = $2 ; }
4243
4315
| SQL_INDICATOR name { check_indicator((find_variable($2 ))->type); $$ = $2 ; }
4244
4316
0 commit comments