Commit c306c1fe authored by James Clark's avatar James Clark Committed by Peng Zhang
Browse files

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

stable inclusion
from stable-v6.6.33
commit 95e33c0f617b436436492d4fd0acdd5c0395071c
category: bugfix
bugzilla: https://gitee.com/openeuler/kernel/issues/IA74DQ

Reference: https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=95e33c0f617b436436492d4fd0acdd5c0395071c



--------------------------------

commit 8a55c1e2c9e123b399b272a7db23f09dbb74af21 upstream.

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: default avatarIan Rogers <irogers@google.com>
Signed-off-by: default avatarJames 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: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: default avatarGreg Kroah-Hartman <gregkh@linuxfoundation.org>

Conflicts:
	tools/perf/tests/Build
[Context conflict]
Signed-off-by: default avatarZhangPeng <zhangpeng362@huawei.com>
parent 2456f06d
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -66,6 +66,7 @@ perf-y += dlfilter-test.o
perf-y += sigtrap.o
perf-y += event_groups.o
perf-y += symbols.o
perf-y += util.o

ifeq ($(SRCARCH),$(filter $(SRCARCH),x86 arm arm64 powerpc sw_64))
perf-$(CONFIG_DWARF_UNWIND) += dwarf-unwind.o
+1 −0
Original line number Diff line number Diff line
@@ -123,6 +123,7 @@ static struct test_suite *generic_tests[] = {
	&suite__sigtrap,
	&suite__event_groups,
	&suite__symbols,
	&suite__util,
	NULL,
};

+1 −0
Original line number Diff line number Diff line
@@ -145,6 +145,7 @@ DECLARE_SUITE(dlfilter);
DECLARE_SUITE(sigtrap);
DECLARE_SUITE(event_groups);
DECLARE_SUITE(symbols);
DECLARE_SUITE(util);

/*
 * PowerPC and S390 do not support creation of instruction breakpoints using the
+31 −0
Original line number Diff line number Diff line
// SPDX-License-Identifier: GPL-2.0
#include "tests.h"
#include "util/debug.h"

#include <linux/compiler.h>
#include <stdlib.h>
#include <string2.h>

static int test_strreplace(char needle, const char *haystack,
			   const char *replace, const char *expected)
{
	char *new = strreplace_chars(needle, haystack, replace);
	int ret = strcmp(new, expected);

	free(new);
	return ret == 0;
}

static int test__util(struct test_suite *t __maybe_unused, int subtest __maybe_unused)
{
	TEST_ASSERT_VAL("empty string", test_strreplace(' ', "", "123", ""));
	TEST_ASSERT_VAL("no match", test_strreplace('5', "123", "4", "123"));
	TEST_ASSERT_VAL("replace 1", test_strreplace('3', "123", "4", "124"));
	TEST_ASSERT_VAL("replace 2", test_strreplace('a', "abcabc", "ef", "efbcefbc"));
	TEST_ASSERT_VAL("replace long", test_strreplace('a', "abcabc", "longlong",
							"longlongbclonglongbc"));

	return 0;
}

DEFINE_SUITE("util", util);
+48 −0
Original line number Diff line number Diff line
@@ -301,3 +301,51 @@ unsigned int hex(char c)
		return c - 'a' + 10;
	return c - 'A' + 10;
}

/*
 * Replace all occurrences of character 'needle' in string 'haystack' with
 * string 'replace'
 *
 * The new string could be longer so a new string is returned which must be
 * freed.
 */
char *strreplace_chars(char needle, const char *haystack, const char *replace)
{
	int replace_len = strlen(replace);
	char *new_s, *to;
	const char *loc = strchr(haystack, needle);
	const char *from = haystack;
	int num = 0;

	/* Count occurrences */
	while (loc) {
		loc = strchr(loc + 1, needle);
		num++;
	}

	/* Allocate enough space for replacements and reset first location */
	new_s = malloc(strlen(haystack) + (num * (replace_len - 1) + 1));
	if (!new_s)
		return NULL;
	loc = strchr(haystack, needle);
	to = new_s;

	while (loc) {
		/* Copy original string up to found char and update positions */
		memcpy(to, from, 1 + loc - from);
		to += loc - from;
		from = loc + 1;

		/* Copy replacement string and update positions */
		memcpy(to, replace, replace_len);
		to += replace_len;

		/* needle next occurrence or end of string */
		loc = strchr(from, needle);
	}

	/* Copy any remaining chars + null */
	strcpy(to, from);

	return new_s;
}
Loading