/[m4]/m4/m4/macro.c
ViewVC logotype

Diff of /m4/m4/macro.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.24 by gary, Fri Jun 13 13:05:45 2003 UTC revision 1.25 by gary, Mon Jun 16 10:43:45 2003 UTC
# Line 24  Line 24 
24  #include "m4.h"  #include "m4.h"
25  #include "m4private.h"  #include "m4private.h"
26    
27  static void expand_macro (const char *name, m4_symbol *);  static void    collect_arguments (m4 *context, const char *name,
28  static void expand_token (struct obstack *, m4__token_type, m4_token *);                                    m4_symbol *symbol, struct obstack *argptr,
29                                      struct obstack *arguments);
30    static void    expand_macro      (m4 *context, const char *name,
31                                      m4_symbol *symbol);
32    static void    expand_token      (m4 *context, struct obstack *obs,
33                                      m4__token_type type, m4_token *token);
34    static boolean expand_argument   (m4 *context, struct obstack *obs,
35                                      m4_token *argp);
36    
37  /* Current recursion level in expand_macro ().  */  /* Current recursion level in expand_macro ().  */
38  int m4_expansion_level = 0;  int m4_expansion_level = 0;
# Line 35  static int macro_call_id = 0; Line 42  static int macro_call_id = 0;
42    
43  /* This function reads all input, and expands each token, one at a time.  */  /* This function reads all input, and expands each token, one at a time.  */
44  void  void
45  m4_expand_input (void)  m4_expand_input (m4 *context)
46  {  {
47    m4__token_type type;    m4__token_type type;
48    m4_token token;    m4_token token;
49    
50    while ((type = m4_next_token (&token)) != M4_TOKEN_EOF)    while ((type = m4_next_token (&token)) != M4_TOKEN_EOF)
51      expand_token ((struct obstack *) NULL, type, &token);      expand_token (context, (struct obstack *) NULL, type, &token);
52  }  }
53    
54    
# Line 50  m4_expand_input (void) Line 57  m4_expand_input (void)
57     macro definition.  If they have, they are expanded as macros, otherwise     macro definition.  If they have, they are expanded as macros, otherwise
58     the text are just copied to the output.  */     the text are just copied to the output.  */
59  static void  static void
60  expand_token (struct obstack *obs, m4__token_type type, m4_token *token)  expand_token (m4 *context, struct obstack *obs,
61                  m4__token_type type, m4_token *token)
62  {  {
63    m4_symbol *symbol;    m4_symbol *symbol;
64    char *text = xstrdup (TOKEN_TEXT (token));    char *text = xstrdup (TOKEN_TEXT (token));
# Line 74  expand_token (struct obstack *obs, m4__t Line 82  expand_token (struct obstack *obs, m4__t
82          if (M4_IS_ESCAPE(*textp))          if (M4_IS_ESCAPE(*textp))
83            ++textp;            ++textp;
84    
85          symbol = m4_symbol_lookup (textp);          symbol = m4_symbol_lookup (M4SYMTAB, textp);
86          if (symbol == NULL          if (symbol == NULL
87              || SYMBOL_TYPE (symbol) == M4_TOKEN_VOID              || SYMBOL_TYPE (symbol) == M4_TOKEN_VOID
88              || (SYMBOL_TYPE (symbol) == M4_TOKEN_FUNC              || (SYMBOL_TYPE (symbol) == M4_TOKEN_FUNC
# Line 84  expand_token (struct obstack *obs, m4__t Line 92  expand_token (struct obstack *obs, m4__t
92              m4_shipout_text (obs, text, strlen (text));              m4_shipout_text (obs, text, strlen (text));
93            }            }
94          else          else
95            expand_macro (textp, symbol);            expand_macro (context, textp, symbol);
96        }        }
97        break;        break;
98    
# Line 106  expand_token (struct obstack *obs, m4__t Line 114  expand_token (struct obstack *obs, m4__t
114     the last for the active macro call.  The arguments are build on the     the last for the active macro call.  The arguments are build on the
115     obstack OBS, indirectly through expand_token ().      */     obstack OBS, indirectly through expand_token ().      */
116  static boolean  static boolean
117  expand_argument (struct obstack *obs, m4_token *argp)  expand_argument (m4 *context, struct obstack *obs, m4_token *argp)
118  {  {
119    m4__token_type type;    m4__token_type type;
120    m4_token token;    m4_token token;
# Line 149  expand_argument (struct obstack *obs, m4 Line 157  expand_argument (struct obstack *obs, m4
157              paren_level++;              paren_level++;
158            else if (M4_IS_CLOSE (*text))            else if (M4_IS_CLOSE (*text))
159              paren_level--;              paren_level--;
160            expand_token (obs, type, &token);            expand_token (context, obs, type, &token);
161            break;            break;
162    
163          case M4_TOKEN_EOF:          case M4_TOKEN_EOF:
# Line 160  expand_argument (struct obstack *obs, m4 Line 168  expand_argument (struct obstack *obs, m4
168          case M4_TOKEN_WORD:          case M4_TOKEN_WORD:
169          case M4_TOKEN_SPACE:          case M4_TOKEN_SPACE:
170          case M4_TOKEN_STRING:          case M4_TOKEN_STRING:
171            expand_token (obs, type, &token);            expand_token (context, obs, type, &token);
172            break;            break;
173    
174          case M4_TOKEN_MACDEF:          case M4_TOKEN_MACDEF:
# Line 178  expand_argument (struct obstack *obs, m4 Line 186  expand_argument (struct obstack *obs, m4
186      }      }
187  }  }
188    
189    
190    /* The macro expansion is handled by expand_macro ().  It parses the
191       arguments, using collect_arguments (), and builds a table of pointers to
192       the arguments.  The arguments themselves are stored on a local obstack.
193       Expand_macro () uses call_macro () to do the call of the macro.
194    
195       Expand_macro () is potentially recursive, since it calls expand_argument
196       (), which might call expand_token (), which might call expand_macro ().  */
197    static void
198    expand_macro (m4 *context, const char *name, m4_symbol *symbol)
199    {
200      struct obstack arguments;
201      struct obstack argptr;
202      m4_token **argv;
203      int argc;
204      struct obstack *expansion;
205      const char *expanded;
206      boolean traced;
207      int my_call_id;
208    
209      m4_expansion_level++;
210      if (m4_expansion_level > nesting_limit)
211        M4ERROR ((EXIT_FAILURE, 0, _("\
212    ERROR: Recursion limit of %d exceeded, use -L<N> to change it"),
213                  nesting_limit));
214    
215      macro_call_id++;
216      my_call_id = macro_call_id;
217    
218      traced = (boolean) ((debug_level & M4_DEBUG_TRACE_ALL) || SYMBOL_TRACED (symbol));
219    
220      obstack_init (&argptr);
221      obstack_init (&arguments);
222    
223      if (traced && (debug_level & M4_DEBUG_TRACE_CALL))
224        m4_trace_prepre (name, my_call_id);
225    
226      collect_arguments (context, name, symbol, &argptr, &arguments);
227    
228      argc = obstack_object_size (&argptr) / sizeof (m4_token *);
229      argv = (m4_token **) obstack_finish (&argptr);
230    
231      if (traced)
232        m4_trace_pre (name, my_call_id, argc, argv);
233    
234      expansion = m4_push_string_init ();
235      if (!m4_bad_argc (argc, argv,
236                        SYMBOL_MIN_ARGS (symbol), SYMBOL_MAX_ARGS (symbol)))
237        m4_call_macro (symbol, context, expansion, argc, argv);
238      expanded = m4_push_string_finish ();
239    
240      if (traced)
241        m4_trace_post (name, my_call_id, argc, argv, expanded);
242    
243      --m4_expansion_level;
244    
245      obstack_free (&arguments, NULL);
246      obstack_free (&argptr, NULL);
247    }
248    
249  /* Collect all the arguments to a call of the macro SYMBOL (called NAME).  /* Collect all the arguments to a call of the macro SYMBOL (called NAME).
250     The arguments are stored on the obstack ARGUMENTS and a table of pointers     The arguments are stored on the obstack ARGUMENTS and a table of pointers
251     to the arguments on the obstack ARGPTR.  */     to the arguments on the obstack ARGPTR.  */
252  static void  static void
253  collect_arguments (const char *name, m4_symbol *symbol,  collect_arguments (m4 *context, const char *name, m4_symbol *symbol,
254                     struct obstack *argptr, struct obstack *arguments)                     struct obstack *argptr, struct obstack *arguments)
255  {  {
256    int ch;                       /* lookahead for ( */    int ch;                       /* lookahead for ( */
# Line 205  collect_arguments (const char *name, m4_ Line 273  collect_arguments (const char *name, m4_
273        m4_next_token (&token);           /* gobble parenthesis */        m4_next_token (&token);           /* gobble parenthesis */
274        do        do
275          {          {
276            more_args = expand_argument (arguments, &token);            more_args = expand_argument (context, arguments, &token);
277    
278            if (!groks_macro_args && TOKEN_TYPE (&token) == M4_TOKEN_FUNC)            if (!groks_macro_args && TOKEN_TYPE (&token) == M4_TOKEN_FUNC)
279              {              {
# Line 219  collect_arguments (const char *name, m4_ Line 287  collect_arguments (const char *name, m4_
287        while (more_args);        while (more_args);
288      }      }
289  }  }
   
290    
291    
292  /* The actual call of a macro is handled by m4_call_macro ().  /* The actual call of a macro is handled by m4_call_macro ().
# Line 229  collect_arguments (const char *name, m4_ Line 296  collect_arguments (const char *name, m4_
296     the call, stored in the ARGV table.  The expansion is left on     the call, stored in the ARGV table.  The expansion is left on
297     the obstack EXPANSION.  Macro tracing is also handled here.  */     the obstack EXPANSION.  Macro tracing is also handled here.  */
298  void  void
299  m4_call_macro (m4_symbol *symbol, int argc, m4_token **argv,  m4_call_macro (m4_symbol *symbol, m4 *context, struct obstack *expansion,
300                 struct obstack *expansion)                 int argc, m4_token **argv)
301  {  {
302    switch (SYMBOL_TYPE (symbol))    switch (SYMBOL_TYPE (symbol))
303      {      {
304      case M4_TOKEN_FUNC:      case M4_TOKEN_FUNC:
305        (*SYMBOL_FUNC (symbol)) (expansion, argc, argv);        (*SYMBOL_FUNC (symbol)) (context, expansion, argc, argv);
306        break;        break;
307    
308      case M4_TOKEN_TEXT:      case M4_TOKEN_TEXT:
309        m4_process_macro (expansion, symbol, argc, argv);        m4_process_macro (symbol, context, expansion, argc, argv);
310        break;        break;
311    
312      case M4_TOKEN_VOID:      case M4_TOKEN_VOID:
# Line 249  m4_call_macro (m4_symbol *symbol, int ar Line 316  m4_call_macro (m4_symbol *symbol, int ar
316      }      }
317  }  }
318    
 /* The macro expansion is handled by expand_macro ().  It parses the  
    arguments, using collect_arguments (), and builds a table of pointers to  
    the arguments.  The arguments themselves are stored on a local obstack.  
    Expand_macro () uses call_macro () to do the call of the macro.  
   
    Expand_macro () is potentially recursive, since it calls expand_argument  
    (), which might call expand_token (), which might call expand_macro ().  */  
 static void  
 expand_macro (const char *name, m4_symbol *symbol)  
 {  
   struct obstack arguments;  
   struct obstack argptr;  
   m4_token **argv;  
   int argc;  
   struct obstack *expansion;  
   const char *expanded;  
   boolean traced;  
   int my_call_id;  
   
   m4_expansion_level++;  
   if (m4_expansion_level > nesting_limit)  
     M4ERROR ((EXIT_FAILURE, 0, _("\  
 ERROR: Recursion limit of %d exceeded, use -L<N> to change it"),  
               nesting_limit));  
   
   macro_call_id++;  
   my_call_id = macro_call_id;  
   
   traced = (boolean) ((debug_level & M4_DEBUG_TRACE_ALL) || SYMBOL_TRACED (symbol));  
   
   obstack_init (&argptr);  
   obstack_init (&arguments);  
   
   if (traced && (debug_level & M4_DEBUG_TRACE_CALL))  
     m4_trace_prepre (name, my_call_id);  
   
   collect_arguments (name, symbol, &argptr, &arguments);  
   
   argc = obstack_object_size (&argptr) / sizeof (m4_token *);  
   argv = (m4_token **) obstack_finish (&argptr);  
   
   if (traced)  
     m4_trace_pre (name, my_call_id, argc, argv);  
   
   expansion = m4_push_string_init ();  
   if (!m4_bad_argc (argc, argv,  
                     SYMBOL_MIN_ARGS (symbol), SYMBOL_MAX_ARGS (symbol)))  
     m4_call_macro (symbol, argc, argv, expansion);  
   expanded = m4_push_string_finish ();  
   
   if (traced)  
     m4_trace_post (name, my_call_id, argc, argv, expanded);  
   
   --m4_expansion_level;  
   
   obstack_free (&arguments, NULL);  
   obstack_free (&argptr, NULL);  
 }  
   
319  /* This function handles all expansion of user defined and predefined  /* This function handles all expansion of user defined and predefined
320     macros.  It is called with an obstack OBS, where the macros expansion     macros.  It is called with an obstack OBS, where the macros expansion
321     will be placed, as an unfinished object.  SYMBOL points to the macro     will be placed, as an unfinished object.  SYMBOL points to the macro
322     definition, giving the expansion text.  ARGC and ARGV are the arguments,     definition, giving the expansion text.  ARGC and ARGV are the arguments,
323     as usual.  */     as usual.  */
324  void  void
325  m4_process_macro (struct obstack *obs, m4_symbol *symbol, int argc,  m4_process_macro (m4_symbol *symbol, m4 *context, struct obstack *obs,
326                    m4_token **argv)                    int argc, m4_token **argv)
327  {  {
328    const unsigned char *text;    const unsigned char *text;
329    int i;    int i;

Legend:
Removed from v.1.24  
changed lines
  Added in v.1.25

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26