+2016-09-30 Tadek Kijkowski <tkijkowski@gmail.com>
+
+ * 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 <danglin@gcc.gnu.org>
* inclhack.def (hpux_longjmp): Adjust select regular expression.
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
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]);
#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);
puts (zBuf + 5);
exit (strcmp (run_shell (zBuf), program_id));
#else
- exit (system (zBuf));
+ exit (system_with_shell (zBuf));
#endif
}
/* 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);
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
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
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
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
*/
}
}
+ /*
+ * 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);
}
/* * * * * * * * * * * * *
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
}
#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__) */
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 */