Merge patch series "some string cleanup, and a tweak of the "config" command"
Rasmus Villemoes <rv@rasmusvillemoes.dk> says: This started by me wanting something like what patch 8 does. That wasn't too hard, except we had no strcasestr(), and also our regex engine (which I didn't really want to pull into the mix anyway) doesn't have a flag that requests case-insensitive matching. So I wanted to add strcasestr(), but then I stumbled on a bunch of stuff that should be cleaned up in str-land. Link: https://lore.kernel.org/r/20260708203711.849489-1-rv@rasmusvillemoes.dk
This commit is contained in:
@@ -8,8 +8,6 @@
|
||||
* from linux kernel code.
|
||||
*/
|
||||
|
||||
#ifdef __KERNEL__ /* only set these up for kernel code */
|
||||
|
||||
#define __HAVE_ARCH_STRCPY
|
||||
static inline char *strcpy(char *__dest, const char *__src)
|
||||
{
|
||||
@@ -81,53 +79,4 @@ static inline int strcmp(const char *__cs, const char *__ct)
|
||||
return __res;
|
||||
}
|
||||
|
||||
#undef __HAVE_ARCH_STRNCMP
|
||||
extern int strncmp(const char *__cs, const char *__ct, size_t __n);
|
||||
|
||||
#undef __HAVE_ARCH_MEMSET
|
||||
extern void *memset(void *__s, int __c, size_t __count);
|
||||
|
||||
#undef __HAVE_ARCH_MEMCPY
|
||||
extern void *memcpy(void *__to, __const__ void *__from, size_t __n);
|
||||
|
||||
#undef __HAVE_ARCH_MEMMOVE
|
||||
extern void *memmove(void *__dest, __const__ void *__src, size_t __n);
|
||||
|
||||
#undef __HAVE_ARCH_MEMCHR
|
||||
extern void *memchr(const void *__s, int __c, size_t __n);
|
||||
|
||||
#undef __HAVE_ARCH_STRLEN
|
||||
extern size_t strlen(const char *);
|
||||
|
||||
/* arch/sh/lib/strcasecmp.c */
|
||||
extern int strcasecmp(const char *, const char *);
|
||||
|
||||
#else /* KERNEL */
|
||||
|
||||
/*
|
||||
* let user libraries deal with these,
|
||||
* IMHO the kernel has no place defining these functions for user apps
|
||||
*/
|
||||
|
||||
#define __HAVE_ARCH_STRCPY 1
|
||||
#define __HAVE_ARCH_STRNCPY 1
|
||||
#define __HAVE_ARCH_STRCAT 1
|
||||
#define __HAVE_ARCH_STRNCAT 1
|
||||
#define __HAVE_ARCH_STRCMP 1
|
||||
#define __HAVE_ARCH_STRNCMP 1
|
||||
#define __HAVE_ARCH_STRNICMP 1
|
||||
#define __HAVE_ARCH_STRCHR 1
|
||||
#define __HAVE_ARCH_STRRCHR 1
|
||||
#define __HAVE_ARCH_STRSTR 1
|
||||
#define __HAVE_ARCH_STRLEN 1
|
||||
#define __HAVE_ARCH_STRNLEN 1
|
||||
#define __HAVE_ARCH_MEMSET 1
|
||||
#define __HAVE_ARCH_MEMCPY 1
|
||||
#define __HAVE_ARCH_MEMMOVE 1
|
||||
#define __HAVE_ARCH_MEMSCAN 1
|
||||
#define __HAVE_ARCH_MEMCMP 1
|
||||
#define __HAVE_ARCH_MEMCHR 1
|
||||
#define __HAVE_ARCH_STRTOK 1
|
||||
|
||||
#endif /* KERNEL */
|
||||
#endif /* __ASM_SH_STRING_H */
|
||||
|
||||
+23
-3
@@ -6,6 +6,7 @@
|
||||
#include <command.h>
|
||||
#include <gzip.h>
|
||||
#include <malloc.h>
|
||||
#include <linux/string.h>
|
||||
|
||||
#include "config_data_gz.h"
|
||||
#include "config_data_size.h"
|
||||
@@ -29,7 +30,23 @@ static int do_config(struct cmd_tbl *cmdtp, int flag, int argc,
|
||||
}
|
||||
|
||||
dst[data_size] = 0;
|
||||
puts(dst);
|
||||
if (argc > 1) {
|
||||
const char *s = argv[1];
|
||||
char *b = dst, *e = dst + data_size, *n;
|
||||
|
||||
while (b < e) {
|
||||
n = strchrnul(b, '\n');
|
||||
*n = '\0';
|
||||
|
||||
if (strcasestr(b, s)) {
|
||||
puts(b);
|
||||
puts("\n");
|
||||
}
|
||||
b = n + 1;
|
||||
}
|
||||
} else {
|
||||
puts(dst);
|
||||
}
|
||||
|
||||
free:
|
||||
free(dst);
|
||||
@@ -38,7 +55,10 @@ free:
|
||||
}
|
||||
|
||||
U_BOOT_CMD(
|
||||
config, 1, 1, do_config,
|
||||
config, 2, 1, do_config,
|
||||
"print .config",
|
||||
""
|
||||
"[str]\n"
|
||||
"\n"
|
||||
"When the optional argument is given, only lines containing\n"
|
||||
"that string are printed. Matching is case-insensitive."
|
||||
);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
.. SPDX-License-Identifier: GPL-2.0
|
||||
|
||||
.. index::
|
||||
single: config (command)
|
||||
|
||||
config command
|
||||
==============
|
||||
|
||||
Synopsis
|
||||
--------
|
||||
|
||||
::
|
||||
|
||||
config [<str>]
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The config command prints the `.config` file used when building U-Boot
|
||||
to the console. Note that the `.config` file is usually several 1000
|
||||
lines long.
|
||||
|
||||
If the optional argument is given, only lines containing that string
|
||||
(case insensitively) are printed. That can be useful if one wants to
|
||||
check whether a specific option is enabled, or just to limit the
|
||||
output to the subsystem of interest.
|
||||
|
||||
The `.config` file is stored inside the U-Boot binary in
|
||||
gzip-compressed format.
|
||||
|
||||
Examples
|
||||
--------
|
||||
|
||||
.. code-block:: bash
|
||||
|
||||
# Print the entire .config
|
||||
config
|
||||
|
||||
# Print all lines related to pinctrl
|
||||
config pinctrl
|
||||
+3
-10
@@ -43,12 +43,8 @@ extern int strcmp(const char *,const char *);
|
||||
#ifndef __HAVE_ARCH_STRNCMP
|
||||
extern int strncmp(const char *,const char *,__kernel_size_t);
|
||||
#endif
|
||||
#ifndef __HAVE_ARCH_STRCASECMP
|
||||
int strcasecmp(const char *s1, const char *s2);
|
||||
#endif
|
||||
#ifndef __HAVE_ARCH_STRNCASECMP
|
||||
extern int strncasecmp(const char *s1, const char *s2, __kernel_size_t len);
|
||||
#endif
|
||||
int strncasecmp(const char *s1, const char *s2, __kernel_size_t len);
|
||||
#ifndef __HAVE_ARCH_STRCHR
|
||||
extern char * strchr(const char *,int);
|
||||
#endif
|
||||
@@ -63,7 +59,7 @@ extern char * strchr(const char *,int);
|
||||
* @c: character to search for
|
||||
* Return: position of @c in @s, or end of @s if not found
|
||||
*/
|
||||
const char *strchrnul(const char *s, int c);
|
||||
char *strchrnul(const char *s, int c);
|
||||
|
||||
#ifndef __HAVE_ARCH_STRRCHR
|
||||
extern char * strrchr(const char *,int);
|
||||
@@ -75,6 +71,7 @@ extern char * strstr(const char *,const char *);
|
||||
#ifndef __HAVE_ARCH_STRNSTR
|
||||
extern char *strnstr(const char *, const char *, size_t);
|
||||
#endif
|
||||
char *strcasestr(const char *, const char *);
|
||||
#ifndef __HAVE_ARCH_STRLEN
|
||||
extern __kernel_size_t strlen(const char *);
|
||||
#endif
|
||||
@@ -107,10 +104,6 @@ extern char * strndup(const char *, size_t);
|
||||
extern const char *strdup_const(const char *s);
|
||||
extern void kfree_const(const void *x);
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSWAB
|
||||
extern char * strswab(const char *);
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMSET
|
||||
extern void * memset(void *,int,__kernel_size_t);
|
||||
#endif
|
||||
|
||||
+30
-40
@@ -263,12 +263,12 @@ char * strchr(const char * s, int c)
|
||||
}
|
||||
#endif
|
||||
|
||||
const char *strchrnul(const char *s, int c)
|
||||
char *strchrnul(const char *s, int c)
|
||||
{
|
||||
for (; *s != (char)c; ++s)
|
||||
if (*s == '\0')
|
||||
break;
|
||||
return s;
|
||||
return (char *)s;
|
||||
}
|
||||
|
||||
#ifndef __HAVE_ARCH_STRRCHR
|
||||
@@ -399,7 +399,6 @@ void kfree_const(const void *x)
|
||||
}
|
||||
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSPN
|
||||
/**
|
||||
* strspn - Calculate the length of the initial substring of @s which only
|
||||
* contain letters in @accept
|
||||
@@ -424,9 +423,7 @@ size_t strspn(const char *s, const char *accept)
|
||||
|
||||
return count;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRPBRK
|
||||
/**
|
||||
* strpbrk - Find the first occurrence of a set of characters
|
||||
* @cs: The string to be searched
|
||||
@@ -444,9 +441,7 @@ char * strpbrk(const char * cs,const char * ct)
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRTOK
|
||||
/**
|
||||
* strtok - Split a string into tokens
|
||||
* @s: The string to be searched
|
||||
@@ -473,9 +468,7 @@ char * strtok(char * s,const char * ct)
|
||||
___strtok = send;
|
||||
return (sbegin);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSEP
|
||||
/**
|
||||
* strsep - Split a string into tokens
|
||||
* @s: The string to be searched
|
||||
@@ -501,35 +494,6 @@ char * strsep(char **s, const char *ct)
|
||||
|
||||
return sbegin;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_STRSWAB
|
||||
/**
|
||||
* strswab - swap adjacent even and odd bytes in %NUL-terminated string
|
||||
* s: address of the string
|
||||
*
|
||||
* returns the address of the swapped string or NULL on error. If
|
||||
* string length is odd, last byte is untouched.
|
||||
*/
|
||||
char *strswab(const char *s)
|
||||
{
|
||||
char *p, *q;
|
||||
|
||||
if ((NULL == s) || ('\0' == *s)) {
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
for (p=(char *)s, q=p+1; (*p != '\0') && (*q != '\0'); p+=2, q+=2) {
|
||||
char tmp;
|
||||
|
||||
tmp = *p;
|
||||
*p = *q;
|
||||
*q = tmp;
|
||||
}
|
||||
|
||||
return (char *) s;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMSET
|
||||
/**
|
||||
@@ -702,7 +666,7 @@ void *memdup(const void *src, size_t len)
|
||||
*
|
||||
* @s1: string to be searched
|
||||
* @s2: string to search for
|
||||
* @len: maximum number of characters in s2 to consider
|
||||
* @len: maximum number of characters in s1 to consider
|
||||
*
|
||||
* Return: pointer to the first occurrence or NULL
|
||||
*/
|
||||
@@ -728,7 +692,6 @@ char *strnstr(const char *s1, const char *s2, size_t len)
|
||||
*
|
||||
* @s1: string to be searched
|
||||
* @s2: string to search for
|
||||
* @len: maximum number of characters in s2 to consider
|
||||
*
|
||||
* Return: pointer to the first occurrence or NULL
|
||||
*/
|
||||
@@ -738,6 +701,33 @@ char *strstr(const char *s1, const char *s2)
|
||||
}
|
||||
#endif
|
||||
|
||||
/**
|
||||
* strcasestr() - Case insensitive substring search
|
||||
*
|
||||
* @haystack: string to be searched
|
||||
* @needle: string to search for
|
||||
*
|
||||
* Return: pointer to the first occurrence or NULL
|
||||
*
|
||||
* The case of both strings are ignored.
|
||||
*/
|
||||
char *strcasestr(const char *haystack, const char *needle)
|
||||
{
|
||||
size_t l1, l2;
|
||||
|
||||
l1 = strlen(haystack);
|
||||
l2 = strlen(needle);
|
||||
|
||||
while (l1 >= l2) {
|
||||
if (!strncasecmp(haystack, needle, l2))
|
||||
return (char *)haystack;
|
||||
haystack++;
|
||||
l1--;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifndef __HAVE_ARCH_MEMCHR
|
||||
/**
|
||||
* memchr - Find a character in an area of memory.
|
||||
|
||||
@@ -17,6 +17,7 @@ ifdef CONFIG_CONSOLE_RECORD
|
||||
obj-$(CONFIG_CMD_ACPI) += acpi.o
|
||||
endif
|
||||
obj-$(CONFIG_CMD_BDI) += bdinfo.o
|
||||
obj-$(CONFIG_CMD_CONFIG) += config.o
|
||||
obj-$(CONFIG_COREBOOT_SYSINFO) += coreboot.o
|
||||
obj-$(CONFIG_CMD_FDT) += fdt.o
|
||||
obj-$(CONFIG_CMD_HASH) += hash.o
|
||||
|
||||
@@ -0,0 +1,28 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Tests for config command
|
||||
*/
|
||||
|
||||
#include <console.h>
|
||||
#include <test/cmd.h>
|
||||
#include <test/ut.h>
|
||||
|
||||
static int cmd_test_config(struct unit_test_state *uts)
|
||||
{
|
||||
ut_assertok(run_command("config", 0));
|
||||
ut_assert_skip_to_line("# Automatically generated file; DO NOT EDIT.");
|
||||
ut_assert_skip_to_linen("# Compiler:");
|
||||
ut_assert_skip_to_line("CONFIG_CMD_CONFIG=y");
|
||||
|
||||
console_record_reset_enable();
|
||||
|
||||
ut_assertok(run_command("config cmd_config=y", 0));
|
||||
ut_assert_nextline("CONFIG_CMD_CONFIG=y");
|
||||
ut_assert_console_end();
|
||||
|
||||
ut_assertok(run_command("config 'this string never appears in .config'", 0));
|
||||
ut_assert_console_end();
|
||||
|
||||
return 0;
|
||||
}
|
||||
CMD_TEST(cmd_test_config, UTF_CONSOLE);
|
||||
+21
-3
@@ -284,18 +284,36 @@ static int lib_strstr(struct unit_test_state *uts)
|
||||
{
|
||||
const char *s1 = "Itsy Bitsy Teenie Weenie";
|
||||
const char *s2 = "eenie";
|
||||
const char *s3 = "easy";
|
||||
const char *s3 = "bits";
|
||||
|
||||
ut_asserteq_ptr(&s1[12], strstr(s1, s2));
|
||||
ut_asserteq_ptr(&s1[13], strstr(&s1[3], &s2[1]));
|
||||
ut_assertnull(strstr(s1, s3));
|
||||
ut_asserteq_ptr(&s1[2], strstr(s1, &s3[2]));
|
||||
ut_asserteq_ptr(&s1[8], strstr(&s1[5], &s3[2]));
|
||||
ut_asserteq_ptr(&s1[1], strstr(s1, &s3[2]));
|
||||
ut_asserteq_ptr(&s1[7], strstr(&s1[5], &s3[2]));
|
||||
|
||||
return 0;
|
||||
}
|
||||
LIB_TEST(lib_strstr, 0);
|
||||
|
||||
/** lib_strcasestr() - unit test for strcasestr() */
|
||||
static int lib_strcasestr(struct unit_test_state *uts)
|
||||
{
|
||||
const char *s1 = "Itsy Bitsy Teenie Weenie";
|
||||
const char *s2 = "eenie";
|
||||
const char *s3 = "bits";
|
||||
|
||||
ut_asserteq_ptr(&s1[12], strcasestr(s1, s2));
|
||||
ut_asserteq_ptr(&s1[13], strcasestr(&s1[3], &s2[1]));
|
||||
ut_asserteq_ptr(&s1[5], strcasestr(s1, s3));
|
||||
ut_asserteq_ptr(&s1[1], strcasestr(s1, &s3[2]));
|
||||
ut_asserteq_ptr(&s1[7], strcasestr(&s1[5], &s3[2]));
|
||||
ut_assertnull(strcasestr(&s1[6], s3));
|
||||
|
||||
return 0;
|
||||
}
|
||||
LIB_TEST(lib_strcasestr, 0);
|
||||
|
||||
static int lib_strim(struct unit_test_state *uts)
|
||||
{
|
||||
char buf[BUFLEN], *p;
|
||||
|
||||
Reference in New Issue
Block a user