From 716028e405fab6526e3580bd060f896bb3672681 Mon Sep 17 00:00:00 2001 From: Tadek Kijkowski Date: Fri, 30 Sep 2016 16:36:18 +0000 Subject: check.tpl: Convert line endings to unix on test outputs 2016-09-30 Tadek Kijkowski * check.tpl: Convert line endings to unix on test outputs * fixfixes.c: Fixed passing file name to apply_fix when SEPARATE_FIX_PROC is defined * fixincl.c: Use system_with_shell, fixes for MinGW and DJGPP * fixlib.c, fixlib.h: Added system_with_shell and fix_path_separators From-SVN: r240664 --- fixincludes/ChangeLog | 8 +++ fixincludes/check.tpl | 5 ++ fixincludes/fixfixes.c | 3 +- fixincludes/fixincl.c | 67 +++++++++++++++++++++--- fixincludes/fixlib.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++++ fixincludes/fixlib.h | 15 ++++++ 6 files changed, 228 insertions(+), 8 deletions(-) (limited to 'fixincludes') diff --git a/fixincludes/ChangeLog b/fixincludes/ChangeLog index 6b4aa421050..1d55b657d8c 100644 --- a/fixincludes/ChangeLog +++ b/fixincludes/ChangeLog @@ -1,3 +1,11 @@ +2016-09-30 Tadek Kijkowski + + * check.tpl: Convert line endings to unix on test outputs + * fixfixes.c: Fixed passing file name to apply_fix when + SEPARATE_FIX_PROC is defined + * fixincl.c: Use system_with_shell, fixes for MinGW and DJGPP + * fixlib.c, fixlib.h: Added system_with_shell and fix_path_separators + 2016-09-04 John David Anglin * inclhack.def (hpux_longjmp): Adjust select regular expression. diff --git a/fixincludes/check.tpl b/fixincludes/check.tpl index ffd2b66c7fb..496420846bd 100644 --- a/fixincludes/check.tpl +++ b/fixincludes/check.tpl @@ -123,6 +123,11 @@ exitok=` exec < ${TESTDIR}/LIST while read f do + if [ -n "$MSYSTEM" -o -n "$DJGPP" ] + then + # On MinGW and DJGPP convert line endings to avoid false positives + mv $f $f.dos; tr -d '\r' < $f.dos > $f; rm $f.dos + fi if [ ! -f ${TESTBASE}/$f ] then echo "Newly fixed header: $f" >&2 diff --git a/fixincludes/fixfixes.c b/fixincludes/fixfixes.c index 5616bf14975..034e15d9985 100644 --- a/fixincludes/fixfixes.c +++ b/fixincludes/fixfixes.c @@ -790,7 +790,8 @@ main( int argc, char** argv ) return EXIT_FAILURE; } - apply_fix (pFix, argv[1]); + /* Second parameter of apply_fix is file name */ + apply_fix (pFix, argv[2]); fclose (stdout); fclose (stdin); unlink (argv[4]); diff --git a/fixincludes/fixincl.c b/fixincludes/fixincl.c index 98bb98d6bd6..6dba2f6e830 100644 --- a/fixincludes/fixincl.c +++ b/fixincludes/fixincl.c @@ -74,9 +74,12 @@ int altered_ct = 0; #endif /* DO_STATS */ const char incl_quote_pat[] = "^[ \t]*#[ \t]*include[ \t]*\"[^/]"; -tSCC z_fork_err[] = "Error %d (%s) starting filter process for %s\n"; regex_t incl_quote_re; +#ifndef SEPARATE_FIX_PROC +tSCC z_fork_err[] = "Error %d (%s) starting filter process for %s\n"; +#endif + static void do_version (void) ATTRIBUTE_NORETURN; char *load_file (const char *); void run_compiles (void); @@ -188,7 +191,7 @@ do_version (void) puts (zBuf + 5); exit (strcmp (run_shell (zBuf), program_id)); #else - exit (system (zBuf)); + exit (system_with_shell (zBuf)); #endif } @@ -275,6 +278,11 @@ initialize ( int argc, char** argv ) /* NULL as the first argument to `tempnam' causes it to DTRT wrt the temporary directory where the file will be created. */ pz_temp_file = tempnam( NULL, "fxinc" ); + +#if defined(__MINGW32__) + fix_path_separators (pz_temp_file); +#endif + # endif signal (SIGQUIT, SIG_IGN); @@ -566,6 +574,26 @@ fi"; free ((void *) pz_res); return res; } +#elif defined(__MINGW32__) || defined(__DJGPP__) +static int +test_test (tTestDesc* p_test, char* pz_test_file) +{ + tSCC cmd_fmt[] = +#if defined(__DJGPP__) + "file=%s; test %s >/dev/null 2>/dev/null"; +#else + "file=%s; test %s > /dev/null 2>&1"; +#endif + int res; + + char *cmd_buf = XNEWVEC (char, strlen(cmd_fmt) + strlen(pz_test_file) + strlen(p_test->pz_test_text)); + + sprintf (cmd_buf, cmd_fmt, pz_test_file, p_test->pz_test_text); + res = system_with_shell (cmd_buf); + + free (cmd_buf); + return res ? SKIP_FIX : APPLY_FIX; +} #else /* * IF we are in MS-DOS land, then whatever shell-type test is required @@ -887,7 +915,7 @@ fix_with_system (tFixDesc* p_fixd, else /* NOT an "internal" fix: */ { size_t parg_size; -#ifdef __MSDOS__ +#if defined(__MSDOS__) && !defined(__DJGPP__) /* Don't use the "src > dstX; rm -f dst; mv -f dstX dst" trick: dst is a temporary file anyway, so we know there's no other file by that name; and DOS's system(3) doesn't mind to @@ -906,12 +934,18 @@ fix_with_system (tFixDesc* p_fixd, implementations cannot cope :-(. */ tSCC z_cmd_fmt[] = " %s > %sX ; rm -f %s; mv -f %sX %s"; #endif + tSCC z_subshell_start[] = "( "; + tSCC z_subshell_end[] = " ) < "; tCC** ppArgs = p_fixd->patch_args; argsize = sizeof( z_cmd_fmt ) + strlen( pz_temp_file ) + strlen( pz_file_source ); parg_size = argsize; + if (p_fixd->fd_flags & FD_SHELL_SCRIPT) + { + argsize += strlen( z_subshell_start ) + strlen ( z_subshell_end ); + } /* * Compute the size of the command line. Add lotsa extra space @@ -936,6 +970,16 @@ fix_with_system (tFixDesc* p_fixd, ppArgs = p_fixd->patch_args; + /* + * If it's shell script, enclose it in parentheses and skip "sh -c". + */ + if (p_fixd->fd_flags & FD_SHELL_SCRIPT) + { + strcpy (pz_scan, z_subshell_start); + pz_scan += strlen (z_subshell_start); + ppArgs += 2; + } + /* * Copy the program name, unquoted */ @@ -977,18 +1021,27 @@ fix_with_system (tFixDesc* p_fixd, } } + /* + * Close parenthesis if it's shell script. + */ + if (p_fixd->fd_flags & FD_SHELL_SCRIPT) + { + strcpy (pz_scan, z_subshell_end); + pz_scan += strlen (z_subshell_end); + } + /* * add the file machinations. */ -#ifdef __MSDOS__ +#if defined(__MSDOS__) && !defined(__DJGPP__) sprintf (pz_scan, z_cmd_fmt, pz_file_source, pz_temp_file ); #else sprintf (pz_scan, z_cmd_fmt, pz_file_source, pz_temp_file, pz_temp_file, pz_temp_file, pz_temp_file); #endif } - system( pz_cmd ); - free( (void*)pz_cmd ); + system_with_shell (pz_cmd); + free (pz_cmd); } /* * * * * * * * * * * * * @@ -1090,7 +1143,7 @@ fix_applies (tFixDesc* p_fixd) t_bool saw_sum_test = BOOL_FALSE; t_bool one_sum_passed = BOOL_FALSE; -#ifdef SEPARATE_FIX_PROC +#if defined(__MSDOS__) && !defined(__DJGPP__) /* * There is only one fix that uses a shell script as of this writing. * I hope to nuke it anyway, it does not apply to DOS and it would diff --git a/fixincludes/fixlib.c b/fixincludes/fixlib.c index 1fec773d393..4cdefe0bef4 100644 --- a/fixincludes/fixlib.c +++ b/fixincludes/fixlib.c @@ -278,3 +278,141 @@ make_raw_shell_str( char* pz_d, tCC* pz_s, size_t smax ) } #endif + +#if defined(__MINGW32__) +void +fix_path_separators (char* p) +{ + while (p != NULL) + { + p = strchr (p, '\\'); + if (p != NULL) + { + *p = '/'; + ++p; + } + } +} + +/* Count number of needle character ocurrences in str */ +static int +count_occurrences_of_char (char* str, char needle) +{ + int cnt = 0; + + while (str) + { + str = strchr (str, needle); + if (str) + { + ++str; + ++cnt; + } + } + + return cnt; +} + +/* On Mingw32, system function will just start cmd by default. + Call system function, but prepend ${CONFIG_SHELL} or ${SHELL} -c to the command, + replace newlines with '$'\n'', enclose command with double quotes + and escape special characters which were originally enclosed in single quotes. + */ +int +system_with_shell (char* s) +{ + static const char z_shell_start_args[] = " -c \""; + static const char z_shell_end_args[] = "\""; + static const char z_shell_newline[] = "'$'\\n''"; + + /* Use configured shell if present */ + char *env_shell = getenv ("CONFIG_SHELL"); + int newline_cnt = count_occurrences_of_char (s, '\n'); + int escapes_cnt = count_occurrences_of_char( s, '\\') + + count_occurrences_of_char (s, '"') + + count_occurrences_of_char (s, '`'); + char *long_cmd; + char *cmd_endp; + int sys_result; + char *s_scan; + int in_quotes; + + if (env_shell == NULL) + env_shell = getenv ("SHELL"); + + /* If neither CONFIGURED_SHELL nor SHELL is set, just call standard system function */ + if (env_shell == NULL) + return system (s); + + /* Allocate enough memory to fit newly created command string */ + long_cmd = XNEWVEC (char, strlen (env_shell) + + strlen (z_shell_start_args) + + strlen (s) + + newline_cnt * (strlen (z_shell_newline) - 1) + + escapes_cnt + + strlen (z_shell_end_args) + + 1); + + /* Start with ${SHELL} */ + strcpy (long_cmd, env_shell); + cmd_endp = long_cmd + strlen (long_cmd); + + /* Opening quote */ + strcpy (cmd_endp, z_shell_start_args); + cmd_endp += strlen (z_shell_start_args); + + /* Replace newlines and escape special chars */ + in_quotes = 0; + for (s_scan = s; *s_scan; ++s_scan) + { + switch (*s_scan) + { + case '\n': + if (in_quotes) + { + /* Replace newline inside quotes with '$'\n'' */ + strcpy (cmd_endp, z_shell_newline); + cmd_endp += strlen (z_shell_newline); + } + else + { + /* Replace newlines outside quotes with ; and merge subsequent newlines */ + *(cmd_endp++) = ';'; + *(cmd_endp++) = ' '; + while (*(s_scan + 1) == '\n' || *(s_scan + 1) == ' ' || *(s_scan + 1) == '\t') + ++s_scan; + } + break; + case '\'': + /* Escape single quote and toggle in_quotes flag */ + in_quotes = !in_quotes; + *(cmd_endp++) = *s_scan; + break; + case '\\': + case '`': + /* Escape backslash and backtick inside quotes */ + if (in_quotes) + *(cmd_endp++) = '\\'; + *(cmd_endp++) = *s_scan; + break; + case '"': + /* Escape double quotes always */ + *(cmd_endp++) = '\\'; + *(cmd_endp++) = *s_scan; + break; + default: + *(cmd_endp++) = *s_scan; + } + } + + /* Closing quote */ + strcpy (cmd_endp, z_shell_end_args); + + sys_result = system (long_cmd); + + free (long_cmd); + + return sys_result; +} + +#endif /* defined(__MINGW32__) */ diff --git a/fixincludes/fixlib.h b/fixincludes/fixlib.h index 03277454c22..07beb3afcce 100644 --- a/fixincludes/fixlib.h +++ b/fixincludes/fixlib.h @@ -269,4 +269,19 @@ char* make_raw_shell_str ( char* pz_d, tCC* pz_s, size_t smax ); t_bool mn_get_regexps ( regex_t** label_re, regex_t** name_re, tCC *who ); void initialize_opts ( void ); + +#if defined(__MINGW32__) + +void fix_path_separators ( char* p ); + +/* prepend shell name to command passed to system call */ +int system_with_shell ( char* s ); + +#else + +/* normal call */ +#define system_with_shell system + +#endif /* defined(__MINGW32__) */ + #endif /* ! GCC_FIXLIB_H */ -- cgit v1.2.3