From 39f848a431c95aaa11cab5727b48a85bc9f229be Mon Sep 17 00:00:00 2001 From: Ben Pfaff Date: Sun, 28 Aug 2022 14:20:22 -0700 Subject: [PATCH] str: New functions for case-matching of substrings, prefixes, and suffixes. --- src/libpspp/str.c | 32 ++++++++++++++++++++++++++++++++ src/libpspp/str.h | 3 +++ 2 files changed, 35 insertions(+) diff --git a/src/libpspp/str.c b/src/libpspp/str.c index 811674225c..2a592b9064 100644 --- a/src/libpspp/str.c +++ b/src/libpspp/str.c @@ -615,6 +615,21 @@ ss_match_string (struct substring *ss, const struct substring target) return false; } +/* If SS begins with TARGET, except possibly for case differences, removes it + and returns true. Otherwise, returns false without changing SS. */ +bool +ss_match_string_case (struct substring *ss, const struct substring target) +{ + size_t length = ss_length (target); + if (ss_equals_case (ss_head (*ss, length), target)) + { + ss_advance (ss, length); + return true; + } + else + return false; +} + /* Removes the first byte from SS and returns it. If SS is empty, returns EOF without modifying SS. */ int @@ -743,6 +758,14 @@ ss_starts_with (struct substring ss, struct substring prefix) && !memcmp (ss.string, prefix.string, prefix.length)); } +/* Returns true if SS starts with PREFIX in any case, false otherwise. */ +bool +ss_starts_with_case (struct substring ss, struct substring prefix) +{ + return (ss.length >= prefix.length + && !memcasecmp (ss.string, prefix.string, prefix.length)); +} + /* Returns true if SS ends with SUFFIX, false otherwise. */ bool ss_ends_with (struct substring ss, struct substring suffix) @@ -752,6 +775,15 @@ ss_ends_with (struct substring ss, struct substring suffix) suffix.length)); } +/* Returns true if SS ends with SUFFIX in any case, false otherwise. */ +bool +ss_ends_with_case (struct substring ss, struct substring suffix) +{ + return (ss.length >= suffix.length + && !memcasecmp (&ss.string[ss.length - suffix.length], suffix.string, + suffix.length)); +} + /* Returns the number of contiguous bytes at the beginning of SS that are in SKIP_SET. */ size_t diff --git a/src/libpspp/str.h b/src/libpspp/str.h index 91de05f395..c40915d939 100644 --- a/src/libpspp/str.h +++ b/src/libpspp/str.h @@ -118,6 +118,7 @@ void ss_advance (struct substring *, size_t); bool ss_match_byte (struct substring *, char); int ss_match_byte_in (struct substring *, struct substring); bool ss_match_string (struct substring *, const struct substring); +bool ss_match_string_case (struct substring *, const struct substring); int ss_get_byte (struct substring *); size_t ss_get_bytes (struct substring *, size_t n, struct substring *); bool ss_get_until (struct substring *, char delimiter, struct substring *); @@ -132,7 +133,9 @@ int ss_at (struct substring, size_t idx); int ss_first (struct substring); int ss_last (struct substring); bool ss_starts_with (struct substring, struct substring prefix); +bool ss_starts_with_case (struct substring, struct substring prefix); bool ss_ends_with (struct substring, struct substring suffix); +bool ss_ends_with_case (struct substring, struct substring suffix); size_t ss_span (struct substring, struct substring skip_set); size_t ss_cspan (struct substring, struct substring stop_set); size_t ss_find_byte (struct substring, char); -- 2.30.2