Please review the patch below. Context:
Op 3 jul 2009, om 15:37 heeft Raphaël “Kena” Poss het volgende geschreven: > as part of a project I am looking for ways to perform context-insensitive but > parameterized substitutions on C code. It happens that m4 delivers well for > what I need to do. Except for the following. > [...] using m4 after the C preprocessor mostly works, but then m4 does not > recognize the location markers (#line) inserted by the preprocessor and > therefore most m4 errors are reported at an incorrect location, and > multi-line expansions cause m4 to use wrong relative numbers in new > synclines. [...] > I tried a possible route forward by replacing any occurrence of "#line X" in > the m4 input by m4_define(`__line__', X), but unfortunately that doesn't seem > to help. Is there an option to allow __line__ (and __file__) to be reset by > macros? Patch: * src/input.c (reset_line, reset_file): Add functions to reset the current location. * src/m4.h: Declare them. * src/builtin.c (m4___file__, m4___line__): Use them. * doc/m4.texinfo (Location): Document the new feature. Add a test. * NEWS: Document the new feature. --- ChangeLog | 12 ++++++++++++ NEWS | 2 ++ doc/m4.texinfo | 39 ++++++++++++++++++++++++++++++++++----- src/builtin.c | 26 ++++++++++++++++++++------ src/input.c | 19 +++++++++++++++++++ src/m4.h | 5 +++++ 6 files changed, 92 insertions(+), 11 deletions(-) diff --git a/ChangeLog b/ChangeLog index 5e5889e..9761fb0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,15 @@ +2010-10-06 Raphael 'kena' Poss <[email protected]> + + Add support for resetting '__file__' and '__line__'. + * src/input.c (reset_line, reset_file): Add functions to reset the + current location. + * src/m4.h: Declare them. + * src/builtin.c (m4___file__, m4___line__): Use them. + + * doc/m4.texinfo (Location): Document the new feature. Add a + test. + * NEWS: Document the new feature. + 2010-08-30 Eric Blake <[email protected]> Clean up compiler warnings. diff --git a/NEWS b/NEWS index 1afe792..c45462a 100644 --- a/NEWS +++ b/NEWS @@ -3,6 +3,8 @@ GNU M4 NEWS - User visible changes. * Noteworthy changes in Version 1.6 (????-??-??) [stable] Released by ????, based on git versions 1.4.10b.x-* and 1.5.* +** Add support for resetting '__file__' and '__line__'. + ** Fix regressions introduced in 1.4.10b: *** Using `builtin' or `indir' to perform nested `shift' calls triggered an assertion failure (not present in 1.4.11). diff --git a/doc/m4.texinfo b/doc/m4.texinfo index 91b8e00..c803c35 100644 --- a/doc/m4.texinfo +++ b/doc/m4.texinfo @@ -7779,11 +7779,12 @@ Line numbers start at 1 for each file. If the file was found due to the @option{-I} option or @env{M4PATH} environment variable, that is reflected in the file name. The syncline option (@option{-s}, -...@pxref{preprocessor features, , Invoking m4}), and the -...@samp{f} and @samp{l} flags of @code{debugmode} (@pxref{Debugmode}), -also use this notion of current file and line. Redefining the three -location macros has no effect on syncline, debug, warning, or error -message output. +...@pxref{preprocessor features, , Invoking m4}), and the @samp{f} and +...@samp{l} flags of @code{debugmode} (@pxref{Debugmode}), also use this +notion of current file and line. Redefining the three location macros +has no effect on syncline, debug, warning, or error message output, +although the line numbers and file names can be reset as described +below. This example reuses the file @file{incl.m4} mentioned earlier (@pxref{Include}): @@ -7841,6 +7842,34 @@ @result{}12 @end example +The @co...@w{__file__}} and @co...@w{__line__}} macros take an optional +argument which allow to reset the current input file name and line +number, respectively. If @option{-s} is enabled, a synchronization line +will be emitted at the next newline in the input. Input line numbers +will autoincrement from the new value, and the file name will stay +active for the current input source until the input source is exhausted +or the name is reset again. This feature can be used when the input to +M4 already contains synchronization information, as when M4 is used as a +filter between a preprocessor and a compiler. + +...@comment options: -s +...@example +$ @kbd{m4 -s} +foo __line__(42)bar __line__ +baz __line__ +__line__ +...@result{}#line 1 "stdin" +...@result{}foo bar 42 +...@result{}#line 43 +...@result{}baz 43 +...@result{}44 +foo __file__(`newname')bar __file__ +baz __file__ +...@result{}foo bar newname +...@result{}#line 46 "newname" +...@result{}baz newname +...@end example + The @co...@w{__program__}} macro behaves like @samp{$0} in shell terminology. If you invoke @code{m4} through an absolute path or a link with a different spelling, rather than by relying on a @env{PATH} search diff --git a/src/builtin.c b/src/builtin.c index bc0cde2..fd57970 100644 --- a/src/builtin.c +++ b/src/builtin.c @@ -1613,17 +1613,31 @@ m4_errprint (struct obstack *obs, int argc, macro_arguments *argv) static void m4___file__ (struct obstack *obs, int argc, macro_arguments *argv) { - bad_argc (arg_info (argv), argc, 0, 0); - obstack_grow (obs, curr_quote.str1, curr_quote.len1); - obstack_grow (obs, current_file, strlen (current_file)); - obstack_grow (obs, curr_quote.str2, curr_quote.len2); + bad_argc (arg_info (argv), argc, 0, 1); + if (argc > 1) + reset_file (ARG (1)); + else + { + obstack_grow (obs, curr_quote.str1, curr_quote.len1); + obstack_grow (obs, current_file, strlen (current_file)); + obstack_grow (obs, curr_quote.str2, curr_quote.len2); + } } static void m4___line__ (struct obstack *obs, int argc, macro_arguments *argv) { - bad_argc (arg_info (argv), argc, 0, 0); - shipout_int (obs, current_line); + int line; + + bad_argc (arg_info (argv), argc, 0, 1); + if (argc > 1) + { + if (!numeric_arg (arg_info (argv), ARG (1), ARG_LEN (1), &line)) + return; + reset_line (line); + } + else + shipout_int (obs, current_line); } static void diff --git a/src/input.c b/src/input.c index 04f0991..316d4bd 100644 --- a/src/input.c +++ b/src/input.c @@ -2226,3 +2226,22 @@ lex_debug (void) print_token ("lex", t, &td); } #endif /* DEBUG_INPUT */ + +/*---------------------------------. + | Reset the current line counter. | + `--------------------------------*/ +void reset_line(int line) +{ + isp->line = line; + input_change = true; +} + +/*-------------------------------. + | Reset the current file title. | + `------------------------------*/ +void reset_file(const char *title) +{ + isp->file = (char *) obstack_copy0 (&file_names, title, strlen (title)); + output_current_line = -1; + input_change = true; +} diff --git a/src/m4.h b/src/m4.h index d333c24..b2662ef 100644 --- a/src/m4.h +++ b/src/m4.h @@ -565,6 +565,11 @@ void expand_format (struct obstack *, int, macro_arguments *); void produce_frozen_state (const char *); void reload_frozen_state (const char *); +/* File: input.c --- input sources. */ + +void reset_line (int); +void reset_file (const char *); + /* Debugging the memory allocator. */ #ifdef WITH_DMALLOC -- 1.7.2.3 _______________________________________________ M4-patches mailing list [email protected] http://lists.gnu.org/mailman/listinfo/m4-patches
