From 63bb04509e79e2edc4b16962c7fa947b56b2a2a0 Mon Sep 17 00:00:00 2001 From: Karel Zak Date: Mon, 2 May 2022 15:07:42 +0200 Subject: [PATCH] lib/strutils: add ul_strchr_escaped() Like strchr(), but ignores escaped chars. Signed-off-by: Karel Zak --- include/strutils.h | 2 ++ lib/strutils.c | 35 +++++++++++++++++++++++++++++++++++ 2 files changed, 37 insertions(+) diff --git a/include/strutils.h b/include/strutils.h index ca2b0d9a25..45c8f98241 100644 --- a/include/strutils.h +++ b/include/strutils.h @@ -389,6 +389,8 @@ extern int strappend(char **a, const char *b); extern const char *split(const char **state, size_t *l, const char *separator, int quoted); +extern char *ul_strchr_escaped(const char *s, int c); + extern int skip_fline(FILE *fp); extern int ul_stralnumcmp(const char *p1, const char *p2); diff --git a/lib/strutils.c b/lib/strutils.c index 2dcc03d149..efa2505c07 100644 --- a/lib/strutils.c +++ b/lib/strutils.c @@ -998,6 +998,37 @@ static size_t strcspn_escaped(const char *s, const char *reject) return n - escaped; } +/* + * Like strchr() but ignores @c if escaped by '\', '\\' is interpreted like '\'. + * + * For example for @c='X': + * + * "abcdXefgXh" --> "XefgXh" + * "abcd\XefgXh" --> "Xh" + * "abcd\\XefgXh" --> "XefgXh" + * "abcd\\\XefgXh" --> "Xh" + * "abcd\Xefg\Xh" --> (null) + * + * "abcd\\XefgXh" --> "\XefgXh" for @c='\\' + */ +char *ul_strchr_escaped(const char *s, int c) +{ + char *p; + int esc = 0; + + for (p = (char *) s; p && *p; p++) { + if (!esc && *p == '\\') { + esc = 1; + continue; + } + if (*p == c && (!esc || c == '\\')) + return p; + esc = 0; + } + + return NULL; +} + /* Split a string into words. */ const char *split(const char **state, size_t *l, const char *separator, int quoted) { @@ -1295,6 +1326,10 @@ int main(int argc, char *argv[]) printf("'%s'-->%hu\n", argv[2], strtou16_or_err(argv[2], "strtou16 failed")); return EXIT_SUCCESS; + } else if (argc == 4 && strcmp(argv[1], "--strchr-escaped") == 0) { + printf("\"%s\" --> \"%s\"\n", argv[2], ul_strchr_escaped(argv[2], *argv[3])); + return EXIT_SUCCESS; + } else { fprintf(stderr, "usage: %1$s --size [suffix]\n" " %1$s --cmp-paths \n" -- 2.47.3