Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 718430e

Browse files
committed
From: Michael Meskes <meskes@topsystem.de>
And the next update. Now you can use only parts of a struct like this: exec sql select a into :struct.string from foo;
1 parent 3e3477f commit 718430e

File tree

9 files changed

+173
-93
lines changed

9 files changed

+173
-93
lines changed

src/interfaces/ecpg/ChangeLog

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,3 +142,10 @@ Fri Apr 24 13:50:15 CEST 1998
142142

143143
- Fixed some bugs.
144144
- Set version to 2.1.1
145+
146+
Mon Apr 27 14:26:55 CEST 1998
147+
148+
- Parser now able to understand and process syntax like :foo->bar
149+
and :foo.bar as variables.
150+
- Set version to 2.2.0
151+

src/interfaces/ecpg/TODO

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,3 @@ exec sql disconnect {current|default|all|connectionname|connection_hostvar};
5353
commit release|commit work release auch disconnect
5454

5555
It is not neccessary to check for "not found" after all commands.
56-
57-
It would be nice to be able to specify parts of a structure like :foo.bar or
58-
:foo->bar.

src/interfaces/ecpg/include/ecpgtype.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
* Complex types:
1919
* VARCHAR, VARCHAR2 - Strings with length (maxlen is given in the declaration)
2020
* Arrays of simple types and of VARCHAR, VARCHAR2 (size given in declaration)
21-
* Records build of simple types, arrays and other records.
21+
* Records build of simple types, arrays and other structs.
2222
*
2323
* Complicating things:
2424
* typedefs and struct names!
@@ -41,7 +41,7 @@ enum ECPGttype
4141
ECPGt_float, ECPGt_double,
4242
ECPGt_varchar, ECPGt_varchar2,
4343
ECPGt_array,
44-
ECPGt_record,
44+
ECPGt_struct,
4545
ECPGt_EOIT, /* End of insert types. */
4646
ECPGt_EORT, /* End of result types. */
4747
ECPGt_NO_INDICATOR /* no indicator */

src/interfaces/ecpg/preproc/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,8 @@ SRCDIR= ../../..
22
include $(SRCDIR)/Makefile.global
33

44
MAJOR_VERSION=2
5-
MINOR_VERSION=1
6-
PATCHLEVEL=1
5+
MINOR_VERSION=2
6+
PATCHLEVEL=0
77

88
CFLAGS+=-I../include -DMAJOR_VERSION=$(MAJOR_VERSION) \
99
-DMINOR_VERSION=$(MINOR_VERSION) -DPATCHLEVEL=$(PATCHLEVEL) \

src/interfaces/ecpg/preproc/pgc.l

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,6 +306,7 @@ sql [sS][qQ][lL]
306306
return (yytext[0]);
307307
}
308308
<SQL>{self} { return (yytext[0]); }
309+
<SQL>"->" { return S_STRUCTPOINTER; }
309310
<SQL>{operator}/-[\.0-9] {
310311
yylval.str = strdup((char*)yytext);
311312
return (Op);

src/interfaces/ecpg/preproc/preproc.y

Lines changed: 108 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ static int QueryIsRule = 0;
1717
static enum ECPGttype actual_type[128];
1818
static char *actual_storage[128];
1919

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 };
2222

2323
/* keep a list of cursors */
2424
struct cursor *cur = NULL;
@@ -89,36 +89,107 @@ int braces_open;
8989
static struct variable * allvariables = NULL;
9090

9191
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)
93167
{
94168
struct variable * p;
95-
char * errorstring = (char *) mm_alloc(strlen(name) + 100);
96169

97170
for (p = allvariables; p; p = p->next)
98171
{
99172
if (strcmp(p->name, name) == 0)
100173
return p;
101174
}
102175

103-
sprintf(errorstring, "The variable %s is not declared", name);
104-
yyerror(errorstring);
105-
free (errorstring);
106-
107-
return NULL;
176+
return(NULL);
108177
}
109178

110-
111-
static void
112-
new_variable(const char * name, struct ECPGtype * type)
179+
static struct variable *
180+
find_variable(char * name)
113181
{
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);
115185

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+
}
119191

120-
p->next = allvariables;
121-
allvariables = p;
192+
return(p);
122193
}
123194

124195
static void
@@ -215,7 +286,7 @@ check_indicator(struct ECPGtype *var)
215286
/* make sure this is a valid indicator variable */
216287
switch (var->typ)
217288
{
218-
struct ECPGrecord_member *p;
289+
struct ECPGstruct_member *p;
219290

220291
case ECPGt_short:
221292
case ECPGt_int:
@@ -225,7 +296,7 @@ check_indicator(struct ECPGtype *var)
225296
case ECPGt_unsigned_long:
226297
break;
227298

228-
case ECPGt_record:
299+
case ECPGt_struct:
229300
for (p = var->u.members; p; p = p->next)
230301
check_indicator(p->typ);
231302
break;
@@ -392,8 +463,8 @@ output_statement(const char * stmt)
392463
/* C token */
393464
%token S_ANYTHING S_AUTO S_BOOL S_CHAR S_CONST S_DOUBLE S_EXTERN
394465
%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
397468

398469
/* I need this and don't know where it is defined inside the backend */
399470
%token TYPECAST
@@ -3704,7 +3775,7 @@ declaration: storage_clause type
37043775
{
37053776
actual_storage[struct_level] = $1;
37063777
actual_type[struct_level] = $2;
3707-
if ($2 != ECPGt_varchar && $2 != ECPGt_record)
3778+
if ($2 != ECPGt_varchar && $2 != ECPGt_struct)
37083779
fprintf(yyout, "%s %s", $1, ECPGtype_name($2));
37093780
}
37103781
variable_list ';' { fputc(';', yyout); }
@@ -3723,11 +3794,13 @@ type: simple_type
37233794
struct_type: s_struct '{' variable_declarations '}'
37243795
{
37253796
struct_level--;
3726-
$$ = actual_type[struct_level] = ECPGt_record;
3797+
fputs("} ", yyout);
3798+
$$ = ECPGt_struct;
37273799
}
37283800

37293801
s_struct : S_STRUCT symbol
37303802
{
3803+
struct_member_list[struct_level] = NULL;
37313804
struct_level++;
37323805
fprintf(yyout, "struct %s {", $2);
37333806
}
@@ -3764,14 +3837,13 @@ variable: opt_pointer symbol opt_index opt_initializer
37643837

37653838
switch (actual_type[struct_level])
37663839
{
3767-
case ECPGt_record:
3840+
case ECPGt_struct:
37683841
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]));
37703843
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]));
37723845

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);
37753847

37763848
break;
37773849
case ECPGt_varchar:
@@ -3781,7 +3853,7 @@ variable: opt_pointer symbol opt_index opt_initializer
37813853
if (struct_level == 0)
37823854
new_variable($2, ECPGmake_varchar_type(actual_type[struct_level], length));
37833855
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]));
37853857

37863858
if (length > 0)
37873859
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
37943866
if (struct_level == 0)
37953867
new_variable($2, ECPGmake_simple_type(actual_type[struct_level], length));
37963868
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]));
37983870

37993871
fprintf(yyout, "%s%s%s%s", $1, $2, $3.str, $4);
38003872

@@ -4230,15 +4302,15 @@ civariableonly : cvariable name {
42304302
}
42314303

42324304
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); }
42354307

42364308
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); }
42394311

42404312
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; }
42424314
| SQL_INDICATOR cvariable { check_indicator((find_variable($2))->type); $$ = $2; }
42434315
| SQL_INDICATOR name { check_indicator((find_variable($2))->type); $$ = $2; }
42444316

0 commit comments

Comments
 (0)