[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH] Add support for resetting '__file__' and '__line__'.
From: |
Raphael 'kena' Poss |
Subject: |
[PATCH] Add support for resetting '__file__' and '__line__'. |
Date: |
Wed, 6 Oct 2010 22:59:43 +0200 |
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 <address@hidden>
+
+ 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 <address@hidden>
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},
address@hidden features, , Invoking m4}), and the
address@hidden 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.
address@hidden features, , Invoking m4}), and the @samp{f} and
address@hidden 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 @address@hidden and @address@hidden 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.
+
address@hidden options: -s
address@hidden
+$ @kbd{m4 -s}
+foo __line__(42)bar __line__
+baz __line__
+__line__
address@hidden 1 "stdin"
address@hidden bar 42
address@hidden 43
address@hidden 43
address@hidden
+foo __file__(`newname')bar __file__
+baz __file__
address@hidden bar newname
address@hidden 46 "newname"
address@hidden newname
address@hidden example
+
The @address@hidden 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
- [PATCH] Add support for resetting '__file__' and '__line__'.,
Raphael 'kena' Poss <=