[Top][All Lists]
[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);
}
}
- Changes to m4/modules/gnu.c,v, Gary V. Vaughan, 2006/07/05
- Changes to m4/modules/gnu.c,v,
Gary V. Vaughan <=
- Changes to m4/modules/gnu.c,v, Gary V. Vaughan, 2006/07/10
- Changes to m4/modules/gnu.c,v, Gary V. Vaughan, 2006/07/10
- Changes to m4/modules/gnu.c,v, Gary V. Vaughan, 2006/07/13
- Changes to m4/modules/gnu.c,v, Eric Blake, 2006/07/14