Skip to content

Commit 8a55c1e

Browse files
James-A-Clarkacmel
authored andcommitted
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 <[email protected]> Signed-off-by: James Clark <[email protected]> Cc: Adrian Hunter <[email protected]> Cc: Alexander Shishkin <[email protected]> Cc: Chen Zhongjin <[email protected]> Cc: Eduard Zingerman <[email protected]> Cc: Haixin Yu <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Jing Zhang <[email protected]> Cc: Jiri Olsa <[email protected]> Cc: John Garry <[email protected]> Cc: Kajol Jain <[email protected]> Cc: Kan Liang <[email protected]> Cc: Leo Yan <[email protected]> Cc: Liam Howlett <[email protected]> Cc: Madhavan Srinivasan <[email protected]> Cc: Mark Rutland <[email protected]> Cc: Mike Leach <[email protected]> Cc: Namhyung Kim <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Ravi Bangoria <[email protected]> Cc: Will Deacon <[email protected]> Cc: Yang Jihong <[email protected]> Cc: [email protected] Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Arnaldo Carvalho de Melo <[email protected]>
1 parent f561fc7 commit 8a55c1e

File tree

6 files changed

+83
-0
lines changed

6 files changed

+83
-0
lines changed

tools/perf/tests/Build

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ perf-y += dlfilter-test.o
6666
perf-y += sigtrap.o
6767
perf-y += event_groups.o
6868
perf-y += symbols.o
69+
perf-y += util.o
6970

7071
ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc))
7172
perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o

tools/perf/tests/builtin-test.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ static struct test_suite *generic_tests[] = {
123123
&suite__sigtrap,
124124
&suite__event_groups,
125125
&suite__symbols,
126+
&suite__util,
126127
NULL,
127128
};
128129

tools/perf/tests/tests.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,7 @@ DECLARE_SUITE(dlfilter);
145145
DECLARE_SUITE(sigtrap);
146146
DECLARE_SUITE(event_groups);
147147
DECLARE_SUITE(symbols);
148+
DECLARE_SUITE(util);
148149

149150
/*
150151
* PowerPC and S390 do not support creation of instruction breakpoints using the

tools/perf/tests/util.c

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
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);

tools/perf/util/string.c

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,3 +301,51 @@ unsigned int hex(char c)
301301
return c - 'a' + 10;
302302
return c - 'A' + 10;
303303
}
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+
}

tools/perf/util/string2.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,5 +39,6 @@ char *strpbrk_esc(char *str, const char *stopset);
3939
char *strdup_esc(const char *str);
4040

4141
unsigned int hex(char c);
42+
char *strreplace_chars(char needle, const char *haystack, const char *replace);
4243

4344
#endif /* PERF_STRING_H */

0 commit comments

Comments
 (0)