m4-patches
[Top][All Lists]
Advanced

[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






reply via email to

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