libalpm
Arch Linux Package Manager Library
|
00001 /*************************************************************************** 00002 * _ _ ____ _ 00003 * Project ___| | | | _ \| | 00004 * / __| | | | |_) | | 00005 * | (__| |_| | _ <| |___ 00006 * \___|\___/|_| \_\_____| 00007 * 00008 * Copyright (C) 1998 - 2011, Daniel Stenberg, <daniel@haxx.se>, et al. 00009 * 00010 * This software is licensed as described in the file COPYING, which 00011 * you should have received as part of this distribution. The terms 00012 * are also available at http://curl.haxx.se/docs/copyright.html. 00013 * 00014 * You may opt to use, copy, modify, merge, publish, distribute and/or sell 00015 * copies of the Software, and permit persons to whom the Software is 00016 * furnished to do so, under the terms of the COPYING file. 00017 * 00018 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 00019 * KIND, either express or implied. 00020 * 00021 ***************************************************************************/ 00022 00023 /* These functions are borrowed from libcurl's lib/rawstr.c with minor 00024 * modifications to style and naming. Curl_raw_equal and Curl_raw_nequal are 00025 * further modified to be true cmp style functions, returning negative, zero, 00026 * or positive. */ 00027 00028 #include <stdlib.h> 00029 00030 #include "util.h" 00031 00032 /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because 00033 its behavior is altered by the current locale. */ 00034 static char raw_toupper(char in) 00035 { 00036 switch(in) { 00037 case 'a': 00038 return 'A'; 00039 case 'b': 00040 return 'B'; 00041 case 'c': 00042 return 'C'; 00043 case 'd': 00044 return 'D'; 00045 case 'e': 00046 return 'E'; 00047 case 'f': 00048 return 'F'; 00049 case 'g': 00050 return 'G'; 00051 case 'h': 00052 return 'H'; 00053 case 'i': 00054 return 'I'; 00055 case 'j': 00056 return 'J'; 00057 case 'k': 00058 return 'K'; 00059 case 'l': 00060 return 'L'; 00061 case 'm': 00062 return 'M'; 00063 case 'n': 00064 return 'N'; 00065 case 'o': 00066 return 'O'; 00067 case 'p': 00068 return 'P'; 00069 case 'q': 00070 return 'Q'; 00071 case 'r': 00072 return 'R'; 00073 case 's': 00074 return 'S'; 00075 case 't': 00076 return 'T'; 00077 case 'u': 00078 return 'U'; 00079 case 'v': 00080 return 'V'; 00081 case 'w': 00082 return 'W'; 00083 case 'x': 00084 return 'X'; 00085 case 'y': 00086 return 'Y'; 00087 case 'z': 00088 return 'Z'; 00089 } 00090 return in; 00091 } 00092 00093 /* 00094 * _alpm_raw_cmp() is for doing "raw" case insensitive strings. This is meant 00095 * to be locale independent and only compare strings we know are safe for 00096 * this. See http://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for 00097 * some further explanation to why this function is necessary. 00098 * 00099 * The function is capable of comparing a-z case insensitively even for 00100 * non-ascii. 00101 */ 00102 00103 int _alpm_raw_cmp(const char *first, const char *second) 00104 { 00105 while(*first && *second) { 00106 if(raw_toupper(*first) != raw_toupper(*second)) { 00107 /* get out of the loop as soon as they don't match */ 00108 break; 00109 } 00110 first++; 00111 second++; 00112 } 00113 /* we do the comparison here (possibly again), just to make sure that if the 00114 loop above is skipped because one of the strings reached zero, we must not 00115 return this as a successful match */ 00116 return (raw_toupper(*first) - raw_toupper(*second)); 00117 } 00118 00119 int _alpm_raw_ncmp(const char *first, const char *second, size_t max) 00120 { 00121 while(*first && *second && max) { 00122 if(raw_toupper(*first) != raw_toupper(*second)) { 00123 break; 00124 } 00125 max--; 00126 first++; 00127 second++; 00128 } 00129 if(0 == max) { 00130 /* they are equal this far */ 00131 return 0; 00132 } 00133 00134 return (raw_toupper(*first) - raw_toupper(*second)); 00135 } 00136 00137 /* vim: set ts=2 sw=2 noet: */