check.tpl: Convert line endings to unix on test outputs
authorTadek Kijkowski <tkijkowski@gmail.com>
Fri, 30 Sep 2016 16:36:18 +0000 (16:36 +0000)
committerJeff Law <law@gcc.gnu.org>
Fri, 30 Sep 2016 16:36:18 +0000 (10:36 -0600)
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

From-SVN: r240664

fixincludes/ChangeLog
fixincludes/check.tpl
fixincludes/fixfixes.c
fixincludes/fixincl.c
fixincludes/fixlib.c
fixincludes/fixlib.h

index 6b4aa42..1d55b65 100644 (file)
@@ -1,3 +1,11 @@
+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.
index ffd2b66..4964208 100644 (file)
@@ -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
index 5616bf1..034e15d 100644 (file)
@@ -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]);
index 98bb98d..6dba2f6 100644 (file)
@@ -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
@@ -937,6 +971,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
        */
       {
@@ -978,17 +1022,26 @@ 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
index 1fec773..4cdefe0 100644 (file)
@@ -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__) */
index 0327745..07beb3a 100644 (file)
@@ -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 */