Hello,

Attached is a prototype patch which adds option -C (--synclines-as-comments).

When enabled, it is intended to output synclines enclosed in comment
delimiters. This is useful for using m4 and option -s outside of the
context of a C compiler.

Example:

#config.m4:
changecom(`(*', `*)')
define(A, B)

#file1.m4:
A

# m4 config.m4 -s file1.m4
(* #line 1 "file1.m4" *)
B

I do not have the latest toolchain needed to build m4 so the patch
is a prototype; it needs a couple more lines to work. Please
complete it if possible.

Thanks,
Davor
diff --git a/m4/m4private.h b/m4/m4private.h
index a09ca9f8..86c612a2 100644
--- a/m4/m4private.h
+++ b/m4/m4private.h
@@ -93,6 +93,7 @@ struct m4 {
 #define M4_OPT_FATAL_WARN_BIT           (1 << 6) /* -E once */
 #define M4_OPT_WARN_EXIT_BIT            (1 << 7) /* -E twice */
 #define M4_OPT_SAFER_BIT                (1 << 8) /* --safer */
+#define M4_OPT_SYNCLINES_AS_COMMENTS_BIT(1 << 9) /* -C */
 
 /* Fast macro versions of accessor functions for public fields of m4,
    that also have an identically named function exported in m4module.h.  */
@@ -134,6 +135,8 @@ struct m4 {
                 (BIT_TEST((C)->opt_flags, M4_OPT_INTERACTIVE_BIT))
 #  define m4_get_syncoutput_opt(C)                                      \
                 (BIT_TEST((C)->opt_flags, M4_OPT_SYNCOUTPUT_BIT))
+#  define m4_get_synclines_as_comments_opt(C)                           \
+                (BIT_TEST((C)->opt_flags, M4_OPT_SYNCLINES_AS_COMMENTS_BIT))
 #  define m4_get_posixly_correct_opt(C)                                 \
                 (BIT_TEST((C)->opt_flags, M4_OPT_POSIXLY_CORRECT_BIT))
 #  define m4_get_fatal_warnings_opt(C)                                  \
diff --git a/m4/output.c b/m4/output.c
index b9371956..63f838e9 100644
--- a/m4/output.c
+++ b/m4/output.c
@@ -669,7 +669,15 @@ m4_divert_text (m4 *context, m4_obstack *obs, const char *text, size_t length,
 
           if (m4_get_output_line (context) != line)
             {
-              char linebuf[sizeof "#line " + INT_BUFSIZE_BOUND (line)];
+              char linebuf[sizeof "#line " + INT_BUFSIZE_BOUND (line) +
+                m4_get_synclines_as_comments_opt (context) ?
+                  strlen (m4_get_syntax_bcomm (M4SYNTAX)) + strlen (m4_get_syntax_ecomm (M4SYNTAX)) + 2 : 0];
+              if (m4_get_synclines_as_comments_opt (context))
+                {
+                  const char *bcomm = m4_get_syntax_bcomm (M4SYNTAX);
+                  m4_output_text (context, bcomm, strlen (bcomm));
+                  OUTPUT_CHARACTER (' ');
+                }
               sprintf (linebuf, "#line %lu",
                        (unsigned long int) m4_get_current_line (context));
               m4_output_text (context, linebuf, strlen (linebuf));
@@ -682,6 +690,12 @@ m4_divert_text (m4 *context, m4_obstack *obs, const char *text, size_t length,
                   m4_output_text (context, file, strlen (file));
                   OUTPUT_CHARACTER ('"');
                 }
+              if (m4_get_synclines_as_comments_opt (context))
+                {
+                  const char *ecomm = m4_get_syntax_ecomm (M4SYNTAX);
+                  OUTPUT_CHARACTER (' ');
+                  m4_output_text (context, ecomm, strlen (ecomm));
+                }
               OUTPUT_CHARACTER ('\n');
               m4_set_output_line (context, line);
             }
diff --git a/src/main.c b/src/main.c
index 4b897e34..920be7f3 100644
--- a/src/main.c
+++ b/src/main.c
@@ -121,6 +121,7 @@ Preprocessor features:\n\
   -s, --synclines              short for --syncoutput=1\n\
       --syncoutput[=STATE]     set generation of `#line NUM \"FILE\"' lines\n\
                                  to STATE (0=off, 1=on, default 0)\n\
+  -C, --synclines-as-comments  enclose sync output in comment delimiters\n\
   -U, --undefine=NAME          undefine NAME\n\
 "), stdout);
       puts ("");
@@ -229,6 +230,7 @@ static const struct option long_options[] =
   {"reload-state", required_argument, NULL, 'R'},
   {"silent", no_argument, NULL, 'Q'},
   {"synclines", no_argument, NULL, 's'},
+  {"synclines-as-comments", no_argument, NULL, 'C'},
   {"trace", required_argument, NULL, 't'},
   {"traceon", required_argument, NULL, 't'},
   {"traditional", no_argument, NULL, 'G'},
@@ -258,7 +260,7 @@ static const struct option long_options[] =
    behavior also handles -s between files.  Starting OPTSTRING with
    '-' forces getopt_long to hand back file names as arguments to opt
    '\1', rather than reordering the command line.  */
-#define OPTSTRING "-B:D:EF:GH:I:L:PQR:S:T:U:Wbcd::egil:o:p:r::st:"
+#define OPTSTRING "-B:CD:EF:GH:I:L:PQR:S:T:U:Wbcd::egil:o:p:r::st:"
 
 /* For determining whether to be interactive.  */
 enum interactive_choice
@@ -432,6 +434,10 @@ main (int argc, char *const *argv, char *const *envp)
           m4_add_include_directory (context, optarg, true);
           break;
 
+        case 'C':
+          m4_set_synclines_as_comments_opt (context, true);
+          break;
+
         case 'E':
           m4_debug_decode (context, "-d", SIZE_MAX);
           if (m4_get_fatal_warnings_opt (context))
_______________________________________________
M4-patches mailing list
M4-patches@gnu.org
https://lists.gnu.org/mailman/listinfo/m4-patches

Reply via email to