1 /* 2 Functions for replacing substrings in strings. 3 4 Copyright (C) 2013-2024 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 /*** forward declarations (file scope functions) *************************************************/ 39 40 /*** file scope variables ************************************************************************/ 41 42 /* --------------------------------------------------------------------------------------------- */ 43 /*** file scope functions ************************************************************************/ 44 /* --------------------------------------------------------------------------------------------- */ 45 46 /* --------------------------------------------------------------------------------------------- */ 47 /*** public functions ****************************************************************************/ 48 /* --------------------------------------------------------------------------------------------- */ 49 /** 50 * Replace all substrings 'needle' in string 'haystack' by 'replacement'. 51 * If the 'needle' in the 'haystack' is escaped by backslash, 52 * then this occurrence isn't be replaced. 53 * 54 * @param haystack string contains substrings for replacement. Cannot be NULL. 55 * @param needle string for search. Cannot be NULL. 56 * @param replacement string for replace. Cannot be NULL. 57 * @return newly allocated string with replaced substrings or NULL if @haystack is empty. 58 */ 59 60 char * 61 str_replace_all (const char *haystack, const char *needle, const char *replacement) /* */ 62 { 63 size_t needle_len, replacement_len; 64 GString *return_str = NULL; 65 char *needle_in_str; 66 67 needle_len = strlen (needle); 68 replacement_len = strlen (replacement); 69 70 while ((needle_in_str = strstr (haystack, needle)) != NULL) 71 { 72 if (return_str == NULL) 73 return_str = g_string_sized_new (32); 74 75 if (strutils_is_char_escaped (haystack, needle_in_str)) 76 { 77 char *backslash = needle_in_str - 1; 78 79 if (haystack != backslash) 80 g_string_append_len (return_str, haystack, backslash - haystack); 81 g_string_append_len (return_str, needle_in_str, needle_in_str - backslash); 82 haystack = needle_in_str + 1; 83 } 84 else 85 { 86 if (needle_in_str != haystack) 87 g_string_append_len (return_str, haystack, needle_in_str - haystack); 88 g_string_append_len (return_str, replacement, replacement_len); 89 haystack = needle_in_str + needle_len; 90 } 91 } 92 93 if (*haystack != '\0') 94 { 95 if (return_str == NULL) 96 return strdup (haystack); 97 98 g_string_append (return_str, haystack); 99 } 100 101 return (return_str != NULL ? g_string_free (return_str, FALSE) : NULL); 102 } 103 104 /* --------------------------------------------------------------------------------------------- */