X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=fixincludes%2Ffixlib.c;h=4cdefe0bef4220bbc73e6cf1819f611d0bca6856;hb=b113af959cc00dd8726298003e837b5824288649;hp=2dc9bb1cd9e3ba4f6797afafe31955d806060254;hpb=9ae83b845687ff04cd89613745214f43b6700626;p=gcc.git diff --git a/fixincludes/fixlib.c b/fixincludes/fixlib.c index 2dc9bb1cd9e..4cdefe0bef4 100644 --- a/fixincludes/fixlib.c +++ b/fixincludes/fixlib.c @@ -3,13 +3,13 @@ files which are fixed to work correctly with ANSI C and placed in a directory that GCC will search. - Copyright (C) 1999, 2000, 2001, 2004 Free Software Foundation, Inc. + Copyright (C) 1999, 2000, 2001, 2004, 2009 Free Software Foundation, Inc. This file is part of GCC. GCC is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by -the Free Software Foundation; either version 2, or (at your option) +the Free Software Foundation; either version 3, or (at your option) any later version. GCC is distributed in the hope that it will be useful, @@ -18,9 +18,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License -along with GCC; see the file COPYING. If not, write to -the Free Software Foundation, 51 Franklin Street, Fifth Floor, -Boston, MA 02110-1301, USA. */ +along with GCC; see the file COPYING3. If not see +. */ #include "fixlib.h" @@ -259,7 +258,7 @@ make_raw_shell_str( char* pz_d, tCC* pz_s, size_t smax ) *(pz_d++) = '\''; for (;;) { - if (((size_t) (pz_d - pz_d_start) >= smax) + if ((size_t) (pz_d - pz_d_start) >= smax) return (char*)NULL; switch (*(pz_d++) = *(pz_s++)) { case NUL: @@ -279,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__) */