From: Martin Mares Date: Mon, 18 Apr 2011 20:48:21 +0000 (+0200) Subject: Added string functions for matching of prefixes and suffixes X-Git-Tag: v5.0~74^2~18 X-Git-Url: http://mj.ucw.cz/gitweb/?a=commitdiff_plain;h=521609b4721376161eabe89c9431aa221e87e263;p=libucw.git Added string functions for matching of prefixes and suffixes --- diff --git a/ucw/Makefile b/ucw/Makefile index 8d787711..fab1a16e 100644 --- a/ucw/Makefile +++ b/ucw/Makefile @@ -30,7 +30,7 @@ LIBUCW_MODS= \ base64 base224 \ sync \ qache \ - string str-esc str-split str-match str-imatch str-hex \ + string str-esc str-split str-match str-imatch str-hex str-fix \ bbuf gary \ getopt \ strtonum \ @@ -130,7 +130,7 @@ $(o)/ucw/bbuf.test: $(o)/ucw/bbuf-t $(o)/ucw/getopt.test: $(o)/ucw/getopt-t $(o)/ucw/ff-unicode.test: $(o)/ucw/ff-unicode-t $(o)/ucw/eltpool.test: $(o)/ucw/eltpool-t -$(o)/ucw/string.test: $(o)/ucw/str-hex-t $(o)/ucw/str-esc-t +$(o)/ucw/string.test: $(o)/ucw/str-hex-t $(o)/ucw/str-esc-t $(o)/ucw/str-fix-t $(o)/ucw/sha1.test: $(o)/ucw/sha1-t $(o)/ucw/sha1-hmac-t $(o)/ucw/trie-test.test: $(o)/ucw/trie-test $(o)/ucw/asort-test.test: $(o)/ucw/asort-test diff --git a/ucw/str-fix.c b/ucw/str-fix.c new file mode 100644 index 00000000..deb128e8 --- /dev/null +++ b/ucw/str-fix.c @@ -0,0 +1,111 @@ +/* + * UCW Library -- Matching Prefixes and Suffixes + * + * (c) 2011 Martin Mares + * + * This software may be freely distributed and used according to the terms + * of the GNU Lesser General Public License. + */ + +#include "ucw/lib.h" +#include "ucw/string.h" + +#include + +int +str_has_prefix(char *str, char *prefix) +{ + size_t pxlen = strlen(prefix); + return !strncmp(str, prefix, pxlen); +} + +int +str_has_suffix(char *str, char *suffix) +{ + size_t sxlen = strlen(suffix); + size_t len = strlen(str); + + if (len < sxlen) + return 0; + else + return !strcmp(str + len - sxlen, suffix); +} + +int +str_hier_prefix(char *str, char *prefix, uns sep) +{ + while (*str && *prefix) + { + size_t sl=0, pl=0; + while (str[sl] && (uns) str[sl] != sep) + sl++; + while (prefix[pl] && (uns) prefix[pl] != sep) + pl++; + if (sl != pl || memcmp(str, prefix, sl)) + return 0; + str += sl, prefix += pl; + if (!*str) + return !*prefix; + if (!*prefix) + return 1; + str++, prefix++; + } + return !*prefix; +} + +int +str_hier_suffix(char *str, char *suffix, uns sep) +{ + char *st = str + strlen(str); + char *sx = suffix + strlen(suffix); + while (st > str && sx > suffix) + { + size_t sl=0, pl=0; + while (st-sl > str && (uns) st[-sl-1] != sep) + sl++; + while (sx-pl > suffix && (uns) sx[-pl-1] != sep) + pl++; + if (sl != pl || memcmp(st-sl, sx-pl, sl)) + return 0; + st -= sl, sx -= pl; + if (st == str) + return (sx == suffix); + if (sx == suffix) + return 1; + st--, sx--; + } + return (sx == suffix); +} + +#ifdef TEST + +#include + +int main(int argc, char **argv) +{ + if (argc != 4) + return 1; + + int ret; + switch (argv[1][0]) + { + case 'p': + ret = str_has_prefix(argv[2], argv[3]); + break; + case 's': + ret = str_has_suffix(argv[2], argv[3]); + break; + case 'P': + ret = str_hier_prefix(argv[2], argv[3], '.'); + break; + case 'S': + ret = str_hier_suffix(argv[2], argv[3], '.'); + break; + default: + return 1; + } + printf("%s\n", (ret ? "YES" : "NO")); + return 0; +} + +#endif diff --git a/ucw/string.h b/ucw/string.h index 935da33b..8cb3cd42 100644 --- a/ucw/string.h +++ b/ucw/string.h @@ -2,7 +2,7 @@ * UCW Library -- String Routines * * (c) 2006 Pavel Charvat - * (c) 2007--2008 Martin Mares + * (c) 2007--2011 Martin Mares * * This software may be freely distributed and used according to the terms * of the GNU Lesser General Public License. @@ -42,4 +42,26 @@ const char *hex_to_mem(byte *dest, const char *src, uns max_bytes, uns flags); // Bottom 8 bits of flags are an optional separator of bytes, the rest is: #define MEM_TO_HEX_UPCASE 0x100 +/* str-fix.c */ + +int str_has_prefix(char *str, char *prefix); /** Tests if @str starts with @prefix. **/ +int str_has_suffix(char *str, char *suffix); /** Tests if @str ends with @suffix. **/ + +/** + * Let @str and @prefix be hierarchical names with components separated by + * a character @sep. Returns true if @str starts with @prefix, respecting + * component boundaries. + * + * For example, when @sep is '/' and @str is "/usr/local/bin", then: + * - "/usr/local" is a prefix + * - "/usr/local/" is a prefix, too + * - "/usr/loc" is not, + * - "/usr/local/bin" is a prefix, + * - "/usr/local/bin/" is not, + * - "/" is a prefix, + * - "" is a prefix, + **/ +int str_hier_prefix(char *str, char *prefix, uns sep); +int str_hier_suffix(char *str, char *suffix, uns sep); /** Like @str_hier_prefix(), but for suffixes. **/ + #endif diff --git a/ucw/string.t b/ucw/string.t index 6173026c..8c159379 100644 --- a/ucw/string.t +++ b/ucw/string.t @@ -13,3 +13,87 @@ Out: 40 08 61 01 61 Run: ../obj/ucw/str-esc-t '\a\b\f\r\n\t\v\?\"'"\\'" Out: 07 08 0c 0d 0a 09 0b 3f 22 27 + +Name: prefix1 +Run: ../obj/ucw/str-fix-t p homo.sapiens.neanderthalensis homo.sap +Out: YES + +Name: prefix2 +Run: ../obj/ucw/str-fix-t p homo.sapiens.neanderthalensis homo.sapiens.neanderthalensis +Out: YES + +Name: prefix3 +Run: ../obj/ucw/str-fix-t p homo.sapiens.neanderthalensis "" +Out: YES + +Name: prefix4 +Run: ../obj/ucw/str-fix-t p homo.sapiens.neanderthalensis homo.sapiens.neanderthalensisis +Out: NO + +Name: suffix1 +Run: ../obj/ucw/str-fix-t s homo.sapiens.neanderthalensis ensis +Out: YES + +Name: suffix2 +Run: ../obj/ucw/str-fix-t s homo.sapiens.neanderthalensis homo.sapiens.neanderthalensis +Out: YES + +Name: suffix3 +Run: ../obj/ucw/str-fix-t s homo.sapiens.neanderthalensis "" +Out: YES + +Name: suffix4 +Run: ../obj/ucw/str-fix-t s homo.sapiens.neanderthalensis ecce.homo.sapiens.neanderthalensis +Out: NO + +Name: hier-prefix1 +Run: ../obj/ucw/str-fix-t P homo.sapiens.neanderthalensis homo.sap +Out: NO + +Name: hier-prefix2 +Run: ../obj/ucw/str-fix-t P homo.sapiens.neanderthalensis homo.sapiens +Out: YES + +Name: hier-prefix3 +Run: ../obj/ucw/str-fix-t P homo.sapiens.neanderthalensis homo.sapiens. +Out: YES + +Name: hier-prefix4 +Run: ../obj/ucw/str-fix-t P homo.sapiens.neanderthalensis homo.sapiens.neanderthalensis +Out: YES + +Name: hier-prefix5 +Run: ../obj/ucw/str-fix-t P homo.sapiens.neanderthalensis homo.sapiens.neanderthalensis. +Out: NO + +Name: hier-prefix6 +Run: ../obj/ucw/str-fix-t P homo.sapiens.neanderthalensis "" +Out: YES + +Name: hier-suffix1 +Run: ../obj/ucw/str-fix-t S homo.sapiens.neanderthalensis ensis +Out: NO + +Name: hier-suffix2 +Run: ../obj/ucw/str-fix-t S homo.sapiens.neanderthalensis sapiens.neanderthalensis +Out: YES + +Name: hier-suffix3 +Run: ../obj/ucw/str-fix-t S homo.sapiens.neanderthalensis .sapiens.neanderthalensis +Out: YES + +Name: hier-suffix4 +Run: ../obj/ucw/str-fix-t P homo.sapiens.neanderthalensis homo.sapiens.neanderthalensis +Out: YES + +Name: hier-suffix5 +Run: ../obj/ucw/str-fix-t P homo.sapiens.neanderthalensis .homo.sapiens.neanderthalensis +Out: NO + +Name: hier-suffix6 +Run: ../obj/ucw/str-fix-t S homo.sapiens.neanderthalensis "" +Out: YES + +Name: hier-suffix7 +Run: ../obj/ucw/str-fix-t S homo.sapiens.neanderthalensis ecce.homo.sapiens.neanderthalensis +Out: NO