1 /* GNU m4 -- A simple macro processor
2 Copyright (C) 2000, 2004, 2005, 2006, 2007, 2008, 2009 Free
3 Software Foundation, Inc.
5 This file is part of GNU M4.
7 GNU M4 is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
12 GNU M4 is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 /* Build using only the exported interfaces, unles NDEBUG is set, in
24 which case use private symbols to speed things up as much as possible. */
26 # include <m4/m4module.h>
28 # include "m4private.h"
31 #include "modules/m4.h"
34 /* Rename exported symbols for dlpreload()ing. */
35 #define m4_builtin_table gnu_LTX_m4_builtin_table
36 #define m4_macro_table gnu_LTX_m4_macro_table
39 /* Maintain each of the builtins implemented in this modules along
40 with their details in a single table for easy maintenance.
42 function macros blind side minargs maxargs */
43 #define builtin_functions \
44 BUILTIN (__file__, false, false, false, 0, 0 ) \
45 BUILTIN (__line__, false, false, false, 0, 0 ) \
46 BUILTIN (__program__, false, false, false, 0, 0 ) \
47 BUILTIN (builtin, true, true, false, 1, -1 ) \
48 BUILTIN (changeresyntax,false,true, false, 1, 1 ) \
49 BUILTIN (changesyntax,false, true, false, 1, -1 ) \
50 BUILTIN (debugfile, false, false, false, 0, 1 ) \
51 BUILTIN (debuglen, false, true, false, 1, 1 ) \
52 BUILTIN (debugmode, false, false, false, 0, 1 ) \
53 BUILTIN (esyscmd, false, true, true, 1, 1 ) \
54 BUILTIN (format, false, true, false, 1, -1 ) \
55 BUILTIN (indir, true, true, false, 1, -1 ) \
56 BUILTIN (mkdtemp, false, true, false, 1, 1 ) \
57 BUILTIN (patsubst, false, true, true, 2, 4 ) \
58 BUILTIN (regexp, false, true, true, 2, 4 ) \
59 BUILTIN (renamesyms, false, true, false, 2, 3 ) \
60 BUILTIN (m4symbols, true, false, false, 0, -1 ) \
61 BUILTIN (syncoutput, false, true, false, 1, 1 ) \
64 /* Generate prototypes for each builtin handler function. */
65 #define BUILTIN(handler, macros, blind, side, min, max) M4BUILTIN (handler)
70 /* Generate a table for mapping m4 symbol names to handler functions. */
71 const m4_builtin m4_builtin_table
[] =
73 #define BUILTIN(handler, macros, blind, side, min, max) \
74 M4BUILTIN_ENTRY (handler, #handler, macros, blind, side, min, max)
79 { NULL
, NULL
, 0, 0, 0 },
83 /* A table for mapping m4 symbol names to simple expansion text. */
84 const m4_macro m4_macro_table
[] =
86 /* name text min max */
88 { "__unix__", "", 0, 0 },
91 { "__windows__", "", 0, 0 },
94 { "__os2__", "", 0, 0 },
96 { "__gnu__", "", 0, 0 },
97 { "__m4_version__", VERSION
,0, 0 },
104 /* Regular expressions. Reuse re_registers among multiple
105 re_pattern_buffer allocations to reduce malloc usage. */
107 /* Maybe this is worth making runtime tunable. Too small, and nothing
108 gets cached because the working set of active regex is larger than
109 the cache, and we are always swapping out entries. Too large, and
110 the time spent searching the cache for a match overtakes the time
111 saved by caching. For now, this size proved reasonable for the
112 typical working set of Autoconf 2.62. */
113 #define REGEX_CACHE_SIZE 16
115 /* Structure for using a compiled regex, as well as making it easier
116 to cache frequently used expressions. */
118 unsigned count
; /* usage counter */
119 int resyntax
; /* flavor of regex */
120 size_t len
; /* length of string */
121 char *str
; /* copy of compiled string */
122 struct re_pattern_buffer
*pat
; /* compiled regex, allocated */
123 struct re_registers regs
; /* match registers, reused */
126 /* Storage for the cache of regular expressions. */
127 static m4_pattern_buffer regex_cache
[REGEX_CACHE_SIZE
];
129 /* Compile a REGEXP of length LEN using the RESYNTAX flavor, and
130 return the buffer. On error, report the problem on behalf of
131 CALLER, and return NULL. */
133 static m4_pattern_buffer
*
134 regexp_compile (m4
*context
, const m4_call_info
*caller
, const char *regexp
,
135 size_t len
, int resyntax
)
137 /* regex_cache is guaranteed to start life 0-initialized, which
138 works in the algorithm below.
140 FIXME - this method is not reentrant, since re_compile_pattern
141 mallocs memory, depends on the global variable re_syntax_options
142 for its syntax (but at least the compiled regex remembers its
143 syntax even if the global variable changes later), and since we
144 use a static variable. To be reentrant, we would need a mutex in
145 this method, and move the storage for regex_cache into context. */
147 const char *msg
; /* error message from re_compile_pattern */
148 int i
; /* iterator */
149 m4_pattern_buffer
*victim
; /* cache slot to replace */
150 unsigned victim_count
; /* track which victim to replace */
151 struct re_pattern_buffer
*pat
;/* newly compiled regex */
153 /* First, check if REGEXP is already cached with the given RESYNTAX.
154 If so, increase its use count and return it. */
155 for (i
= 0; i
< REGEX_CACHE_SIZE
; i
++)
156 if (len
== regex_cache
[i
].len
&& resyntax
== regex_cache
[i
].resyntax
157 && regex_cache
[i
].str
&& memcmp (regexp
, regex_cache
[i
].str
, len
) == 0)
159 regex_cache
[i
].count
++;
160 return ®ex_cache
[i
];
163 /* Next, check if REGEXP can be compiled. */
164 pat
= (struct re_pattern_buffer
*) xzalloc (sizeof *pat
);
165 re_set_syntax (resyntax
);
166 msg
= re_compile_pattern (regexp
, len
, pat
);
170 m4_warn (context
, 0, caller
, _("bad regular expression %s: %s"),
171 quotearg_style_mem (locale_quoting_style
, regexp
, len
), msg
);
176 /* Use a fastmap for speed; it is freed by regfree. */
177 pat
->fastmap
= xcharalloc (UCHAR_MAX
+ 1);
179 /* Now, find a victim slot. Decrease the count of all entries, then
180 prime the count of the victim slot at REGEX_CACHE_SIZE. This
181 way, frequently used entries and newly created entries are least
182 likely to be victims next time we have a cache miss. */
183 victim
= regex_cache
;
184 victim_count
= victim
->count
;
187 for (i
= 1; i
< REGEX_CACHE_SIZE
; i
++)
189 if (regex_cache
[i
].count
< victim_count
)
191 victim_count
= regex_cache
[i
].count
;
192 victim
= ®ex_cache
[i
];
194 if (regex_cache
[i
].count
)
195 regex_cache
[i
].count
--;
197 victim
->count
= REGEX_CACHE_SIZE
;
198 victim
->resyntax
= resyntax
;
203 regfree (victim
->pat
);
206 victim
->str
= xstrdup (regexp
);
208 re_set_registers (pat
, &victim
->regs
, victim
->regs
.num_regs
,
209 victim
->regs
.start
, victim
->regs
.end
);
214 /* Wrap up GNU Regex re_search call to work with an m4_pattern_buffer.
215 If NO_SUB, then storing matches in buf->regs is not necessary. */
218 regexp_search (m4_pattern_buffer
*buf
, const char *string
, const int size
,
219 const int start
, const int range
, bool no_sub
)
221 return re_search (buf
->pat
, string
, size
, start
, range
,
222 no_sub
? NULL
: &buf
->regs
);
226 /* Function to perform substitution by regular expressions. Used by
227 the builtins regexp, patsubst and renamesyms. The changed text is
228 placed on the obstack OBS. The substitution is REPL of length
229 REPL_LEN, with \& substituted by this part of VICTIM matched by the
230 last whole regular expression, and \N substituted by the text
231 matched by the Nth parenthesized sub-expression in BUF. Any
232 warnings are issued on behalf of CALLER. BUF may be NULL for the
236 substitute (m4
*context
, m4_obstack
*obs
, const m4_call_info
*caller
,
237 const char *victim
, const char *repl
, size_t repl_len
,
238 m4_pattern_buffer
*buf
)
247 obstack_1grow (obs
, ch
);
252 m4_warn (context
, 0, caller
,
253 _("trailing \\ ignored in replacement"));
263 obstack_grow (obs
, victim
+ buf
->regs
.start
[0],
264 buf
->regs
.end
[0] - buf
->regs
.start
[0]);
267 case '1': case '2': case '3': case '4': case '5': case '6':
268 case '7': case '8': case '9':
270 if (!buf
|| buf
->pat
->re_nsub
< ch
)
271 m4_warn (context
, 0, caller
, _("sub-expression %d not present"),
273 else if (buf
->regs
.end
[ch
] > 0)
274 obstack_grow (obs
, victim
+ buf
->regs
.start
[ch
],
275 buf
->regs
.end
[ch
] - buf
->regs
.start
[ch
]);
279 obstack_1grow (obs
, ch
);
286 /* For each match against REGEXP of length REGEXP_LEN (precompiled in
287 BUF as returned by regexp_compile) in VICTIM of length LEN,
288 substitute REPLACE of length REPL_LEN. Non-matching characters are
289 copied verbatim, and the result copied to the obstack. Errors are
290 reported on behalf of CALLER. Return true if a substitution was
291 made. If OPTIMIZE is set, don't worry about copying the input if
292 no changes are made. */
295 regexp_substitute (m4
*context
, m4_obstack
*obs
, const m4_call_info
*caller
,
296 const char *victim
, size_t len
, const char *regexp
,
297 size_t regexp_len
, m4_pattern_buffer
*buf
,
298 const char *replace
, size_t repl_len
, bool optimize
)
300 regoff_t matchpos
= 0; /* start position of match */
301 size_t offset
= 0; /* current match offset */
302 bool subst
= !optimize
; /* if a substitution has been made */
304 while (offset
<= len
)
306 matchpos
= regexp_search (buf
, victim
, len
, offset
, len
- offset
,
312 /* Match failed -- either error or there is no match in the
313 rest of the string, in which case the rest of the string is
317 m4_error (context
, 0, 0, caller
,
318 _("problem matching regular expression %s"),
319 quotearg_style_mem (locale_quoting_style
, regexp
,
321 else if (offset
< len
&& subst
)
322 obstack_grow (obs
, victim
+ offset
, len
- offset
);
326 /* Copy the part of the string that was skipped by re_search (). */
328 if (matchpos
> offset
)
329 obstack_grow (obs
, victim
+ offset
, matchpos
- offset
);
331 /* Handle the part of the string that was covered by the match. */
333 substitute (context
, obs
, caller
, victim
, replace
, repl_len
, buf
);
336 /* Update the offset to the end of the match. If the regexp
337 matched a null string, advance offset one more, to avoid
340 offset
= buf
->regs
.end
[0];
341 if (buf
->regs
.start
[0] == buf
->regs
.end
[0])
344 obstack_1grow (obs
, victim
[offset
]);
353 /* Reclaim memory used by this module. */
354 M4FINISH_HANDLER(gnu
)
357 for (i
= 0; i
< REGEX_CACHE_SIZE
; i
++)
358 if (regex_cache
[i
].str
)
360 free (regex_cache
[i
].str
);
361 regfree (regex_cache
[i
].pat
);
362 free (regex_cache
[i
].pat
);
363 free (regex_cache
[i
].regs
.start
);
364 free (regex_cache
[i
].regs
.end
);
366 /* If this module was preloaded, then we need to explicitly reset
367 the memory in case it gets reloaded. */
368 memset (®ex_cache
, 0, sizeof regex_cache
);
376 M4BUILTIN_HANDLER (__file__
)
378 m4_shipout_string (context
, obs
, m4_get_current_file (context
), SIZE_MAX
,
386 M4BUILTIN_HANDLER (__line__
)
388 m4_shipout_int (obs
, m4_get_current_line (context
));
395 M4BUILTIN_HANDLER (__program__
)
397 m4_shipout_string (context
, obs
, m4_get_program_name (), SIZE_MAX
, true);
401 /* The builtin "builtin" allows calls to builtin macros, even if their
402 definition has been overridden or shadowed. It is thus possible to
403 redefine builtins, and still access their original definition. A
404 special form allows one to retrieve the special token that defn
405 would normally return, even if that builtin is not currently
406 defined and hence can't be passed to defn. */
409 * builtin(MACRO, [...])
410 * builtin(defn(`builtin'), MACRO)
412 M4BUILTIN_HANDLER (builtin
)
414 const m4_call_info
*me
= m4_arg_info (argv
);
417 m4_symbol_value
*value
= NULL
;
419 if (!m4_is_arg_text (argv
, 1))
421 assert (m4_is_arg_func (argv
, 1));
422 if (m4_arg_func (argv
, 1) == builtin_builtin
)
424 if (m4_bad_argc (context
, argc
, me
, 2, 2, false))
426 if (!m4_is_arg_text (argv
, 2))
428 m4_warn (context
, 0, me
, _("invalid macro name ignored"));
433 if (len
== strlen (name
))
434 value
= m4_builtin_find_by_name (NULL
, name
);
437 m4_push_builtin (context
, obs
, value
);
440 else if (m4_is_debug_bit (context
, M4_DEBUG_TRACE_DEREF
))
441 m4_warn (context
, 0, me
, _("undefined builtin %s"),
442 quotearg_style_mem (locale_quoting_style
, name
, len
));
445 m4_warn (context
, 0, me
, _("invalid macro name ignored"));
451 if (len
== strlen (name
))
452 value
= m4_builtin_find_by_name (NULL
, name
);
455 if (m4_is_debug_bit (context
, M4_DEBUG_TRACE_DEREF
))
456 m4_warn (context
, 0, me
, _("undefined builtin %s"),
457 quotearg_style_mem (locale_quoting_style
, name
, len
));
461 const m4_builtin
*bp
= m4_get_symbol_value_builtin (value
);
462 m4_macro_args
*new_argv
;
463 bool flatten
= (bp
->flags
& M4_BUILTIN_FLATTEN_ARGS
) != 0;
464 new_argv
= m4_make_argv_ref (context
, argv
, name
, len
, flatten
,
466 if (!m4_bad_argc (context
, argc
- 1, m4_arg_info (new_argv
),
467 bp
->min_args
, bp
->max_args
,
468 (bp
->flags
& M4_BUILTIN_SIDE_EFFECT
) != 0))
469 bp
->func (context
, obs
, argc
- 1, new_argv
);
476 /* Change the current regexp syntax to SPEC of length LEN, or report
477 failure on behalf of CALLER. Currently this affects the builtins:
478 `patsubst', `regexp' and `renamesyms'. */
481 m4_resyntax_encode_safe (m4
*context
, const m4_call_info
*caller
,
482 const char *spec
, size_t len
)
486 if (strlen (spec
) < len
)
489 resyntax
= m4_regexp_syntax_encode (spec
);
492 m4_warn (context
, 0, caller
, _("bad syntax-spec: %s"),
493 quotearg_style_mem (locale_quoting_style
, spec
, len
));
500 * changeresyntax(RESYNTAX-SPEC)
502 M4BUILTIN_HANDLER (changeresyntax
)
504 int resyntax
= m4_resyntax_encode_safe (context
, m4_arg_info (argv
),
505 M4ARG (1), M4ARGLEN (1));
508 m4_set_regexp_syntax_opt (context
, resyntax
);
512 /* Change the current input syntax. The function m4_set_syntax ()
513 lives in syntax.c. Any changes to comment delimiters and quotes
514 made here will be overridden by a call to `changecom' or
518 * changesyntax(SYNTAX-SPEC, ...)
520 M4BUILTIN_HANDLER (changesyntax
)
522 const m4_call_info
*me
= m4_arg_info (argv
);
523 M4_MODULE_IMPORT (m4
, m4_expand_ranges
);
525 if (m4_expand_ranges
)
528 for (i
= 1; i
< argc
; i
++)
530 size_t len
= M4ARGLEN (i
);
537 m4_reset_syntax (M4SYNTAX
);
543 action
= len
? *spec
: '\0';
561 spec
= m4_expand_ranges (spec
, &len
, m4_arg_scratch (context
));
562 if (m4_set_syntax (M4SYNTAX
, key
, action
, spec
, len
) < 0)
563 m4_warn (context
, 0, me
, _("undefined syntax code: %s"),
564 quotearg_style_mem (locale_quoting_style
, &key
, 1));
568 assert (!"Unable to import from m4 module");
572 /* Specify the destination of the debugging output. With one argument, the
573 argument is taken as a file name, with no arguments, revert to stderr. */
576 * debugfile([FILENAME])
578 M4BUILTIN_HANDLER (debugfile
)
580 const m4_call_info
*me
= m4_arg_info (argv
);
583 m4_debug_set_output (context
, me
, NULL
);
584 else if (m4_get_safer_opt (context
) && !m4_arg_empty (argv
, 1))
585 m4_error (context
, 0, 0, me
, _("disabled by --safer"));
586 else if (!m4_debug_set_output (context
, me
, M4ARG (1)))
587 m4_error (context
, 0, errno
, me
, _("cannot set debug file %s"),
588 quotearg_style (locale_quoting_style
, M4ARG (1)));
592 /* On-the-fly control of debug length. It takes one integer
598 M4BUILTIN_HANDLER (debuglen
)
602 if (!m4_numeric_arg (context
, m4_arg_info (argv
), M4ARG (1), M4ARGLEN (1),
605 /* FIXME - make m4_numeric_arg more powerful - we want to accept
606 suffixes, and limit the result to size_t. */
607 s
= i
<= 0 ? SIZE_MAX
: i
;
608 m4_set_max_debug_arg_length_opt (context
, s
);
611 /* On-the-fly control of the format of the tracing output. It takes one
612 argument, which is a character string like given to the -d option, or
613 none in which case the debug_level is zeroed. */
618 M4BUILTIN_HANDLER (debugmode
)
621 m4_set_debug_level_opt (context
, 0);
622 else if (m4_debug_decode (context
, M4ARG (1)) < 0)
623 m4_error (context
, 0, 0, m4_arg_info (argv
),
624 _("bad debug flags: `%s'"), M4ARG (1));
628 /* Same as the sysymd builtin from m4.c module, but expand to the
629 output of SHELL-COMMAND. */
632 * esyscmd(SHELL-COMMAND)
635 M4BUILTIN_HANDLER (esyscmd
)
637 const m4_call_info
*me
= m4_arg_info (argv
);
638 M4_MODULE_IMPORT (m4
, m4_set_sysval
);
639 M4_MODULE_IMPORT (m4
, m4_sysval_flush
);
641 if (m4_set_sysval
&& m4_sysval_flush
)
646 if (m4_get_safer_opt (context
))
648 m4_error (context
, 0, 0, me
, _("disabled by --safer"));
652 /* Optimize the empty command. */
653 if (m4_arg_empty (argv
, 1))
659 m4_sysval_flush (context
, false);
661 pin
= popen (M4ARG (1), "r");
664 m4_error (context
, 0, errno
, me
,
665 _("cannot open pipe to command `%s'"), M4ARG (1));
670 while ((ch
= getc (pin
)) != EOF
)
671 obstack_1grow (obs
, ch
);
672 m4_set_sysval (pclose (pin
));
676 assert (!"Unable to import from m4 module");
680 /* Frontend for printf like formatting. The function format () lives in
681 the file format.c. */
686 * format(FORMAT-STRING, [...])
688 M4BUILTIN_HANDLER (format
)
690 format (context
, obs
, argc
, argv
);
694 /* The builtin "indir" allows indirect calls to macros, even if their name
695 is not a proper macro name. It is thus possible to define macros with
696 ill-formed names for internal use in larger macro packages. */
699 * indir(MACRO, [...])
701 M4BUILTIN_HANDLER (indir
)
703 const m4_call_info
*me
= m4_arg_info (argv
);
704 if (!m4_is_arg_text (argv
, 1))
705 m4_warn (context
, 0, me
, _("invalid macro name ignored"));
708 const char *name
= M4ARG (1);
709 size_t len
= M4ARGLEN (1);
710 m4_symbol
*symbol
= m4_symbol_lookup (M4SYMTAB
, name
, len
);
714 if (m4_is_debug_bit (context
, M4_DEBUG_TRACE_DEREF
))
715 m4_warn (context
, 0, me
, _("undefined macro %s"),
716 quotearg_style_mem (locale_quoting_style
, name
, len
));
720 m4_macro_args
*new_argv
;
721 m4_symbol_value
*value
= m4_get_symbol_value (symbol
);
722 new_argv
= m4_make_argv_ref (context
, argv
, name
, len
,
723 m4_symbol_flatten_args (symbol
),
724 m4_get_symbol_traced (symbol
));
725 m4_trace_prepare (context
, m4_arg_info (new_argv
), value
);
726 m4_macro_call (context
, value
, obs
, new_argv
);
732 /* The builtin "mkdtemp" allows creation of temporary directories. */
737 M4BUILTIN_HANDLER (mkdtemp
)
739 M4_MODULE_IMPORT (m4
, m4_make_temp
);
742 m4_make_temp (context
, obs
, m4_arg_info (argv
), M4ARG (1), M4ARGLEN (1),
745 assert (!"Unable to import from m4 module");
749 /* Substitute all matches of a regexp occurring in a string. Each
750 match of the second argument (a regexp) in the first argument is
751 changed to the optional third argument, with \& substituted by the
752 matched text, and \N substituted by the text matched by the Nth
753 parenthesized sub-expression. The optional fourth argument changes
757 * patsubst(VICTIM, REGEXP, [REPLACEMENT], [RESYNTAX])
759 M4BUILTIN_HANDLER (patsubst
)
761 const m4_call_info
*me
= m4_arg_info (argv
);
762 const char *pattern
; /* regular expression */
763 const char *replace
; /* replacement */
764 m4_pattern_buffer
*buf
; /* compiled regular expression */
767 resyntax
= m4_get_regexp_syntax_opt (context
);
768 if (argc
>= 5) /* additional args ignored */
770 resyntax
= m4_resyntax_encode_safe (context
, me
, M4ARG (4),
776 /* The empty regex matches everywhere, but if there is no
777 replacement, we need not waste time with it. */
778 if (m4_arg_empty (argv
, 2) && m4_arg_empty (argv
, 3))
780 m4_push_arg (context
, obs
, argv
, 1);
787 buf
= regexp_compile (context
, me
, pattern
, M4ARGLEN (2), resyntax
);
791 regexp_substitute (context
, obs
, me
, M4ARG (1), M4ARGLEN (1), pattern
,
792 M4ARGLEN (2), buf
, replace
, M4ARGLEN (3), false);
796 /* Regular expression version of index. Given two arguments, expand
797 to the index of the first match of the second argument (a regexp)
798 in the first. Expand to -1 if there is no match. Given a third
799 argument, a match is substituted according to this argument. The
800 optional fourth argument changes the regex flavor. */
803 * regexp(VICTIM, REGEXP, RESYNTAX)
804 * regexp(VICTIM, REGEXP, [REPLACEMENT], [RESYNTAX])
806 M4BUILTIN_HANDLER (regexp
)
808 const m4_call_info
*me
= m4_arg_info (argv
);
809 const char *victim
; /* string to search */
810 const char *pattern
; /* regular expression */
811 const char *replace
; /* optional replacement string */
812 m4_pattern_buffer
*buf
; /* compiled regular expression */
813 regoff_t startpos
; /* start position of match */
814 size_t len
; /* length of first argument */
819 resyntax
= m4_get_regexp_syntax_opt (context
);
823 resyntax
= m4_regexp_syntax_encode (replace
);
825 /* The first case is the most difficult, because the empty string
826 is a valid RESYNTAX, yet we want `regexp(aab, a*, )' to return
827 an empty string as per M4 1.4.x. */
829 if (m4_arg_empty (argv
, 3) || (resyntax
< 0))
830 /* regexp(VICTIM, REGEXP, REPLACEMENT) */
831 resyntax
= m4_get_regexp_syntax_opt (context
);
833 /* regexp(VICTIM, REGEXP, RESYNTAX) */
838 /* regexp(VICTIM, REGEXP, REPLACEMENT, RESYNTAX) */
839 resyntax
= m4_resyntax_encode_safe (context
, me
, M4ARG (4),
845 /* regexp(VICTIM, REGEXP) */
848 if (m4_arg_empty (argv
, 2))
850 /* The empty regex matches everything. */
852 substitute (context
, obs
, me
, M4ARG (1), replace
, M4ARGLEN (3), NULL
);
854 m4_shipout_int (obs
, 0);
858 buf
= regexp_compile (context
, me
, pattern
, M4ARGLEN (2), resyntax
);
864 startpos
= regexp_search (buf
, victim
, len
, 0, len
, replace
== NULL
);
868 m4_error (context
, 0, 0, me
, _("problem matching regular expression %s"),
869 quotearg_style_mem (locale_quoting_style
, pattern
,
875 m4_shipout_int (obs
, startpos
);
876 else if (startpos
>= 0)
877 substitute (context
, obs
, me
, victim
, replace
, M4ARGLEN (3), buf
);
881 /* Rename all current symbols that match REGEXP according to the
882 REPLACEMENT specification. */
885 * renamesyms(REGEXP, REPLACEMENT, [RESYNTAX])
887 M4BUILTIN_HANDLER (renamesyms
)
889 M4_MODULE_IMPORT (m4
, m4_dump_symbols
);
893 const m4_call_info
*me
= m4_arg_info (argv
);
894 const char *regexp
; /* regular expression string */
896 const char *replace
; /* replacement expression string */
899 m4_pattern_buffer
*buf
; /* compiled regular expression */
901 m4_dump_symbol_data data
;
906 regexp_len
= M4ARGLEN (1);
908 replace_len
= M4ARGLEN (2);
910 resyntax
= m4_get_regexp_syntax_opt (context
);
913 resyntax
= m4_resyntax_encode_safe (context
, me
, M4ARG (3),
919 buf
= regexp_compile (context
, me
, regexp
, regexp_len
, resyntax
);
923 data
.obs
= m4_arg_scratch (context
);
924 m4_dump_symbols (context
, &data
, 1, argv
, false);
926 for (; data
.size
> 0; --data
.size
, data
.base
++)
928 const m4_string
*key
= &data
.base
[0];
930 if (regexp_substitute (context
, data
.obs
, me
, key
->str
, key
->len
,
931 regexp
, regexp_len
, buf
, replace
, replace_len
,
934 size_t newlen
= obstack_object_size (data
.obs
);
935 m4_symbol_rename (M4SYMTAB
, key
->str
, key
->len
,
936 (char *) obstack_finish (data
.obs
), newlen
);
941 assert (!"Unable to import from m4 module");
945 /* Implementation of "m4symbols". It builds up a table of pointers to
946 symbols, sorts it and ships out the symbol names. */
951 M4BUILTIN_HANDLER (m4symbols
)
953 M4_MODULE_IMPORT (m4
, m4_dump_symbols
);
957 m4_dump_symbol_data data
;
959 data
.obs
= m4_arg_scratch (context
);
960 m4_dump_symbols (context
, &data
, argc
, argv
, false);
962 for (; data
.size
> 0; --data
.size
, data
.base
++)
964 m4_shipout_string (context
, obs
, data
.base
->str
, data
.base
->len
,
967 obstack_1grow (obs
, ',');
971 assert (!"Unable to import from m4 module");
975 /* This contains macro which implements syncoutput() which takes one arg
976 1, on, yes - turn on sync lines
977 0, off, no, blank - turn off sync lines
978 everything else is silently ignored */
983 M4BUILTIN_HANDLER (syncoutput
)
985 bool value
= m4_get_syncoutput_opt (context
);
986 value
= m4_parse_truth_arg (context
, m4_arg_info (argv
), M4ARG (1), value
);
987 m4_set_syncoutput_opt (context
, value
);