m4-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Changes to m4/src/input.c [branch-1_4]


From: Eric Blake
Subject: Changes to m4/src/input.c [branch-1_4]
Date: Thu, 01 Jun 2006 00:09:07 +0000

Index: m4/src/input.c
diff -u m4/src/input.c:1.1.1.1.2.4 m4/src/input.c:1.1.1.1.2.5
--- m4/src/input.c:1.1.1.1.2.4  Sun Dec  4 20:17:36 2005
+++ m4/src/input.c      Thu Jun  1 00:09:06 2006
@@ -1,6 +1,6 @@
 /* GNU m4 -- A simple macro processor
 
-   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2004, 2005
+   Copyright (C) 1989, 1990, 1991, 1992, 1993, 1994, 2004, 2005, 2006
    Free Software Foundation, Inc.
 
    This program is free software; you can redistribute it and/or modify
@@ -28,15 +28,17 @@
    or quoted macro definitions (as returned by the builtin "defn").
    Unread input are organised in a stack, implemented with an obstack.
    Each input source is described by a "struct input_block".  The obstack
-   is "input_stack".  The top of the input stack is "isp".
+   is "current_input".  The top of the input stack is "isp".
 
-   The macro "m4wrap" places the text to be saved on another input stack,
-   on the obstack "wrapup_stack", whose top is "wsp".  When EOF is seen
-   on normal input (eg, when "input_stack" is empty), input is switched
-   over to "wrapup_stack".  To make this easier, all references to the
-   current input stack, whether it be "input_stack" or "wrapup_stack",
-   are done through a pointer "current_input", which points to either
-   "input_stack" or "wrapup_stack".
+   The macro "m4wrap" places the text to be saved on another input
+   stack, on the obstack "wrapup_stack", whose top is "wsp".  When EOF
+   is seen on normal input (eg, when "current_input" is empty), input is
+   switched over to "wrapup_stack", and the original "current_input" is
+   freed.  A new stack is allocated for "wrapup_stack", which will
+   accept any text produced by calls to "m4wrap" from within the
+   wrapped text.  This process of shuffling "wrapup_stack" to
+   "current_input" can continue indefinitely, even generating infinite
+   loops (e.g. "define(`f',`m4wrap(`f')')f"), without memory leaks.
 
    Pushing new input on the input stack is done by push_file (),
    push_string (), push_wrapup () (for wrapup text), and push_macro ()
@@ -109,13 +111,10 @@
 /* Obstack for storing individual tokens.  */
 static struct obstack token_stack;
 
-/* Normal input stack.  */
-static struct obstack input_stack;
-
 /* Wrapup input stack.  */
-static struct obstack wrapup_stack;
+static struct obstack *wrapup_stack;
 
-/* Input or wrapup.  */
+/* Current stack, from input or wrapup.  */
 static struct obstack *current_input;
 
 /* Bottom of token_stack, for obstack_free.  */
@@ -283,11 +282,11 @@
 void
 push_wrapup (const char *s)
 {
-  input_block *i = (input_block *) obstack_alloc (&wrapup_stack,
+  input_block *i = (input_block *) obstack_alloc (wrapup_stack,
                                                  sizeof (struct input_block));
   i->prev = wsp;
   i->type = INPUT_STRING;
-  i->u.u_s.string = obstack_copy0 (&wrapup_stack, s, strlen (s));
+  i->u.u_s.string = obstack_copy0 (wrapup_stack, s, strlen (s));
   wsp = i;
 }
 
@@ -343,10 +342,20 @@
 boolean
 pop_wrapup (void)
 {
+  obstack_free (current_input, NULL);
+  xfree (current_input);
+
   if (wsp == NULL)
-    return FALSE;
+    {
+      obstack_free (wrapup_stack, NULL);
+      xfree (wrapup_stack);
+      return FALSE;
+    }
+
+  current_input = wrapup_stack;
+  wrapup_stack = (struct obstack *) xmalloc (sizeof (struct obstack));
+  obstack_init (wrapup_stack);
 
-  current_input = &wrapup_stack;
   isp = wsp;
   wsp = NULL;
 
@@ -566,10 +575,11 @@
   current_line = 0;
 
   obstack_init (&token_stack);
-  obstack_init (&input_stack);
-  obstack_init (&wrapup_stack);
 
-  current_input = &input_stack;
+  current_input = (struct obstack *) xmalloc (sizeof (struct obstack));
+  obstack_init (current_input);
+  wrapup_stack = (struct obstack *) xmalloc (sizeof (struct obstack));
+  obstack_init (wrapup_stack);
 
   obstack_1grow (&token_stack, '\0');
   token_bottom = obstack_finish (&token_stack);
@@ -699,7 +709,7 @@
 | for a quoted string; TOKEN_WORD for something that is a potential macro  |
 | name; and TOKEN_SIMPLE for any single character that is not a part of        
   |
 | any of the previous types.                                              |
-|                                                                         |
+|                                                                         |
 | Next_token () return the token type, and passes back a pointer to the        
   |
 | token data through TD.  The token text is collected on the obstack      |
 | token_stack, which never contains more than one token text at a time.        
   |




reply via email to

[Prev in Thread] Current Thread [Next in Thread]