/[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.13 by gary, Thu Sep 20 03:48:05 2001 UTC revision 1.14 by gary, Sun Sep 30 14:43:38 2001 UTC
# Line 23  Line 23 
23  #include "m4.h"  #include "m4.h"
24  #include "m4private.h"  #include "m4private.h"
25    
26  static void expand_macro (const char *name, m4_symbol *token);  static void expand_macro (const char *name, m4_symbol *);
27  static void expand_token (struct obstack *, m4_token_t t, m4_symbol *token);  static void expand_token (struct obstack *, m4_token_t, m4_token_data *);
28    
29  /* Current recursion level in expand_macro ().  */  /* Current recursion level in expand_macro ().  */
30  int m4_expansion_level = 0;  int m4_expansion_level = 0;
# Line 37  void Line 37  void
37  m4_expand_input (void)  m4_expand_input (void)
38  {  {
39    m4_token_t t;    m4_token_t t;
40    m4_symbol tokenbuf;    m4_token_data td;
41    
42    while ((t = m4_next_token (&tokenbuf)) != M4_TOKEN_EOF)    while ((t = m4_next_token (&td)) != M4_TOKEN_EOF)
43      expand_token ((struct obstack *) NULL, t, &tokenbuf);      expand_token ((struct obstack *) NULL, t, &td);
44  }  }
45    
46    
# Line 49  m4_expand_input (void) Line 49  m4_expand_input (void)
49     macro definition.  If they have, they are expanded as macros, otherwise     macro definition.  If they have, they are expanded as macros, otherwise
50     the text are just copied to the output.  */     the text are just copied to the output.  */
51  static void  static void
52  expand_token (struct obstack *obs, m4_token_t t, m4_symbol *token)  expand_token (struct obstack *obs, m4_token_t t, m4_token_data *td)
53  {  {
54    m4_symbol *symbol;    m4_symbol *symbol;
55    char *text = xstrdup (M4_SYMBOL_TEXT (token));    char *text = xstrdup (M4_TOKEN_DATA_TEXT (td));
56    
57    switch (t)    switch (t)
58      {                           /* TOKSW */      {                           /* TOKSW */
# Line 79  expand_token (struct obstack *obs, m4_to Line 79  expand_token (struct obstack *obs, m4_to
79                  && M4_SYMBOL_BLIND_NO_ARGS (symbol)                  && M4_SYMBOL_BLIND_NO_ARGS (symbol)
80                  && !M4_IS_OPEN(m4_peek_input ())))                  && !M4_IS_OPEN(m4_peek_input ())))
81            {            {
82              m4_shipout_text (obs, M4_SYMBOL_TEXT (token),              m4_shipout_text (obs, M4_TOKEN_DATA_TEXT (td),
83                               strlen (M4_SYMBOL_TEXT (token)));                               strlen (M4_TOKEN_DATA_TEXT (td)));
84            }            }
85          else          else
86            expand_macro (p, symbol);            expand_macro (p, symbol);
# Line 95  expand_token (struct obstack *obs, m4_to Line 95  expand_token (struct obstack *obs, m4_to
95    
96    XFREE (text);    XFREE (text);
97  }  }
   
   
98    
99    
100  /* This function parses one argument to a macro call.  It expects the first  /* This function parses one argument to a macro call.  It expects the first
101     left parenthesis, or the separating comma to have been read by the     left parenthesis, or the separating comma to have been read by the
102     caller.  It skips leading whitespace, and reads and expands tokens,     caller.  It skips leading whitespace, and reads and expands tokens,
# Line 106  expand_token (struct obstack *obs, m4_to Line 105  expand_token (struct obstack *obs, m4_to
105     the last for the active macro call.  The argument are build on the     the last for the active macro call.  The argument are build on the
106     obstack OBS, indirectly through expand_token ().      */     obstack OBS, indirectly through expand_token ().      */
107  static boolean  static boolean
108  expand_argument (struct obstack *obs, m4_symbol *argp)  expand_argument (struct obstack *obs, m4_token_data *argp)
109  {  {
110    m4_token_t t;    m4_token_t t;
111    m4_symbol tokenbuf;    m4_token_data td;
112    char *text;    char *text;
113    int paren_level;    int paren_level;
114    
115    M4_SYMBOL_TYPE (argp) = M4_TOKEN_VOID;    M4_TOKEN_DATA_TYPE (argp) = M4_TOKEN_VOID;
116    
117    /* Skip leading white space.  */    /* Skip leading white space.  */
118    do    do
119      {      {
120        t = m4_next_token (&tokenbuf);        t = m4_next_token (&td);
121      }      }
122    while (t == M4_TOKEN_SPACE);    while (t == M4_TOKEN_SPACE);
123    
# Line 126  expand_argument (struct obstack *obs, m4 Line 125  expand_argument (struct obstack *obs, m4
125    
126    while (1)    while (1)
127      {      {
128    
129        switch (t)        switch (t)
130          {                       /* TOKSW */          {                       /* TOKSW */
131          case M4_TOKEN_SIMPLE:          case M4_TOKEN_SIMPLE:
132            text = M4_SYMBOL_TEXT (&tokenbuf);            text = M4_TOKEN_DATA_TEXT (&td);
133            if ((M4_IS_COMMA (*text) || M4_IS_CLOSE (*text)) && paren_level == 0)            if ((M4_IS_COMMA(*text) || M4_IS_CLOSE(*text)) && paren_level == 0)
134              {              {
135    
136                /* The argument MUST be finished, whether we want it or not.  */                /* The argument MUST be finished, whether we want it or not.  */
137                obstack_1grow (obs, '\0');                obstack_1grow (obs, '\0');
138                text = obstack_finish (obs);                text = obstack_finish (obs);
139    
140                if (M4_SYMBOL_TYPE (argp) == M4_TOKEN_VOID)                if (M4_TOKEN_DATA_TYPE (argp) == M4_TOKEN_VOID)
141                  {                  {
142                    M4_SYMBOL_TYPE (argp) = M4_TOKEN_TEXT;                    M4_TOKEN_DATA_TYPE (argp) = M4_TOKEN_TEXT;
143                    M4_SYMBOL_TEXT (argp) = text;                    M4_TOKEN_DATA_TEXT (argp) = text;
144                  }                  }
145                return (boolean) (M4_IS_COMMA (*M4_SYMBOL_TEXT (&tokenbuf)));                return (boolean) (M4_IS_COMMA(*M4_TOKEN_DATA_TEXT (&td)));
146              }              }
147    
148            if (M4_IS_OPEN(*text))            if (M4_IS_OPEN(*text))
149              paren_level++;              paren_level++;
150            else if (M4_IS_CLOSE(*text))            else if (M4_IS_CLOSE(*text))
151              paren_level--;              paren_level--;
152            expand_token (obs, t, &tokenbuf);            expand_token (obs, t, &td);
153            break;            break;
154    
155          case M4_TOKEN_EOF:          case M4_TOKEN_EOF:
# Line 160  expand_argument (struct obstack *obs, m4 Line 160  expand_argument (struct obstack *obs, m4
160          case M4_TOKEN_WORD:          case M4_TOKEN_WORD:
161          case M4_TOKEN_SPACE:          case M4_TOKEN_SPACE:
162          case M4_TOKEN_STRING:          case M4_TOKEN_STRING:
163            expand_token (obs, t, &tokenbuf);            expand_token (obs, t, &td);
164            break;            break;
165    
166          case M4_TOKEN_MACDEF:          case M4_TOKEN_MACDEF:
167            if (obstack_object_size (obs) == 0)            if (obstack_object_size (obs) == 0)
168              {              {
169                M4_SYMBOL_TYPE (argp)   = M4_TOKEN_FUNC;                M4_TOKEN_DATA_TYPE (argp)   = M4_TOKEN_FUNC;
170                M4_SYMBOL_HANDLE (argp) = M4_SYMBOL_HANDLE (&tokenbuf);                M4_TOKEN_DATA_HANDLE (argp) = M4_TOKEN_DATA_HANDLE (&td);
171                M4_SYMBOL_FUNC (argp)   = M4_SYMBOL_FUNC (&tokenbuf);                M4_TOKEN_DATA_FUNC (argp)   = M4_TOKEN_DATA_FUNC (&td);
172                M4_SYMBOL_TRACED (argp) = M4_SYMBOL_TRACED (&tokenbuf);                M4_TOKEN_TRACED (argp)      = M4_TOKEN_TRACED (&td);
173              }              }
174            break;            break;
175    
# Line 179  INTERNAL ERROR: Bad token type in expand Line 179  INTERNAL ERROR: Bad token type in expand
179            abort ();            abort ();
180          }          }
181    
182        t = m4_next_token (&tokenbuf);        t = m4_next_token (&td);
183      }      }
184  }  }
185    
# Line 191  collect_arguments (const char *name, m4_ Line 191  collect_arguments (const char *name, m4_
191                     struct obstack *argptr, struct obstack *arguments)                     struct obstack *argptr, struct obstack *arguments)
192  {  {
193    int ch;                       /* lookahead for ( */    int ch;                       /* lookahead for ( */
194    m4_symbol tokenbuf;    m4_token_data td;
195    m4_symbol *token;    m4_token_data *tdp;
196    boolean more_args;    boolean more_args;
197    boolean groks_macro_args = M4_SYMBOL_MACRO_ARGS (symbol);    boolean groks_macro_args = M4_SYMBOL_MACRO_ARGS (symbol);
198    
199    M4_SYMBOL_TYPE (&tokenbuf) = M4_TOKEN_TEXT;    M4_TOKEN_DATA_TYPE (&td) = M4_TOKEN_TEXT;
200    M4_SYMBOL_TEXT (&tokenbuf) = (char *) name;    M4_TOKEN_DATA_TEXT (&td) = (char *) name;
201    token = (m4_symbol *) obstack_copy (arguments, (void *) &tokenbuf, sizeof (tokenbuf));    tdp = (m4_token_data *) obstack_copy (arguments, (void *) &td, sizeof (td));
202    obstack_grow (argptr, (void *) &token, sizeof (token));    obstack_grow (argptr, (void *) &tdp, sizeof (tdp));
203    
204    ch = m4_peek_input ();    ch = m4_peek_input ();
205    if (M4_IS_OPEN(ch))    if (M4_IS_OPEN(ch))
206      {      {
207        m4_next_token (&tokenbuf);                /* gobble parenthesis */        m4_next_token (&td);              /* gobble parenthesis */
208        do        do
209          {          {
210            more_args = expand_argument (arguments, &tokenbuf);            more_args = expand_argument (arguments, &td);
211    
212            if (!groks_macro_args && M4_SYMBOL_TYPE (&tokenbuf) == M4_TOKEN_FUNC)            if (!groks_macro_args && M4_TOKEN_DATA_TYPE (&td) == M4_TOKEN_FUNC)
213              {              {
214                M4_SYMBOL_TYPE (&tokenbuf) = M4_TOKEN_TEXT;                M4_TOKEN_DATA_TYPE (&td) = M4_TOKEN_TEXT;
215                M4_SYMBOL_TEXT (&tokenbuf) = "";                M4_TOKEN_DATA_TEXT (&td) = "";
216              }              }
217            token = (m4_symbol *)            tdp = (m4_token_data *)
218              obstack_copy (arguments, (void *) &tokenbuf, sizeof (tokenbuf));              obstack_copy (arguments, (void *) &td, sizeof (td));
219            obstack_grow (argptr, (void *) &token, sizeof (token));            obstack_grow (argptr, (void *) &tdp, sizeof (tdp));
220          }          }
221        while (more_args);        while (more_args);
222      }      }
# Line 231  collect_arguments (const char *name, m4_ Line 231  collect_arguments (const char *name, m4_
231     arguments to the call, stored in the ARGV table.  The expansion is     arguments to the call, stored in the ARGV table.  The expansion is
232     left on the obstack EXPANSION.  Macro tracing is also handled here.  */     left on the obstack EXPANSION.  Macro tracing is also handled here.  */
233  void  void
234  m4_call_macro (m4_symbol *symbol, int argc, m4_symbol **argv,  m4_call_macro (m4_symbol *symbol, int argc, m4_token_data **argv,
235                 struct obstack *expansion)                 struct obstack *expansion)
236  {  {
237    switch (M4_SYMBOL_TYPE (symbol))    switch (M4_SYMBOL_TYPE (symbol))
# Line 263  expand_macro (const char *name, m4_symbo Line 263  expand_macro (const char *name, m4_symbo
263  {  {
264    struct obstack arguments;    struct obstack arguments;
265    struct obstack argptr;    struct obstack argptr;
266    m4_symbol **argv;    m4_token_data **argv;
267    int argc;    int argc;
268    struct obstack *expansion;    struct obstack *expansion;
269    const char *expanded;    const char *expanded;
# Line 289  ERROR: Recursion limit of %d exceeded, u Line 289  ERROR: Recursion limit of %d exceeded, u
289    
290    collect_arguments (name, symbol, &argptr, &arguments);    collect_arguments (name, symbol, &argptr, &arguments);
291    
292    argc = obstack_object_size (&argptr) / sizeof (m4_symbol *);    argc = obstack_object_size (&argptr) / sizeof (m4_token_data *);
293    argv = (m4_symbol **) obstack_finish (&argptr);    argv = (m4_token_data **) obstack_finish (&argptr);
294    
295    if (traced)    if (traced)
296      m4_trace_pre (name, my_call_id, argc, argv);      m4_trace_pre (name, my_call_id, argc, argv);
# Line 315  ERROR: Recursion limit of %d exceeded, u Line 315  ERROR: Recursion limit of %d exceeded, u
315     as usual.  */     as usual.  */
316  void  void
317  m4_process_macro (struct obstack *obs, m4_symbol *symbol, int argc,  m4_process_macro (struct obstack *obs, m4_symbol *symbol, int argc,
318                    m4_symbol **argv)                    m4_token_data **argv)
319  {  {
320    const unsigned char *text;    const unsigned char *text;
321    int i;    int i;
# Line 344  m4_process_macro (struct obstack *obs, m Line 344  m4_process_macro (struct obstack *obs, m
344                text = endp;                text = endp;
345              }              }
346            if (i < argc)            if (i < argc)
347              m4_shipout_string (obs, M4_SYMBOL_TEXT (argv[i]), 0, FALSE);              m4_shipout_string (obs, M4_TOKEN_DATA_TEXT (argv[i]), 0, FALSE);
348            break;            break;
349    
350          case '#':               /* number of arguments */          case '#':               /* number of arguments */

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14

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