tests: call the parser from another compilation unit.
authorAkim Demaille <akim@lrde.epita.fr>
Mon, 11 Jun 2012 14:47:46 +0000 (16:47 +0200)
committerAkim Demaille <akim@lrde.epita.fr>
Fri, 15 Jun 2012 13:39:19 +0000 (15:39 +0200)
In order to improve the testing of %defines, which exports the
interface of the generated parser, change the calc.at tests so that
when %defines is passed, main will be in another compilation unit.  It
loads the generated header.

* tests/calc.at (AT_CALC_MAIN): New.
Includes the definition of the global variables.
Therefore, now declare them from the %requires section of the parser.
Adjust to yydebug and yyparse being renamed by %name-prefix.

tests/calc.at

index 790c4e6..e54a367 100644 (file)
 # Don't call this macro directly, because it contains some occurrences
 # of `$1' etc. which will be interpreted by m4.  So you should call it
 # with $1, $2, and $3 as arguments, which is what AT_DATA_CALC_Y does.
+#
+# When %defines is not passed, generate a single self-contained file.
+# Otherwise, generate three: calc.y with the parser, calc-lex.c with
+# the scanner, and calc-main.c with "main()".  This is in order to
+# stress the use of the generated parser header.  To avoid code
+# duplication, AT_CALC_LEX and AT_CALC_MAIN contain the body of these
+# two later files.
 m4_define([_AT_DATA_CALC_Y],
 [m4_if([$1$2$3], $[1]$[2]$[3], [],
        [m4_fatal([$0: Invalid arguments: $@])])dnl
+
+m4_pushdef([AT_CALC_MAIN],
+[#if HAVE_UNISTD_H
+# include <unistd.h>
+#else
+# undef alarm
+# define alarm(seconds) /* empty */
+#endif
+
+AT_SKEL_CC_IF([[
+/* A C++ ]AT_NAME_PREFIX[parse that simulates the C signature.  */
+int
+]AT_NAME_PREFIX[parse (]AT_PARAM_IF([semantic_value *result, int *count]))[
+{
+  ]AT_NAME_PREFIX[::parser parser]AT_PARAM_IF([ (result, count)])[;
+#if YYDEBUG
+  parser.set_debug_level (1);
+#endif
+  return parser.parse ();
+}
+]])[
+
+semantic_value global_result = 0;
+int global_count = 0;
+
+/* A C main function.  */
+int
+main (int argc, const char **argv)
+{
+  semantic_value result = 0;
+  int count = 0;
+  int status;
+
+  /* This used to be alarm (10), but that isn't enough time for
+     a July 1995 vintage DEC Alphastation 200 4/100 system,
+     according to Nelson H. F. Beebe.  100 seconds is enough.  */
+  alarm (100);
+
+  if (argc == 2)
+    input = fopen (argv[1], "r");
+  else
+    input = stdin;
+
+  if (!input)
+    {
+      perror (argv[1]);
+      return 3;
+    }
+
+]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug],
+[  ]AT_NAME_PREFIX[debug = 1;])])[
+  status = ]AT_NAME_PREFIX[parse (]AT_PARAM_IF([[&result, &count]])[);
+  if (fclose (input))
+    perror ("fclose");
+  if (global_result != result)
+    abort ();
+  if (global_count != count)
+    abort ();
+  return status;
+}
+]])
+
+
 m4_pushdef([AT_CALC_LEX],
 [[#include <ctype.h>
 
@@ -198,7 +268,9 @@ AT_SKEL_CC_IF(
 {
 #include <stdio.h>
 /* The input.  */
-extern FILE *input;]AT_SKEL_CC_IF([[
+extern FILE *input;
+extern semantic_value global_result;
+extern int global_count;]AT_SKEL_CC_IF([[
 #ifndef YYLTYPE
 # define YYLTYPE ]AT_NAME_PREFIX[::parser::location_type
 #endif
@@ -210,17 +282,9 @@ extern FILE *input;]AT_SKEL_CC_IF([[
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
-#if HAVE_UNISTD_H
-# include <unistd.h>
-#else
-# undef alarm
-# define alarm(seconds) /* empty */
-#endif
 #define USE(Var)
 
 FILE *input;
-static semantic_value global_result = 0;
-static int global_count = 0;
 static int power (int base, int exponent);
 
 ]AT_SKEL_CC_IF(,
@@ -320,17 +384,6 @@ AT_NAME_PREFIX::parser::error (const location_type& l, const std::string& m)
   (void) l;
   std::cerr << AT_LOCATION_IF([l << ": " << ])m << std::endl;
 }
-
-/* A C++ yyparse that simulates the C signature.  */
-int
-yyparse (AT_PARAM_IF([semantic_value *result, int *count]))
-{
-  AT_NAME_PREFIX::parser parser[]AT_PARAM_IF([ (result, count)]);
-#if YYDEBUG
-  parser.set_debug_level (1);
-#endif
-  return parser.parse ();
-}
 ],
 [/* A C error reporting function.  */
 static void
@@ -352,48 +405,21 @@ AT_YYERROR_SEES_LOC_IF([
   fprintf (stderr, "%s\n", s);
 }])[
 
-]AT_DEFINES_IF(, [AT_CALC_LEX])[
-
-/* A C main function.  */
-int
-main (int argc, const char **argv)
-{
-  semantic_value result = 0;
-  int count = 0;
-  int status;
-
-  /* This used to be alarm (10), but that isn't enough time for
-     a July 1995 vintage DEC Alphastation 200 4/100 system,
-     according to Nelson H. F. Beebe.  100 seconds is enough.  */
-  alarm (100);
-
-  if (argc == 2)
-    input = fopen (argv[1], "r");
-  else
-    input = stdin;
-
-  if (!input)
-    {
-      perror (argv[1]);
-      return 3;
-    }
-
-]AT_SKEL_CC_IF([], [m4_bmatch([$4], [%debug],
-[  yydebug = 1;])])[
-  status = yyparse (]AT_PARAM_IF([[&result, &count]])[);
-  if (fclose (input))
-    perror ("fclose");
-  if (global_result != result)
-    abort ();
-  if (global_count != count)
-    abort ();
-  return status;
-}
+]AT_DEFINES_IF([],
+[AT_CALC_LEX
+AT_CALC_MAIN])[
 ]])
+
 AT_DEFINES_IF([AT_DATA_SOURCE([[calc-lex.c]AT_SKEL_CC_IF([[c]])],
 [[#include "calc.h]AT_SKEL_CC_IF([[h]])["
 
-]AT_CALC_LEX])])
+]AT_CALC_LEX])
+AT_DATA_SOURCE([[calc-main.c]AT_SKEL_CC_IF([[c]])],
+[[#include "calc.h]AT_SKEL_CC_IF([[h]])["
+
+]AT_CALC_MAIN])
+])
+m4_popdef([AT_CALC_MAIN])
 m4_popdef([AT_CALC_LEX])
 ])# _AT_DATA_CALC_Y
 
@@ -506,7 +532,7 @@ m4_ifval([$2], [AT_CHECK([exit 77])])
 AT_BISON_OPTION_PUSHDEFS([$1])
 
 AT_DATA_CALC_Y([$1])
-AT_FULL_COMPILE([calc], [AT_DEFINES_IF([[lex]])])
+AT_FULL_COMPILE([calc], AT_DEFINES_IF([[lex], [main]]))
 
 # Test the priorities.
 _AT_CHECK_CALC([$1],