This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
Preliminary patch for
- To: gcc-patches at gcc dot gnu dot org, autogen at linuxbox dot com
- Subject: Preliminary patch for
- From: korbb at sourceware dot cygnus dot com
- Date: Fri, 15 Oct 1999 12:36:00 -0700 (PDT)
- Reply-To: "Bruce Korb" <ddsinc09 at ix dot netcom dot com>
I knocked this out rather quickly and gave it a spin on my
Linux box. It seemed to work. Unless someone finds problems,
it should forever fix the incorrect comments that sometimes
appear, without ever breaking anything. Ha! C code can be a
little more rigorous than sed.
Regards,
Bruce
Index: inclhack.def
===================================================================
RCS file: /cvs/gcc/egcs/gcc/fixinc/inclhack.def,v
retrieving revision 1.38
diff -u -r1.38 inclhack.def
--- inclhack.def 1999/10/15 06:02:01 1.38
+++ inclhack.def 1999/10/15 17:37:06
@@ -582,47 +582,10 @@
/*
* Select files that contain '#endif' or '#else' directives with
- * some sort of following junk. (Between the ascii '.'
- * and '0' lies the character '/'. This will *NOT*
- * match '#endif / * foo * /', but it also wont match
- * '#endif / done' either.
- *
- * We have a second regexp in the selector to detect
- * #endif followed by a / followed by anything other
- * than a *. For example "#endif / * foo * /" or
- * "#endif /% blah %/ which appear on OSF4.0A and AIX4.2
- * repsectively.
- *
- * We use the pattern [!-.0-z{|}~] instead of [^/ \t] to match a
- * noncomment following #else or #endif because some buggy egreps
- * think [^/] matches newline, and they thus think `#else ' matches
- * `#e[ndiflse]*[ \t]+[^/ \t]'.
- * [!-.0-~] does not work properly on AIX 4.1.
+ * some sort of following junk.
*/
- select = "^[ \t]*#[ \t]*(else|endif)[ \t]+"
- "(" '[!-.0-z\{\|\}\~]' "|" '/[^\*]' ")";
-
- /*
- * First, join the continued input lines.
- * IF the resulting line is an endif preprocessing directive,
- * then trim off the following patterns:
- * 1. sequences that start with '/' and is *NOT* followed by '*'
- * 2. Sequences that start with '*' and is *NOT* followed by '/'
- * 3. sequences that do not start with any of '/', '*', '\t' or ' '.
- *
- * The fixinc_eol stuff is to work around a bug in the sed
- */
- sed = ":loop\n"
- '/\\\\$/' "N\n"
- 's/\\\\$/\\\\+++fixinc_eol+++/' "\n"
- '/\\\\$/' "b loop\n"
- 's/\\\\+++fixinc_eol+++/\\\\/g' "\n"
-
- "s%^\\([ \t]*#[ \t]*else\\)[ \t][ \t]*/[^*].*%\\1%\n"
- "s%^\\([ \t]*#[ \t]*else\\)[ \t][ \t]*[^/ \t].*%\\1%\n"
- "s%^\\([ \t]*#[ \t]*endif\\)[ \t][ \t]*/[^*].*%\\1%\n"
- "s%^\\([ \t]*#[ \t]*endif\\)[ \t][ \t]*\\*[^/].*%\\1%\n"
- "s%^\\([ \t]*#[ \t]*endif\\)[ \t][ \t]*[^/* \t].*%\\1%";
+ c_test = "else_endif_label";
+ c_fix = "else_endif_label";
};
Index: fixtests.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/fixinc/fixtests.c,v
retrieving revision 1.2
diff -u -r1.2 fixtests.c
--- fixtests.c 1999/10/12 14:30:29 1.2
+++ fixtests.c 1999/10/15 17:37:06
@@ -62,7 +62,8 @@
} test_entry_t;
#define FIX_TEST_TABLE \
- _FT_( "double_slash", double_slash_test )
+ _FT_( "double_slash", double_slash_test ) \
+ _FT_( "else_endif_label", else_endif_label_test )
#define TEST_FOR_FIX_PROC_HEAD( test ) \
@@ -154,6 +155,133 @@
return SKIP_FIX;
}
+
+TEST_FOR_FIX_PROC_HEAD( else_endif_label_test )
+{
+ static int compiled = 0;
+ static const char label_pat[] = "^[ \t]*#[ \t]*(else|endif)";
+ static regex_t label_re;
+
+ char ch;
+ const char* pz_next = (char*)NULL;
+ regmatch_t match[2];
+
+ /*
+ This routine may be run many times within a single execution.
+ Do the compile once only in that case. In the standalone case,
+ we waste 10 bytes of memory and a test, branch and increment delay. */
+ if (! compiled)
+ {
+ compiled++;
+ re_set_syntax (RE_SYNTAX_EGREP);
+ (void)re_compile_pattern (label_pat, sizeof (label_pat)-1,
+ &label_re);
+ }
+
+ for (;;) /* entire file */
+ {
+ /*
+ See if we need to advance to the next candidate directive
+ If the scanning pointer passes over the end of the directive,
+ then the directive is inside a comment */
+ if (pz_next < text)
+ {
+ if (regexec (&label_re, text, 2, match, 0) != 0)
+ break;
+ pz_next = text + match[0].rm_eo;
+ }
+
+ /*
+ IF the scan pointer has not reached the directive end, ... */
+ if (pz_next > text)
+ {
+ /*
+ Advance the scanning pointer. If we are at the start
+ of a quoted string or a comment, then skip the entire unit */
+ ch = *(text++);
+
+ switch (ch)
+ {
+ case '/':
+ /*
+ Skip comments */
+ if (*text == '*')
+ {
+ text = strstr( text+1, "*/" );
+ if (text == (char*)NULL)
+ return SKIP_FIX;
+ text += 2;
+ continue;
+ }
+ break;
+
+ case '"':
+ case '\'':
+ text = skip_quote( ch, text );
+ break;
+ } /* switch (ch) */
+ continue;
+ } /* if (still shy of directive end) */
+
+ /*
+ The scanning pointer (text) has reached the end of the current
+ directive under test, then check for bogons here */
+ for (;;) /* bogon check */
+ {
+ char ch = *(pz_next++);
+ if (isspace (ch))
+ {
+ if (ch == '\n')
+ {
+ /*
+ It is clean. No bogons on this directive */
+ text = pz_next;
+ pz_next = (char*)NULL; /* force a new regex search */
+ break;
+ }
+ continue;
+ }
+
+ switch (ch)
+ {
+ case '\\':
+ /*
+ Skip escaped newlines. Otherwise, we have a bogon */
+ if (*pz_next != '\n')
+ return APPLY_FIX;
+
+ pz_next++;
+ break;
+
+ case '/':
+ /*
+ Skip comments. Otherwise, we have a bogon */
+ if (*pz_next == '*')
+ {
+ pz_next = strstr( pz_next+1, "*/" );
+ if (pz_next == (char*)NULL)
+ return SKIP_FIX;
+ pz_next += 2;
+ break;
+ }
+
+ /*
+ FIXME: if this is a C++ file, then a double slash comment
+ is allowed to follow the directive. */
+
+ /* FALLTHROUGH */
+
+ default:
+ /*
+ GOTTA BE A BOGON */
+ return APPLY_FIX;
+ } /* switch (ch) */
+ } /* for (bogon check loop) */
+ } /* for (entire file) loop */
+
+ return SKIP_FIX;
+}
+
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
test for fix selector
@@ -179,6 +307,7 @@
{
if (strcmp( pte->test_name, tname ) == 0)
return (*pte->test_proc)( fname, text );
+ pte++;
} while (--ct > 0);
fprintf( stderr, "fixincludes error: the `%s' fix test is unknown\n",
tname );
Index: fixfixes.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/fixinc/fixfixes.c,v
retrieving revision 1.2
diff -u -r1.2 fixfixes.c
--- fixfixes.c 1999/10/12 14:27:31 1.2
+++ fixfixes.c 1999/10/15 17:37:07
@@ -72,7 +72,8 @@
} fix_entry_t;
#define FIXUP_TABLE \
- _FT_( "no_double_slash", double_slash_fix )
+ _FT_( "no_double_slash", double_slash_fix ) \
+ _FT_( "else_endif_label", else_endif_label_fix )
#define FIX_PROC_HEAD( fix ) \
@@ -180,6 +181,184 @@
fclose (stdout);;
}
+
+FIX_PROC_HEAD( else_endif_label_fix )
+{
+ static const char label_pat[] = "^[ \t]*#[ \t]*(else|endif)";
+ static regex_t label_re;
+
+ char ch;
+ char* pz_next = (char*)NULL;
+ regmatch_t match[2];
+
+ re_set_syntax (RE_SYNTAX_EGREP);
+ (void)re_compile_pattern (label_pat, sizeof (label_pat)-1,
+ &label_re);
+
+ for (;;) /* entire file */
+ {
+ /*
+ See if we need to advance to the next candidate directive
+ If the scanning pointer passes over the end of the directive,
+ then the directive is inside a comment */
+ if (pz_next < text)
+ {
+ if (regexec (&label_re, text, 2, match, 0) != 0)
+ {
+ fputs( text, stdout );
+ break;
+ }
+
+ pz_next = text + match[0].rm_eo;
+ }
+
+ /*
+ IF the scan pointer has not reached the directive end, ... */
+ if (pz_next > text)
+ {
+ /*
+ Advance the scanning pointer. If we are at the start
+ of a quoted string or a comment, then skip the entire unit */
+ ch = *text;
+
+ switch (ch)
+ {
+ case '/':
+ /*
+ Skip comments */
+ if (text[1] == '*')
+ {
+ char* pz = strstr( text+2, "*/" );
+ if (pz == (char*)NULL)
+ {
+ fputs( text, stdout );
+ return;
+ }
+ pz += 2;
+ fwrite( text, 1, (pz - text), stdout );
+ text = pz;
+ continue;
+ }
+ putc( ch, stdout );
+ text++;
+ break;
+
+ case '"':
+ case '\'':
+ text = print_quote( ch, text+1 );
+ break;
+
+ default:
+ putc( ch, stdout );
+ text++;
+ } /* switch (ch) */
+ continue;
+ } /* if (still shy of directive end) */
+
+ /*
+ The scanning pointer (text) has reached the end of the current
+ directive under test. Check for bogons here. */
+ for (;;) /* bogon check */
+ {
+ char ch = *(text++);
+ if (isspace (ch))
+ {
+ putc( ch, stdout );
+ if (ch == '\n')
+ {
+ /*
+ It is clean. No bogons on this directive */
+ pz_next = (char*)NULL; /* force a new regex search */
+ goto dont_fix_bogon;
+ }
+ continue;
+ }
+
+ switch (ch)
+ {
+ case NUL:
+ return;
+
+ case '\\':
+ /*
+ Skip escaped newlines. Otherwise, we have a bogon */
+ if (*text != '\n') {
+ text--;
+ goto fix_the_bogon;
+ }
+
+ /*
+ Emit the escaped newline and keep scanning for possible junk */
+ putc( '\\', stdout );
+ putc( '\n', stdout );
+ text++;
+ break;
+
+ case '/':
+ /*
+ Skip comments. Otherwise, we have a bogon */
+ if (*text == '*')
+ {
+ text--;
+ pz_next = strstr( text+2, "*/" );
+ if (pz_next == (char*)NULL)
+ {
+ putc( '\n', stdout );
+ return;
+ }
+ pz_next += 2;
+ fwrite( text, 1, (pz_next - text), stdout );
+ text = pz_next;
+ break;
+ }
+
+ /*
+ FIXME: if this is a C++ file, then a double slash comment
+ is allowed to follow the directive. */
+
+ /* FALLTHROUGH */
+
+ default:
+ /*
+ GOTTA BE A BOGON */
+ text--;
+ goto fix_the_bogon;
+ } /* switch (ch) */
+ } /* for (bogon check loop) */
+
+ fix_the_bogon:
+ /*
+ `text' points to the start of the bogus data */
+ for (;;)
+ {
+ /*
+ NOT an escaped newline. Find the end of line that
+ is not preceeded by an escape character: */
+ pz_next = strchr( text, '\n' );
+ if (pz_next == (char*)NULL)
+ {
+ putc( '\n', stdout );
+ return;
+ }
+
+ if (pz_next[-1] != '\\')
+ {
+ text = pz_next;
+ pz_next = (char*)NULL; /* force a new regex search */
+ break;
+ }
+
+ /*
+ The newline was escaped. We gotta keep going. */
+ text = pz_next + 1;
+ }
+
+ dont_fix_bogon:;
+ } /* for (entire file) loop */
+
+ return;
+}
+
/* = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = = =
test for fix selector
@@ -206,11 +385,12 @@
if (strcmp (pfe->fix_name, fixname) == 0)
break;
if (--ct <= 0)
- {
- fprintf (stderr, "fixincludes error: the `%s' fix is unknown\n",
- fixname );
- exit (3);
- }
+ {
+ fprintf (stderr, "fixincludes error: the `%s' fix is unknown\n",
+ fixname );
+ exit (3);
+ }
+ pfe++;
}
buf = load_file_data (stdin);