m4-patches
[Top][All Lists]
Advanced

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

FYI: 21-gary-syntax-table-encapsulation.patch


From: Gary V. Vaughan
Subject: FYI: 21-gary-syntax-table-encapsulation.patch
Date: Thu, 26 Jun 2003 16:03:51 +0100
User-agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.4) Gecko/20030617

Applied to HEAD.
--
  ())_.  Gary V. Vaughan    gary@(oranda.demon.co.uk|gnu.org)
  ( '/   Research Scientist http://www.oranda.demon.co.uk       ,_())____
  / )=   GNU Hacker         http://www.gnu.org/software/libtool  \'      `&
`(_~)_   Tech' Author       http://sources.redhat.com/autobook   =`---d__/
Index: ChangeLog
from  Gary V. Vaughan  <address@hidden>
        Move the global variables that pertain to syntax to a new `struct
        m4_syntax_table', and then add one of these to `struct m4'.  The
        ripple effect through the code to both change formerly global
        references, and make sure a suitable context is available in
        lexical scope is disproportionately large compared to the size of
        the change proper.  This change is a large part of decoupling
        syntax.c from the rest of the code that uses it.

        * m4/m4private.h (struct m4): Add a syntax field.
        * m4/m4.c (m4_create): Initialise it,
        (m4_delete): Recycle it.
        (m4_get_symtab): Remove hand coded version...
        (m4_get_symbol_table): ...and generate this with cpp.  Changed all
        callers.
        * m4/m4module.h (m4_context_field_table): Add an extra field so we
        can generate m4_get_symbol_table.  Add a new row for
        m4_get_syntax_table.
        (M4SYNTAX): Syntactic sugar for module writers.
        (m4_symtab): Renamed to m4_symbol_table.  Changed all callers.
        (m4_syntax_table): New home for syntax related formerly global
        variables.
        * m4/m4private.h (struct m4_syntax_table): Define it.
        * m4/input.c (m4_input_init): Initialisation of these formerly
        global variables moved...
        * m4/syntax.c (m4_syntax_create): ...to here.
        * m4/input.c (m4_input_exit): And similarly, recycling of the
        memory used by those values moved...
        * m4/syntax.c (m4_syntax_delete): ...to here.
        * m4/m4module.h (DEF_LQUOTE, DEF_RQUOTE, DEF_BCOMM, DEF_ECOMM):
        Moved to m4/m4private.h.
        * m4/syntax.c (m4_get_syntax_lquote, m4_get_syntax_rquote)
        (m4_get_syntax_bcomm, m4_get_syntax_ecomm)
        (m4_is_syntax_single_quotes, m4_is_syntax_single_comments)
        (m4_is_syntax_macro_escaped): New accessors for m4_syntax_table
        objects.  Changed all callers that used to directly access the
        global equivalents.
        (m4__single_quotes, m4__single_comments, m4__use_macro_escape):
        Removed and incorporated into m4_syntax_table structure.
        * m4/utility.c (lquote, rquote, bcomm, ecomm): Ditto.
        * m4/syntax.c (m4_set_syntax): Now returns an error status,
        instead of requiring a `struct m4' to generate its own errors.
        Changed all callers.
        * src/main.c (main): Now that the syntax table is initialised as
        part of m4_create, we have to manually wipe the syntax entries if
        we are about to read a frozen file.

2003-06-26  Gary V. Vaughan  <address@hidden>

Index: m4/debug.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/debug.c,v
retrieving revision 1.14
diff -u -p -u -r1.14 debug.c
--- m4/debug.c 20 Jun 2003 15:43:19 -0000 1.14
+++ m4/debug.c 26 Jun 2003 14:56:58 -0000
@@ -257,13 +257,13 @@ m4_trace_format (m4 *context, va_alist)
 
        case 'l':
          s = BIT_TEST(m4_get_debug_level_opt(context), M4_DEBUG_TRACE_QUOTE)
-               ? (char *) lquote.string
+               ? m4_get_syntax_lquote (M4SYNTAX)
                : "";
          break;
 
        case 'r':
          s = BIT_TEST(m4_get_debug_level_opt(context), M4_DEBUG_TRACE_QUOTE)
-               ? (char *) rquote.string
+               ? m4_get_syntax_rquote (M4SYNTAX)
                : "";
          break;
 
Index: m4/input.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/input.c,v
retrieving revision 1.28
diff -u -p -u -r1.28 input.c
--- m4/input.c 20 Jun 2003 15:43:19 -0000 1.28
+++ m4/input.c 26 Jun 2003 14:56:58 -0000
@@ -700,29 +700,11 @@ m4_input_init (void)
   next = NULL;
 
   start_of_input_line = FALSE;
-
-  lquote.string = xstrdup (DEF_LQUOTE);
-  lquote.length = strlen (lquote.string);
-  rquote.string = xstrdup (DEF_RQUOTE);
-  rquote.length = strlen (rquote.string);
-  m4__single_quotes = TRUE;
-
-  bcomm.string = xstrdup (DEF_BCOMM);
-  bcomm.length = strlen (bcomm.string);
-  ecomm.string = xstrdup (DEF_ECOMM);
-  ecomm.length = strlen (ecomm.string);
-  m4__single_comments = TRUE;
-
-  m4__use_macro_escape = FALSE;
 }
 
  void
 m4_input_exit (void)
 {
-  XFREE (lquote.string);
-  XFREE (rquote.string);
-  XFREE (bcomm.string);
-  XFREE (ecomm.string);
   obstack_free (&wrapup_stack, NULL);
   obstack_free (&input_stack, NULL);
   obstack_free (&token_stack, NULL);
@@ -773,10 +755,11 @@ m4__next_token (m4 *context, m4_symbol_v
       }
 
     (void) next_char (context);
-    if (M4_IS_BCOMM(ch))                       /* COMMENT, SHORT DELIM */
+    if (M4_IS_BCOMM (M4SYNTAX, ch))    /* COMMENT, SHORT DELIM */
       {
        obstack_1grow (&token_stack, ch);
-       while ((ch = next_char (context)) != CHAR_EOF && !M4_IS_ECOMM(ch))
+       while ((ch = next_char (context)) != CHAR_EOF
+              && !M4_IS_ECOMM (M4SYNTAX, ch))
          obstack_1grow (&token_stack, ch);
        if (ch != CHAR_EOF)
          obstack_1grow (&token_stack, ch);
@@ -784,25 +767,30 @@ m4__next_token (m4 *context, m4_symbol_v
                ? M4_TOKEN_NONE : M4_TOKEN_STRING;
       }
                                        /* COMMENT, LONGER DELIM */
-    else if (!m4__single_comments && MATCH (context, ch, bcomm.string))
+    else if (!m4_is_syntax_single_comments (M4SYNTAX)
+            && MATCH (context, ch, context->syntax->bcomm.string))
       {
-       obstack_grow (&token_stack, bcomm.string, bcomm.length);
-       while ((ch = next_char (context)) != CHAR_EOF && !MATCH (context, ch, 
ecomm.string))
+       obstack_grow (&token_stack, context->syntax->bcomm.string,
+                     context->syntax->bcomm.length);
+       while ((ch = next_char (context)) != CHAR_EOF
+              && !MATCH (context, ch, context->syntax->ecomm.string))
          obstack_1grow (&token_stack, ch);
        if (ch != CHAR_EOF)
-         obstack_grow (&token_stack, ecomm.string, ecomm.length);
+         obstack_grow (&token_stack, context->syntax->ecomm.string,
+                       context->syntax->ecomm.length);
        type = m4_get_discard_comments_opt (context)
                ? M4_TOKEN_NONE : M4_TOKEN_STRING;
       }
-    else if (M4_IS_ESCAPE(ch))         /* ESCAPED WORD */
+    else if (M4_IS_ESCAPE (M4SYNTAX, ch))      /* ESCAPED WORD */
       {
        obstack_1grow (&token_stack, ch);
        if ((ch = next_char (context)) != CHAR_EOF)
          {
-           if (M4_IS_ALPHA(ch))
+           if (M4_IS_ALPHA (M4SYNTAX, ch))
              {
                obstack_1grow (&token_stack, ch);
-               while ((ch = next_char (context)) != CHAR_EOF && 
(M4_IS_ALNUM(ch)))
+               while ((ch = next_char (context)) != CHAR_EOF
+                      && (M4_IS_ALNUM (M4SYNTAX, ch)))
                  {
                    obstack_1grow (&token_stack, ch);
                  }
@@ -822,19 +810,21 @@ m4__next_token (m4 *context, m4_symbol_v
            type = M4_TOKEN_SIMPLE;     /* escape before eof */
          }
       }
-    else if (M4_IS_ALPHA (ch))
+    else if (M4_IS_ALPHA (M4SYNTAX, ch))
       {
        obstack_1grow (&token_stack, ch);
-       while ((ch = next_char (context)) != CHAR_EOF && (M4_IS_ALNUM(ch)))
+       while ((ch = next_char (context)) != CHAR_EOF
+              && (M4_IS_ALNUM (M4SYNTAX, ch)))
          {
            obstack_1grow (&token_stack, ch);
          }
        if (ch != CHAR_EOF)
          unget_input(ch);
 
-       type = m4__use_macro_escape ? M4_TOKEN_STRING : M4_TOKEN_WORD;
+       type = m4_is_syntax_macro_escaped (M4SYNTAX)
+               ? M4_TOKEN_STRING : M4_TOKEN_WORD;
       }
-    else if (M4_IS_LQUOTE(ch))         /* QUOTED STRING, SINGLE QUOTES */
+    else if (M4_IS_LQUOTE (M4SYNTAX, ch)) /* QUOTED STRING, SINGLE QUOTES */
       {
        const char *current_file = m4_current_file;
        int current_line = m4_current_line;
@@ -847,13 +837,13 @@ m4__next_token (m4 *context, m4_symbol_v
                              current_file, current_line,
                              _("EOF in string"));
 
-           if (M4_IS_RQUOTE(ch))
+           if (M4_IS_RQUOTE (M4SYNTAX, ch))
              {
                if (--quote_level == 0)
                  break;
                obstack_1grow (&token_stack, ch);
              }
-           else if (M4_IS_LQUOTE(ch))
+           else if (M4_IS_LQUOTE (M4SYNTAX, ch))
              {
                quote_level++;
                obstack_1grow (&token_stack, ch);
@@ -864,7 +854,8 @@ m4__next_token (m4 *context, m4_symbol_v
        type = M4_TOKEN_STRING;
       }
                                        /* QUOTED STRING, LONGER QUOTES */
-    else if (!m4__single_quotes && MATCH (context, ch, lquote.string))
+    else if (!m4_is_syntax_single_quotes (M4SYNTAX)
+            && MATCH (context, ch, context->syntax->lquote.string))
       {
        const char *current_file = m4_current_file;
        int current_line = m4_current_line;
@@ -876,41 +867,45 @@ m4__next_token (m4 *context, m4_symbol_v
              error_at_line (EXIT_FAILURE, 0,
                              current_file, current_line,
                              _("EOF in string"));
-           if (MATCH (context, ch, rquote.string))
+           if (MATCH (context, ch, context->syntax->rquote.string))
              {
                if (--quote_level == 0)
                  break;
-               obstack_grow (&token_stack, rquote.string, rquote.length);
+               obstack_grow (&token_stack, context->syntax->rquote.string,
+                             context->syntax->rquote.length);
              }
-           else if (MATCH (context, ch, lquote.string))
+           else if (MATCH (context, ch, context->syntax->lquote.string))
              {
                quote_level++;
-               obstack_grow (&token_stack, lquote.string, lquote.length);
+               obstack_grow (&token_stack, context->syntax->lquote.string,
+                             context->syntax->lquote.length);
              }
            else
              obstack_1grow (&token_stack, ch);
          }
        type = M4_TOKEN_STRING;
       }
-    else if (m4__single_quotes && m4__single_comments) /* EVERYTHING ELSE */
+    else if (m4_is_syntax_single_quotes (M4SYNTAX)
+            && m4_is_syntax_single_comments (M4SYNTAX)) /* EVERYTHING ELSE */
       {
        obstack_1grow (&token_stack, ch);
 
-       if (M4_IS_OTHER(ch) || M4_IS_NUM(ch))
+       if (M4_IS_OTHER (M4SYNTAX, ch) || M4_IS_NUM (M4SYNTAX, ch))
          {
            while ((ch = next_char(context)) != CHAR_EOF
-                  && (M4_IS_OTHER(ch) || M4_IS_NUM(ch)))
+                  && (M4_IS_OTHER (M4SYNTAX, ch) || M4_IS_NUM (M4SYNTAX, ch)))
              obstack_1grow (&token_stack, ch);
 
            if (ch != CHAR_EOF)
              unget_input(ch);
            type = M4_TOKEN_STRING;
          }
-       else if (M4_IS_SPACE(ch))
+       else if (M4_IS_SPACE (M4SYNTAX, ch))
          {
            if (!m4_get_interactive_opt (context))
              {
-               while ((ch = next_char(context)) != CHAR_EOF && M4_IS_SPACE(ch))
+               while ((ch = next_char (context)) != CHAR_EOF
+                      && M4_IS_SPACE (M4SYNTAX, ch))
                  obstack_1grow (&token_stack, ch);
 
                if (ch != CHAR_EOF)
@@ -918,7 +913,7 @@ m4__next_token (m4 *context, m4_symbol_v
              }
            type = M4_TOKEN_SPACE;
          }
-       else if (M4_IS_ACTIVE(ch))
+       else if (M4_IS_ACTIVE (M4SYNTAX, ch))
          type = M4_TOKEN_WORD;
        else
          type = M4_TOKEN_SIMPLE;
@@ -927,11 +922,11 @@ m4__next_token (m4 *context, m4_symbol_v
       {
        obstack_1grow (&token_stack, ch);
 
-       if (M4_IS_OTHER(ch) || M4_IS_NUM(ch))
+       if (M4_IS_OTHER (M4SYNTAX, ch) || M4_IS_NUM (M4SYNTAX, ch))
          type = M4_TOKEN_STRING;
-       else if (M4_IS_SPACE(ch))
+       else if (M4_IS_SPACE (M4SYNTAX, ch))
          type = M4_TOKEN_SPACE;
-       else if (M4_IS_ACTIVE(ch))
+       else if (M4_IS_ACTIVE (M4SYNTAX, ch))
          type = M4_TOKEN_WORD;
        else
          type = M4_TOKEN_SIMPLE;
Index: m4/m4.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4.c,v
retrieving revision 1.3
diff -u -p -u -r1.3 m4.c
--- m4/m4.c 20 Jun 2003 15:43:19 -0000 1.3
+++ m4/m4.c 26 Jun 2003 14:56:58 -0000
@@ -26,6 +26,7 @@ m4_create (void)
   m4 *context = XCALLOC (m4, 1);
 
   context->symtab = m4_symtab_create (0, &context->no_gnu_extensions);
+  context->syntax = m4_syntax_create ();
   context->nesting_limit = M4_DEFAULT_NESTING_LIMIT;
 
   return context;
@@ -39,21 +40,18 @@ m4_delete (m4 *context)
   if (context->symtab)
     m4_symtab_delete (context->symtab);
 
-  xfree (context);
-}
+  if (context->syntax)
+    m4_syntax_delete (context->syntax);
 
-#undef m4_get_symtab
-m4_symtab *
-m4_get_symtab (m4 *context)
-{
-  assert (context);
-  return context->symtab;
+  xfree (context);
 }
 
 
 
 /* Use the preprocessor to generate the repetitive bit twiddling functions
    for us.  */
+#undef m4_get_symbol_table
+#undef m4_get_syntax_table
 #undef m4_get_warning_status_opt
 #undef m4_get_no_gnu_extensions_opt
 #undef m4_get_nesting_limit_opt
@@ -66,20 +64,20 @@ m4_get_symtab (m4 *context)
 #undef m4_get_sync_output_opt
 
 
-#define M4FIELD(type, name)                                            \
-       type CONC(m4_get_, CONC(name, _opt)) (m4 *context)              \
+#define M4FIELD(type, base, field)                                     \
+       type CONC(m4_get_, base) (m4 *context)                          \
        {                                                               \
          assert (context);                                             \
-         return context->name;                                         \
+         return context->field;                                        \
        }
 m4_context_field_table
 #undef M4FIELD
 
-#define M4FIELD(type, name)                                            \
-       type CONC(m4_set_, CONC(name, _opt)) (m4 *context, type value)  \
+#define M4FIELD(type, base, field)                                     \
+       type CONC(m4_set_, base) (m4 *context, type value)              \
        {                                                               \
          assert (context);                                             \
-         return context->name = value;                                 \
+         return context->field = value;                                \
        }
 m4_context_field_table
 #undef M4FIELD
Index: m4/m4module.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4module.h,v
retrieving revision 1.51
diff -u -p -u -r1.51 m4module.h
--- m4/m4module.h 20 Jun 2003 15:43:19 -0000 1.51
+++ m4/m4module.h 26 Jun 2003 14:56:58 -0000
@@ -82,19 +82,21 @@ typedef struct {
 
 /* --- CONTEXT MANAGEMENT --- */
 
-typedef struct m4_symtab       m4_symtab;
+typedef struct m4_syntax_table m4_syntax_table;
+typedef struct m4_symbol_table m4_symbol_table;
 typedef struct m4_symbol       m4_symbol;
 
-extern m4 *      m4_create     (void);
-extern void      m4_delete     (m4 *);
-extern m4_symtab *m4_get_symtab        (m4 *);
+extern m4 *            m4_create       (void);
+extern void            m4_delete       (m4 *);
 
 #define m4_context_field_table                                                 
\
-       M4FIELD(int,            warning_status)                         \
-       M4FIELD(boolean,        no_gnu_extensions)                      \
-       M4FIELD(int,            nesting_limit)                          \
-       M4FIELD(int,            debug_level)                            \
-       M4FIELD(int,            max_debug_arg_length)                   \
+       M4FIELD(m4_symbol_table *, symbol_table,   symtab)              \
+       M4FIELD(m4_syntax_table *, syntax_table,   syntax)              \
+       M4FIELD(int,     warning_status_opt,       warning_status)      \
+       M4FIELD(boolean, no_gnu_extensions_opt,    no_gnu_extensions)   \
+       M4FIELD(int,     nesting_limit_opt,        nesting_limit)       \
+       M4FIELD(int,     debug_level_opt,          debug_level)         \
+       M4FIELD(int,     max_debug_arg_length_opt, max_debug_arg_length)\
 
 
 #define m4_context_opt_bit_table                                       \
@@ -105,9 +107,9 @@ extern m4_symtab *m4_get_symtab     (m4 *);
        M4OPT_BIT(M4_OPT_SYNC_OUTPUT_BIT,       sync_output_opt)        \
 
 
-#define M4FIELD(type, name)                                            \
-       extern type CONC(m4_get_, CONC(name, _opt)) (m4 *context);      \
-       extern type CONC(m4_set_, CONC(name, _opt)) (m4 *context, type value);
+#define M4FIELD(type, base, field)                                     \
+       extern type CONC(m4_get_, base) (m4 *context);                  \
+       extern type CONC(m4_set_, base) (m4 *context, type value);
 m4_context_field_table
 #undef M4FIELD
 
@@ -117,7 +119,8 @@ m4_context_field_table
 m4_context_opt_bit_table
 #undef M4OPT_BIT
 
-#define M4SYMTAB       (m4_get_symtab (context))
+#define M4SYMTAB       (m4_get_symbol_table (context))
+#define M4SYNTAX       (m4_get_syntax_table (context))
 
 
 
@@ -138,18 +141,18 @@ extern m4_macro      *m4_get_module_macro_
 /* --- SYMBOL TABLE MANAGEMENT --- */
 
 
-typedef void *m4_symtab_apply_func (m4_symtab *symtab, const char *key,
+typedef void *m4_symtab_apply_func (m4_symbol_table *symtab, const char *key,
                                    m4_symbol *symbol, void *userdata);
 
-extern m4_symtab *m4_symtab_create  (size_t, boolean *);
-extern void      m4_symtab_delete  (m4_symtab*);
-extern void *    m4_symtab_apply   (m4_symtab*, m4_symtab_apply_func*, void*);
-
-extern m4_symbol *m4_symbol_lookup  (m4_symtab*, const char *);
-extern m4_symbol *m4_symbol_pushdef (m4_symtab*, const char *, m4_symbol_value 
*);
-extern m4_symbol *m4_symbol_define  (m4_symtab*, const char *, m4_symbol_value 
*);
-extern void       m4_symbol_popdef  (m4_symtab*, const char *);
-extern void       m4_symbol_delete  (m4_symtab*, const char *);
+extern m4_symbol_table *m4_symtab_create  (size_t, boolean *);
+extern void      m4_symtab_delete  (m4_symbol_table*);
+extern void *    m4_symtab_apply   (m4_symbol_table*, m4_symtab_apply_func*, 
void*);
+
+extern m4_symbol *m4_symbol_lookup  (m4_symbol_table*, const char *);
+extern m4_symbol *m4_symbol_pushdef (m4_symbol_table*, const char *, 
m4_symbol_value *);
+extern m4_symbol *m4_symbol_define  (m4_symbol_table*, const char *, 
m4_symbol_value *);
+extern void       m4_symbol_popdef  (m4_symbol_table*, const char *);
+extern void       m4_symbol_delete  (m4_symbol_table*, const char *);
 
 #define m4_symbol_delete(symtab, name)                 M4_STMT_START { \
        while (m4_symbol_lookup ((symtab), (name)))                     \
@@ -158,7 +161,7 @@ extern void       m4_symbol_delete  (m4_
 extern m4_symbol_value *m4_get_symbol_value      (m4_symbol*);
 extern boolean         m4_get_symbol_traced      (m4_symbol*);
 extern boolean         m4_set_symbol_traced      (m4_symbol*, boolean);
-extern boolean         m4_set_symbol_name_traced (m4_symtab*, const char *);
+extern boolean         m4_set_symbol_name_traced (m4_symbol_table*, const char 
*);
 
 #define m4_is_symbol_text(symbol)                                      \
        (m4_is_symbol_value_text (m4_get_symbol_value (symbol)))
@@ -203,23 +206,12 @@ typedef struct {
     size_t length;             /* length of the string */
 } m4_string;
 
-extern m4_string lquote;
-extern m4_string rquote;
-
-extern m4_string bcomm;
-extern m4_string ecomm;
-
-#define DEF_LQUOTE "`"
-#define DEF_RQUOTE "\'"
-#define DEF_BCOMM "#"
-#define DEF_ECOMM "\n"
-
 extern boolean m4_bad_argc (m4 *, int, m4_symbol_value **, int, int);
-extern const char *m4_skip_space (const char *);
+extern const char *m4_skip_space (m4 *, const char *);
 extern boolean m4_numeric_arg (m4 *, int, m4_symbol_value **, int, int *);
 extern void m4_shipout_int (struct obstack *, int);
-extern void m4_shipout_string (struct obstack*, const char*, int, boolean);
-extern void m4_dump_args (struct obstack *obs, int argc, m4_symbol_value 
**argv, const char *sep, boolean quoted);
+extern void m4_shipout_string (m4 *, struct obstack*, const char*, int, 
boolean);
+extern void m4_dump_args (m4 *, struct obstack *obs, int argc, m4_symbol_value 
**argv, const char *sep, boolean quoted);
 
 
 
@@ -322,12 +314,18 @@ extern void          m4_process_macro (m4 *con
 
 /* --- SYNTAX TABLE DEFINITIONS --- */
 
-/* Please read the comment at the top of input.c for details */
-extern unsigned short m4_syntax_table[256];
-
-extern void    m4_syntax_init  (void);
-extern void    m4_syntax_exit  (void);
-extern int     m4_syntax_code  (char ch);
+extern m4_syntax_table *m4_syntax_create       (void);
+extern void             m4_syntax_delete       (m4_syntax_table *syntax);
+extern int              m4_syntax_code         (char ch);
+
+extern const char *     m4_get_syntax_lquote   (m4_syntax_table *syntax);
+extern const char *     m4_get_syntax_rquote   (m4_syntax_table *syntax);
+extern const char *     m4_get_syntax_bcomm    (m4_syntax_table *syntax);
+extern const char *     m4_get_syntax_ecomm    (m4_syntax_table *syntax);
+
+extern boolean          m4_is_syntax_single_quotes     (m4_syntax_table *);
+extern boolean          m4_is_syntax_single_comments   (m4_syntax_table *);
+extern boolean          m4_is_syntax_macro_escaped     (m4_syntax_table *);
 
 /* These are simple values, not bit masks.  There is no overlap. */
 #define M4_SYNTAX_OTHER                (0x0000)
@@ -359,30 +357,31 @@ extern    int     m4_syntax_code  (char ch);
 #define M4_SYNTAX_VALUE                
(0x00FF|M4_SYNTAX_LQUOTE|M4_SYNTAX_BCOMM)
 #define M4_SYNTAX_MASKS                (0xFF00)
 
-#define m4__syntax(ch) m4_syntax_table[(int)(ch)]
+#define m4__is_syntax(S,C,T)                                           \
+       (((S)->table[(int)(C)] & M4_SYNTAX_VALUE) == (T))
 
-#define M4_IS_OTHER(ch)  ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_OTHER)
-#define M4_IS_IGNORE(ch) ((m4__syntax(ch)) == M4_SYNTAX_IGNORE)
-#define M4_IS_SPACE(ch)  ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_SPACE)
-
-#define M4_IS_OPEN(ch)   ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_OPEN)
-#define M4_IS_CLOSE(ch)  ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_CLOSE)
-#define M4_IS_COMMA(ch)  ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_COMMA)
-#define M4_IS_DOLLAR(ch) ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_DOLLAR)
-#define M4_IS_ACTIVE(ch) ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_ACTIVE)
-#define M4_IS_ESCAPE(ch) ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_ESCAPE)
-#define M4_IS_ASSIGN(ch) ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_ASSIGN)
-
-#define M4_IS_ALPHA(ch)  ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_ALPHA)
-#define M4_IS_NUM(ch)    ((m4__syntax(ch)&M4_SYNTAX_VALUE) == M4_SYNTAX_NUM)
-#define M4_IS_ALNUM(ch)  (((m4__syntax(ch)) & M4_SYNTAX_ALNUM) != 0)
-
-#define M4_IS_LQUOTE(ch) (m4__syntax(ch) & M4_SYNTAX_LQUOTE)
-#define M4_IS_RQUOTE(ch) (m4__syntax(ch) & M4_SYNTAX_RQUOTE)
-#define M4_IS_BCOMM(ch)  (m4__syntax(ch) & M4_SYNTAX_BCOMM)
-#define M4_IS_ECOMM(ch)  (m4__syntax(ch) & M4_SYNTAX_ECOMM)
+#define M4_IS_IGNORE(S, C) (((S)->table[(int)(C)]) == M4_SYNTAX_IGNORE)
+#define M4_IS_OTHER(S, C)  (m4__is_syntax((S), (C), M4_SYNTAX_OTHER))
+#define M4_IS_SPACE(S, C)  (m4__is_syntax((S), (C), M4_SYNTAX_SPACE))
+
+#define M4_IS_OPEN(S, C)   (m4__is_syntax((S), (C), M4_SYNTAX_OPEN))
+#define M4_IS_CLOSE(S, C)  (m4__is_syntax((S), (C), M4_SYNTAX_CLOSE))
+#define M4_IS_COMMA(S, C)  (m4__is_syntax((S), (C), M4_SYNTAX_COMMA))
+#define M4_IS_DOLLAR(S, C) (m4__is_syntax((S), (C), M4_SYNTAX_DOLLAR))
+#define M4_IS_ACTIVE(S, C) (m4__is_syntax((S), (C), M4_SYNTAX_ACTIVE))
+#define M4_IS_ESCAPE(S, C) (m4__is_syntax((S), (C), M4_SYNTAX_ESCAPE))
+#define M4_IS_ASSIGN(S, C) (m4__is_syntax((S), (C), M4_SYNTAX_ASSIGN))
+
+#define M4_IS_ALPHA(S, C)  (m4__is_syntax((S), (C), M4_SYNTAX_ALPHA))
+#define M4_IS_NUM(S, C)    (m4__is_syntax((S), (C), M4_SYNTAX_NUM))
+#define M4_IS_ALNUM(S, C)  ((S)->table[(int)(C)] & M4_SYNTAX_ALNUM)
+
+#define M4_IS_LQUOTE(S, C) ((S)->table[(int)(C)] & M4_SYNTAX_LQUOTE)
+#define M4_IS_RQUOTE(S, C) ((S)->table[(int)(C)] & M4_SYNTAX_RQUOTE)
+#define M4_IS_BCOMM(S, C)  ((S)->table[(int)(C)] & M4_SYNTAX_BCOMM)
+#define M4_IS_ECOMM(S, C)  ((S)->table[(int)(C)] & M4_SYNTAX_ECOMM)
 
-#define M4_IS_IDENT(ch)         (M4_IS_OTHER(ch) || M4_IS_ALNUM(ch))
+#define M4_IS_IDENT(S, C)  (M4_IS_OTHER((S),(C))||M4_IS_ALNUM((S),(C)))
 
 
 /* --- TOKENISATION AND INPUT --- */
@@ -406,9 +405,9 @@ extern      const char *m4_push_string_finish
 extern void    m4_push_wrapup  (const char *);
 extern boolean m4_pop_wrapup   (void);
 
-extern void    m4_set_quotes   (const char *, const char *);
-extern void    m4_set_comment  (const char *, const char *);
-extern void    m4_set_syntax   (m4 *, char, const unsigned char *);
+extern void    m4_set_quotes   (m4_syntax_table *, const char *, const char *);
+extern void    m4_set_comment  (m4_syntax_table *, const char *, const char *);
+extern int     m4_set_syntax   (m4_syntax_table *, char, const unsigned char 
*);
 
 extern int m4_current_diversion;
 extern int m4_output_current_line;
@@ -460,7 +459,7 @@ struct m4_dump_symbol_data
   int size;                    /* size of table */
 };
 
-extern void *m4_dump_symbol_CB (m4_symtab*, const char*, m4_symbol *, void *);
+extern void *m4_dump_symbol_CB (m4_symbol_table*, const char*, m4_symbol *, 
void *);
 extern void m4_dump_symbols (m4 *context, struct m4_dump_symbol_data *data, 
int argc, m4_symbol_value **argv, boolean complain);
 
 
Index: m4/m4private.h
===================================================================
RCS file: /cvsroot/m4/m4/m4/m4private.h,v
retrieving revision 1.25
diff -u -p -u -r1.25 m4private.h
--- m4/m4private.h 20 Jun 2003 15:43:19 -0000 1.25
+++ m4/m4private.h 26 Jun 2003 14:56:58 -0000
@@ -42,7 +42,8 @@ typedef enum {
 /* --- CONTEXT MANAGEMENT --- */
 
 struct m4 {
-  m4_symtab *  symtab;
+  m4_symbol_table *symtab;
+  m4_syntax_table *syntax;
 
   /* Option flags  (set in src/main.c).  */
   int          warning_status;                 /* -E */
@@ -60,7 +61,8 @@ struct m4 {
 #define M4_OPT_SYNC_OUTPUT_BIT         (1 << 4) /* -s */
 
 #ifdef NDEBUG
-#  define m4_get_symtab(C)                     ((C)->symtab)
+#  define m4_get_symbol_table(C)               ((C)->symtab)
+#  define m4_get_syntax_table(C)               ((C)->syntax)
 #  define m4_get_warning_status_opt(C)         ((C)->warning_status)
 #  define m4_get_no_gnu_extensions_opt(C)      ((C)->no_gnu_extensions)
 #  define m4_get_nesting_limit_opt(C)          ((C)->nesting_limit)
@@ -174,20 +176,47 @@ struct m4_symbol_arg {
 #define SYMBOL_ARG_REST_BIT    (1 << 0)
 #define SYMBOL_ARG_KEY_BIT     (1 << 1)
 
-extern void    m4__symtab_remove_module_references (m4_symtab*, lt_dlhandle);
+extern void    m4__symtab_remove_module_references (m4_symbol_table*, 
lt_dlhandle);
 
 
 
 
-/* TRUE iff strlen(rquote) == strlen(lquote) == 1 */
-extern boolean m4__single_quotes;
+/* --- SYNTAX TABLE MANAGEMENT --- */
 
-/* TRUE iff strlen(bcomm) == strlen(ecomm) == 1 */
-extern boolean m4__single_comments;
+#define DEF_LQUOTE "`"
+#define DEF_RQUOTE "\'"
+#define DEF_BCOMM "#"
+#define DEF_ECOMM "\n"
 
-/* TRUE iff some character has M4_SYNTAX_ESCAPE */
-extern boolean m4__use_macro_escape;
+struct m4_syntax_table {
+  /* Please read the comment at the top of input.c for details */
+  unsigned short table[256];
 
+  m4_string lquote, rquote;
+  m4_string bcomm, ecomm;
+
+  /* TRUE iff strlen(rquote) == strlen(lquote) == 1 */
+  boolean is_single_quotes;
+
+  /* TRUE iff strlen(bcomm) == strlen(ecomm) == 1 */
+  boolean is_single_comments;
+
+  /* TRUE iff some character has M4_SYNTAX_ESCAPE */
+  boolean is_macro_escaped;
+};
+
+#ifdef NDEBUG
+#  define m4_get_syntax_lquote(S)      ((S)->lquote.string)
+#  define m4_get_syntax_rquote(S)      ((S)->rquote.string)
+#  define m4_get_syntax_bcomm(S)       ((S)->bcomm.string)
+#  define m4_get_syntax_ecomm(S)       ((S)->ecomm.string)
+
+#  define m4_is_syntax_single_quotes(S)                ((S)->is_single_quotes)
+#  define m4_is_syntax_single_comments(S)      ((S)->is_single_comments)
+#  define m4_is_syntax_macro_escaped(S)                ((S)->is_macro_escaped)
+#endif
+
+
 /* Various different token types.  */
 typedef enum {
   M4_TOKEN_EOF,                        /* end of file */
Index: m4/macro.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/macro.c,v
retrieving revision 1.29
diff -u -p -u -r1.29 macro.c
--- m4/macro.c 20 Jun 2003 15:43:19 -0000 1.29
+++ m4/macro.c 26 Jun 2003 14:56:58 -0000
@@ -79,7 +79,7 @@ expand_token (m4 *context, struct obstac
       {
        char *textp = text;
 
-       if (M4_IS_ESCAPE(*textp))
+       if (M4_IS_ESCAPE (M4SYNTAX, *textp))
          ++textp;
 
        symbol = m4_symbol_lookup (M4SYMTAB, textp);
@@ -87,7 +87,7 @@ expand_token (m4 *context, struct obstac
            || symbol->value->type == M4_SYMBOL_VOID
            || (symbol->value->type == M4_SYMBOL_FUNC
                && BIT_TEST (SYMBOL_FLAGS (symbol), VALUE_BLIND_ARGS_BIT)
-               && !M4_IS_OPEN (m4_peek_input (context))))
+               && !M4_IS_OPEN (M4SYNTAX, m4_peek_input (context))))
          {
            m4_shipout_text (context, obs, text, strlen (text));
          }
@@ -138,7 +138,8 @@ expand_argument (m4 *context, struct obs
        {                       /* TOKSW */
        case M4_TOKEN_SIMPLE:
          text = m4_get_symbol_value_text (&token);
-         if ((M4_IS_COMMA (*text) || M4_IS_CLOSE (*text)) && paren_level == 0)
+         if ((M4_IS_COMMA (M4SYNTAX, *text) || M4_IS_CLOSE (M4SYNTAX, *text))
+             && paren_level == 0)
            {
 
              /* The argument MUST be finished, whether we want it or not.  */
@@ -149,12 +150,12 @@ expand_argument (m4 *context, struct obs
                {
                  m4_set_symbol_value_text (argp, text);
                }
-             return (boolean) (M4_IS_COMMA (*m4_get_symbol_value_text 
(&token)));
+             return (boolean) (M4_IS_COMMA (M4SYNTAX, 
*m4_get_symbol_value_text (&token)));
            }
 
-         if (M4_IS_OPEN (*text))
+         if (M4_IS_OPEN (M4SYNTAX, *text))
            paren_level++;
-         else if (M4_IS_CLOSE (*text))
+         else if (M4_IS_CLOSE (M4SYNTAX, *text))
            paren_level--;
          expand_token (context, obs, type, &token);
          break;
@@ -269,7 +270,7 @@ collect_arguments (m4 *context, const ch
   obstack_grow (argptr, (void *) &tokenp, sizeof (tokenp));
 
   ch = m4_peek_input (context);
-  if (M4_IS_OPEN(ch))
+  if (M4_IS_OPEN (M4SYNTAX, ch))
     {
       m4__next_token (context, &token);                /* gobble parenthesis */
       do
@@ -351,7 +352,7 @@ m4_process_macro (m4 *context, m4_symbol
              text = endp;
            }
          if (i < argc)
-           m4_shipout_string (obs, M4ARG (i), 0, FALSE);
+           m4_shipout_string (context, obs, M4ARG (i), 0, FALSE);
          break;
 
        case '#':               /* number of arguments */
@@ -361,7 +362,7 @@ m4_process_macro (m4 *context, m4_symbol
 
        case '*':               /* all arguments */
        case '@':               /* ... same, but quoted */
-         m4_dump_args (obs, argc, argv, ",", *text == '@');
+         m4_dump_args (context, obs, argc, argv, ",", *text == '@');
          text++;
          break;
 
@@ -377,7 +378,7 @@ m4_process_macro (m4 *context, m4_symbol
              const char * endp;
              const char * key;
 
-             for (endp = ++text; *endp && M4_IS_IDENT (*endp); ++endp)
+             for (endp = ++text; *endp && M4_IS_IDENT (M4SYNTAX, *endp); 
++endp)
                ++len;
              key = xstrzdup (text, len);
 
@@ -392,7 +393,7 @@ m4_process_macro (m4 *context, m4_symbol
                      i = SYMBOL_ARG_INDEX (*arg);
 
                      if (i < argc)
-                       m4_shipout_string (obs, M4ARG (i), 0, FALSE);
+                       m4_shipout_string (context, obs, M4ARG (i), 0, FALSE);
                      else
                        M4ERROR ((EXIT_FAILURE, 0, "\
 INTERNAL ERROR: %s: out of range reference `%d' from argument %s",
Index: m4/output.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/output.c,v
retrieving revision 1.11
diff -u -p -u -r1.11 output.c
--- m4/output.c 20 Jun 2003 15:43:20 -0000 1.11
+++ m4/output.c 26 Jun 2003 14:56:58 -0000
@@ -488,7 +488,7 @@ m4_shipout_int (struct obstack *obs, int
 }
 
 void
-m4_shipout_string (struct obstack *obs, const char *s, int len,
+m4_shipout_string (m4 *context, struct obstack *obs, const char *s, int len,
                   boolean quoted)
 {
   if (s == NULL)
@@ -498,10 +498,12 @@ m4_shipout_string (struct obstack *obs, 
     len = strlen(s);
 
   if (quoted)
-    obstack_grow (obs, lquote.string, lquote.length);
+    obstack_grow (obs, context->syntax->lquote.string,
+                 context->syntax->lquote.length);
   obstack_grow (obs, s, len);
   if (quoted)
-    obstack_grow (obs, rquote.string, rquote.length);
+    obstack_grow (obs, context->syntax->rquote.string,
+                 context->syntax->rquote.length);
 }
 
 
Index: m4/symtab.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/symtab.c,v
retrieving revision 1.40
diff -u -p -u -r1.40 symtab.c
--- m4/symtab.c 20 Jun 2003 15:43:20 -0000 1.40
+++ m4/symtab.c 26 Jun 2003 14:56:58 -0000
@@ -44,14 +44,14 @@
 
 #define M4_SYMTAB_DEFAULT_SIZE         2047
 
-struct m4_symtab {
+struct m4_symbol_table {
   m4_hash *table;
   boolean *nuke_trace_bit;     /* default: &(context->no_gnu_ext_opt) */
 };
 
-static m4_symbol *symtab_fetch         (m4_symtab*, const char *);
+static m4_symbol *symtab_fetch         (m4_symbol_table*, const char *);
 static void      symbol_popval         (m4_symbol *symbol);
-static void *    symbol_destroy_CB     (m4_symtab *symtab, const char *name,
+static void *    symbol_destroy_CB     (m4_symbol_table *symtab, const char 
*name,
                                         m4_symbol *symbol, void *ignored);
 static void *    arg_destroy_CB        (m4_hash *hash, const void *name,
                                         void *arg, void *ignored);
@@ -64,10 +64,10 @@ static void *         arg_copy_CB           (m4_hash *s
 
    These functions are used to manage a symbol table as a whole.  */
 
-m4_symtab *
+m4_symbol_table *
 m4_symtab_create (size_t size, boolean *nuke_trace_bit)
 {
-  m4_symtab *symtab = XMALLOC (m4_symtab, 1);
+  m4_symbol_table *symtab = XMALLOC (m4_symbol_table, 1);
 
   symtab->table = m4_hash_new (size ? size : M4_SYMTAB_DEFAULT_SIZE,
                               m4_hash_string_hash, m4_hash_string_cmp);
@@ -76,7 +76,7 @@ m4_symtab_create (size_t size, boolean *
 }
 
 void
-m4_symtab_delete (m4_symtab *symtab)
+m4_symtab_delete (m4_symbol_table *symtab)
 {
   assert (symtab);
   assert (symtab->table);
@@ -87,7 +87,8 @@ m4_symtab_delete (m4_symtab *symtab)
 }
 
 void *
-m4_symtab_apply (m4_symtab *symtab, m4_symtab_apply_func *func, void *userdata)
+m4_symtab_apply (m4_symbol_table *symtab,
+                m4_symtab_apply_func *func, void *userdata)
 {
   m4_hash_iterator *place  = NULL;
   void *           result = NULL;
@@ -111,7 +112,7 @@ m4_symtab_apply (m4_symtab *symtab, m4_s
 }
 
 static m4_symbol *
-symtab_fetch (m4_symtab *symtab, const char *name)
+symtab_fetch (m4_symbol_table *symtab, const char *name)
 {
   m4_symbol **psymbol;
   m4_symbol *symbol;
@@ -136,7 +137,7 @@ symtab_fetch (m4_symtab *symtab, const c
 /* Remove every symbol that references the given module handle from
    the symbol table.  */
 void
-m4__symtab_remove_module_references (m4_symtab *symtab, lt_dlhandle handle)
+m4__symtab_remove_module_references (m4_symbol_table *symtab, lt_dlhandle 
handle)
 {
   m4_hash_iterator *place = 0;
 
@@ -181,7 +182,7 @@ m4__symtab_remove_module_references (m4_
    on every symbol so that m4_symbol_popdef() doesn't try to preserve
    the table entry.  */
 static void *
-symbol_destroy_CB (m4_symtab *symtab, const char *name, m4_symbol *symbol,
+symbol_destroy_CB (m4_symbol_table *symtab, const char *name, m4_symbol 
*symbol,
                   void *ignored)
 {
   char *key = xstrdup ((char *) name);
@@ -205,7 +206,7 @@ symbol_destroy_CB (m4_symtab *symtab, co
 
 /* Return the symbol associated to NAME, or else NULL.  */
 m4_symbol *
-m4_symbol_lookup (m4_symtab *symtab, const char *name)
+m4_symbol_lookup (m4_symbol_table *symtab, const char *name)
 {
   m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, name);
 
@@ -219,7 +220,7 @@ m4_symbol_lookup (m4_symtab *symtab, con
    associated with NAME, push the new VALUE on top of the value stack
    for this symbol.  Otherwise create a new association.  */
 m4_symbol *
-m4_symbol_pushdef (m4_symtab *symtab, const char *name, m4_symbol_value *value)
+m4_symbol_pushdef (m4_symbol_table *symtab, const char *name, m4_symbol_value 
*value)
 {
   m4_symbol *symbol;
 
@@ -239,7 +240,8 @@ m4_symbol_pushdef (m4_symtab *symtab, co
 /* Return the symbol associated with NAME in the symbol table, creating
    a new symbol if necessary.  In either case set the symbol's VALUE.  */
 m4_symbol *
-m4_symbol_define (m4_symtab *symtab, const char *name, m4_symbol_value *value)
+m4_symbol_define (m4_symbol_table *symtab,
+                 const char *name, m4_symbol_value *value)
 {
   m4_symbol *symbol;
 
@@ -263,7 +265,7 @@ m4_symbol_define (m4_symtab *symtab, con
    NAME, deleting it from the table entirely if that was the last
    remaining value in the stack.  */
 void
-m4_symbol_popdef (m4_symtab *symtab, const char *name)
+m4_symbol_popdef (m4_symbol_table *symtab, const char *name)
 {
   m4_symbol **psymbol = (m4_symbol **) m4_hash_lookup (symtab->table, name);
 
@@ -367,7 +369,7 @@ arg_copy_CB (m4_hash *src, const void *n
 }
 
 boolean
-m4_set_symbol_name_traced (m4_symtab *symtab, const char *name)
+m4_set_symbol_name_traced (m4_symbol_table *symtab, const char *name)
 {
   m4_symbol *symbol;
 
@@ -386,7 +388,7 @@ m4_set_symbol_name_traced (m4_symtab *sy
 /* Pop all values from the symbol associated with NAME.  */
 #undef m4_symbol_delete
 void
-m4_symbol_delete (m4_symtab *symtab, const char *name)
+m4_symbol_delete (m4_symbol_table *symtab, const char *name)
 {
   while (m4_symbol_lookup (symtab, name))
     m4_symbol_popdef (symtab, name);
@@ -481,16 +483,16 @@ m4_set_symbol_value_func (m4_symbol_valu
 
 #ifdef DEBUG_SYM
 
-static void *symtab_dump       (m4_symtab *symtab);
-static void  dump_symbol_CB    (m4_symtab *symtab, const char *name,
+static void *symtab_dump       (m4_symbol_table *symtab);
+static void  dump_symbol_CB    (m4_symbol_table *symtab, const char *name,
                                 m4_symbol *symbol, void *userdata);
 static void *
-symtab_dump (m4_symtab *symtab)
+symtab_dump (m4_symbol_table *symtab)
 {
   return symtab_apply (symtab, dump_symbol_CB, NULL);
 }
 
-static void *dump_symbol_CB (m4_symtab *symtab, const char *name,
+static void *dump_symbol_CB (m4_symbol_table *symtab, const char *name,
                             m4_symbol *symbol, void *ignored)
 {
   m4_symbol_value *value       = m4_get_symbol_value (symbol);
Index: m4/syntax.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/syntax.c,v
retrieving revision 1.3
diff -u -p -u -r1.3 syntax.c
--- m4/syntax.c 20 Jun 2003 15:43:20 -0000 1.3
+++ m4/syntax.c 26 Jun 2003 14:56:58 -0000
@@ -91,56 +91,69 @@
    that a string is parsed equally whether there is a $ or not.  The
    character $ is used by convention in user macros.  */
 
-static void  check_use_macro_escape    (void);
-static void  set_syntax_internal       (int code, int ch);
-static void  unset_syntax_attribute    (int code, int ch);
+static boolean check_is_macro_escaped (m4_syntax_table *syntax);
+static int add_syntax_attribute           (m4_syntax_table *syntax, int ch, 
int code);
+static int remove_syntax_attribute (m4_syntax_table *syntax, int ch, int code);
 
-/* TRUE iff strlen(rquote) == strlen(lquote) == 1 */
-boolean m4__single_quotes;
-
-/* TRUE iff strlen(bcomm) == strlen(ecomm) == 1 */
-boolean m4__single_comments;
-
-/* TRUE iff some character has M4_SYNTAX_ESCAPE */
-boolean m4__use_macro_escape;
-
-void
-m4_syntax_init (void)
+m4_syntax_table *
+m4_syntax_create (void)
 {
+  m4_syntax_table *syntax = XCALLOC (m4_syntax_table, 1);
   int ch;
 
   for (ch = 256; --ch > 0;)
     {
       if (ch == '(')
-       set_syntax_internal (M4_SYNTAX_OPEN, ch);
+       add_syntax_attribute (syntax, ch, M4_SYNTAX_OPEN);
       else if (ch == ')')
-       set_syntax_internal (M4_SYNTAX_CLOSE, ch);
+       add_syntax_attribute (syntax, ch, M4_SYNTAX_CLOSE);
       else if (ch == ',')
-       set_syntax_internal (M4_SYNTAX_COMMA, ch);
+       add_syntax_attribute (syntax, ch, M4_SYNTAX_COMMA);
       else if (ch == '=')
-       set_syntax_internal (M4_SYNTAX_ASSIGN, ch);
+       add_syntax_attribute (syntax, ch, M4_SYNTAX_ASSIGN);
       else if (isspace (ch))
-       set_syntax_internal (M4_SYNTAX_SPACE, ch);
+       add_syntax_attribute (syntax, ch, M4_SYNTAX_SPACE);
       else if (isalpha (ch) || ch == '_')
-       set_syntax_internal (M4_SYNTAX_ALPHA, ch);
+       add_syntax_attribute (syntax, ch, M4_SYNTAX_ALPHA);
       else if (isdigit (ch))
-       set_syntax_internal (M4_SYNTAX_NUM, ch);
+       add_syntax_attribute (syntax, ch, M4_SYNTAX_NUM);
       else
-       set_syntax_internal (M4_SYNTAX_OTHER, ch);
+       add_syntax_attribute (syntax, ch, M4_SYNTAX_OTHER);
     }
-  /* set_syntax_internal(M4_SYNTAX_IGNORE, 0); */
+  /* add_syntax_attribute(syntax, 0, M4_SYNTAX_IGNORE); */
 
   /* Default quotes and comment delimiters are always one char */
-  set_syntax_internal (M4_SYNTAX_LQUOTE, lquote.string[0]);
-  set_syntax_internal (M4_SYNTAX_RQUOTE, rquote.string[0]);
-  set_syntax_internal (M4_SYNTAX_BCOMM, bcomm.string[0]);
-  set_syntax_internal (M4_SYNTAX_ECOMM, ecomm.string[0]);
+  syntax->lquote.string                = xstrdup (DEF_LQUOTE);
+  syntax->lquote.length                = strlen (syntax->lquote.string);
+  syntax->rquote.string                = xstrdup (DEF_RQUOTE);
+  syntax->rquote.length                = strlen (syntax->rquote.string);
+  syntax->bcomm.string         = xstrdup (DEF_BCOMM);
+  syntax->bcomm.length         = strlen (syntax->bcomm.string);
+  syntax->ecomm.string         = xstrdup (DEF_ECOMM);
+  syntax->ecomm.length         = strlen (syntax->ecomm.string);
+
+  syntax->is_single_quotes     = TRUE;
+  syntax->is_single_comments   = TRUE;
+  syntax->is_macro_escaped     = FALSE;
+
+  add_syntax_attribute (syntax, syntax->lquote.string[0], M4_SYNTAX_LQUOTE);
+  add_syntax_attribute (syntax, syntax->rquote.string[0], M4_SYNTAX_RQUOTE);
+  add_syntax_attribute (syntax, syntax->bcomm.string[0], M4_SYNTAX_BCOMM);
+  add_syntax_attribute (syntax, syntax->ecomm.string[0], M4_SYNTAX_ECOMM);
+
+  return syntax;
 }
 
 void
-m4_syntax_exit (void)
+m4_syntax_delete (m4_syntax_table *syntax)
 {
-  return;
+  assert (syntax);
+
+  XFREE (syntax->lquote.string);
+  XFREE (syntax->rquote.string);
+  XFREE (syntax->bcomm.string);
+  XFREE (syntax->ecomm.string);
+  xfree (syntax);
 }
 
 int
@@ -181,124 +194,194 @@ m4_syntax_code (char ch)
 
 /* Functions for setting quotes and comment delimiters.  Used by
    m4_changecom () and m4_changequote ().  Both functions overrides the
-   syntax_table to maintain compatibility.  */
+   syntax table to maintain compatibility.  */
 void
-m4_set_quotes (const char *lq, const char *rq)
+m4_set_quotes (m4_syntax_table *syntax, const char *lq, const char *rq)
 {
   int ch;
+
+  assert (syntax);
+
   for (ch = 256; --ch >= 0;)   /* changequote overrides syntax_table */
-    if (M4_IS_LQUOTE (ch) || M4_IS_RQUOTE (ch))
-      unset_syntax_attribute (M4_SYNTAX_LQUOTE | M4_SYNTAX_RQUOTE, ch);
+    if (M4_IS_LQUOTE (syntax, ch) || M4_IS_RQUOTE (syntax, ch))
+      remove_syntax_attribute (syntax, ch, M4_SYNTAX_LQUOTE | 
M4_SYNTAX_RQUOTE);
 
-  xfree (lquote.string);
-  xfree (rquote.string);
+  xfree (syntax->lquote.string);
+  xfree (syntax->rquote.string);
 
-  lquote.string = xstrdup (lq ? lq : DEF_LQUOTE);
-  lquote.length = strlen (lquote.string);
-  rquote.string = xstrdup (rq ? rq : DEF_RQUOTE);
-  rquote.length = strlen (rquote.string);
+  syntax->lquote.string = xstrdup (lq ? lq : DEF_LQUOTE);
+  syntax->lquote.length = strlen (syntax->lquote.string);
+  syntax->rquote.string = xstrdup (rq ? rq : DEF_RQUOTE);
+  syntax->rquote.length = strlen (syntax->rquote.string);
 
-  m4__single_quotes = (lquote.length == 1 && rquote.length == 1);
+  syntax->is_single_quotes = (syntax->lquote.length == 1
+                             && syntax->rquote.length == 1);
 
-  if (m4__single_quotes)
+  if (syntax->is_single_quotes)
     {
-      set_syntax_internal (M4_SYNTAX_LQUOTE, lquote.string[0]);
-      set_syntax_internal (M4_SYNTAX_RQUOTE, rquote.string[0]);
+      add_syntax_attribute (syntax, syntax->lquote.string[0], 
M4_SYNTAX_LQUOTE);
+      add_syntax_attribute (syntax, syntax->rquote.string[0], 
M4_SYNTAX_RQUOTE);
     }
 
-  if (m4__use_macro_escape)
-    check_use_macro_escape ();
+  if (syntax->is_macro_escaped)
+    check_is_macro_escaped (syntax);
+}
+
+const char *
+m4_get_syntax_lquote (m4_syntax_table *syntax)
+{
+  assert (syntax);
+  return syntax->lquote.string;
+}
+
+const char *
+m4_get_syntax_rquote (m4_syntax_table *syntax)
+{
+  assert (syntax);
+  return syntax->rquote.string;
 }
 
 void
-m4_set_comment (const char *bc, const char *ec)
+m4_set_comment (m4_syntax_table *syntax, const char *bc, const char *ec)
 {
   int ch;
+
+  assert (syntax);
+
   for (ch = 256; --ch >= 0;)   /* changecom overrides syntax_table */
-    if (M4_IS_BCOMM (ch) || M4_IS_ECOMM (ch))
-      unset_syntax_attribute (M4_SYNTAX_BCOMM | M4_SYNTAX_ECOMM, ch);
+    if (M4_IS_BCOMM (syntax, ch) || M4_IS_ECOMM (syntax, ch))
+      remove_syntax_attribute (syntax, ch, M4_SYNTAX_BCOMM | M4_SYNTAX_ECOMM);
 
-  xfree (bcomm.string);
-  xfree (ecomm.string);
+  xfree (syntax->bcomm.string);
+  xfree (syntax->ecomm.string);
 
-  bcomm.string = xstrdup (bc ? bc : DEF_BCOMM);
-  bcomm.length = strlen (bcomm.string);
-  ecomm.string = xstrdup (ec ? ec : DEF_ECOMM);
-  ecomm.length = strlen (ecomm.string);
+  syntax->bcomm.string = xstrdup (bc ? bc : DEF_BCOMM);
+  syntax->bcomm.length = strlen (syntax->bcomm.string);
+  syntax->ecomm.string = xstrdup (ec ? ec : DEF_ECOMM);
+  syntax->ecomm.length = strlen (syntax->ecomm.string);
 
-  m4__single_comments = (bcomm.length == 1 && ecomm.length == 1);
+  syntax->is_single_comments = (syntax->bcomm.length == 1
+                               && syntax->ecomm.length == 1);
 
-  if (m4__single_comments)
+  if (syntax->is_single_comments)
     {
-      set_syntax_internal (M4_SYNTAX_BCOMM, bcomm.string[0]);
-      set_syntax_internal (M4_SYNTAX_ECOMM, ecomm.string[0]);
+      add_syntax_attribute (syntax, syntax->bcomm.string[0], M4_SYNTAX_BCOMM);
+      add_syntax_attribute (syntax, syntax->ecomm.string[0], M4_SYNTAX_ECOMM);
     }
 
-  if (m4__use_macro_escape)
-    check_use_macro_escape ();
+  if (syntax->is_macro_escaped)
+    check_is_macro_escaped (syntax);
 }
 
+const char *
+m4_get_syntax_bcomm (m4_syntax_table *syntax)
+{
+  assert (syntax);
+  return syntax->bcomm.string;
+}
+
+const char *
+m4_get_syntax_ecomm (m4_syntax_table *syntax)
+{
+  assert (syntax);
+  return syntax->ecomm.string;
+}
+
+boolean
+m4_is_syntax_single_quotes (m4_syntax_table *syntax)
+{
+  assert (syntax);
+  return syntax->is_single_quotes;
+}
+
+boolean
+m4_is_syntax_single_comments (m4_syntax_table *syntax)
+{
+  assert (syntax);
+  return syntax->is_single_comments;
+}
+
+boolean
+m4_is_syntax_macro_escaped (m4_syntax_table *syntax)
+{
+  assert (syntax);
+  return syntax->is_macro_escaped;
+}
+
+
+
 /* Functions to manipulate the syntax table.  */
-static void
-set_syntax_internal (int code, int ch)
+static int
+add_syntax_attribute (m4_syntax_table *syntax, int ch, int code)
 {
   if (code & M4_SYNTAX_MASKS)
-    m4_syntax_table[ch] |= code;
+    syntax->table[ch] |= code;
   else
-    m4_syntax_table[ch] = code;
+    syntax->table[ch] = code;
 
 #ifdef DEBUG_SYNTAX
   fprintf(stderr, "Set syntax %o %c = %04X\n",
          ch, isprint(ch) ? ch : '-',
-         m4_syntax_table[ch]);
+         syntax->table[ch]);
 #endif
+
+  return syntax->table[ch];
 }
 
-static void
-unset_syntax_attribute (int code, int ch)
+static int
+remove_syntax_attribute (m4_syntax_table *syntax, int ch, int code)
 {
   if (code & M4_SYNTAX_MASKS)
-    m4_syntax_table[ch] &= ~code;
+    syntax->table[ch] &= ~code;
 
 #ifdef DEBUG_SYNTAX
   fprintf(stderr, "Unset syntax %o %c = %04X\n",
          ch, isprint(ch) ? ch : '-',
-         m4_syntax_table[ch]);
+         syntax->table[ch]);
 #endif
+
+  return syntax->table[ch];
 }
 
-void
-m4_set_syntax (m4 *context, char key, const unsigned char *chars)
+int
+m4_set_syntax (m4_syntax_table *syntax, char key, const unsigned char *chars)
 {
   int ch, code;
 
+  assert (syntax);
+
   code = m4_syntax_code (key);
 
   if ((code < 0) && (key != '\0'))
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("Undefined syntax code %c"), key));
-      return;
+      return -1;
     }
 
   if (*chars != '\0')
     while ((ch = *chars++))
-      set_syntax_internal (code, ch);
+      add_syntax_attribute (syntax, ch, code);
   else
     for (ch = 256; --ch > 0; )
-      set_syntax_internal (code, ch);
+      add_syntax_attribute (syntax, ch, code);
+
+  if (syntax->is_macro_escaped || code == M4_SYNTAX_ESCAPE)
+    check_is_macro_escaped (syntax);
 
-  if (m4__use_macro_escape || code == M4_SYNTAX_ESCAPE)
-    check_use_macro_escape();
+  return code;
 }
 
-static void
-check_use_macro_escape (void)
+static boolean
+check_is_macro_escaped (m4_syntax_table *syntax)
 {
   int ch;
 
-  m4__use_macro_escape = FALSE;
+  syntax->is_macro_escaped = FALSE;
   for (ch = 256; --ch >= 0; )
-    if (M4_IS_ESCAPE (ch))
-      m4__use_macro_escape = TRUE;
+    if (M4_IS_ESCAPE (syntax, ch))
+      {
+       syntax->is_macro_escaped = TRUE;
+       break;
+      }
+
+  return syntax->is_macro_escaped;
 }
Index: m4/utility.c
===================================================================
RCS file: /cvsroot/m4/m4/m4/utility.c,v
retrieving revision 1.28
diff -u -p -u -r1.28 utility.c
--- m4/utility.c 20 Jun 2003 15:43:20 -0000 1.28
+++ m4/utility.c 26 Jun 2003 14:56:58 -0000
@@ -29,17 +29,6 @@ static int dumpdef_cmp (const void *s1, 
 /* Exit code from last "syscmd" command.  */
 int m4_sysval = 0;
 
-/* input syntax table. */
-unsigned short m4_syntax_table[256];
-
-/* Quote chars.  */
-m4_string rquote;
-m4_string lquote;
-
-/* Comment chars.  */
-m4_string bcomm;
-m4_string ecomm;
-
 
 /* Give friendly warnings if a builtin macro is passed an
    inappropriate number of arguments.  ARGC/ARGV are the arguments,
@@ -70,9 +59,9 @@ m4_bad_argc (m4 *context, int argc, m4_s
 }
 
 const char *
-m4_skip_space (const char *arg)
+m4_skip_space (m4 *context, const char *arg)
 {
-  while (M4_IS_SPACE(*arg))
+  while (M4_IS_SPACE (M4SYNTAX, *arg))
     arg++;
   return arg;
 }
@@ -87,8 +76,8 @@ m4_numeric_arg (m4 *context, int argc, m
   char *endp;
 
   if (*M4ARG (arg) == 0
-      || (*valuep = strtol (m4_skip_space (M4ARG (arg)), &endp, 10),
-         *m4_skip_space (endp) != 0))
+      || (*valuep = strtol (m4_skip_space (context, M4ARG (arg)), &endp, 10),
+         *m4_skip_space (context, endp) != 0))
     {
       M4WARN ((m4_get_warning_status_opt (context), 0,
               _("Warning: %s: argument %d non-numeric: %s"),
@@ -102,8 +91,8 @@ m4_numeric_arg (m4 *context, int argc, m
 /* Print ARGC arguments from the table ARGV to obstack OBS, separated by
    SEP, and quoted by the current quotes, if QUOTED is TRUE.  */
 void
-m4_dump_args (struct obstack *obs, int argc, m4_symbol_value **argv,
-             const char *sep, boolean quoted)
+m4_dump_args (m4 *context, struct obstack *obs, int argc,
+             m4_symbol_value **argv, const char *sep, boolean quoted)
 {
   int i;
   size_t len = strlen (sep);
@@ -113,7 +102,7 @@ m4_dump_args (struct obstack *obs, int a
       if (i > 1)
        obstack_grow (obs, sep, len);
 
-      m4_shipout_string (obs, M4ARG (i), 0, quoted);
+      m4_shipout_string (context, obs, M4ARG (i), 0, quoted);
     }
 }
 
@@ -169,7 +158,7 @@ dumpdef_cmp (const void *s1, const void 
 /* The function dump_symbol () is for use by "dumpdef".  It builds up a
    table of all defined symbol names.  */
 void *
-m4_dump_symbol_CB (m4_symtab *ignored, const char *name, m4_symbol *symbol,
+m4_dump_symbol_CB (m4_symbol_table *ignored, const char *name, m4_symbol 
*symbol,
                   void *userdata)
 {
   assert (name);
Index: modules/gnu.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/gnu.c,v
retrieving revision 1.23
diff -u -p -u -r1.23 gnu.c
--- modules/gnu.c 20 Jun 2003 15:43:20 -0000 1.23
+++ modules/gnu.c 26 Jun 2003 14:56:58 -0000
@@ -172,7 +172,7 @@ M4BUILTIN_HANDLER (indir)
 
 /* Change the current input syntax.  The function set_syntax () lives
    in input.c.  For compability reasons, this function is not called,
-   if not followed by an SYNTAX_OPEN.  Also, any changes to comment
+   if not followed by a` SYNTAX_OPEN.  Also, any changes to comment
    delimiters and quotes made here will be overridden by a call to
    `changecom' or `changequote'.  */
 
@@ -185,8 +185,14 @@ M4BUILTIN_HANDLER (changesyntax)
 
   for (i = 1; i < argc; i++)
     {
-      m4_set_syntax (context, *M4ARG (i),
-                    m4_expand_ranges (M4ARG (i)+1, obs));
+      char key = *M4ARG (i);
+      if ((m4_set_syntax (M4SYNTAX, key,
+                         m4_expand_ranges (M4ARG (i)+1, obs)) < 0)
+         && (key != '\0'))
+       {
+         M4ERROR ((m4_get_warning_status_opt (context), 0,
+                   _("Undefined syntax code %c"), key));
+       }
     }
 }
 
@@ -463,7 +469,7 @@ M4BUILTIN_HANDLER (symbols)
 
   for (; data.size > 0; --data.size, data.base++)
     {
-      m4_shipout_string (obs, data.base[0], 0, TRUE);
+      m4_shipout_string (context, obs, data.base[0], 0, TRUE);
       if (data.size > 1)
        obstack_1grow (obs, ',');
     }
@@ -536,7 +542,7 @@ M4BUILTIN_HANDLER (format)
  **/
 M4BUILTIN_HANDLER (__file__)
 {
-  m4_shipout_string (obs, m4_current_file, 0, TRUE);
+  m4_shipout_string (context, obs, m4_current_file, 0, TRUE);
 }
 
 
Index: modules/load.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/load.c,v
retrieving revision 1.11
diff -u -p -u -r1.11 load.c
--- modules/load.c 20 Jun 2003 15:43:20 -0000 1.11
+++ modules/load.c 26 Jun 2003 14:56:58 -0000
@@ -98,7 +98,7 @@ M4BUILTIN_HANDLER (modules)
   if (handle)
     do
       {
-       m4_shipout_string (obs, m4_get_module_name (handle), 0, TRUE);
+       m4_shipout_string (context, obs, m4_get_module_name (handle), 0, TRUE);
 
        if ((handle = lt_dlhandle_next (handle)))
          obstack_1grow (obs, ',');
Index: modules/m4.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/m4.c,v
retrieving revision 1.44
diff -u -p -u -r1.44 m4.c
--- modules/m4.c 20 Jun 2003 15:43:20 -0000 1.44
+++ modules/m4.c 26 Jun 2003 14:56:58 -0000
@@ -98,7 +98,7 @@ typedef unsigned long int unumber;
 
 static void    include         (m4 *context, int argc, m4_symbol_value **argv,
                                 boolean silent);
-static void *  set_trace_CB    (m4_symtab *symtab, const char *ignored,
+static void *  set_trace_CB    (m4_symbol_table *symtab, const char *ignored,
                                 m4_symbol *symbol, void *userdata);
 static const char *ntoa                (number value, int radix);
 static void    numb_obstack    (struct obstack *obs, const number value,
@@ -286,8 +286,9 @@ M4BUILTIN_HANDLER (dumpdef)
        {
          if (m4_get_debug_level_opt (context) & M4_DEBUG_TRACE_QUOTE)
            fprintf (stderr, "%s%s%s\n",
-                    lquote.string, m4_get_symbol_text (symbol),
-                    rquote.string);
+                    m4_get_syntax_lquote (M4SYNTAX),
+                    m4_get_symbol_text (symbol),
+                    m4_get_syntax_rquote (M4SYNTAX));
          else
            fprintf (stderr, "%s\n", m4_get_symbol_text (symbol));
        }
@@ -321,7 +322,7 @@ M4BUILTIN_HANDLER (defn)
     }
 
   if (m4_is_symbol_text (symbol))
-    m4_shipout_string (obs, m4_get_symbol_text (symbol), 0, TRUE);
+    m4_shipout_string (context, obs, m4_get_symbol_text (symbol), 0, TRUE);
   else if (m4_is_symbol_func (symbol))
     m4_push_builtin (m4_get_symbol_value (symbol));
   else
@@ -434,13 +435,14 @@ M4BUILTIN_HANDLER (dnl)
    output argument is quoted with the current quotes.  */
 M4BUILTIN_HANDLER (shift)
 {
-  m4_dump_args (obs, argc - 1, argv + 1, ",", TRUE);
+  m4_dump_args (context, obs, argc - 1, argv + 1, ",", TRUE);
 }
 
 /* Change the current quotes.  The function set_quotes () lives in input.c.  */
 M4BUILTIN_HANDLER (changequote)
 {
-  m4_set_quotes ((argc >= 2) ? M4ARG (1) : NULL,
+  m4_set_quotes (M4SYNTAX,
+                (argc >= 2) ? M4ARG (1) : NULL,
                 (argc >= 3) ? M4ARG (2) : NULL);
 }
 
@@ -449,9 +451,9 @@ M4BUILTIN_HANDLER (changequote)
 M4BUILTIN_HANDLER (changecom)
 {
   if (argc == 1)
-    m4_set_comment ("", "");   /* disable comments */
+    m4_set_comment (M4SYNTAX, "", ""); /* disable comments */
   else
-    m4_set_comment (M4ARG (1), (argc >= 3) ? M4ARG (2) : NULL);
+    m4_set_comment (M4SYNTAX, M4ARG (1), (argc >= 3) ? M4ARG (2) : NULL);
 }
 
 
@@ -499,13 +501,13 @@ M4BUILTIN_HANDLER (sinclude)
 M4BUILTIN_HANDLER (maketemp)
 {
   mktemp (M4ARG (1));
-  m4_shipout_string (obs, M4ARG (1), 0, FALSE);
+  m4_shipout_string (context, obs, M4ARG (1), 0, FALSE);
 }
 
 /* Print all arguments on standard error.  */
 M4BUILTIN_HANDLER (errprint)
 {
-  m4_dump_args (obs, argc, argv, " ", FALSE);
+  m4_dump_args (context, obs, argc, argv, " ", FALSE);
   obstack_1grow (obs, '\0');
   fputs ((char *) obstack_finish (obs), stderr);
   fflush (stderr);
@@ -537,9 +539,9 @@ M4BUILTIN_HANDLER (m4exit)
 M4BUILTIN_HANDLER (m4wrap)
 {
   if (m4_get_no_gnu_extensions_opt (context))
-    m4_shipout_string (obs, M4ARG (1), 0, FALSE);
+    m4_shipout_string (context, obs, M4ARG (1), 0, FALSE);
   else
-    m4_dump_args (obs, argc, argv, " ", FALSE);
+    m4_dump_args (context, obs, argc, argv, " ", FALSE);
   obstack_1grow (obs, '\0');
   m4_push_wrapup (obstack_finish (obs));
 }
@@ -552,7 +554,7 @@ M4BUILTIN_HANDLER (m4wrap)
    tracing of a macro.  It disables tracing if DATA is NULL, otherwise it
    enable tracing.  */
 static void *
-set_trace_CB (m4_symtab *hash, const char *ignored, m4_symbol *symbol,
+set_trace_CB (m4_symbol_table *hash, const char *ignored, m4_symbol *symbol,
           void *userdata)
 {
   m4_set_symbol_traced (symbol, (boolean) (userdata != NULL));
Index: modules/perl.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/perl.c,v
retrieving revision 1.9
diff -u -p -u -r1.9 perl.c
--- modules/perl.c 4 Nov 2002 16:31:04 -0000 1.9
+++ modules/perl.c 26 Jun 2003 14:56:58 -0000
@@ -113,6 +113,6 @@ M4BUILTIN_HANDLER (perleval)
 
       val = perl_eval_pv(M4ARG(i), TRUE);
 
-      m4_shipout_string(obs, SvPV(val,PL_na), 0, FALSE);
+      m4_shipout_string(context, obs, SvPV(val,PL_na), 0, FALSE);
     }
 }
Index: modules/stdlib.c
===================================================================
RCS file: /cvsroot/m4/m4/modules/stdlib.c,v
retrieving revision 1.9
diff -u -p -u -r1.9 stdlib.c
--- modules/stdlib.c 20 Jun 2003 15:43:20 -0000 1.9
+++ modules/stdlib.c 26 Jun 2003 14:56:58 -0000
@@ -80,7 +80,7 @@ M4BUILTIN_HANDLER (getcwd)
   bp = getcwd (buf, sizeof buf);
 
   if (bp != NULL)              /* in case of error return null string */
-    m4_shipout_string (obs, buf, 0, FALSE);
+    m4_shipout_string (context, obs, buf, 0, FALSE);
 }
 
 /**
@@ -93,7 +93,7 @@ M4BUILTIN_HANDLER (getenv)
   env = getenv (M4ARG (1));
 
   if (env != NULL)
-    m4_shipout_string (obs, env, 0, FALSE);
+    m4_shipout_string (context, obs, env, 0, FALSE);
 }
 
 /**
@@ -148,7 +148,7 @@ M4BUILTIN_HANDLER (getlogin)
   login = getlogin ();
 
   if (login != NULL)
-    m4_shipout_string (obs, login, 0, FALSE);
+    m4_shipout_string (context, obs, login, 0, FALSE);
 }
 
 /**
@@ -178,19 +178,19 @@ M4BUILTIN_HANDLER (getpwnam)
 
   if (pw != NULL)
     {
-      m4_shipout_string (obs, pw->pw_name, 0, TRUE);
+      m4_shipout_string (context, obs, pw->pw_name, 0, TRUE);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, pw->pw_passwd, 0, TRUE);
+      m4_shipout_string (context, obs, pw->pw_passwd, 0, TRUE);
       obstack_1grow (obs, ',');
       m4_shipout_int (obs, pw->pw_uid);
       obstack_1grow (obs, ',');
       m4_shipout_int (obs, pw->pw_gid);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, pw->pw_gecos, 0, TRUE);
+      m4_shipout_string (context, obs, pw->pw_gecos, 0, TRUE);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, pw->pw_dir, 0, TRUE);
+      m4_shipout_string (context, obs, pw->pw_dir, 0, TRUE);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, pw->pw_shell, 0, TRUE);
+      m4_shipout_string (context, obs, pw->pw_shell, 0, TRUE);
     }
 }
 
@@ -209,19 +209,19 @@ M4BUILTIN_HANDLER (getpwuid)
 
   if (pw != NULL)
     {
-      m4_shipout_string (obs, pw->pw_name, 0, TRUE);
+      m4_shipout_string (context, obs, pw->pw_name, 0, TRUE);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, pw->pw_passwd, 0, TRUE);
+      m4_shipout_string (context, obs, pw->pw_passwd, 0, TRUE);
       obstack_1grow (obs, ',');
       m4_shipout_int (obs, pw->pw_uid);
       obstack_1grow (obs, ',');
       m4_shipout_int (obs, pw->pw_gid);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, pw->pw_gecos, 0, TRUE);
+      m4_shipout_string (context, obs, pw->pw_gecos, 0, TRUE);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, pw->pw_dir, 0, TRUE);
+      m4_shipout_string (context, obs, pw->pw_dir, 0, TRUE);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, pw->pw_shell, 0, TRUE);
+      m4_shipout_string (context, obs, pw->pw_shell, 0, TRUE);
     }
 }
 
@@ -235,7 +235,7 @@ M4BUILTIN_HANDLER (hostname)
   if (gethostname (buf, sizeof buf) < 0)
     return;
 
-  m4_shipout_string (obs, buf, 0, FALSE);
+  m4_shipout_string (context, obs, buf, 0, FALSE);
 }
 
 /**
@@ -273,15 +273,15 @@ M4BUILTIN_HANDLER (uname)
 
   if (uname (&ut) == 0)
     {
-      m4_shipout_string (obs, ut.sysname, 0, TRUE);
+      m4_shipout_string (context, obs, ut.sysname, 0, TRUE);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, ut.nodename, 0, TRUE);
+      m4_shipout_string (context, obs, ut.nodename, 0, TRUE);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, ut.release, 0, TRUE);
+      m4_shipout_string (context, obs, ut.release, 0, TRUE);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, ut.version, 0, TRUE);
+      m4_shipout_string (context, obs, ut.version, 0, TRUE);
       obstack_1grow (obs, ',');
-      m4_shipout_string (obs, ut.machine, 0, TRUE);
+      m4_shipout_string (context, obs, ut.machine, 0, TRUE);
     }
 }
 
Index: src/freeze.c
===================================================================
RCS file: /cvsroot/m4/m4/src/freeze.c,v
retrieving revision 1.31
diff -u -p -u -r1.31 freeze.c
--- src/freeze.c 20 Jun 2003 15:43:20 -0000 1.31
+++ src/freeze.c 26 Jun 2003 14:56:58 -0000
@@ -26,12 +26,14 @@
 static int   decode_char          (FILE *in);
 static void  issue_expect_message (int expected);
 static int   produce_char_dump    (char *buf, int ch);
-static void  produce_syntax_dump  (FILE *file, char ch, int mask);
+static void  produce_syntax_dump  (FILE *file, m4_syntax_table *syntax,
+                                   char ch, int mask);
 static void  produce_module_dump  (FILE *file, lt_dlhandle handle);
 static void  produce_symbol_dump  (m4 *context, FILE *file,
-                                   m4_symtab *symtab);
-static void *dump_symbol_CB       (m4_symtab *symtab, const char *symbol_name,
-                                   m4_symbol *symbol, void *userdata);
+                                   m4_symbol_table *symtab);
+static void *dump_symbol_CB       (m4_symbol_table *symtab,
+                                   const char *symbol_name, m4_symbol *symbol,
+                                   void *userdata);
 
 
 /* Produce a frozen state to the given file NAME. */
@@ -77,7 +79,7 @@ produce_char_dump (char *buf, int ch)
 #define MAX_CHAR_LENGTH 4      /* '\377' -> 4 characters */
 
 static void
-produce_syntax_dump (FILE *file, char ch, int mask)
+produce_syntax_dump (FILE *file, m4_syntax_table *syntax, char ch, int mask)
 {
   char buf[1+ MAX_CHAR_LENGTH * sizeof (m4_syntax_table)];
   int code = m4_syntax_code (ch);
@@ -86,13 +88,13 @@ produce_syntax_dump (FILE *file, char ch
   int i;
 
   /* FIXME:  Can't set the syntax of '\000' since that character marks
-             the end of a string, and when passed to `set_syntax', tells
+             the end of a string, and when passed to `m4_set_syntax', tells
             it to set the syntax of every table entry. */
 
   for (i = 1; i < 256; ++i)
     {
-      if ((mask && ((m4_syntax_table[i] & mask) == code))
-         || (!mask && ((m4_syntax_table[i] & code) == code)))
+      if ((mask && ((syntax->table[i] & mask) == code))
+         || (!mask && ((syntax->table[i] & code) == code)))
        {
          offset += produce_char_dump (buf + offset, i);
          ++count;
@@ -125,7 +127,7 @@ produce_module_dump (FILE *file, lt_dlha
    This order ensures that, at reload time, pushdef's will be
    executed with the oldest definitions first.  */
 void
-produce_symbol_dump (m4 *context, FILE *file, m4_symtab *symtab)
+produce_symbol_dump (m4 *context, FILE *file, m4_symbol_table *symtab)
 {
   const char *errormsg = m4_symtab_apply (symtab, dump_symbol_CB, file);
 
@@ -137,7 +139,7 @@ produce_symbol_dump (m4 *context, FILE *
 }
 
 static void *
-dump_symbol_CB (m4_symtab *symtab, const char *symbol_name, m4_symbol *symbol,
+dump_symbol_CB (m4_symbol_table *symtab, const char *symbol_name, m4_symbol 
*symbol,
                void *userdata)
 {
   lt_dlhandle   handle         = SYMBOL_HANDLE (symbol);
@@ -208,48 +210,49 @@ produce_frozen_state (m4 *context, const
 
   /* Dump quote delimiters.  */
 
-  if (strcmp (lquote.string, DEF_LQUOTE)
-      || strcmp (rquote.string, DEF_RQUOTE))
+  if (strcmp (m4_get_syntax_lquote (M4SYNTAX), DEF_LQUOTE)
+      || strcmp (m4_get_syntax_rquote (M4SYNTAX), DEF_RQUOTE))
     {
       fprintf (file, "Q%lu,%lu\n",
-              (unsigned long) lquote.length,
-              (unsigned long) rquote.length);
-      fputs (lquote.string, file);
-      fputs (rquote.string, file);
+              (unsigned long) context->syntax->lquote.length,
+              (unsigned long) context->syntax->rquote.length);
+      fputs (context->syntax->lquote.string, file);
+      fputs (context->syntax->rquote.string, file);
       fputc ('\n', file);
     }
 
   /* Dump comment delimiters.  */
 
-  if (strcmp (bcomm.string, DEF_BCOMM) || strcmp (ecomm.string, DEF_ECOMM))
+  if (strcmp (m4_get_syntax_bcomm (M4SYNTAX), DEF_BCOMM)
+      || strcmp (m4_get_syntax_ecomm (M4SYNTAX), DEF_ECOMM))
     {
       fprintf (file, "C%lu,%lu\n",
-              (unsigned long) bcomm.length,
-              (unsigned long) ecomm.length);
-      fputs (bcomm.string, file);
-      fputs (ecomm.string, file);
+              (unsigned long) context->syntax->bcomm.length,
+              (unsigned long) context->syntax->ecomm.length);
+      fputs (context->syntax->bcomm.string, file);
+      fputs (context->syntax->ecomm.string, file);
       fputc ('\n', file);
     }
 
   /* Dump syntax table. */
 
-  produce_syntax_dump (file, 'I', M4_SYNTAX_VALUE);
-  produce_syntax_dump (file, 'S', M4_SYNTAX_VALUE);
-  produce_syntax_dump (file, '(', M4_SYNTAX_VALUE);
-  produce_syntax_dump (file, ')', M4_SYNTAX_VALUE);
-  produce_syntax_dump (file, ',', M4_SYNTAX_VALUE);
-  produce_syntax_dump (file, '$', M4_SYNTAX_VALUE);
-  produce_syntax_dump (file, 'A', M4_SYNTAX_VALUE);
-  produce_syntax_dump (file, '@', M4_SYNTAX_VALUE);
-  produce_syntax_dump (file, 'O', M4_SYNTAX_VALUE);
-
-  produce_syntax_dump (file, 'W', M4_SYNTAX_VALUE);
-  produce_syntax_dump (file, 'D', M4_SYNTAX_VALUE);
-
-  produce_syntax_dump (file, 'L', 0);
-  produce_syntax_dump (file, 'R', 0);
-  produce_syntax_dump (file, 'B', 0);
-  produce_syntax_dump (file, 'E', 0);
+  produce_syntax_dump (file, M4SYNTAX, 'I', M4_SYNTAX_VALUE);
+  produce_syntax_dump (file, M4SYNTAX, 'S', M4_SYNTAX_VALUE);
+  produce_syntax_dump (file, M4SYNTAX, '(', M4_SYNTAX_VALUE);
+  produce_syntax_dump (file, M4SYNTAX, ')', M4_SYNTAX_VALUE);
+  produce_syntax_dump (file, M4SYNTAX, ',', M4_SYNTAX_VALUE);
+  produce_syntax_dump (file, M4SYNTAX, '$', M4_SYNTAX_VALUE);
+  produce_syntax_dump (file, M4SYNTAX, 'A', M4_SYNTAX_VALUE);
+  produce_syntax_dump (file, M4SYNTAX, '@', M4_SYNTAX_VALUE);
+  produce_syntax_dump (file, M4SYNTAX, 'O', M4_SYNTAX_VALUE);
+
+  produce_syntax_dump (file, M4SYNTAX, 'W', M4_SYNTAX_VALUE);
+  produce_syntax_dump (file, M4SYNTAX, 'D', M4_SYNTAX_VALUE);
+
+  produce_syntax_dump (file, M4SYNTAX, 'L', 0);
+  produce_syntax_dump (file, M4SYNTAX, 'R', 0);
+  produce_syntax_dump (file, M4SYNTAX, 'B', 0);
+  produce_syntax_dump (file, M4SYNTAX, 'E', 0);
 
   /* Dump all loaded modules.  */
   produce_module_dump (file, lt_dlhandle_next (0));
@@ -550,7 +553,12 @@ reload_frozen_state (m4 *context, const 
          }
        string[0][number[0]] = '\0';
 
-       m4_set_syntax (context, syntax, string[0]);
+       if ((m4_set_syntax (context->syntax, syntax, string[0]) < 0)
+           && (syntax != '\0'))
+         {
+           M4ERROR ((m4_get_warning_status_opt (context), 0,
+                     _("Undefined syntax code %c"), syntax));
+         }
        break;
 
       case 'C':
@@ -590,7 +598,7 @@ reload_frozen_state (m4 *context, const 
 
            /* Change comment strings.  */
 
-           m4_set_comment (string[0], string[1]);
+           m4_set_comment (M4SYNTAX, string[0], string[1]);
            break;
 
          case 'D':
@@ -606,7 +614,7 @@ reload_frozen_state (m4 *context, const 
 
            /* Change quote strings.  */
 
-           m4_set_quotes (string[0], string[1]);
+           m4_set_quotes (M4SYNTAX, string[0], string[1]);
            break;
 
          default:
Index: src/main.c
===================================================================
RCS file: /cvsroot/m4/m4/src/main.c,v
retrieving revision 1.42
diff -u -p -u -r1.42 main.c
--- src/main.c 20 Jun 2003 15:43:20 -0000 1.42
+++ src/main.c 26 Jun 2003 14:56:58 -0000
@@ -390,11 +390,16 @@ warranty; not even for MERCHANTABILITY o
 
   if (frozen_file_to_read)
     {
+      int ch;
+
+      /* Take care not to mix frozen state with startup state.  */
+      for (ch = 256; --ch > 0;)
+       context->syntax->table[ch] = 0;
+
       reload_frozen_state (context, frozen_file_to_read);
     }
   else
     {
-      m4_syntax_init ();
       m4_module_load (context, "m4", 0);
       if (m4_get_no_gnu_extensions_opt (context))
        m4_module_load (context, "traditional", 0);
@@ -429,7 +434,6 @@ warranty; not even for MERCHANTABILITY o
       {
        macro_definition *next;
        char *macro_value;
-       m4_symbol *symbol;
 
        switch (defines->code)
          {
@@ -533,7 +537,6 @@ warranty; not even for MERCHANTABILITY o
      a whole lot easier!  */
 
   m4__module_exit (context);
-  m4_syntax_exit ();
   m4_output_exit ();
   m4_input_exit ();
   m4_debug_exit ();

reply via email to

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