Skip to content

Commit 73b92d1

Browse files
author
Michael Meskes
committed
Added typedef patches and a new option '-c' to automatically create C typedefs from SQL ones.
1 parent a13ddd3 commit 73b92d1

File tree

6 files changed

+123
-35
lines changed

6 files changed

+123
-35
lines changed

src/interfaces/ecpg/ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1225,6 +1225,12 @@ Wed Mar 6 10:40:28 CET 2002
12251225
Sun Mar 10 13:08:22 CET 2002
12261226

12271227
- Fixed two bugs in define command in lexer.
1228+
1229+
Thu Mar 21 08:25:08 CET 2002
1230+
1231+
- Applied patch by Nicolas Bazin <nbazin@ingenico.com.au> for improved
1232+
typedef handling.
1233+
- Added option '-c' to automatically create C typedef from SQL one.
12281234
- Set ecpg version to 2.10.0.
12291235
- Set library version to 3.4.0.
12301236

src/interfaces/ecpg/preproc/c_keywords.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ static ScanKeyword ScanKeywords[] = {
3636
{"signed", SQL_SIGNED},
3737
{"static", S_STATIC},
3838
{"struct", SQL_STRUCT},
39+
{"typedef", S_TYPEDEF},
3940
{"union", UNION},
4041
{"unsigned", SQL_UNSIGNED},
4142
{"varchar", VARCHAR},

src/interfaces/ecpg/preproc/ecpg.c

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.53 2002/01/10 10:42:54 meskes Exp $ */
1+
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.54 2002/03/21 09:42:50 meskes Exp $ */
22

33
/* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
44
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
@@ -17,7 +17,8 @@ extern char *optarg;
1717
#include "extern.h"
1818

1919
int ret_value = 0,
20-
autocommit = 0;
20+
autocommit = false;
21+
auto_create_c = false;
2122
struct _include_path *include_paths = NULL;
2223
struct cursor *cur = NULL;
2324
struct typedefs *types = NULL;
@@ -31,11 +32,11 @@ help(const char *progname)
3132
/* printf is a macro some places; don't #ifdef inside its arguments */
3233
#ifdef YYDEBUG
3334
printf("Usage:\n"
34-
" %s [-d] [-I DIRECTORY] [-o OUTFILE] [-t] file1 [file2...]\n\n",
35+
" %s [-d] [-I DIRECTORY] [-o OUTFILE] [-t] [-c] [-D symbol] file1 [file2...]\n\n",
3536
progname);
3637
#else
3738
printf("Usage:\n"
38-
" %s [-I DIRECTORY] [-o OUTFILE] [-t] file1 [file2...]\n\n",
39+
" %s [-I DIRECTORY] [-o OUTFILE] [-t] [-c] [-D symbol] file1 [file2...]\n\n",
3940
progname);
4041
#endif
4142
printf("Options:\n");
@@ -45,6 +46,8 @@ help(const char *progname)
4546
printf(" -I DIRECTORY search DIRECTORY for include files\n");
4647
printf(" -o OUTFILE write result to OUTFILE\n");
4748
printf(" -t turn on autocommit of transactions\n");
49+
printf(" -c automatically generate C code from embedded SQL code\n currently this works for EXEC SQL TYPE\n");
50+
printf(" -D symbol define symbo\n");
4851
printf("\nIf no output file is specified, the name is formed by adding .c\n"
4952
"to the input file name, after stripping off .pgc if present.\n");
5053
printf("\nReport bugs to <pgsql-bugs@postgresql.org>.\n");
@@ -58,6 +61,7 @@ add_include_path(char *path)
5861
include_paths = mm_alloc(sizeof(struct _include_path));
5962
include_paths->path = path;
6063
include_paths->next = ip;
64+
6165
}
6266

6367
static void
@@ -107,7 +111,7 @@ main(int argc, char *const argv[])
107111
add_include_path("/usr/local/include");
108112
add_include_path(".");
109113

110-
while ((c = getopt(argc, argv, "vo:I:tD:d")) != -1)
114+
while ((c = getopt(argc, argv, "vco:I:tD:d")) != -1)
111115
{
112116
switch (c)
113117
{
@@ -122,13 +126,15 @@ main(int argc, char *const argv[])
122126
add_include_path(optarg);
123127
break;
124128
case 't':
125-
autocommit = 1;
129+
autocommit = true;
126130
break;
127131
case 'v':
128132
verbose = true;
129133
break;
134+
case 'c':
135+
auto_create_c = true;
136+
break;
130137
case 'D':
131-
/* XXX not documented */
132138
add_preprocessor_define(optarg);
133139
break;
134140
case 'd':

src/interfaces/ecpg/preproc/extern.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
extern int braces_open,
1313
autocommit,
14+
auto_create_c,
1415
ret_value,
1516
struct_level;
1617
extern char *descriptor_index;

src/interfaces/ecpg/preproc/preproc.y

Lines changed: 101 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,7 @@ make_name(void)
169169
S_DOTPOINT S_EQUAL S_EXTERN S_INC S_LSHIFT S_MEMPOINT
170170
S_MEMBER S_MOD S_MUL S_NEQUAL S_OR S_REGISTER S_RSHIFT
171171
S_STATIC S_SUB S_VOLATILE
172+
S_TYPEDEF
172173

173174
/* I need this and don't know where it is defined inside the backend */
174175
%token TYPECAST
@@ -354,12 +355,13 @@ make_name(void)
354355
%type <str> stmt ECPGRelease execstring server_name
355356
%type <str> connection_object opt_server opt_port c_stuff c_stuff_item
356357
%type <str> user_name opt_user char_variable ora_user ident opt_reference
357-
%type <str> quoted_ident_stringvar
358+
%type <str> quoted_ident_stringvar var_type_declarations
358359
%type <str> db_prefix server opt_options opt_connection_name c_list
359360
%type <str> ECPGSetConnection cpp_line ECPGTypedef c_args ECPGKeywords
360361
%type <str> enum_type civar civarind ECPGCursorStmt ECPGDeallocate
361362
%type <str> ECPGFree ECPGDeclare ECPGVar opt_at enum_definition
362-
%type <str> struct_type s_struct declaration declarations variable_declarations
363+
%type <str> struct_type s_struct vt_declarations variable_declarations
364+
%type <str> var_declaration type_declaration
363365
%type <str> s_union union_type ECPGSetAutocommit on_off
364366
%type <str> ECPGAllocateDescr ECPGDeallocateDescr symbol opt_symbol
365367
%type <str> ECPGGetDescriptorHeader ECPGColLabel
@@ -418,7 +420,7 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
418420
| AlterUserSetStmt { output_statement($1, 0, connection); }
419421
| ClosePortalStmt { output_statement($1, 0, connection); }
420422
| CommentStmt { output_statement($1, 0, connection); }
421-
| CopyStmt { output_statement($1, 0, connection); }
423+
| CopyStmt { output_statement($1, 0, connection); }
422424
| CreateStmt { output_statement($1, 0, connection); }
423425
| CreateAsStmt { output_statement($1, 0, connection); }
424426
| CreateSchemaStmt { output_statement($1, 0, connection); }
@@ -429,20 +431,20 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
429431
| CreateUserStmt { output_statement($1, 0, connection); }
430432
| ClusterStmt { output_statement($1, 0, connection); }
431433
| DefineStmt { output_statement($1, 0, connection); }
432-
| DropStmt { output_statement($1, 0, connection); }
434+
| DropStmt { output_statement($1, 0, connection); }
433435
| DropSchemaStmt { output_statement($1, 0, connection); }
434436
| TruncateStmt { output_statement($1, 0, connection); }
435437
| DropGroupStmt { output_statement($1, 0, connection); }
436438
| DropPLangStmt { output_statement($1, 0, connection); }
437439
| DropTrigStmt { output_statement($1, 0, connection); }
438440
| DropUserStmt { output_statement($1, 0, connection); }
439441
| ExplainStmt { output_statement($1, 0, connection); }
440-
| FetchStmt { output_statement($1, 1, connection); }
441-
| GrantStmt { output_statement($1, 0, connection); }
442-
| IndexStmt { output_statement($1, 0, connection); }
442+
| FetchStmt { output_statement($1, 1, connection); }
443+
| GrantStmt { output_statement($1, 0, connection); }
444+
| IndexStmt { output_statement($1, 0, connection); }
443445
| ListenStmt { output_statement($1, 0, connection); }
444446
| UnlistenStmt { output_statement($1, 0, connection); }
445-
| LockStmt { output_statement($1, 0, connection); }
447+
| LockStmt { output_statement($1, 0, connection); }
446448
| NotifyStmt { output_statement($1, 0, connection); }
447449
| ProcedureStmt { output_statement($1, 0, connection); }
448450
| ReindexStmt { output_statement($1, 0, connection); }
@@ -458,23 +460,23 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
458460
else
459461
output_statement($1, 1, connection);
460462
}
461-
| RuleStmt { output_statement($1, 0, connection); }
463+
| RuleStmt { output_statement($1, 0, connection); }
462464
| TransactionStmt
463465
{
464466
fprintf(yyout, "{ ECPGtrans(__LINE__, %s, \"%s\");", connection ? connection : "NULL", $1);
465467
whenever_action(2);
466468
free($1);
467469
}
468-
| ViewStmt { output_statement($1, 0, connection); }
469-
| LoadStmt { output_statement($1, 0, connection); }
470+
| ViewStmt { output_statement($1, 0, connection); }
471+
| LoadStmt { output_statement($1, 0, connection); }
470472
| CreatedbStmt { output_statement($1, 0, connection); }
471473
| DropdbStmt { output_statement($1, 0, connection); }
472474
| VacuumStmt { output_statement($1, 0, connection); }
473475
| AnalyzeStmt { output_statement($1, 0, connection); }
474476
| VariableSetStmt { output_statement($1, 0, connection); }
475477
| VariableShowStmt { output_statement($1, 0, connection); }
476-
| VariableResetStmt { output_statement($1, 0, connection); }
477-
| ConstraintsSetStmt { output_statement($1, 0, connection); }
478+
| VariableResetStmt { output_statement($1, 0, connection); }
479+
| ConstraintsSetStmt { output_statement($1, 0, connection); }
478480
| CheckPointStmt { output_statement($1, 0, connection); }
479481
| ECPGAllocateDescr
480482
{
@@ -605,7 +607,9 @@ stmt: AlterDatabaseSetStmt { output_statement($1, 0, connection); }
605607
if (connection)
606608
mmerror(PARSE_ERROR, ET_ERROR, "no at option for typedef statement.\n");
607609

608-
output_simple_statement($1);
610+
fprintf(yyout, "%s", $1);
611+
free($1);
612+
output_line_number();
609613
}
610614
| ECPGVar
611615
{
@@ -3666,7 +3670,7 @@ ECPGDeallocate: SQL_DEALLOCATE SQL_PREPARE ident
36663670
*/
36673671
ECPGDeclaration: sql_startdeclare
36683672
{ fputs("/* exec sql begin declare section */", yyout); }
3669-
variable_declarations sql_enddeclare
3673+
var_type_declarations sql_enddeclare
36703674
{
36713675
fprintf(yyout, "%s/* exec sql end declare section */", $3);
36723676
free($3);
@@ -3678,15 +3682,82 @@ sql_startdeclare: ecpgstart BEGIN_TRANS DECLARE SQL_SECTION ';' {};
36783682

36793683
sql_enddeclare: ecpgstart END_TRANS DECLARE SQL_SECTION ';' {};
36803684

3681-
variable_declarations: /*EMPTY*/ { $$ = EMPTY; }
3682-
| declarations { $$ = $1; }
3685+
var_type_declarations: /*EMPTY*/ { $$ = EMPTY; }
3686+
| vt_declarations { $$ = $1; }
36833687
;
36843688

3685-
declarations: declaration { $$ = $1; }
3686-
| declarations declaration { $$ = cat2_str($1, $2); }
3689+
vt_declarations: var_declaration { $$ = $1; }
3690+
| type_declaration { $$ = $1; }
3691+
| vt_declarations var_declaration { $$ = cat2_str($1, $2); }
3692+
| vt_declarations type_declaration { $$ = cat2_str($1, $2); }
36873693
;
36883694

3689-
declaration: storage_clause storage_modifier
3695+
variable_declarations: var_declaration { $$ = $1; }
3696+
| variable_declarations var_declaration { $$ = cat2_str($1, $2); }
3697+
;
3698+
3699+
type_declaration: S_TYPEDEF
3700+
{
3701+
/* reset this variable so we see if there was */
3702+
/* an initializer specified */
3703+
initializer = 0;
3704+
}
3705+
type opt_pointer ECPGColLabel opt_type_array_bounds ';'
3706+
{
3707+
/* add entry to list */
3708+
struct typedefs *ptr, *this;
3709+
int dimension = $6.index1;
3710+
int length = $6.index2;
3711+
3712+
if (($3.type_enum == ECPGt_struct ||
3713+
$3.type_enum == ECPGt_union) &&
3714+
initializer == 1)
3715+
{
3716+
mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in typedef command");
3717+
3718+
}
3719+
else
3720+
{
3721+
for (ptr = types; ptr != NULL; ptr = ptr->next)
3722+
{
3723+
if (strcmp($5, ptr->name) == 0)
3724+
{
3725+
/* re-definition is a bug */
3726+
sprintf(errortext, "Type %s already defined", $5);
3727+
mmerror(PARSE_ERROR, ET_ERROR, errortext);
3728+
}
3729+
}
3730+
3731+
adjust_array($3.type_enum, &dimension, &length, $3.type_dimension, $3.type_index, *$4?1:0);
3732+
3733+
this = (struct typedefs *) mm_alloc(sizeof(struct typedefs));
3734+
3735+
/* initial definition */
3736+
this->next = types;
3737+
this->name = $5;
3738+
this->type = (struct this_type *) mm_alloc(sizeof(struct this_type));
3739+
this->type->type_enum = $3.type_enum;
3740+
this->type->type_str = mm_strdup($5);
3741+
this->type->type_dimension = dimension; /* dimension of array */
3742+
this->type->type_index = length; /* lenght of string */
3743+
this->struct_member_list = ($3.type_enum == ECPGt_struct || $3.type_enum == ECPGt_union) ?
3744+
struct_member_list[struct_level] : NULL;
3745+
3746+
if ($3.type_enum != ECPGt_varchar &&
3747+
$3.type_enum != ECPGt_char &&
3748+
$3.type_enum != ECPGt_unsigned_char &&
3749+
this->type->type_index >= 0)
3750+
mmerror(PARSE_ERROR, ET_ERROR, "No multi-dimensional array support for simple data types");
3751+
3752+
types = this;
3753+
}
3754+
3755+
fprintf(yyout, "typedef %s %s %s %s;\n", $3.type_str, *$4?"*":"", $5, $6.str);
3756+
output_line_number();
3757+
$$ = make_str("");
3758+
};
3759+
3760+
var_declaration: storage_clause storage_modifier
36903761
{
36913762
actual_storage[struct_level] = cat2_str(mm_strdup($1), mm_strdup($2));
36923763
actual_startline[struct_level] = hashline_number();
@@ -4239,7 +4310,7 @@ ECPGTypedef: TYPE_P
42394310
if (($5.type_enum == ECPGt_struct ||
42404311
$5.type_enum == ECPGt_union) &&
42414312
initializer == 1)
4242-
mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL VAR command");
4313+
mmerror(PARSE_ERROR, ET_ERROR, "Initializer not allowed in EXEC SQL TYPE command");
42434314
else
42444315
{
42454316
for (ptr = types; ptr != NULL; ptr = ptr->next)
@@ -4276,7 +4347,10 @@ ECPGTypedef: TYPE_P
42764347
types = this;
42774348
}
42784349

4279-
$$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
4350+
if (auto_create_c == false)
4351+
$$ = cat_str(7, make_str("/* exec sql type"), mm_strdup($3), make_str("is"), mm_strdup($5.type_str), mm_strdup($6.str), $7, make_str("*/"));
4352+
else
4353+
$$ = cat_str(6, make_str("typedef "), mm_strdup($5.type_str), *$7?make_str("*"):make_str(""), mm_strdup($6.str), mm_strdup($3), make_str(";"));
42804354
}
42814355
;
42824356

@@ -4504,10 +4578,10 @@ ECPGKeywords: SQL_BREAK { $$ = make_str("break"); }
45044578
;
45054579

45064580
/* additional keywords that can be SQL type names (but not ECPGColLabels) */
4507-
ECPGTypeName: SQL_BOOL { $$ = make_str("bool"); }
4508-
| SQL_INT { $$ = make_str("int"); }
4509-
| SQL_LONG { $$ = make_str("long"); }
4510-
| SQL_SHORT { $$ = make_str("short"); }
4581+
ECPGTypeName: SQL_BOOL { $$ = make_str("bool"); }
4582+
| SQL_INT { $$ = make_str("int"); }
4583+
| SQL_LONG { $$ = make_str("long"); }
4584+
| SQL_SHORT { $$ = make_str("short"); }
45114585
| SQL_STRUCT { $$ = make_str("struct"); }
45124586
| SQL_SIGNED { $$ = make_str("signed"); }
45134587
| SQL_UNSIGNED { $$ = make_str("unsigned"); }
@@ -5006,6 +5080,7 @@ c_anything: IDENT { $$ = $1; }
50065080
| S_RSHIFT { $$ = make_str(">>"); }
50075081
| S_STATIC { $$ = make_str("static"); }
50085082
| S_SUB { $$ = make_str("-="); }
5083+
| S_TYPEDEF { $$ = make_str("typedef"); }
50095084
| SQL_BOOL { $$ = make_str("bool"); }
50105085
| SQL_ENUM { $$ = make_str("enum"); }
50115086
| SQL_INT { $$ = make_str("int"); }

src/interfaces/ecpg/test/test3.pgc

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,8 @@ exec sql type str is varchar[10];
1111
int
1212
main ()
1313
{
14-
typedef struct { long born; short age; } birthinfo;
15-
exec sql type birthinfo is struct { long born; short age; };
1614
exec sql begin declare section;
15+
typedef struct { long born; short age; } birthinfo;
1716
struct personal_struct { str name;
1817
birthinfo birth;
1918
} personal;

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy