X-Git-Url: https://git.notmuchmail.org/git?p=notmuch;a=blobdiff_plain;f=util%2Fstring-util.c;h=de8430b2add34dea3fdf52507cf442c420cd170f;hp=9e2f728fc6750c586f3effed3ecac5673ea980e0;hb=b23902a61158ecdbca2d9d96c6eaf509d6e3d205;hpb=029790d3ff6e9fccfed2214efac777b8c438e318 diff --git a/util/string-util.c b/util/string-util.c index 9e2f728f..de8430b2 100644 --- a/util/string-util.c +++ b/util/string-util.c @@ -13,7 +13,7 @@ * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License - * along with this program. If not, see http://www.gnu.org/licenses/ . + * along with this program. If not, see https://www.gnu.org/licenses/ . * * Author: Jani Nikula */ @@ -37,6 +37,14 @@ strtok_len (char *s, const char *delim, size_t *len) return *len ? s : NULL; } +const char * +strtok_len_c (const char *s, const char *delim, size_t *len) +{ + /* strtok_len is already const-safe, but we can't express both + * versions in the C type system. */ + return strtok_len ((char *) s, delim, len); +} + char * sanitize_string (const void *ctx, const char *str) { @@ -52,7 +60,7 @@ sanitize_string (const void *ctx, const char *str) for (loop = out; *loop; loop++) { if (*loop == '\t' || *loop == '\n') *loop = ' '; - else if ((unsigned char)(*loop) < 32) + else if ((unsigned char) (*loop) < 32) *loop = '?'; } @@ -75,11 +83,13 @@ make_boolean_term (void *ctx, const char *prefix, const char *term, int need_quoting = 0; /* Do we need quoting? To be paranoid, we quote anything - * containing a quote, even though it only matters at the + * containing a quote or '(', even though these only matter at the * beginning, and anything containing non-ASCII text. */ - for (in = term; *in && !need_quoting; in++) - if (is_unquoted_terminator (*in) || *in == '"' - || (unsigned char)*in > 127) + if (! term[0]) + need_quoting = 1; + for (in = term; *in && ! need_quoting; in++) + if (is_unquoted_terminator (*in) || *in == '"' || *in == '(' + || (unsigned char) *in > 127) need_quoting = 1; if (need_quoting) @@ -131,7 +141,7 @@ make_boolean_term (void *ctx, const char *prefix, const char *term, return 0; } -static const char* +const char * skip_space (const char *str) { while (*str && isspace ((unsigned char) *str)) @@ -144,6 +154,7 @@ parse_boolean_term (void *ctx, const char *str, char **prefix_out, char **term_out) { int err = EINVAL; + *prefix_out = *term_out = NULL; /* Parse prefix */ @@ -183,7 +194,7 @@ parse_boolean_term (void *ctx, const char *str, } /* Did the term terminate without a closing quote or is there * trailing text after the closing quote? */ - if (!closed || *pos) + if (! closed || *pos) goto FAIL; *out = '\0'; } else { @@ -205,9 +216,57 @@ parse_boolean_term (void *ctx, const char *str, } return 0; - FAIL: + FAIL: talloc_free (*prefix_out); talloc_free (*term_out); errno = err; return -1; } + +int +strcmp_null (const char *s1, const char *s2) +{ + if (s1 && s2) + return strcmp (s1, s2); + else if (! s1 && ! s2) + return 0; + else if (s1) + return 1; /* s1 (non-NULL) is greater than s2 (NULL) */ + else + return -1; /* s1 (NULL) is less than s2 (non-NULL) */ +} + +int +strcase_equal (const void *a, const void *b) +{ + return strcasecmp (a, b) == 0; +} + +unsigned int +strcase_hash (const void *ptr) +{ + const char *s = ptr; + + /* This is the djb2 hash. */ + unsigned int hash = 5381; + + while (s && *s) { + hash = ((hash << 5) + hash) + tolower (*s); + s++; + } + + return hash; +} + +void +strip_trailing (char *str, char ch) +{ + int i; + + for (i = strlen (str) - 1; i >= 0; i--) { + if (str[i] == ch) + str[i] = '\0'; + else + break; + } +}