Add string_contains_word_strv()
I had to move STRV_MAKE to macro.h. There is a circular dependency between extract-word.h, strv.h, and string-util.h that makes it hard to define the inline function otherwise.
This commit is contained in:
parent
81823e6c12
commit
46bf625aca
|
@ -14,6 +14,7 @@
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
|
#include "strv.h"
|
||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
|
|
||||||
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
|
int extract_first_word(const char **p, char **ret, const char *separators, ExtractFlags flags) {
|
||||||
|
|
|
@ -538,6 +538,9 @@ static inline int __coverity_check_and_return__(int condition) {
|
||||||
(y) = (_t); \
|
(y) = (_t); \
|
||||||
} while (false)
|
} while (false)
|
||||||
|
|
||||||
|
#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
|
||||||
|
#define STRV_MAKE_EMPTY ((char*[1]) { NULL })
|
||||||
|
|
||||||
/* Iterates through a specified list of pointers. Accepts NULL pointers, but uses (void*) -1 as internal marker for EOL. */
|
/* Iterates through a specified list of pointers. Accepts NULL pointers, but uses (void*) -1 as internal marker for EOL. */
|
||||||
#define FOREACH_POINTER(p, x, ...) \
|
#define FOREACH_POINTER(p, x, ...) \
|
||||||
for (typeof(p) *_l = (typeof(p)[]) { ({ p = x; }), ##__VA_ARGS__, (void*) -1 }; \
|
for (typeof(p) *_l = (typeof(p)[]) { ({ p = x; }), ##__VA_ARGS__, (void*) -1 }; \
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
#include "macro.h"
|
#include "macro.h"
|
||||||
#include "memory-util.h"
|
#include "memory-util.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
|
#include "strv.h"
|
||||||
#include "terminal-util.h"
|
#include "terminal-util.h"
|
||||||
#include "utf8.h"
|
#include "utf8.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
@ -1209,11 +1210,13 @@ int string_extract_line(const char *s, size_t i, char **ret) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int string_contains_word(const char *string, const char *separators, const char *word) {
|
int string_contains_word_strv(const char *string, const char *separators, char **words, const char **ret_word) {
|
||||||
/* In the default mode with no separators specified, we split on whitespace and
|
/* In the default mode with no separators specified, we split on whitespace and
|
||||||
* don't coalesce separators. */
|
* don't coalesce separators. */
|
||||||
const ExtractFlags flags = separators ? EXTRACT_DONT_COALESCE_SEPARATORS : 0;
|
const ExtractFlags flags = separators ? EXTRACT_DONT_COALESCE_SEPARATORS : 0;
|
||||||
|
|
||||||
|
const char *found = NULL;
|
||||||
|
|
||||||
for (const char *p = string;;) {
|
for (const char *p = string;;) {
|
||||||
_cleanup_free_ char *w = NULL;
|
_cleanup_free_ char *w = NULL;
|
||||||
int r;
|
int r;
|
||||||
|
@ -1222,8 +1225,14 @@ int string_contains_word(const char *string, const char *separators, const char
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
return r;
|
return r;
|
||||||
if (r == 0)
|
if (r == 0)
|
||||||
return false;
|
break;
|
||||||
if (streq(w, word))
|
|
||||||
return true;
|
found = strv_find(words, w);
|
||||||
|
if (found)
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (ret_word)
|
||||||
|
*ret_word = found;
|
||||||
|
return !!found;
|
||||||
}
|
}
|
||||||
|
|
|
@ -280,4 +280,8 @@ char* string_erase(char *x);
|
||||||
|
|
||||||
int string_truncate_lines(const char *s, size_t n_lines, char **ret);
|
int string_truncate_lines(const char *s, size_t n_lines, char **ret);
|
||||||
int string_extract_line(const char *s, size_t i, char **ret);
|
int string_extract_line(const char *s, size_t i, char **ret);
|
||||||
int string_contains_word(const char *string, const char *separators, const char *word);
|
|
||||||
|
int string_contains_word_strv(const char *string, const char *separators, char **words, const char **ret_word);
|
||||||
|
static inline int string_contains_word(const char *string, const char *separators, const char *word) {
|
||||||
|
return string_contains_word_strv(string, separators, STRV_MAKE(word), NULL);
|
||||||
|
}
|
||||||
|
|
|
@ -123,10 +123,6 @@ bool strv_overlap(char * const *a, char * const *b) _pure_;
|
||||||
char **strv_sort(char **l);
|
char **strv_sort(char **l);
|
||||||
void strv_print(char * const *l);
|
void strv_print(char * const *l);
|
||||||
|
|
||||||
#define STRV_MAKE(...) ((char**) ((const char*[]) { __VA_ARGS__, NULL }))
|
|
||||||
|
|
||||||
#define STRV_MAKE_EMPTY ((char*[1]) { NULL })
|
|
||||||
|
|
||||||
#define strv_from_stdarg_alloca(first) \
|
#define strv_from_stdarg_alloca(first) \
|
||||||
({ \
|
({ \
|
||||||
char **_l; \
|
char **_l; \
|
||||||
|
|
|
@ -796,6 +796,35 @@ static void test_string_extract_line(void) {
|
||||||
test_string_extract_lines_one("\n\n\nx\n", 3, "x", false);
|
test_string_extract_lines_one("\n\n\nx\n", 3, "x", false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void test_string_contains_word_strv(void) {
|
||||||
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
|
const char *w;
|
||||||
|
|
||||||
|
assert_se(string_contains_word_strv("a b cc", NULL, STRV_MAKE("a", "b"), NULL));
|
||||||
|
|
||||||
|
assert_se(string_contains_word_strv("a b cc", NULL, STRV_MAKE("a", "b"), &w));
|
||||||
|
assert_se(streq(w, "a"));
|
||||||
|
|
||||||
|
assert_se(!string_contains_word_strv("a b cc", NULL, STRV_MAKE("d"), &w));
|
||||||
|
assert_se(w == NULL);
|
||||||
|
|
||||||
|
assert_se(string_contains_word_strv("a b cc", NULL, STRV_MAKE("b", "a"), &w));
|
||||||
|
assert_se(streq(w, "a"));
|
||||||
|
|
||||||
|
assert_se(string_contains_word_strv("b a b cc", NULL, STRV_MAKE("b", "a", "b"), &w));
|
||||||
|
assert_se(streq(w, "b"));
|
||||||
|
|
||||||
|
assert_se(string_contains_word_strv("a b cc", NULL, STRV_MAKE("b", ""), &w));
|
||||||
|
assert_se(streq(w, "b"));
|
||||||
|
|
||||||
|
assert_se(!string_contains_word_strv("a b cc", NULL, STRV_MAKE(""), &w));
|
||||||
|
assert_se(w == NULL);
|
||||||
|
|
||||||
|
assert_se(string_contains_word_strv("a b cc", " ", STRV_MAKE(""), &w));
|
||||||
|
assert_se(streq(w, ""));
|
||||||
|
}
|
||||||
|
|
||||||
static void test_string_contains_word(void) {
|
static void test_string_contains_word(void) {
|
||||||
log_info("/* %s */", __func__);
|
log_info("/* %s */", __func__);
|
||||||
|
|
||||||
|
@ -884,6 +913,7 @@ int main(int argc, char *argv[]) {
|
||||||
test_memory_startswith_no_case();
|
test_memory_startswith_no_case();
|
||||||
test_string_truncate_lines();
|
test_string_truncate_lines();
|
||||||
test_string_extract_line();
|
test_string_extract_line();
|
||||||
|
test_string_contains_word_strv();
|
||||||
test_string_contains_word();
|
test_string_contains_word();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
Loading…
Reference in a new issue