1212 *
1313 *
1414 * IDENTIFICATION
15- * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.106 2003/02/17 14:06:39 meskes Exp $
15+ * $Header: /cvsroot/pgsql/src/interfaces/ecpg/preproc/pgc.l,v 1.107 2003/05/01 17:16:57 meskes Exp $
1616 *
1717 *-------------------------------------------------------------------------
1818*/
2525
2626#include " extern.h"
2727
28-
2928extern YYSTYPE yylval;
3029
3130static int xcdepth =0 ;/* depth of nesting in slash-star comments*/
@@ -44,6 +43,7 @@ static intliteralalloc;/* current allocated buffer size */
4443static void addlit (char *ytext,int yleng);
4544static void addlitchar (unsigned char );
4645static void string_unput (char *);
46+ static void parse_include (void );
4747
4848char *token_start;
4949int state_before;
@@ -265,12 +265,17 @@ else[eE][lL][sS][eE]
265265elif [eE ][lL ][iI ][fF ]
266266endif [eE ][nN ][dD ][iI ][fF ]
267267
268+ struct [sS ][tT ][rR ][uU ][cC ][tT ]
269+
268270exec_sql {exec }{space }* {sql }{space }*
269271ipdigit ({digit }| {digit }{digit }| {digit }{digit }{digit })
270272ip {ipdigit }\. {ipdigit }\. {ipdigit }\. {ipdigit }
271273
274+ /* we might want to parse all cpp include files */
275+ cppinclude {space }* #{include }{space }*
276+
272277/* Take care of cpp continuation lines */
273- cppline {space }* #(. * \\ {space })* . *
278+ cppline {space }* #(. * \\ {space })+ . *
274279
275280/*
276281 * Quoted strings must allow some special characters such as single-quote
@@ -429,6 +434,20 @@ cppline{space}*#(.*\\{space})*.*
429434else
430435return yytext[0 ];
431436}
437+ <C >{informix_special }{struct } {
438+ /* are we simulating Informix? */
439+ if (compat == ECPG_COMPAT_INFORMIX)
440+ {
441+ string_unput (" typedef struct" );
442+ BEGIN SQL;
443+ return SQL_START;
444+ }
445+ else
446+ {
447+ string_unput (" struct" );
448+ return S_ANYTHING;
449+ }
450+ }
432451<SQL >{self }{/*
433452 * We may find a ';' inside a structure
434453 * definition in a TYPE or VAR statement.
@@ -550,22 +569,6 @@ cppline{space}*#(.*\\{space})*.*
550569ScanKeyword *keyword;
551570struct _defines *ptr;
552571
553- /* Is it an SQL keyword? */
554- keyword =ScanKeywordLookup (yytext);
555- if (keyword !=NULL )
556- return keyword->value ;
557-
558- /* Is it an ECPG keyword? */
559- keyword =ScanECPGKeywordLookup ( yytext);
560- if (keyword !=NULL )
561- return keyword->value ;
562-
563- /* Is it a C keyword? */
564- keyword =ScanCKeywordLookup (yytext);
565- if (keyword !=NULL )
566- return keyword->value ;
567-
568-
569572/* How about a DEFINE? */
570573for (ptr = defines; ptr; ptr = ptr->next )
571574{
@@ -587,6 +590,21 @@ cppline{space}*#(.*\\{space})*.*
587590}
588591}
589592
593+ /* Is it an SQL keyword? */
594+ keyword =ScanKeywordLookup (yytext);
595+ if (keyword !=NULL )
596+ return keyword->value ;
597+
598+ /* Is it an ECPG keyword? */
599+ keyword =ScanECPGKeywordLookup ( yytext);
600+ if (keyword !=NULL )
601+ return keyword->value ;
602+
603+ /* Is it a C keyword? */
604+ keyword =ScanCKeywordLookup (yytext);
605+ if (keyword !=NULL )
606+ return keyword->value ;
607+
590608/*
591609 * None of the above. Return it as an identifier.
592610 *
@@ -627,42 +645,53 @@ cppline{space}*#(.*\\{space})*.*
627645}
628646return ICONST;
629647}
648+ <C >{cppinclude }{
649+ if (system_includes)
650+ {
651+ BEGIN (incl);
652+ }
653+ else
654+ {
655+ yylval.str =mm_strdup (yytext);
656+ return (CPP_LINE);
657+ }
658+ }
630659<C >{cppline }{
631660yylval.str =mm_strdup (yytext);
632661return (CPP_LINE);
633662}
634663<C >{identifier } {
635664ScanKeyword*keyword;
665+ struct _defines *ptr;
636666
637- keyword =ScanCKeywordLookup (yytext);
638- if (keyword !=NULL ) {
639- return keyword->value ;
640- }
641- else
667+ /* is it a define? */
668+ for (ptr = defines; ptr; ptr = ptr->next )
642669{
643- struct _defines *ptr;
644-
645- for (ptr = defines; ptr; ptr = ptr->next )
670+ if (strcmp (yytext, ptr->old ) ==0 )
646671{
647- if (strcmp (yytext, ptr->old ) ==0 )
648- {
649- struct _yy_buffer *yb;
672+ struct _yy_buffer *yb;
650673
651- yb =mm_alloc (sizeof (struct _yy_buffer ));
674+ yb =mm_alloc (sizeof (struct _yy_buffer ));
652675
653- yb->buffer = YY_CURRENT_BUFFER;
654- yb->lineno = yylineno;
655- yb->filename =mm_strdup (input_filename);
656- yb->next = yy_buffer;
676+ yb->buffer = YY_CURRENT_BUFFER;
677+ yb->lineno = yylineno;
678+ yb->filename =mm_strdup (input_filename);
679+ yb->next = yy_buffer;
657680
658- yy_buffer = yb;
681+ yy_buffer = yb;
659682
660- yy_scan_string (ptr->new );
661- break ;
662- }
683+ yy_scan_string (ptr->new );
684+ break ;
663685}
664- if (ptr ==NULL )
665- {
686+ }
687+
688+ if (ptr ==NULL )
689+ {
690+ keyword =ScanCKeywordLookup (yytext);
691+ if (keyword !=NULL )
692+ return keyword->value ;
693+
694+ else {
666695yylval.str =mm_strdup (yytext);
667696return IDENT;
668697}
@@ -940,7 +969,11 @@ cppline{space}*#(.*\\{space})*.*
940969}
941970<def >[^ ; ]{addlit (yytext, yyleng); }
942971
943- <incl >[^ ; ]+ " ;" {
972+ <incl >\< [^ \> ]+ \> {space }* " ;" ? {parse_include (); }
973+ <incl >{dquote }{xdinside }{dquote }{space }* " ;" ? {parse_include (); }
974+ <incl >[^ ; \<\>\" ]+ " ;" {
975+ parse_include ();
976+ #if 0
944977/* got the include file name */
945978struct _yy_buffer *yb;
946979 struct _include_path *ip;
@@ -1026,6 +1059,7 @@ cppline{space}*#(.*\\{space})*.*
10261059output_line_number();
10271060
10281061 BEGIN C;
1062+ #endif
10291063}
10301064
10311065<<EOF>> {
@@ -1128,3 +1162,96 @@ string_unput (char *string)
11281162unput (string[i]);
11291163}
11301164
1165+ static void
1166+ parse_include (void )
1167+ {
1168+ /* got the include file name */
1169+ struct _yy_buffer *yb;
1170+ struct _include_path *ip;
1171+ char inc_file[MAXPGPATH];
1172+ unsigned int i;
1173+
1174+ yb =mm_alloc (sizeof (struct _yy_buffer ));
1175+
1176+ yb->buffer =YY_CURRENT_BUFFER;
1177+ yb->lineno = yylineno;
1178+ yb->filename = input_filename;
1179+ yb->next = yy_buffer;
1180+
1181+ yy_buffer = yb;
1182+
1183+ /*
1184+ * skip the ";" if there is one and trailing whitespace. Note that
1185+ * yytext contains at least one non-space character plus the ";"
1186+ */
1187+ for ( i =strlen (yytext)-2 ;
1188+ i >0 &&isspace ((unsigned char ) yytext[i]);
1189+ i-- )
1190+ {}
1191+
1192+ if (yytext[i] ==' ;' )
1193+ i--;
1194+
1195+ yytext[i+1 ] =' \0 ' ;
1196+
1197+ yyin =NULL ;
1198+
1199+ /* If file name is enclosed in '"' remove these and look only in '.' */
1200+ /* Informix does look into all include paths though, except filename starts with '/' */
1201+ if ((yytext[0 ] ==' "' && yytext[i] ==' "' ) && (compat != ECPG_COMPAT_INFORMIX || yytext[1 ] ==' /' ))
1202+ {
1203+ yytext[i] =' \0 ' ;
1204+ memmove (yytext, yytext+1 ,strlen (yytext));
1205+
1206+ strncpy (inc_file, yytext,sizeof (inc_file));
1207+ yyin =fopen (inc_file," r" );
1208+ if (!yyin)
1209+ {
1210+ if (strcmp (inc_file +strlen (inc_file) -2 ," .h" ))
1211+ {
1212+ strcat (inc_file," .h" );
1213+ yyin =fopen (inc_file," r" );
1214+ }
1215+ }
1216+
1217+ }
1218+ else
1219+ {
1220+ if ((yytext[0 ] ==' "' && yytext[i] ==' "' ) || (yytext[0 ] ==' <' && yytext[i] ==' >' ))
1221+ {
1222+ yytext[i] =' \0 ' ;
1223+ memmove (yytext, yytext+1 ,strlen (yytext));
1224+ }
1225+
1226+ for (ip = include_paths; yyin ==NULL && ip !=NULL ; ip = ip->next )
1227+ {
1228+ if (strlen (ip->path ) +strlen (yytext) +3 > MAXPGPATH)
1229+ {
1230+ fprintf (stderr," Error: Path %s/%s is too long in line %d, skipping.\n " , ip->path , yytext, yylineno);
1231+ continue ;
1232+ }
1233+ snprintf (inc_file,sizeof (inc_file)," %s/%s" , ip->path , yytext);
1234+ yyin =fopen (inc_file," r" );
1235+ if (!yyin)
1236+ {
1237+ if (strcmp (inc_file +strlen (inc_file) -2 ," .h" ))
1238+ {
1239+ strcat (inc_file," .h" );
1240+ yyin =fopen ( inc_file," r" );
1241+ }
1242+ }
1243+ }
1244+ }
1245+ if (!yyin)
1246+ {
1247+ snprintf (errortext,sizeof (errortext)," Cannot open include file %s in line %d\n " , yytext, yylineno);
1248+ mmerror (NO_INCLUDE_FILE, ET_FATAL, errortext);
1249+ }
1250+
1251+ input_filename =mm_strdup (inc_file);
1252+ yy_switch_to_buffer (yy_create_buffer (yyin,YY_BUF_SIZE ));
1253+ yylineno =1 ;
1254+ output_line_number ();
1255+
1256+ BEGIN C;
1257+ }