Added script to check if all rule re-definition in ecpg.addons are indeed used
authorMichael Meskes <meskes@postgresql.org>
Fri, 27 Nov 2009 10:00:40 +0000 (10:00 +0000)
committerMichael Meskes <meskes@postgresql.org>
Fri, 27 Nov 2009 10:00:40 +0000 (10:00 +0000)
in the build process. If not the build process will stop with an error message.

src/interfaces/ecpg/preproc/Makefile
src/interfaces/ecpg/preproc/check_rules.pl [new file with mode: 0755]

index e33c0e9c32be111d328fa28d250abc9390791c2a..493e095544e545b3785171a181efb661ffe30e53 100644 (file)
@@ -4,7 +4,7 @@
 #
 # Copyright (c) 1998-2009, PostgreSQL Global Development Group
 #
-# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.146 2009/09/02 19:14:14 mha Exp $
+# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/Makefile,v 1.147 2009/11/27 10:00:40 meskes Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -54,6 +54,7 @@ endif
 
 preproc.y: ../../../backend/parser/gram.y parse.pl ecpg.addons ecpg.header ecpg.tokens ecpg.trailer ecpg.type
    $(PERL) $(srcdir)/parse.pl $(srcdir) < $< > $@ 
+   $(PERL) $(srcdir)/check_rules.pl $(srcdir) $<
 
 ecpg_keywords.o c_keywords.o keywords.o preproc.o parser.o: preproc.h
 
diff --git a/src/interfaces/ecpg/preproc/check_rules.pl b/src/interfaces/ecpg/preproc/check_rules.pl
new file mode 100755 (executable)
index 0000000..73f4486
--- /dev/null
@@ -0,0 +1,136 @@
+#!/usr/bin/perl
+# $PostgreSQL: pgsql/src/interfaces/ecpg/preproc/check_rules.pl,v 1.1 2009/11/27 10:00:40 meskes Exp $
+# test parser generater for ecpg
+# call with backend parser as stdin
+#
+# Copyright (c) 2009, PostgreSQL Global Development Group
+#
+# Written by Michael Meskes <meskes@postgresql.org>
+#
+# Placed under the same license as PostgreSQL.
+#
+
+if (@ARGV) {
+        $path = $ARGV[0];
+        $parser = $ARGV[1];
+}
+
+$[ = 1;                 # set array base to 1
+
+if ($path eq '') { $path = "."; }
+$filename = $path . "/ecpg.addons";
+
+if ($parser eq '') { $parser = "../../../backend/parser/gram.y"; }
+
+$replace_line{'ExecuteStmtEXECUTEnameexecute_param_clause'} = 'EXECUTE prepared_name execute_param_clause execute_rest';
+$replace_line{'ExecuteStmtCREATEOptTempTABLEcreate_as_targetASEXECUTEnameexecute_param_clause'} = 'CREATE OptTemp TABLE create_as_target AS EXECUTE prepared_name execute_param_clause';
+$replace_line{'PrepareStmtPREPAREnameprep_type_clauseASPreparableStmt'} = 'PREPARE prepared_name prep_type_clause AS PreparableStmt';
+
+$block = '';
+$ret = 0;
+$yaccmod = 0;
+$brace_indent = 0;
+
+open GRAM, $parser or die $!;
+while (<GRAM>) {
+   chomp;      # strip record separator
+
+   if (/^%%/) {
+           $yaccmode++;
+   }
+
+   if ($yaccmode != 1) {
+           next;
+       }
+
+   $S = $_;
+   $prec = 0;
+
+   # Make sure any braces are split
+   $S =~ s/{/ { /g;
+   $S =~ s/}/ } /g;
+   # Any comments are split
+   $S =~ s#[/][*]# /* #g;
+   $S =~ s#[*][/]# */ #g;
+
+   # Now split the line into individual fields
+   $n = (@arr = split(' ', $S));
+
+   # Go through each field in turn
+   for ($fieldIndexer = 1; $fieldIndexer <= $n; $fieldIndexer++) {
+       if ($arr[$fieldIndexer] eq '*/' && $comment) {
+           $comment = 0;
+           next;
+       }
+       elsif ($comment) {
+           next;
+       }
+       elsif ($arr[$fieldIndexer] eq '/*') {
+           # start of a multiline comment
+           $comment = 1;
+           next;
+       }
+       elsif ($arr[$fieldIndexer] eq '//') {
+           next;
+       }
+       elsif ($arr[$fieldIndexer] eq '}') {
+           $brace_indent--;
+           next;
+       }
+       elsif ($arr[$fieldIndexer] eq '{') {
+           $brace_indent++;
+           next;
+       }
+
+       if ($brace_indent > 0) {
+           next;
+       }
+
+       if ($arr[$fieldIndexer] eq ';' || $arr[$fieldIndexer] eq '|') {
+           $block = $non_term_id . $block;
+           if ($replace_line{$block}) {
+               $block = &generate_block($replace_line{$block});
+           }
+           $found{$block} = 'found';
+           $block = '';
+       }
+       elsif (($arr[$fieldIndexer] =~ '[A-Za-z0-9]+:') || $arr[$fieldIndexer + 1] eq ':') {
+           $non_term_id = $arr[$fieldIndexer];
+           $non_term_id =~ s/://g;
+       }
+       else  {
+           $block = $block . $arr[$fieldIndexer];
+       }
+   }
+} 
+
+close GRAM;
+
+open ECPG, $filename or die $!;
+
+line: while (<ECPG>) {
+    chomp; # strip record separator
+    @Fld = split(' ', $_, -1);
+
+    if (!/^ECPG:/) {
+   next line; 
+    }
+
+    if ($found{$Fld[2]} ne 'found') {
+   printf $Fld[2] . " is not used for building parser!\n";
+   $ret = 1;
+    }
+}
+
+close ECPG;
+
+exit $ret;
+
+sub generate_block {
+    local($line) = @_;
+    $block = $non_term_id . $line;
+    $block =~ s/ //g;
+    $s = "\\|", $block =~ s/$s//g;
+    return $block;
+}
+