Commit 9e9d8d54 authored by Michael Meskes's avatar Michael Meskes

Added an option to force ecpg to also parse files includes via '#include' and...

Added an option to force ecpg to also parse files includes via '#include' and some more Informix stuff.
parent cffded96
...@@ -1391,6 +1391,11 @@ Tue Apr 8 14:03:32 CEST 2003 ...@@ -1391,6 +1391,11 @@ Tue Apr 8 14:03:32 CEST 2003
- Added rstrdate function. - Added rstrdate function.
- Made Informix mode honor environment variable to set dbname to - Made Informix mode honor environment variable to set dbname to
connect to. connect to.
Thu May 1 14:54:41 CEST 2003
- Enable more Informix shortcuts.
- Added option '-i' to parse files included via cpp diretive as well.
- Set ecpg version to 2.12.0. - Set ecpg version to 2.12.0.
- Set ecpg library to 3.4.2. - Set ecpg library to 3.4.2.
- Set pgtypes library to 1.0.0 - Set pgtypes library to 1.0.0
......
/* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.66 2003/04/08 12:34:25 meskes Exp $ */ /* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/ecpg.c,v 1.67 2003/05/01 17:16:57 meskes Exp $ */
/* New main for ecpg, the PostgreSQL embedded SQL precompiler. */ /* New main for ecpg, the PostgreSQL embedded SQL precompiler. */
/* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */ /* (C) Michael Meskes <meskes@postgresql.org> Feb 5th, 1998 */
...@@ -19,7 +19,8 @@ extern char *optarg; ...@@ -19,7 +19,8 @@ extern char *optarg;
int ret_value = 0, int ret_value = 0,
autocommit = false, autocommit = false,
auto_create_c = false; auto_create_c = false,
system_includes = false;
enum COMPAT_MODE compat = ECPG_COMPAT_PGSQL; enum COMPAT_MODE compat = ECPG_COMPAT_PGSQL;
...@@ -43,11 +44,13 @@ help(const char *progname) ...@@ -43,11 +44,13 @@ help(const char *progname)
printf(" -d generate parser debug output\n"); printf(" -d generate parser debug output\n");
#endif #endif
printf(" -C <mode> set compatibility mode\n" printf(" -C <mode> set compatibility mode\n"
" mode may be INFORMIX only at the moment\n"); " mode may be INFORMIX only at the moment\n"
" INFORMIX mode implies '-i'\n");
printf(" -D SYMBOL define SYMBOL\n"); printf(" -D SYMBOL define SYMBOL\n");
printf(" -I DIRECTORY search DIRECTORY for include files\n"); printf(" -I DIRECTORY search DIRECTORY for include files\n");
printf(" -o OUTFILE write result to OUTFILE\n"); printf(" -o OUTFILE write result to OUTFILE\n");
printf(" -t turn on autocommit of transactions\n"); printf(" -t turn on autocommit of transactions\n");
printf(" -i parse system include files as well\n");
printf(" --help show this help, then exit\n"); printf(" --help show this help, then exit\n");
printf(" --version output version information, then exit\n"); printf(" --version output version information, then exit\n");
printf("\nIf no output file is specified, the name is formed by adding .c to the\n" printf("\nIf no output file is specified, the name is formed by adding .c to the\n"
...@@ -127,7 +130,7 @@ main(int argc, char *const argv[]) ...@@ -127,7 +130,7 @@ main(int argc, char *const argv[])
add_include_path("/usr/local/include"); add_include_path("/usr/local/include");
add_include_path("."); add_include_path(".");
while ((c = getopt(argc, argv, "vco:I:tD:dC:")) != -1) while ((c = getopt(argc, argv, "vcio:I:tD:dC:")) != -1)
{ {
switch (c) switch (c)
{ {
...@@ -150,10 +153,14 @@ main(int argc, char *const argv[]) ...@@ -150,10 +153,14 @@ main(int argc, char *const argv[])
case 'c': case 'c':
auto_create_c = true; auto_create_c = true;
break; break;
case 'i':
system_includes = true;
break;
case 'C': case 'C':
if (strcmp(optarg, "INFORMIX") == 0) if (strcmp(optarg, "INFORMIX") == 0)
{ {
compat = ECPG_COMPAT_INFORMIX; compat = ECPG_COMPAT_INFORMIX;
system_includes = true;
add_preprocessor_define("dec_t=Numeric"); add_preprocessor_define("dec_t=Numeric");
add_preprocessor_define("intrvl_t=Interval"); add_preprocessor_define("intrvl_t=Interval");
} }
......
...@@ -15,6 +15,7 @@ ...@@ -15,6 +15,7 @@
extern int braces_open, extern int braces_open,
autocommit, autocommit,
auto_create_c, auto_create_c,
system_includes,
ret_value, ret_value,
struct_level; struct_level;
extern char *descriptor_index; extern char *descriptor_index;
......
...@@ -12,7 +12,7 @@ ...@@ -12,7 +12,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.106 2003/02/17 14:06:39 meskes Exp $ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.107 2003/05/01 17:16:57 meskes Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -25,7 +25,6 @@ ...@@ -25,7 +25,6 @@
#include "extern.h" #include "extern.h"
extern YYSTYPE yylval; extern YYSTYPE yylval;
static int xcdepth = 0; /* depth of nesting in slash-star comments */ static int xcdepth = 0; /* depth of nesting in slash-star comments */
...@@ -44,6 +43,7 @@ static int literalalloc; /* current allocated buffer size */ ...@@ -44,6 +43,7 @@ static int literalalloc; /* current allocated buffer size */
static void addlit(char *ytext, int yleng); static void addlit(char *ytext, int yleng);
static void addlitchar (unsigned char); static void addlitchar (unsigned char);
static void string_unput (char *); static void string_unput (char *);
static void parse_include (void);
char *token_start; char *token_start;
int state_before; int state_before;
...@@ -265,12 +265,17 @@ else [eE][lL][sS][eE] ...@@ -265,12 +265,17 @@ else [eE][lL][sS][eE]
elif [eE][lL][iI][fF] elif [eE][lL][iI][fF]
endif [eE][nN][dD][iI][fF] endif [eE][nN][dD][iI][fF]
struct [sS][tT][rR][uU][cC][tT]
exec_sql {exec}{space}*{sql}{space}* exec_sql {exec}{space}*{sql}{space}*
ipdigit ({digit}|{digit}{digit}|{digit}{digit}{digit}) ipdigit ({digit}|{digit}{digit}|{digit}{digit}{digit})
ip {ipdigit}\.{ipdigit}\.{ipdigit}\.{ipdigit} ip {ipdigit}\.{ipdigit}\.{ipdigit}\.{ipdigit}
/* we might want to parse all cpp include files */
cppinclude {space}*#{include}{space}*
/* Take care of cpp continuation lines */ /* Take care of cpp continuation lines */
cppline {space}*#(.*\\{space})*.* cppline {space}*#(.*\\{space})+.*
/* /*
* Quoted strings must allow some special characters such as single-quote * Quoted strings must allow some special characters such as single-quote
...@@ -429,6 +434,20 @@ cppline {space}*#(.*\\{space})*.* ...@@ -429,6 +434,20 @@ cppline {space}*#(.*\\{space})*.*
else else
return yytext[0]; return yytext[0];
} }
<C>{informix_special}{struct} {
/* are we simulating Informix? */
if (compat == ECPG_COMPAT_INFORMIX)
{
string_unput("typedef struct ");
BEGIN SQL;
return SQL_START;
}
else
{
string_unput("struct ");
return S_ANYTHING;
}
}
<SQL>{self} { /* <SQL>{self} { /*
* We may find a ';' inside a structure * We may find a ';' inside a structure
* definition in a TYPE or VAR statement. * definition in a TYPE or VAR statement.
...@@ -550,22 +569,6 @@ cppline {space}*#(.*\\{space})*.* ...@@ -550,22 +569,6 @@ cppline {space}*#(.*\\{space})*.*
ScanKeyword *keyword; ScanKeyword *keyword;
struct _defines *ptr; struct _defines *ptr;
/* Is it an SQL keyword? */
keyword = ScanKeywordLookup(yytext);
if (keyword != NULL)
return keyword->value;
/* Is it an ECPG keyword? */
keyword = ScanECPGKeywordLookup( yytext);
if (keyword != NULL)
return keyword->value;
/* Is it a C keyword? */
keyword = ScanCKeywordLookup(yytext);
if (keyword != NULL)
return keyword->value;
/* How about a DEFINE? */ /* How about a DEFINE? */
for (ptr = defines; ptr; ptr = ptr->next) for (ptr = defines; ptr; ptr = ptr->next)
{ {
...@@ -587,6 +590,21 @@ cppline {space}*#(.*\\{space})*.* ...@@ -587,6 +590,21 @@ cppline {space}*#(.*\\{space})*.*
} }
} }
/* Is it an SQL keyword? */
keyword = ScanKeywordLookup(yytext);
if (keyword != NULL)
return keyword->value;
/* Is it an ECPG keyword? */
keyword = ScanECPGKeywordLookup( yytext);
if (keyword != NULL)
return keyword->value;
/* Is it a C keyword? */
keyword = ScanCKeywordLookup(yytext);
if (keyword != NULL)
return keyword->value;
/* /*
* None of the above. Return it as an identifier. * None of the above. Return it as an identifier.
* *
...@@ -627,21 +645,26 @@ cppline {space}*#(.*\\{space})*.* ...@@ -627,21 +645,26 @@ cppline {space}*#(.*\\{space})*.*
} }
return ICONST; return ICONST;
} }
<C>{cppinclude} {
if (system_includes)
{
BEGIN(incl);
}
else
{
yylval.str = mm_strdup(yytext);
return(CPP_LINE);
}
}
<C>{cppline} { <C>{cppline} {
yylval.str = mm_strdup(yytext); yylval.str = mm_strdup(yytext);
return(CPP_LINE); return(CPP_LINE);
} }
<C>{identifier} { <C>{identifier} {
ScanKeyword *keyword; ScanKeyword *keyword;
keyword = ScanCKeywordLookup(yytext);
if (keyword != NULL) {
return keyword->value;
}
else
{
struct _defines *ptr; struct _defines *ptr;
/* is it a define? */
for (ptr = defines; ptr; ptr = ptr->next) for (ptr = defines; ptr; ptr = ptr->next)
{ {
if (strcmp(yytext, ptr->old) == 0) if (strcmp(yytext, ptr->old) == 0)
...@@ -661,8 +684,14 @@ cppline {space}*#(.*\\{space})*.* ...@@ -661,8 +684,14 @@ cppline {space}*#(.*\\{space})*.*
break; break;
} }
} }
if (ptr == NULL) if (ptr == NULL)
{ {
keyword = ScanCKeywordLookup(yytext);
if (keyword != NULL)
return keyword->value;
else {
yylval.str = mm_strdup(yytext); yylval.str = mm_strdup(yytext);
return IDENT; return IDENT;
} }
...@@ -940,7 +969,11 @@ cppline {space}*#(.*\\{space})*.* ...@@ -940,7 +969,11 @@ cppline {space}*#(.*\\{space})*.*
} }
<def>[^;] { addlit(yytext, yyleng); } <def>[^;] { addlit(yytext, yyleng); }
<incl>[^;]+";" { <incl>\<[^\>]+\>{space}*";"? { parse_include(); }
<incl>{dquote}{xdinside}{dquote}{space}*";"? { parse_include(); }
<incl>[^;\<\>\"]+";" {
parse_include();
#if 0
/* got the include file name */ /* got the include file name */
struct _yy_buffer *yb; struct _yy_buffer *yb;
struct _include_path *ip; struct _include_path *ip;
...@@ -1026,6 +1059,7 @@ cppline {space}*#(.*\\{space})*.* ...@@ -1026,6 +1059,7 @@ cppline {space}*#(.*\\{space})*.*
output_line_number(); output_line_number();
BEGIN C; BEGIN C;
#endif
} }
<<EOF>> { <<EOF>> {
...@@ -1128,3 +1162,96 @@ string_unput (char *string) ...@@ -1128,3 +1162,96 @@ string_unput (char *string)
unput(string[i]); unput(string[i]);
} }
static void
parse_include(void)
{
/* got the include file name */
struct _yy_buffer *yb;
struct _include_path *ip;
char inc_file[MAXPGPATH];
unsigned int i;
yb = mm_alloc(sizeof(struct _yy_buffer));
yb->buffer = YY_CURRENT_BUFFER;
yb->lineno = yylineno;
yb->filename = input_filename;
yb->next = yy_buffer;
yy_buffer = yb;
/*
* skip the ";" if there is one and trailing whitespace. Note that
* yytext contains at least one non-space character plus the ";"
*/
for ( i = strlen(yytext)-2;
i > 0 && isspace((unsigned char) yytext[i]);
i-- )
{}
if (yytext[i] == ';')
i--;
yytext[i+1] = '\0';
yyin = NULL;
/* If file name is enclosed in '"' remove these and look only in '.' */
/* Informix does look into all include paths though, except filename starts with '/' */
if ((yytext[0] == '"' && yytext[i] == '"') && (compat != ECPG_COMPAT_INFORMIX || yytext[1] == '/'))
{
yytext[i] = '\0';
memmove(yytext, yytext+1, strlen(yytext));
strncpy(inc_file, yytext, sizeof(inc_file));
yyin = fopen(inc_file, "r");
if (!yyin)
{
if (strcmp(inc_file + strlen(inc_file) - 2, ".h"))
{
strcat(inc_file, ".h");
yyin = fopen(inc_file, "r");
}
}
}
else
{
if ((yytext[0] == '"' && yytext[i] == '"') || (yytext[0] == '<' && yytext[i] == '>'))
{
yytext[i] = '\0';
memmove(yytext, yytext+1, strlen(yytext));
}
for (ip = include_paths; yyin == NULL && ip != NULL; ip = ip->next)
{
if (strlen(ip->path) + strlen(yytext) + 3 > MAXPGPATH)
{
fprintf(stderr, "Error: Path %s/%s is too long in line %d, skipping.\n", ip->path, yytext, yylineno);
continue;
}
snprintf (inc_file, sizeof(inc_file), "%s/%s", ip->path, yytext);
yyin = fopen(inc_file, "r");
if (!yyin)
{
if (strcmp(inc_file + strlen(inc_file) - 2, ".h"))
{
strcat(inc_file, ".h");
yyin = fopen( inc_file, "r" );
}
}
}
}
if (!yyin)
{
snprintf(errortext, sizeof(errortext), "Cannot open include file %s in line %d\n", yytext, yylineno);
mmerror(NO_INCLUDE_FILE, ET_FATAL, errortext);
}
input_filename = mm_strdup(inc_file);
yy_switch_to_buffer(yy_create_buffer(yyin,YY_BUF_SIZE ));
yylineno = 1;
output_line_number();
BEGIN C;
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment