]> git.saurik.com Git - bison.git/blobdiff - data/push.c
* doc/yacc.1.in: New.
[bison.git] / data / push.c
index 58d7db0f13ebae2f23167f00394227a738fc6d53..b0cbeb322f42e5538bbc5c623d56be122cc6ef91 100644 (file)
 # You should have received a copy of the GNU General Public License
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
+# Check the value of %define api.push_pull.
+b4_percent_define_default([[api.push_pull]], [[pull]])
+b4_percent_define_check_values([[[[api.push_pull]],
+                               [[pull]], [[push]], [[both]]]])
+b4_define_flag_if([pull]) m4_define([b4_pull_flag], [[1]])
+b4_define_flag_if([push]) m4_define([b4_push_flag], [[1]])
+m4_case(b4_percent_define_get([[api.push_pull]]),
+        [pull], [m4_define([b4_push_flag], [[0]])],
+        [push], [m4_define([b4_pull_flag], [[0]])])
+
 # Handle BISON_USE_PUSH_FOR_PULL for the test suite.  So that push parsing
 # tests function as written, don't let BISON_USE_PUSH_FOR_PULL modify Bison's
 # behavior at all when push parsing is already requested.
+b4_define_flag_if([use_push_for_pull])
 b4_use_push_for_pull_if([
-  b4_push_if([
-    m4_define([b4_use_push_for_pull_flag], [[0]])
-    b4_define_flag_if([use_push_for_pull])
-  ], [
-    m4_define([b4_push_flag], [[1]])
-    b4_define_flag_if([push])
-  ])])
+  b4_push_if([m4_define([b4_use_push_for_pull_flag], [[0]])],
+             [m4_define([b4_push_flag], [[1]])])])
 
 m4_include(b4_pkgdatadir/[c.m4])
 
@@ -45,6 +51,10 @@ m4_define_default([b4_stack_depth_init],  [200])
 ## Pure/impure interfaces.  ##
 ## ------------------------ ##
 
+b4_percent_define_default([[api.pure]], [[false]])
+b4_define_flag_if([pure])
+m4_define([b4_pure_flag],
+          [b4_percent_define_flag_if([[api.pure]], [[1]], [[0]])])
 
 # b4_yacc_pure_if(IF-TRUE, IF-FALSE)
 # ----------------------------------
@@ -158,6 +168,7 @@ b4_copyright([Skeleton implementation for Bison's Yacc-like parsers in C],dnl '
    USER NAME SPACE" below.  */
 
 ]b4_identification
+
 b4_percent_code_get([[top]])[]dnl
 m4_if(b4_prefix, [yy], [],
 [[/* Substitute the variable and function names.  */
@@ -1076,7 +1087,9 @@ b4_push_if(
 {
   return yypull_parse (0]m4_ifset([b4_parse_param],
                                   [[, ]b4_c_args(b4_parse_param)])[);
-}
+}]b4_pure_if([], [[
+
+static char yypstate_allocated = 0;]])[
 
 ]b4_c_function_def([[yypull_parse]], [[int]],
   [[[yypstate *yyps]], [[yyps]]]m4_ifset([b4_parse_param], [,
@@ -1092,8 +1105,10 @@ b4_push_if(
     {
       yyps_local = yypstate_new ();
       if (!yyps_local)
-        {
-          yyerror (]b4_yyerror_args[YY_("memory exhausted"));
+        {]b4_pure_if([[
+          yyerror (]b4_yyerror_args[YY_("memory exhausted"));]], [[
+          if (!yypstate_allocated)
+            yyerror (]b4_yyerror_args[YY_("memory exhausted"));]])[
           return 2;
         }
     }
@@ -1112,10 +1127,17 @@ b4_push_if(
 /* Initialize the parser data structure.  */
 ]b4_c_function_def([[yypstate_new]], [[yypstate *]])[
 {
-  yypstate *yyps = (yypstate *) malloc (sizeof *yyps);
+  yypstate *yyps;]b4_pure_if([], [[
+  if (yypstate_allocated)
+    {
+      yyerror (]b4_yyerror_args[YY_("cannot allocate multiple impure push-parser instances"));
+      return 0;
+    }]])[
+  yyps = (yypstate *) malloc (sizeof *yyps);
   if (!yyps)
     return 0;
-  yyps->yynew = 1;
+  yyps->yynew = 1;]b4_pure_if([], [[
+  yypstate_allocated = 1;]])[
   return yyps;
 }
 
@@ -1128,7 +1150,8 @@ b4_push_if(
   if (!yyps->yynew && yyps->yyss != yyps->yyssa)
     YYSTACK_FREE (yyps->yyss);
 #endif
-  free (yyps);
+  free (yyps);]b4_pure_if([], [[
+  yypstate_allocated = 0;]])[
 }
 
 ]b4_pure_if([[#define ]b4_prefix[nerrs yyps->]b4_prefix[nerrs