Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

perf util: Add a function for replacing characters in a string

It finds all occurrences of a single character and replaces them with
a multi character string. This will be used in a test in a following
commit.

Reviewed-by: Ian Rogers <irogers@google.com>
Signed-off-by: James Clark <james.clark@arm.com>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Alexander Shishkin <alexander.shishkin@linux.intel.com>
Cc: Chen Zhongjin <chenzhongjin@huawei.com>
Cc: Eduard Zingerman <eddyz87@gmail.com>
Cc: Haixin Yu <yuhaixin.yhx@linux.alibaba.com>
Cc: Ingo Molnar <mingo@redhat.com>
Cc: Jing Zhang <renyu.zj@linux.alibaba.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: John Garry <john.g.garry@oracle.com>
Cc: Kajol Jain <kjain@linux.ibm.com>
Cc: Kan Liang <kan.liang@linux.intel.com>
Cc: Leo Yan <leo.yan@linaro.org>
Cc: Liam Howlett <liam.howlett@oracle.com>
Cc: Madhavan Srinivasan <maddy@linux.ibm.com>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Mike Leach <mike.leach@linaro.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Ravi Bangoria <ravi.bangoria@amd.com>
Cc: Will Deacon <will@kernel.org>
Cc: Yang Jihong <yangjihong1@huawei.com>
Cc: linux-arm-kernel@lists.infradead.org
Link: https://lore.kernel.org/r/20230904095104.1162928-4-james.clark@arm.com
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>

authored by

James Clark and committed by
Arnaldo Carvalho de Melo
8a55c1e2 f561fc78

+83
+1
tools/perf/tests/Build
··· 66 66 perf-y += sigtrap.o 67 67 perf-y += event_groups.o 68 68 perf-y += symbols.o 69 + perf-y += util.o 69 70 70 71 ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc)) 71 72 perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
+1
tools/perf/tests/builtin-test.c
··· 123 123 &suite__sigtrap, 124 124 &suite__event_groups, 125 125 &suite__symbols, 126 + &suite__util, 126 127 NULL, 127 128 }; 128 129
+1
tools/perf/tests/tests.h
··· 145 145 DECLARE_SUITE(sigtrap); 146 146 DECLARE_SUITE(event_groups); 147 147 DECLARE_SUITE(symbols); 148 + DECLARE_SUITE(util); 148 149 149 150 /* 150 151 * PowerPC and S390 do not support creation of instruction breakpoints using the
+31
tools/perf/tests/util.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + #include "tests.h" 3 + #include "util/debug.h" 4 + 5 + #include <linux/compiler.h> 6 + #include <stdlib.h> 7 + #include <string2.h> 8 + 9 + static int test_strreplace(char needle, const char *haystack, 10 + const char *replace, const char *expected) 11 + { 12 + char *new = strreplace_chars(needle, haystack, replace); 13 + int ret = strcmp(new, expected); 14 + 15 + free(new); 16 + return ret == 0; 17 + } 18 + 19 + static int test__util(struct test_suite *t __maybe_unused, int subtest __maybe_unused) 20 + { 21 + TEST_ASSERT_VAL("empty string", test_strreplace(' ', "", "123", "")); 22 + TEST_ASSERT_VAL("no match", test_strreplace('5', "123", "4", "123")); 23 + TEST_ASSERT_VAL("replace 1", test_strreplace('3', "123", "4", "124")); 24 + TEST_ASSERT_VAL("replace 2", test_strreplace('a', "abcabc", "ef", "efbcefbc")); 25 + TEST_ASSERT_VAL("replace long", test_strreplace('a', "abcabc", "longlong", 26 + "longlongbclonglongbc")); 27 + 28 + return 0; 29 + } 30 + 31 + DEFINE_SUITE("util", util);
+48
tools/perf/util/string.c
··· 301 301 return c - 'a' + 10; 302 302 return c - 'A' + 10; 303 303 } 304 + 305 + /* 306 + * Replace all occurrences of character 'needle' in string 'haystack' with 307 + * string 'replace' 308 + * 309 + * The new string could be longer so a new string is returned which must be 310 + * freed. 311 + */ 312 + char *strreplace_chars(char needle, const char *haystack, const char *replace) 313 + { 314 + int replace_len = strlen(replace); 315 + char *new_s, *to; 316 + const char *loc = strchr(haystack, needle); 317 + const char *from = haystack; 318 + int num = 0; 319 + 320 + /* Count occurrences */ 321 + while (loc) { 322 + loc = strchr(loc + 1, needle); 323 + num++; 324 + } 325 + 326 + /* Allocate enough space for replacements and reset first location */ 327 + new_s = malloc(strlen(haystack) + (num * (replace_len - 1) + 1)); 328 + if (!new_s) 329 + return NULL; 330 + loc = strchr(haystack, needle); 331 + to = new_s; 332 + 333 + while (loc) { 334 + /* Copy original string up to found char and update positions */ 335 + memcpy(to, from, 1 + loc - from); 336 + to += loc - from; 337 + from = loc + 1; 338 + 339 + /* Copy replacement string and update positions */ 340 + memcpy(to, replace, replace_len); 341 + to += replace_len; 342 + 343 + /* needle next occurrence or end of string */ 344 + loc = strchr(from, needle); 345 + } 346 + 347 + /* Copy any remaining chars + null */ 348 + strcpy(to, from); 349 + 350 + return new_s; 351 + }
+1
tools/perf/util/string2.h
··· 39 39 char *strdup_esc(const char *str); 40 40 41 41 unsigned int hex(char c); 42 + char *strreplace_chars(char needle, const char *haystack, const char *replace); 42 43 43 44 #endif /* PERF_STRING_H */