libalpm
Arch Linux Package Manager Library
rawstr.c
Go to the documentation of this file.
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: */