The fixincl executable uses system function to call applyfix or to direcly patch a header file, with parameters enclosed in single quotes. This problem is that MinGW system function just calls cmd.exe, which doesn't strip quotes from parameters and completely ignores quotes for embedding spaces in parameters. The MinGW system function also doesn't allow for newlines in executed command parameters. As a result fixincludes doesn't wotk at on when trying to build a cross compiler with mingw as host.
On MinGW host, this patch adds system_with_shell function, which transforms command passed to system function is following way: - Enclose entire command in double quotes - Prepend shell executable name, taken from environment variable SHELL - Replace each occurence of newline with '$'\n'' sequence which is understood by bash and ksh (it is assumed that all newlines are embedded in command parameters enclosed in single quotes) 2016-09-23 Tadek Kijkowski (tkijkow...@gmail.com) * fixincl.c: Added system_with_shell for MinGW host. Index: fixincludes/fixincl.c =================================================================== --- fixincludes/fixincl.c (revision 240386) +++ fixincludes/fixincl.c (working copy) @@ -170,7 +170,111 @@ exit (EXIT_SUCCESS); } +#ifdef __MINGW32__ +/* Count number of \c needle character instances in string */ +static int +count_chars ( char* str, char needle ) +{ + int instances = 0; + + while (str) + { + str = strchr (str, needle); + if (str) + { + ++str; + ++instances; + } + } + + return instances; +} + +/* On Mingw32 system(3) will just start cmd by default. + Try using unix style shell passed via SHELL env. variable. + */ + +/* Call system(3) function, but prepend ${SHELL} -c to the command, + replace newlines with '$'\n'' and enclose command with double quotes. + */ +static 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''"; + + char* env_shell; + char* long_cmd; + char* cmd_endp; + size_t cmd_size; + int sys_result; + int newline_cnt; + char* nl_scan; + + /* If SHELL variable is not defined just call standard shell function */ + env_shell = getenv ("SHELL"); + if (env_shell == NULL) + return system (s); + + /* Count number of newlines in command */ + newline_cnt = count_chars(s, '\n'); + + /* Allocate enough memory to fit newly created command string */ + cmd_size = strlen (env_shell) + (sizeof (z_shell_start_args) - 1) + + strlen (s) + newline_cnt * (sizeof(z_shell_newline) - 1 - 1) + + (sizeof (z_shell_end_args) - 1) + 1; + + long_cmd = XNEWVEC (char, cmd_size); + + /* Start with ${SHELL} -c " */ + strcpy (long_cmd, env_shell); + strcat (long_cmd, z_shell_start_args); + + /* End pointer for appending pieces of command while replacing newlines */ + cmd_endp = long_cmd + strlen(long_cmd); + nl_scan = s; + while (nl_scan != NULL) + { + char* next_nl = strchr (nl_scan, '\n'); + if (next_nl) + { + /* Append part of command between newlines */ + size_t part_len = next_nl - nl_scan; + memcpy(cmd_endp, nl_scan, part_len); + cmd_endp += part_len; + + /* Append newline replacement */ + memcpy(cmd_endp, z_shell_newline, sizeof(z_shell_newline)); + cmd_endp += sizeof(z_shell_newline) - 1; + + /* Skip newline in src */ + ++next_nl; + } + else + { + /* Last portion */ + strcpy (cmd_endp, nl_scan); + } + nl_scan = next_nl; + } + + /* Closing quote */ + strcat (long_cmd, z_shell_end_args); + + sys_result = system (long_cmd); + + free ( (void*) long_cmd); + + return sys_result; +} + +#define system system_with_shell + +#endif /* defined(__MINGW32__) */ + + static void do_version (void) {