diff options
author | Dave Reisner <dreisner@archlinux.org> | 2011-07-04 00:55:04 +0200 |
---|---|---|
committer | Dave Reisner <dreisner@archlinux.org> | 2011-07-05 23:18:23 +0200 |
commit | 6cce517f1a78df885a1574252b3db9886185159d (patch) | |
tree | 83aade5d80b9399e2419818b04b893b9d5607900 | |
parent | dfc532668d4a4182ce196a895fdd5b017b505c6f (diff) | |
download | pacman-6cce517f1a78df885a1574252b3db9886185159d.tar.gz pacman-6cce517f1a78df885a1574252b3db9886185159d.tar.xz |
lib/rawstr: borrow raw string functions from curl
We'll need these functions to do locale agnostic and case insensitive
string comparisons.
Signed-off-by: Dave Reisner <dreisner@archlinux.org>
-rw-r--r-- | lib/libalpm/Makefile.am | 1 | ||||
-rw-r--r-- | lib/libalpm/rawstr.c | 135 | ||||
-rw-r--r-- | lib/libalpm/util.h | 2 |
3 files changed, 138 insertions, 0 deletions
diff --git a/lib/libalpm/Makefile.am b/lib/libalpm/Makefile.am index b2b6d0d2..c863fa9b 100644 --- a/lib/libalpm/Makefile.am +++ b/lib/libalpm/Makefile.am @@ -41,6 +41,7 @@ libalpm_la_SOURCES = \ log.h log.c \ package.h package.c \ pkghash.h pkghash.c \ + rawstr.c \ remove.h remove.c \ signing.c signing.h \ sync.h sync.c \ diff --git a/lib/libalpm/rawstr.c b/lib/libalpm/rawstr.c new file mode 100644 index 00000000..69224cbc --- /dev/null +++ b/lib/libalpm/rawstr.c @@ -0,0 +1,135 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at http://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ***************************************************************************/ + +/* These functions are borrowed from libcurl's lib/rawstr.c with minor + * modifications to style and naming. Curl_raw_equal and Curl_raw_nequal are + * further modified to be true cmp style functions, returning negative, zero, + * or positive. */ + +#include <stdlib.h> + +/* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because + its behavior is altered by the current locale. */ +static char raw_toupper(char in) +{ + switch(in) { + case 'a': + return 'A'; + case 'b': + return 'B'; + case 'c': + return 'C'; + case 'd': + return 'D'; + case 'e': + return 'E'; + case 'f': + return 'F'; + case 'g': + return 'G'; + case 'h': + return 'H'; + case 'i': + return 'I'; + case 'j': + return 'J'; + case 'k': + return 'K'; + case 'l': + return 'L'; + case 'm': + return 'M'; + case 'n': + return 'N'; + case 'o': + return 'O'; + case 'p': + return 'P'; + case 'q': + return 'Q'; + case 'r': + return 'R'; + case 's': + return 'S'; + case 't': + return 'T'; + case 'u': + return 'U'; + case 'v': + return 'V'; + case 'w': + return 'W'; + case 'x': + return 'X'; + case 'y': + return 'Y'; + case 'z': + return 'Z'; + } + return in; +} + +/* + * _alpm_raw_cmp() is for doing "raw" case insensitive strings. This is meant + * to be locale independent and only compare strings we know are safe for + * this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for + * some further explanation to why this function is necessary. + * + * The function is capable of comparing a-z case insensitively even for + * non-ascii. + */ + +int _alpm_raw_cmp(const char *first, const char *second) +{ + while(*first && *second) { + if(raw_toupper(*first) != raw_toupper(*second)) { + /* get out of the loop as soon as they don't match */ + break; + } + first++; + second++; + } + /* we do the comparison here (possibly again), just to make sure that if the + loop above is skipped because one of the strings reached zero, we must not + return this as a successful match */ + return (raw_toupper(*first) - raw_toupper(*second)); +} + +int _alpm_raw_ncmp(const char *first, const char *second, size_t max) +{ + while(*first && *second && max) { + if(raw_toupper(*first) != raw_toupper(*second)) { + break; + } + max--; + first++; + second++; + } + if(0 == max) { + /* they are equal this far */ + return 0; + } + + return (raw_toupper(*first) - raw_toupper(*second)); +} + +/* vim: set ts=2 sw=2 noet: */ diff --git a/lib/libalpm/util.h b/lib/libalpm/util.h index fd97824a..450dac9b 100644 --- a/lib/libalpm/util.h +++ b/lib/libalpm/util.h @@ -113,6 +113,8 @@ int _alpm_splitname(const char *target, char **name, char **version, unsigned long *name_hash); unsigned long _alpm_hash_sdbm(const char *str); long _alpm_parsedate(const char *line); +int _alpm_raw_cmp(const char *first, const char *second); +int _alpm_raw_ncmp(const char *first, const char *second, size_t max); #ifndef HAVE_STRSEP char *strsep(char **, const char *); |