m4-commit
[Top][All Lists]
Advanced

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

Changes to m4/modules/gnu.c,v


From: Gary V. Vaughan
Subject: Changes to m4/modules/gnu.c,v
Date: Mon, 10 Jul 2006 15:08:22 +0000

CVSROOT:        /sources/m4
Module name:    m4
Changes by:     Gary V. Vaughan <gary>  06/07/10 15:08:21

Index: modules/gnu.c
===================================================================
RCS file: /sources/m4/m4/modules/gnu.c,v
retrieving revision 1.40
retrieving revision 1.41
diff -u -b -r1.40 -r1.41
--- modules/gnu.c       5 Jul 2006 16:56:51 -0000       1.40
+++ modules/gnu.c       10 Jul 2006 15:08:21 -0000      1.41
@@ -41,34 +41,6 @@
 #  include "m4private.h"
 #endif
 
-#define RE_SYNTAX_BRE RE_SYNTAX_EMACS
-
-#define RE_SYNTAX_ERE \
-  (/* Allow char classes. */                                   \
-    RE_CHAR_CLASSES                                            \
-  /* Anchors are OK in groups. */                              \
-  | RE_CONTEXT_INDEP_ANCHORS                                   \
-  /* Be picky, `/^?/', for instance, makes no sense. */                \
-  | RE_CONTEXT_INVALID_OPS                                     \
-  /* Allow intervals with `{' and `}', forbid invalid ranges. */\
-  | RE_INTERVALS | RE_NO_BK_BRACES | RE_NO_EMPTY_RANGES                \
-  /* `(' and `)' are the grouping operators. */                        \
-  | RE_NO_BK_PARENS                                            \
-  /* `|' is the alternation. */                                        \
-  | RE_NO_BK_VBAR)
-
-#include "format.c"
-
-
-/* The regs_allocated field in an re_pattern_buffer refers to the
-   state of the re_registers struct used in successive matches with
-   the same compiled pattern:  */
-typedef struct {
-  struct re_pattern_buffer pat;        /* compiled regular expression */
-  struct re_registers regs;    /* match registers */
-} m4_pattern_buffer;
-
-
 /* Rename exported symbols for dlpreload()ing.  */
 #define m4_builtin_table       gnu_LTX_m4_builtin_table
 #define m4_macro_table         gnu_LTX_m4_macro_table
@@ -131,12 +103,6 @@
   { 0, 0 },
 };
 
-static bool regsub     (m4 *context, m4_obstack *obs, const char *caller,
-                        const char *victim, const char *regexp,
-                        m4_pattern_buffer *buf, const char *replace,
-                        bool ignore_duplicates);
-static void substitute (m4 *context, m4_obstack *obs, const char *victim,
-                        const char *repl, m4_pattern_buffer *buf);
 
 static void m4_regexp_do       (m4 *context, m4_obstack *obs, int argc,
                                 m4_symbol_value **argv, int syntax);
@@ -146,6 +112,204 @@
                                 m4_symbol_value **argv, int syntax);
 
 
+
+#define RE_SYNTAX_BRE RE_SYNTAX_EMACS
+
+#define RE_SYNTAX_ERE \
+  (/* Allow char classes. */                                   \
+    RE_CHAR_CLASSES                                            \
+  /* Anchors are OK in groups. */                              \
+  | RE_CONTEXT_INDEP_ANCHORS                                   \
+  /* Be picky, `/^?/', for instance, makes no sense. */                \
+  | RE_CONTEXT_INVALID_OPS                                     \
+  /* Allow intervals with `{' and `}', forbid invalid ranges. */\
+  | RE_INTERVALS | RE_NO_BK_BRACES | RE_NO_EMPTY_RANGES                \
+  /* `(' and `)' are the grouping operators. */                        \
+  | RE_NO_BK_PARENS                                            \
+  /* `|' is the alternation. */                                        \
+  | RE_NO_BK_VBAR)
+
+/* The regs_allocated field in an re_pattern_buffer refers to the
+   state of the re_registers struct used in successive matches with
+   the same compiled pattern:  */
+typedef struct {
+  struct re_pattern_buffer pat;        /* compiled regular expression */
+  struct re_registers regs;    /* match registers */
+} m4_pattern_buffer;
+
+
+/* Compile a REGEXP using the Regex SYNTAX bits return the buffer.
+   Report errors on behalf of CALLER.  */
+
+static m4_pattern_buffer *
+m4_regexp_compile (m4 *context, const char *caller,
+                  const char *regexp, int syntax)
+{
+  static m4_pattern_buffer buf;        /* compiled regular expression */
+  static bool buf_initialized = false;
+  const char *msg;             /* error message from re_compile_pattern */
+
+  if (!buf_initialized)
+    {
+      buf_initialized  = true;
+      buf.pat.buffer   = NULL;
+      buf.pat.allocated        = 0;
+      buf.pat.fastmap  = NULL;
+      buf.pat.translate        = NULL;
+    }
+
+  re_set_syntax (syntax);
+  msg = re_compile_pattern (regexp, strlen (regexp), &buf.pat);
+
+  if (msg != NULL)
+    {
+      M4ERROR ((m4_get_warning_status_opt (context), 0,
+               _("%s: bad regular expression `%s': %s"),
+               caller, regexp, msg));
+      return NULL;
+    }
+
+  return &buf;
+}
+
+static int
+m4_regexp_search (m4_pattern_buffer *buf, const char *string,
+                 const int size, const int start, const int range)
+{
+  return re_search (&(buf->pat), string, size, start, range, &(buf->regs));
+}
+
+
+/* Function to perform substitution by regular expressions.  Used by the
+   builtins regexp, patsubst and renamesyms.  The changed text is placed on
+   the obstack.  The substitution is REPL, with \& substituted by this part
+   of VICTIM matched by the last whole regular expression, taken from
+   REGS[0], and \N substituted by the text matched by the Nth parenthesized
+   sub-expression, taken from REGS[N].  */
+static int substitute_warned = 0;
+
+static void
+substitute (m4 *context, m4_obstack *obs, const char *victim,
+           const char *repl, m4_pattern_buffer *buf)
+{
+  register unsigned int ch;
+
+  for (;;)
+    {
+      while ((ch = *repl++) != '\\')
+       {
+         if (ch == '\0')
+           return;
+         obstack_1grow (obs, ch);
+       }
+
+      switch ((ch = *repl++))
+       {
+       case '0':
+         if (!substitute_warned)
+           {
+             M4ERROR ((m4_get_warning_status_opt (context), 0, _("\
+WARNING: \\0 will disappear, use \\& instead in replacements")));
+             substitute_warned = 1;
+           }
+         /* Fall through.  */
+
+       case '&':
+         obstack_grow (obs, victim + buf->regs.start[0],
+                       buf->regs.end[0] - buf->regs.start[0]);
+         break;
+
+       case '1': case '2': case '3': case '4': case '5': case '6':
+       case '7': case '8': case '9':
+         ch -= '0';
+         if (buf->regs.end[ch] > 0)
+           obstack_grow (obs, victim + buf->regs.start[ch],
+                         buf->regs.end[ch] - buf->regs.start[ch]);
+         break;
+
+       default:
+         obstack_1grow (obs, ch);
+         break;
+       }
+    }
+}
+
+
+static bool
+regsub (m4 *context, m4_obstack *obs, const char *caller,
+       const char *victim, const char *regexp, m4_pattern_buffer *buf,
+       const char *replace, bool ignore_duplicates)
+{
+  int matchpos = 0;            /* start position of match */
+  int offset   = 0;            /* current match offset */
+  int length   = strlen (victim);
+
+  while (offset < length)
+    {
+      matchpos = m4_regexp_search (buf, victim, length,
+                                  offset, length - offset);
+
+      if (matchpos < 0)
+       {
+
+         /* Match failed -- either error or there is no match in the
+            rest of the string, in which case the rest of the string is
+            copied verbatim.  */
+
+         if (matchpos == -2)
+           M4ERROR ((m4_get_warning_status_opt (context), 0,
+                     _("%s: error matching regular expression `%s'"),
+                     caller, regexp));
+         else if (!ignore_duplicates && (offset < length))
+           obstack_grow (obs, victim + offset, length - offset);
+         break;
+       }
+
+      /* Copy the part of the string that was skipped by re_search ().  */
+
+      if (matchpos > offset)
+       obstack_grow (obs, victim + offset, matchpos - offset);
+
+      /* Handle the part of the string that was covered by the match.  */
+
+      substitute (context, obs, victim, replace, buf);
+
+      /* Update the offset to the end of the match.  If the regexp
+        matched a null string, advance offset one more, to avoid
+        infinite loops.  */
+
+      offset = buf->regs.end[0];
+      if (buf->regs.start[0] == buf->regs.end[0])
+       obstack_1grow (obs, victim[offset++]);
+    }
+
+  if (!ignore_duplicates || (matchpos >= 0))
+    obstack_1grow (obs, '\0');
+
+  return (matchpos >= 0);
+}
+
+
+
+
+/**
+ * __file__
+ **/
+M4BUILTIN_HANDLER (__file__)
+{
+  m4_shipout_string (context, obs, m4_current_file, 0, true);
+}
+
+
+/**
+ * __line__
+ **/
+M4BUILTIN_HANDLER (__line__)
+{
+  m4_shipout_int (obs, m4_current_line);
+}
+
+
 /* The builtin "builtin" allows calls to builtin macros, even if their
    definition has been overridden or shadowed.  It is thus possible to
    redefine builtins, and still access their original definition.  */
@@ -168,26 +332,6 @@
 }
 
 
-/* The builtin "indir" allows indirect calls to macros, even if their name
-   is not a proper macro name.  It is thus possible to define macros with
-   ill-formed names for internal use in larger macro packages.  This macro
-   is not available in compatibility mode.  */
-
-/**
- * indir(MACRO, [...])
- **/
-M4BUILTIN_HANDLER (indir)
-{
-  const char * name   = M4ARG (1);
-  m4_symbol *  symbol = m4_symbol_lookup (M4SYMTAB, name);
-
-  if (symbol == NULL)
-    M4ERROR ((m4_get_warning_status_opt (context), 0,
-             _("Undefined name `%s'"), name));
-  else
-    m4_macro_call (context, symbol, obs, argc - 1, argv + 1);
-}
-
 /* 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 a` SYNTAX_OPEN.  Also, any changes to comment
@@ -218,6 +362,23 @@
     }
 }
 
+
+/* Specify the destination of the debugging output.  With one argument, the
+   argument is taken as a file name, with no arguments, revert to stderr.  */
+
+/**
+ * debugfile([FILENAME])
+ **/
+M4BUILTIN_HANDLER (debugfile)
+{
+  if (argc == 1)
+    m4_debug_set_output (context, NULL);
+  else if (!m4_debug_set_output (context, M4ARG (1)))
+    M4ERROR ((m4_get_warning_status_opt (context), errno,
+             _("Cannot set error file: %s"), M4ARG (1)));
+}
+
+
 /* On-the-fly control of the format of the tracing output.  It takes one
    argument, which is a character string like given to the -d option, or
    none in which case the debug_level is zeroed.  */
@@ -269,213 +430,102 @@
     }
 }
 
-/* Specify the destination of the debugging output.  With one argument, the
-   argument is taken as a file name, with no arguments, revert to stderr.  */
 
 /**
- * debugfile([FILENAME])
+ * esyscmd(SHELL-COMMAND)
  **/
-M4BUILTIN_HANDLER (debugfile)
-{
-  if (argc == 1)
-    m4_debug_set_output (context, NULL);
-  else if (!m4_debug_set_output (context, M4ARG (1)))
-    M4ERROR ((m4_get_warning_status_opt (context), errno,
-             _("Cannot set error file: %s"), M4ARG (1)));
-}
-
 
-/* Compile a REGEXP using the Regex SYNTAX bits return the buffer.
-   Report errors on behalf of CALLER.  */
-
-static m4_pattern_buffer *
-m4_regexp_compile (m4 *context, const char *caller,
-                  const char *regexp, int syntax)
+M4BUILTIN_HANDLER (esyscmd)
 {
-  static m4_pattern_buffer buf;        /* compiled regular expression */
-  static bool buf_initialized = false;
-  const char *msg;             /* error message from re_compile_pattern */
+  M4_MODULE_IMPORT (m4, m4_set_sysval);
+  M4_MODULE_IMPORT (m4, m4_sysval_flush);
 
-  if (!buf_initialized)
+  if (m4_set_sysval && m4_sysval_flush)
     {
-      buf_initialized  = true;
-      buf.pat.buffer   = NULL;
-      buf.pat.allocated        = 0;
-      buf.pat.fastmap  = NULL;
-      buf.pat.translate        = NULL;
-    }
-
-  re_set_syntax (syntax);
-  msg = re_compile_pattern (regexp, strlen (regexp), &buf.pat);
+      FILE *pin;
+      int ch;
 
-  if (msg != NULL)
+      m4_sysval_flush (context);
+      errno = 0;
+      pin = popen (M4ARG (1), "r");
+      if (pin == NULL)
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("%s: bad regular expression `%s': %s"),
-               caller, regexp, msg));
-      return NULL;
+         M4ERROR ((m4_get_warning_status_opt (context), errno,
+                   _("Cannot open pipe to command `%s'"), M4ARG (1)));
+         m4_set_sysval (0xffff);
     }
-
-  return &buf;
-}
-
-static int
-m4_regexp_search (m4_pattern_buffer *buf, const char *string,
-                 const int size, const int start, const int range)
-{
-  return re_search (&(buf->pat), string, size, start, range, &(buf->regs));
-}
-
-
-/* Regular expression version of index.  Given two arguments, expand to the
-   index of the first match of the second argument (a regexp) in the first.
-   Expand to -1 if here is no match.  Given a third argument, it changes
-   the expansion to this argument.  */
-
-/**
- * regexp(VICTIM, REGEXP, [REPLACEMENT])
- * eregexp(VICTIM, REGEXP, [REPLACEMENT])
- **/
-
-static void
-m4_regexp_do (m4 *context, m4_obstack *obs, int argc,
-             m4_symbol_value **argv, int syntax)
-{
-  const char *caller;          /* calling macro name */
-  const char *victim;          /* first argument */
-  const char *regexp;          /* regular expression */
-
-  m4_pattern_buffer *buf;      /* compiled regular expression */
-  int startpos;                        /* start position of match */
-  int length;                  /* length of first argument */
-
-  caller = M4ARG (0);
-  victim = M4ARG (1);
-  regexp = M4ARG (2);
-
-  buf = m4_regexp_compile (context, caller, regexp, syntax);
-  if (!buf)
-    return;
-
-  length = strlen (victim);
-  startpos = m4_regexp_search (buf, victim, length, 0, length);
-
-  if (startpos  == -2)
+      else
     {
-      M4ERROR ((m4_get_warning_status_opt (context), 0,
-               _("%s: error matching regular expression `%s'"),
-               caller, regexp));
-      return;
+         while ((ch = getc (pin)) != EOF)
+           obstack_1grow (obs, (char) ch);
+         m4_set_sysval (pclose (pin));
+       }
     }
-
-  if (argc == 3)
-    m4_shipout_int (obs, startpos);
-  else if (startpos >= 0)
-    substitute (context, obs, victim, M4ARG (3), buf);
-
-  return;
 }
 
 
-/**
- * regexp(VICTIM, REGEXP, [REPLACEMENT])
- **/
-M4BUILTIN_HANDLER (regexp)
-{
-  m4_regexp_do (context, obs, argc, argv, RE_SYNTAX_BRE);
-}
+/* Frontend for printf like formatting.  The function format () lives in
+   the file format.c.  */
+
+#include "format.c"
 
 /**
- * eregexp(VICTIM, REGEXP, [REPLACEMENT])
+ * format(FORMAT-STRING, [...])
  **/
-M4BUILTIN_HANDLER (eregexp)
+M4BUILTIN_HANDLER (format)
 {
-  m4_regexp_do (context, obs, argc, argv, RE_SYNTAX_ERE);
+  format (obs, argc - 1, argv + 1);
 }
 
 
-
-/* Substitute all matches of a regexp occuring in a string.  Each match of
-   the second argument (a regexp) in the first argument is changed to the
-   third argument, with \& substituted by the matched text, and \N
-   substituted by the text matched by the Nth parenthesized sub-expression.  */
+/* The builtin "indir" allows indirect calls to macros, even if their name
+   is not a proper macro name.  It is thus possible to define macros with
+   ill-formed names for internal use in larger macro packages.  This macro
+   is not available in compatibility mode.  */
 
 /**
- * patsubst(VICTIM, REGEXP, [REPLACEMENT])
- * epatsubst(VICTIM, REGEXP, [REPLACEMENT])
+ * indir(MACRO, [...])
  **/
-static void
-m4_patsubst_do (m4 *context, m4_obstack *obs, int argc,
-               m4_symbol_value **argv, int syntax)
-{
-  const char *caller;          /* calling macro name */
-  const char *victim;          /* first argument */
-  const char *regexp;          /* regular expression */
-  m4_pattern_buffer *buf;      /* compiled regular expression */
-
-  caller = M4ARG (0);
-  victim = M4ARG (1);
-  regexp = M4ARG (2);
-
-  buf = m4_regexp_compile (context, caller, regexp, syntax);
-  if (!buf)
-    return;
-
-  regsub (context, obs, caller, victim, regexp, buf, M4ARG (3), false);
-}
-
-static bool
-regsub (m4 *context, m4_obstack *obs, const char *caller,
-       const char *victim, const char *regexp, m4_pattern_buffer *buf,
-       const char *replace, bool ignore_duplicates)
+M4BUILTIN_HANDLER (indir)
 {
-  int matchpos = 0;            /* start position of match */
-  int offset   = 0;            /* current match offset */
-  int length   = strlen (victim);
-
-  while (offset < length)
-    {
-      matchpos = m4_regexp_search (buf, victim, length,
-                                  offset, length - offset);
-
-      if (matchpos < 0)
-       {
-
-         /* Match failed -- either error or there is no match in the
-            rest of the string, in which case the rest of the string is
-            copied verbatim.  */
+  const char * name   = M4ARG (1);
+  m4_symbol *  symbol = m4_symbol_lookup (M4SYMTAB, name);
 
-         if (matchpos == -2)
+  if (symbol == NULL)
            M4ERROR ((m4_get_warning_status_opt (context), 0,
-                     _("%s: error matching regular expression `%s'"),
-                     caller, regexp));
-         else if (!ignore_duplicates && (offset < length))
-           obstack_grow (obs, victim + offset, length - offset);
-         break;
-       }
-
-      /* Copy the part of the string that was skipped by re_search ().  */
-
-      if (matchpos > offset)
-       obstack_grow (obs, victim + offset, matchpos - offset);
+             _("Undefined name `%s'"), name));
+  else
+    m4_macro_call (context, symbol, obs, argc - 1, argv + 1);
+}
 
-      /* Handle the part of the string that was covered by the match.  */
 
-      substitute (context, obs, victim, replace, buf);
+/* Substitute all matches of a regexp occuring in a string.  Each match of
+   the second argument (a regexp) in the first argument is changed to the
+   third argument, with \& substituted by the matched text, and \N
+   substituted by the text matched by the Nth parenthesized sub-expression.  */
 
-      /* Update the offset to the end of the match.  If the regexp
-        matched a null string, advance offset one more, to avoid
-        infinite loops.  */
+/**
+ * patsubst(VICTIM, REGEXP, [REPLACEMENT])
+ * epatsubst(VICTIM, REGEXP, [REPLACEMENT])
+ **/
+static void
+m4_patsubst_do (m4 *context, m4_obstack *obs, int argc,
+               m4_symbol_value **argv, int syntax)
+{
+  const char *caller;          /* calling macro name */
+  const char *victim;          /* first argument */
+  const char *regexp;          /* regular expression */
+  m4_pattern_buffer *buf;      /* compiled regular expression */
 
-      offset = buf->regs.end[0];
-      if (buf->regs.start[0] == buf->regs.end[0])
-       obstack_1grow (obs, victim[offset++]);
-    }
+  caller = M4ARG (0);
+  victim = M4ARG (1);
+  regexp = M4ARG (2);
 
-  if (!ignore_duplicates || (matchpos >= 0))
-    obstack_1grow (obs, '\0');
+  buf = m4_regexp_compile (context, caller, regexp, syntax);
+  if (!buf)
+    return;
 
-  return (matchpos >= 0);
+  regsub (context, obs, caller, victim, regexp, buf, M4ARG (3), false);
 }
 
 
@@ -487,6 +537,7 @@
   m4_patsubst_do (context, obs, argc, argv, RE_SYNTAX_BRE);
 }
 
+
 /**
  * epatsubst(STRING, REGEXP, [REPLACEMENT])
  **/
@@ -495,96 +546,74 @@
   m4_patsubst_do (context, obs, argc, argv, RE_SYNTAX_ERE);
 }
 
-/* Implementation of "symbols".  It builds up a table of pointers to
-   symbols, sorts it and ships out the symbol names.  */
+
+/* Regular expression version of index.  Given two arguments, expand to the
+   index of the first match of the second argument (a regexp) in the first.
+   Expand to -1 if here is no match.  Given a third argument, it changes
+   the expansion to this argument.  */
 
 /**
- * symbols([...])
+ * regexp(VICTIM, REGEXP, [REPLACEMENT])
+ * eregexp(VICTIM, REGEXP, [REPLACEMENT])
  **/
-M4BUILTIN_HANDLER (symbols)
+
+static void
+m4_regexp_do (m4 *context, m4_obstack *obs, int argc,
+             m4_symbol_value **argv, int syntax)
 {
-  M4_MODULE_IMPORT (m4, m4_dump_symbols);
+  const char *caller;          /* calling macro name */
+  const char *victim;          /* first argument */
+  const char *regexp;          /* regular expression */
 
-  if (m4_dump_symbols)
-    {
-      m4_dump_symbol_data data;
-      m4_obstack data_obs;
+  m4_pattern_buffer *buf;      /* compiled regular expression */
+  int startpos;                        /* start position of match */
+  int length;                  /* length of first argument */
 
-      obstack_init (&data_obs);
-      data.obs = &data_obs;
-      m4_dump_symbols (context, &data, argc, argv, false);
+  caller = M4ARG (0);
+  victim = M4ARG (1);
+  regexp = M4ARG (2);
 
-      for (; data.size > 0; --data.size, data.base++)
+  buf = m4_regexp_compile (context, caller, regexp, syntax);
+  if (!buf)
+    return;
+
+  length = strlen (victim);
+  startpos = m4_regexp_search (buf, victim, length, 0, length);
+
+  if (startpos  == -2)
        {
-         m4_shipout_string (context, obs, data.base[0], 0, true);
-         if (data.size > 1)
-           obstack_1grow (obs, ',');
-       }
-      obstack_free (&data_obs, NULL);
+      M4ERROR ((m4_get_warning_status_opt (context), 0,
+               _("%s: error matching regular expression `%s'"),
+               caller, regexp));
+      return;
     }
-  else
-    assert (!"Unable to import from m4 module");
-}
 
+  if (argc == 3)
+    m4_shipout_int (obs, startpos);
+  else if (startpos >= 0)
+    substitute (context, obs, victim, M4ARG (3), buf);
+
+  return;
+}
 
-/* This contains macro which implements syncoutput() which takes one arg
-     1, on, yes - turn on sync lines
-     0, off, no - turn off sync lines
-     everything else is silently ignored  */
 
 /**
- * syncoutput(SYNC?)
+ * regexp(VICTIM, REGEXP, [REPLACEMENT])
  **/
-M4BUILTIN_HANDLER (syncoutput)
+M4BUILTIN_HANDLER (regexp)
 {
-  if (m4_is_symbol_value_text (argv[1]))
-    {
-      if (   M4ARG (1)[0] == '0'
-         || M4ARG (1)[0] == 'n'
-         || (M4ARG (1)[0] == 'o' && M4ARG (1)[1] == 'f'))
-       m4_set_sync_output_opt (context, false);
-      else if (   M4ARG (1)[0] == '1'
-              || M4ARG (1)[0] == 'y'
-              || (M4ARG (1)[0] == 'o' && M4ARG (1)[1] == 'n'))
-       m4_set_sync_output_opt (context, true);
-    }
+  m4_regexp_do (context, obs, argc, argv, RE_SYNTAX_BRE);
 }
 
-
 /**
- * esyscmd(SHELL-COMMAND)
+ * eregexp(VICTIM, REGEXP, [REPLACEMENT])
  **/
-
-M4BUILTIN_HANDLER (esyscmd)
+M4BUILTIN_HANDLER (eregexp)
 {
-  M4_MODULE_IMPORT (m4, m4_set_sysval);
-  M4_MODULE_IMPORT (m4, m4_sysval_flush);
-
-  if (m4_set_sysval && m4_sysval_flush)
-    {
-      FILE *pin;
-      int ch;
-
-      m4_sysval_flush (context);
-      errno = 0;
-      pin = popen (M4ARG (1), "r");
-      if (pin == NULL)
-       {
-         M4ERROR ((m4_get_warning_status_opt (context), errno,
-                   _("Cannot open pipe to command `%s'"), M4ARG (1)));
-         m4_set_sysval (0xffff);
-       }
-      else
-       {
-         while ((ch = getc (pin)) != EOF)
-           obstack_1grow (obs, (char) ch);
-         m4_set_sysval (pclose (pin));
-       }
-    }
+  m4_regexp_do (context, obs, argc, argv, RE_SYNTAX_ERE);
 }
 
 
-
 /* Rename all current symbols that match REGEXP according to the
    REPLACEMENT specification.  */
 
@@ -659,86 +688,58 @@
 }
 
 
-
-/* Frontend for printf like formatting.  The function format () lives in
-   the file format.c.  */
-
-/**
- * format(FORMAT-STRING, [...])
- **/
-M4BUILTIN_HANDLER (format)
-{
-  format (obs, argc - 1, argv + 1);
-}
-
-
-/**
- * __file__
- **/
-M4BUILTIN_HANDLER (__file__)
-{
-  m4_shipout_string (context, obs, m4_current_file, 0, true);
-}
-
+/* Implementation of "symbols".  It builds up a table of pointers to
+   symbols, sorts it and ships out the symbol names.  */
 
 /**
- * __line__
+ * symbols([...])
  **/
-M4BUILTIN_HANDLER (__line__)
+M4BUILTIN_HANDLER (symbols)
 {
-  m4_shipout_int (obs, m4_current_line);
-}
+  M4_MODULE_IMPORT (m4, m4_dump_symbols);
 
-/* Function to perform substitution by regular expressions.  Used by the
-   builtins regexp, patsubst and renamesyms.  The changed text is placed on
-   the obstack.  The substitution is REPL, with \& substituted by this part
-   of VICTIM matched by the last whole regular expression, taken from
-   REGS[0], and \N substituted by the text matched by the Nth parenthesized
-   sub-expression, taken from REGS[N].  */
-static int substitute_warned = 0;
+  if (m4_dump_symbols)
+    {
+      m4_dump_symbol_data data;
+      m4_obstack data_obs;
 
-static void
-substitute (m4 *context, m4_obstack *obs, const char *victim,
-           const char *repl, m4_pattern_buffer *buf)
-{
-  register unsigned int ch;
+      obstack_init (&data_obs);
+      data.obs = &data_obs;
+      m4_dump_symbols (context, &data, argc, argv, false);
 
-  for (;;)
-    {
-      while ((ch = *repl++) != '\\')
+      for (; data.size > 0; --data.size, data.base++)
        {
-         if (ch == '\0')
-           return;
-         obstack_1grow (obs, ch);
+         m4_shipout_string (context, obs, data.base[0], 0, true);
+         if (data.size > 1)
+           obstack_1grow (obs, ',');
        }
-
-      switch ((ch = *repl++))
-       {
-       case '0':
-         if (!substitute_warned)
-           {
-             M4ERROR ((m4_get_warning_status_opt (context), 0, _("\
-WARNING: \\0 will disappear, use \\& instead in replacements")));
-             substitute_warned = 1;
+      obstack_free (&data_obs, NULL);
            }
-         /* Fall through.  */
+  else
+    assert (!"Unable to import from m4 module");
+}
 
-       case '&':
-         obstack_grow (obs, victim + buf->regs.start[0],
-                       buf->regs.end[0] - buf->regs.start[0]);
-         break;
 
-       case '1': case '2': case '3': case '4': case '5': case '6':
-       case '7': case '8': case '9':
-         ch -= '0';
-         if (buf->regs.end[ch] > 0)
-           obstack_grow (obs, victim + buf->regs.start[ch],
-                         buf->regs.end[ch] - buf->regs.start[ch]);
-         break;
 
-       default:
-         obstack_1grow (obs, ch);
-         break;
-       }
+/* This contains macro which implements syncoutput() which takes one arg
+     1, on, yes - turn on sync lines
+     0, off, no - turn off sync lines
+     everything else is silently ignored  */
+
+/**
+ * syncoutput(SYNC?)
+ **/
+M4BUILTIN_HANDLER (syncoutput)
+{
+  if (m4_is_symbol_value_text (argv[1]))
+    {
+      if (   M4ARG (1)[0] == '0'
+         || M4ARG (1)[0] == 'n'
+         || (M4ARG (1)[0] == 'o' && M4ARG (1)[1] == 'f'))
+       m4_set_sync_output_opt (context, false);
+      else if (   M4ARG (1)[0] == '1'
+              || M4ARG (1)[0] == 'y'
+              || (M4ARG (1)[0] == 'o' && M4ARG (1)[1] == 'n'))
+       m4_set_sync_output_opt (context, true);
     }
 }




reply via email to

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