bug-m4
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] Line synchronisation output in comments


From: Sergey Poznyakoff
Subject: [PATCH] Line synchronisation output in comments
Date: Thu, 24 May 2007 11:34:53 +0300

Hello,

When outputting comment blocks, m4 inserts line synchronisation
directives into them and this makes compilers get out of sync when
reporting diagnostics.  For example, given this input:

-- sample begin --
changecom(/*,*/)
/* line 1
   line 2
*/
TEXT
-- sample end --

m4 -s produces the following:

-- output begin --
#line 1 "sample.m4"

#line 4
/* line 1
#line 4
   line 2
#line 4
*/
TEXT
-- output end --        

which expands the comment by two lines and forces compiler to believe that
the word `TEXT' appears at the line 9 (instead of the line 5).

The attached patch fixes this bug.

Regards,
Sergey

2007-05-24  Sergey Poznyakoff  <address@hidden>

            * src/m4.h (TOKEN_COMMENT): New token type  
            (shipout_text): Change signature  
            * src/input.c (next_token): Return TOKEN_COMMENT for
            comments
            * src/output.c (shipout_text): Take 4th argument suppressing
            line synchronization output. 
            All callers updated
            * src/macro.c (expand_token): Handle comments separately and
            disable line synchronisation output for them.
            * src/freeze.c: Update calls to shipout_text

Index: src/freeze.c
diff -pu m4-1.4.9/src/freeze.c src/freeze.c
--- m4-1.4.9/src/freeze.c       2007-03-03 04:32:24.000000000 +0200
+++ src/freeze.c        2007-05-24 10:51:47.000000000 +0300
@@ -329,7 +329,7 @@ reload_frozen_state (const char *name)
 
               make_diversion (number[0]);
               if (number[1] > 0)
-                shipout_text (NULL, string[1], number[1]);
+                shipout_text (NULL, string[1], number[1], 0);
               break;
 
             case 'F':
Index: src/input.c
diff -pu m4-1.4.9/src/input.c src/input.c
--- m4-1.4.9/src/input.c        2007-02-05 15:43:36.000000000 +0200
+++ src/input.c 2007-05-24 10:51:47.000000000 +0300
@@ -875,7 +875,7 @@ next_token (token_data *td)
        M4ERROR_AT_LINE ((EXIT_FAILURE, 0, file, line,
                          "ERROR: end of file in comment"));
 
-      type = TOKEN_STRING;
+      type = TOKEN_COMMENT;
     }
   else if (default_word_regexp && (isalpha (ch) || ch == '_'))
     {
Index: src/m4.h
diff -pu m4-1.4.9/src/m4.h src/m4.h
--- m4-1.4.9/src/m4.h   2007-03-03 04:32:24.000000000 +0200
+++ src/m4.h    2007-05-24 10:51:47.000000000 +0300
@@ -238,7 +238,8 @@ void trace_post (const char *, int, int,
 enum token_type
 {
   TOKEN_EOF,                   /* end of file */
-  TOKEN_STRING,                        /* a quoted string or comment */
+  TOKEN_STRING,                        /* a quoted string */
+  TOKEN_COMMENT,                /* a comment */ 
   TOKEN_WORD,                  /* an identifier */
   TOKEN_OPEN,                  /* ( */
   TOKEN_COMMA,                 /* , */
@@ -321,7 +322,7 @@ extern int output_current_line;
 
 void output_init (void);
 void output_exit (void);
-void shipout_text (struct obstack *, const char *, int);
+void shipout_text (struct obstack *, const char *, int, int);
 void make_diversion (int);
 void insert_diversion (int);
 void insert_file (FILE *);
Index: src/macro.c
diff -pu m4-1.4.9/src/macro.c src/macro.c
--- m4-1.4.9/src/macro.c        2006-11-02 00:29:08.000000000 +0200
+++ src/macro.c 2007-05-24 10:56:48.000000000 +0300
@@ -94,9 +94,15 @@ expand_token (struct obstack *obs, token
     case TOKEN_CLOSE:
     case TOKEN_SIMPLE:
     case TOKEN_STRING:
-      shipout_text (obs, TOKEN_DATA_TEXT (td), strlen (TOKEN_DATA_TEXT (td)));
+      shipout_text (obs, TOKEN_DATA_TEXT (td), strlen (TOKEN_DATA_TEXT (td)),
+                   0);
       break;
 
+    case TOKEN_COMMENT:
+      shipout_text (obs, TOKEN_DATA_TEXT (td), strlen (TOKEN_DATA_TEXT (td)),
+                   1);
+      break;
+      
     case TOKEN_WORD:
       sym = lookup_symbol (TOKEN_DATA_TEXT (td), SYMBOL_LOOKUP);
       if (sym == NULL || SYMBOL_TYPE (sym) == TOKEN_VOID
@@ -106,10 +112,10 @@ expand_token (struct obstack *obs, token
        {
 #ifdef ENABLE_CHANGEWORD
          shipout_text (obs, TOKEN_DATA_ORIG_TEXT (td),
-                       strlen (TOKEN_DATA_ORIG_TEXT (td)));
+                       strlen (TOKEN_DATA_ORIG_TEXT (td)), 0);
 #else
          shipout_text (obs, TOKEN_DATA_TEXT (td),
-                       strlen (TOKEN_DATA_TEXT (td)));
+                       strlen (TOKEN_DATA_TEXT (td)), 0);
 #endif
        }
       else
Index: src/output.c
diff -pu m4-1.4.9/src/output.c src/output.c
--- m4-1.4.9/src/output.c       2007-03-23 14:40:03.000000000 +0200
+++ src/output.c        2007-05-24 10:52:55.000000000 +0300
@@ -452,12 +452,14 @@ output_text (const char *text, int lengt
 |                                                                         |
 | If we are generating sync lines, the output have to be examined, because |
 | we need to know how much output each input line generates.  In general,  |
-| sync lines are output whenever a single input lines generates several        
   |
-| output lines, or when several input lines does not generate any output.  |
+| sync lines are output whenever a single input line generates several    |
+| output lines, or when several input lines do not generate any output.    |
+| This behavior is altered by NOSYNC flag, which suppresses output of      | 
+| `#line' directives.  This is used to output multi-line comment blocks.   |
 `-------------------------------------------------------------------------*/
 
 void
-shipout_text (struct obstack *obs, const char *text, int length)
+shipout_text (struct obstack *obs, const char *text, int length, int nosync)
 {
   static bool start_of_output_line = true;
   char line[20];
@@ -519,18 +521,21 @@ shipout_text (struct obstack *obs, const
 
            if (output_current_line != current_line)
              {
-               sprintf (line, "#line %d", current_line);
-               for (cursor = line; *cursor; cursor++)
-                 OUTPUT_CHARACTER (*cursor);
-               if (output_current_line < 1 && current_file[0] != '\0')
+               if (!nosync)
                  {
-                   OUTPUT_CHARACTER (' ');
-                   OUTPUT_CHARACTER ('"');
-                   for (cursor = current_file; *cursor; cursor++)
+                   sprintf (line, "#line %d", current_line);
+                   for (cursor = line; *cursor; cursor++)
                      OUTPUT_CHARACTER (*cursor);
-                   OUTPUT_CHARACTER ('"');
+                   if (output_current_line < 1 && current_file[0] != '\0')
+                     {
+                       OUTPUT_CHARACTER (' ');
+                       OUTPUT_CHARACTER ('"');
+                       for (cursor = current_file; *cursor; cursor++)
+                         OUTPUT_CHARACTER (*cursor);
+                       OUTPUT_CHARACTER ('"');
+                     }
+                   OUTPUT_CHARACTER ('\n');
                  }
-               OUTPUT_CHARACTER ('\n');
                output_current_line = current_line;
              }
          }
            




reply via email to

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