1 /* 2 Functions for replacing substrings in strings. 3 4 Copyright (C) 2013-2020 5 Free Software Foundation, Inc. 6 7 Written by: 8 Slava Zanko <slavazanko@gmail.com>, 2013; 9 10 This file is part of the Midnight Commander. 11 12 The Midnight Commander is free software: you can redistribute it 13 and/or modify it under the terms of the GNU General Public License as 14 published by the Free Software Foundation, either version 3 of the License, 15 or (at your option) any later version. 16 17 The Midnight Commander is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 20 GNU General Public License for more details. 21 22 You should have received a copy of the GNU General Public License 23 along with this program. If not, see <http://www.gnu.org/licenses/>. 24 */ 25 26 #include <config.h> 27 28 #include "lib/global.h" 29 #include "lib/strescape.h" 30 #include "lib/strutil.h" 31 32 /*** global variables ****************************************************************************/ 33 34 /*** file scope macro definitions ****************************************************************/ 35 36 /*** file scope type declarations ****************************************************************/ 37 38 /*** file scope variables ************************************************************************/ 39 40 /* --------------------------------------------------------------------------------------------- */ 41 /*** file scope functions ************************************************************************/ 42 /* --------------------------------------------------------------------------------------------- */ 43 44 static char * 45 str_ptr_array_join (const GPtrArray * str_splints) /**/ 46 { 47 GString *return_str; 48 guint i; 49 50 return_str = g_string_sized_new (32); 51 for (i = 0; i < str_splints->len; i++) 52 g_string_append (return_str, g_ptr_array_index (str_splints, i)); 53 54 return g_string_free (return_str, FALSE); 55 } 56 57 /* --------------------------------------------------------------------------------------------- */ 58 /*** public functions ****************************************************************************/ 59 /* --------------------------------------------------------------------------------------------- */ 60 /** 61 * Replace all substrings 'needle' in string 'haystack' by 'replacement'. 62 * If the 'needle' in the 'haystack' will be escaped by backslash, 63 * then this occurrence isn't be replaced. 64 * 65 * @param haystack string contains substrings for replacement 66 * @param needle string for search 67 * @param replacement string for replace 68 * @return newly allocated string with replaced substrings 69 */ 70 71 char * 72 str_replace_all (const char *haystack, const char *needle, const char *replacement) /*
*/ 73 { 74 size_t needle_len; 75 GPtrArray *str_splints; 76 char *return_str; 77 78 needle_len = strlen (needle); 79 80 str_splints = g_ptr_array_new (); 81 82 while (TRUE) 83 { 84 char *needle_in_str; 85 86 needle_in_str = strstr (haystack, needle); 87 if (needle_in_str == NULL) 88 { 89 if (*haystack != '\0') 90 g_ptr_array_add (str_splints, g_strdup (haystack)); 91 break; 92 } 93 94 if (strutils_is_char_escaped (haystack, needle_in_str)) 95 { 96 char *backslash = needle_in_str - 1; 97 98 if (haystack != backslash) 99 g_ptr_array_add (str_splints, g_strndup (haystack, backslash - haystack)); 100 101 g_ptr_array_add (str_splints, g_strndup (backslash + 1, needle_in_str - backslash)); 102 haystack = needle_in_str + 1; 103 continue; 104 } 105 if (needle_in_str - haystack > 0) 106 g_ptr_array_add (str_splints, g_strndup (haystack, needle_in_str - haystack)); 107 g_ptr_array_add (str_splints, g_strdup (replacement)); 108 haystack = needle_in_str + needle_len; 109 } 110 return_str = str_ptr_array_join (str_splints); 111 112 g_ptr_array_foreach (str_splints, (GFunc) g_free, NULL); 113 g_ptr_array_free (str_splints, TRUE); 114 115 return return_str; 116 } 117 118 /* --------------------------------------------------------------------------------------------- */