Commit 8f9ca912 by Bruce Korb Committed by Bruce Korb

Use C-coded tests and fixes for #endif/#else labels

From-SVN: r30130
parent 5685b5d3
1999-10-22 Bruce Korb <autogen@linuxbox.com>
* fixinc/README: document the "mach" machine matching test
* fixinc/fixfixes.c: Implement the #else/#endif label fix
* fixinc/fixtests.c: Implement the #else/#endif label test
* fixinc/inclhack.def: utilize these tests and fixes
* fixinc/inclhack.sh: regen
* fixinc/fixincl.x: regen
* fixinc/fixincl.sh: regen
Thu Oct 21 20:37:19 1999 Jeffrey A Law (law@cygnus.com) Thu Oct 21 20:37:19 1999 Jeffrey A Law (law@cygnus.com)
* Makefile.in (cse.o): Depend on hashtab.h, not splay-tree.h. Also * Makefile.in (cse.o): Depend on hashtab.h, not splay-tree.h. Also
......
...@@ -71,7 +71,10 @@ Here are the rules for making fixes in the inclhack.def file: ...@@ -71,7 +71,10 @@ Here are the rules for making fixes in the inclhack.def file:
"c_test" because they are performed internally. "test" sends "c_test" because they are performed internally. "test" sends
a command to a server shell that actually fires off one or more a command to a server shell that actually fires off one or more
processes to do the testing. Avoid it, if you can, but it is processes to do the testing. Avoid it, if you can, but it is
still more efficient than a fix process. still more efficient than a fix process. Also available is
"mach". If the target machine matches any of the named
globbing-style patterns, then the machine name test will pass.
It is desired, however, to limit the use of this test.
These tests are required to: These tests are required to:
......
...@@ -72,7 +72,8 @@ typedef struct { ...@@ -72,7 +72,8 @@ typedef struct {
} fix_entry_t; } fix_entry_t;
#define FIXUP_TABLE \ #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 ) \ #define FIX_PROC_HEAD( fix ) \
...@@ -180,6 +181,184 @@ FIX_PROC_HEAD( double_slash_fix ) ...@@ -180,6 +181,184 @@ FIX_PROC_HEAD( double_slash_fix )
fclose (stdout);; 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 test for fix selector
...@@ -211,6 +390,7 @@ apply_fix( fixname, filname ) ...@@ -211,6 +390,7 @@ apply_fix( fixname, filname )
fixname ); fixname );
exit (3); exit (3);
} }
pfe++;
} }
buf = load_file_data (stdin); buf = load_file_data (stdin);
......
...@@ -994,30 +994,19 @@ tSCC zEnd_Else_LabelName[] = ...@@ -994,30 +994,19 @@ tSCC zEnd_Else_LabelName[] =
#define apzEnd_Else_LabelMachs (const char**)NULL #define apzEnd_Else_LabelMachs (const char**)NULL
/* /*
* content selection pattern - do fix if pattern found * perform the C function call test
*/ */
tSCC zEnd_Else_LabelSelect0[] = tSCC zEnd_Else_LabelFTst0[] = "else_endif_label";
"^[ \t]*#[ \t]*(else|endif)[ \t]+([!-.0-z\\{\\|\\}\\~]|/[^\\*])";
#define END_ELSE_LABEL_TEST_CT 1 #define END_ELSE_LABEL_TEST_CT 1
#define END_ELSE_LABEL_RE_CT 1 #define END_ELSE_LABEL_RE_CT 0
tTestDesc aEnd_Else_LabelTests[] = { tTestDesc aEnd_Else_LabelTests[] = {
{ TT_EGREP, zEnd_Else_LabelSelect0, (regex_t*)NULL }, }; { TT_FUNCTION, zEnd_Else_LabelFTst0, 0 /* unused */ }, };
/* /*
* Fix Command Arguments for End_Else_Label * Fix Command Arguments for End_Else_Label
*/ */
const char* apzEnd_Else_LabelPatch[] = { "sed", const char* apzEnd_Else_LabelPatch[] = {"else_endif_label",
"-e", ":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%",
(char*)NULL }; (char*)NULL };
/* * * * * * * * * * * * * * * * * * * * * * * * * * /* * * * * * * * * * * * * * * * * * * * * * * * * *
...@@ -4042,7 +4031,7 @@ extern char *\tsprintf();\\\n\ ...@@ -4042,7 +4031,7 @@ extern char *\tsprintf();\\\n\
* *
* List of all fixes * List of all fixes
*/ */
#define REGEX_COUNT 75 #define REGEX_COUNT 74
#define MACH_LIST_SIZE_LIMIT 154 #define MACH_LIST_SIZE_LIMIT 154
#define FIX_COUNT 107 #define FIX_COUNT 107
...@@ -4179,7 +4168,7 @@ tFixDesc fixDescList[ FIX_COUNT ] = { ...@@ -4179,7 +4168,7 @@ tFixDesc fixDescList[ FIX_COUNT ] = {
{ zEnd_Else_LabelName, zEnd_Else_LabelList, { zEnd_Else_LabelName, zEnd_Else_LabelList,
apzEnd_Else_LabelMachs, (regex_t*)NULL, apzEnd_Else_LabelMachs, (regex_t*)NULL,
END_ELSE_LABEL_TEST_CT, FD_MACH_ONLY, END_ELSE_LABEL_TEST_CT, FD_MACH_ONLY | FD_SUBROUTINE,
aEnd_Else_LabelTests, apzEnd_Else_LabelPatch }, aEnd_Else_LabelTests, apzEnd_Else_LabelPatch },
{ zHp_InlineName, zHp_InlineList, { zHp_InlineName, zHp_InlineList,
......
...@@ -62,7 +62,8 @@ typedef struct { ...@@ -62,7 +62,8 @@ typedef struct {
} test_entry_t; } test_entry_t;
#define FIX_TEST_TABLE \ #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 ) \ #define TEST_FOR_FIX_PROC_HEAD( test ) \
...@@ -154,6 +155,133 @@ TEST_FOR_FIX_PROC_HEAD( double_slash_test ) ...@@ -154,6 +155,133 @@ TEST_FOR_FIX_PROC_HEAD( double_slash_test )
return SKIP_FIX; 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 test for fix selector
...@@ -179,6 +307,7 @@ run_test( tname, fname, text ) ...@@ -179,6 +307,7 @@ run_test( tname, fname, text )
{ {
if (strcmp( pte->test_name, tname ) == 0) if (strcmp( pte->test_name, tname ) == 0)
return (*pte->test_proc)( fname, text ); return (*pte->test_proc)( fname, text );
pte++;
} while (--ct > 0); } while (--ct > 0);
fprintf( stderr, "fixincludes error: the `%s' fix test is unknown\n", fprintf( stderr, "fixincludes error: the `%s' fix test is unknown\n",
tname ); tname );
......
...@@ -527,47 +527,10 @@ fix = { ...@@ -527,47 +527,10 @@ fix = {
/* /*
* Select files that contain '#endif' or '#else' directives with * Select files that contain '#endif' or '#else' directives with
* some sort of following junk. (Between the ascii '.' * some sort of following junk.
* 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.
*/
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" c_test = "else_endif_label";
'/\\\\$/' "N\n" c_fix = "else_endif_label";
'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%";
}; };
......
...@@ -979,28 +979,17 @@ extern "C"\ ...@@ -979,28 +979,17 @@ extern "C"\
# #
# Fix 27: End_Else_Label # Fix 27: End_Else_Label
# #
if ( test -n "`egrep '^[ ]*#[ ]*(else|endif)[ ]+([!-.0-z\\{\\|\\}\\~]|/[^\\*])' ${file}`" if ${FIXTESTS} ${file} else_endif_label
) > /dev/null 2>&1 ; then then
fixlist="${fixlist} fixlist="${fixlist}
end_else_label" end_else_label"
if [ ! -r ${DESTFILE} ] if [ ! -r ${DESTFILE} ]
then infile=${file} then infile=${file}
else infile=${DESTFILE} ; fi else infile=${DESTFILE} ; fi
${FIXFIXES} ${file} else_endif_label < $infile > ${DESTDIR}/fixinc.tmp
sed -e ':loop
/\\$/N
s/\\$/\\+++fixinc_eol+++/
/\\$/b loop
s/\\+++fixinc_eol+++/\\/g
s%^\([ ]*#[ ]*else\)[ ][ ]*/[^*].*%\1%
s%^\([ ]*#[ ]*else\)[ ][ ]*[^/ ].*%\1%
s%^\([ ]*#[ ]*endif\)[ ][ ]*/[^*].*%\1%
s%^\([ ]*#[ ]*endif\)[ ][ ]*\*[^/].*%\1%
s%^\([ ]*#[ ]*endif\)[ ][ ]*[^/* ].*%\1%' \
< $infile > ${DESTDIR}/fixinc.tmp
rm -f ${DESTFILE} rm -f ${DESTFILE}
mv -f ${DESTDIR}/fixinc.tmp ${DESTFILE} mv -f ${DESTDIR}/fixinc.tmp ${DESTFILE}
fi # end of select 'if' fi # end of c_test 'if'
# #
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment