File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / curl / lib / strcase.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Wed Jun 3 10:01:15 2020 UTC (4 years, 1 month ago) by misho
Branches: curl, MAIN
CVS tags: v7_70_0p4, HEAD
curl

    1: /***************************************************************************
    2:  *                                  _   _ ____  _
    3:  *  Project                     ___| | | |  _ \| |
    4:  *                             / __| | | | |_) | |
    5:  *                            | (__| |_| |  _ <| |___
    6:  *                             \___|\___/|_| \_\_____|
    7:  *
    8:  * Copyright (C) 1998 - 2020, Daniel Stenberg, <daniel@haxx.se>, et al.
    9:  *
   10:  * This software is licensed as described in the file COPYING, which
   11:  * you should have received as part of this distribution. The terms
   12:  * are also available at https://curl.haxx.se/docs/copyright.html.
   13:  *
   14:  * You may opt to use, copy, modify, merge, publish, distribute and/or sell
   15:  * copies of the Software, and permit persons to whom the Software is
   16:  * furnished to do so, under the terms of the COPYING file.
   17:  *
   18:  * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
   19:  * KIND, either express or implied.
   20:  *
   21:  ***************************************************************************/
   22: 
   23: #include "curl_setup.h"
   24: 
   25: #include <curl/curl.h>
   26: 
   27: #include "strcase.h"
   28: 
   29: static char raw_tolower(char in);
   30: 
   31: /* Portable, consistent toupper (remember EBCDIC). Do not use toupper() because
   32:    its behavior is altered by the current locale. */
   33: char Curl_raw_toupper(char in)
   34: {
   35: #if !defined(CURL_DOES_CONVERSIONS)
   36:   if(in >= 'a' && in <= 'z')
   37:     return (char)('A' + in - 'a');
   38: #else
   39:   switch(in) {
   40:   case 'a':
   41:     return 'A';
   42:   case 'b':
   43:     return 'B';
   44:   case 'c':
   45:     return 'C';
   46:   case 'd':
   47:     return 'D';
   48:   case 'e':
   49:     return 'E';
   50:   case 'f':
   51:     return 'F';
   52:   case 'g':
   53:     return 'G';
   54:   case 'h':
   55:     return 'H';
   56:   case 'i':
   57:     return 'I';
   58:   case 'j':
   59:     return 'J';
   60:   case 'k':
   61:     return 'K';
   62:   case 'l':
   63:     return 'L';
   64:   case 'm':
   65:     return 'M';
   66:   case 'n':
   67:     return 'N';
   68:   case 'o':
   69:     return 'O';
   70:   case 'p':
   71:     return 'P';
   72:   case 'q':
   73:     return 'Q';
   74:   case 'r':
   75:     return 'R';
   76:   case 's':
   77:     return 'S';
   78:   case 't':
   79:     return 'T';
   80:   case 'u':
   81:     return 'U';
   82:   case 'v':
   83:     return 'V';
   84:   case 'w':
   85:     return 'W';
   86:   case 'x':
   87:     return 'X';
   88:   case 'y':
   89:     return 'Y';
   90:   case 'z':
   91:     return 'Z';
   92:   }
   93: #endif
   94: 
   95:   return in;
   96: }
   97: 
   98: 
   99: /* Portable, consistent tolower (remember EBCDIC). Do not use tolower() because
  100:    its behavior is altered by the current locale. */
  101: static char raw_tolower(char in)
  102: {
  103: #if !defined(CURL_DOES_CONVERSIONS)
  104:   if(in >= 'A' && in <= 'Z')
  105:     return (char)('a' + in - 'A');
  106: #else
  107:   switch(in) {
  108:   case 'A':
  109:     return 'a';
  110:   case 'B':
  111:     return 'b';
  112:   case 'C':
  113:     return 'c';
  114:   case 'D':
  115:     return 'd';
  116:   case 'E':
  117:     return 'e';
  118:   case 'F':
  119:     return 'f';
  120:   case 'G':
  121:     return 'g';
  122:   case 'H':
  123:     return 'h';
  124:   case 'I':
  125:     return 'i';
  126:   case 'J':
  127:     return 'j';
  128:   case 'K':
  129:     return 'k';
  130:   case 'L':
  131:     return 'l';
  132:   case 'M':
  133:     return 'm';
  134:   case 'N':
  135:     return 'n';
  136:   case 'O':
  137:     return 'o';
  138:   case 'P':
  139:     return 'p';
  140:   case 'Q':
  141:     return 'q';
  142:   case 'R':
  143:     return 'r';
  144:   case 'S':
  145:     return 's';
  146:   case 'T':
  147:     return 't';
  148:   case 'U':
  149:     return 'u';
  150:   case 'V':
  151:     return 'v';
  152:   case 'W':
  153:     return 'w';
  154:   case 'X':
  155:     return 'x';
  156:   case 'Y':
  157:     return 'y';
  158:   case 'Z':
  159:     return 'z';
  160:   }
  161: #endif
  162: 
  163:   return in;
  164: }
  165: 
  166: 
  167: /*
  168:  * Curl_strcasecompare() is for doing "raw" case insensitive strings. This is
  169:  * meant to be locale independent and only compare strings we know are safe
  170:  * for this.  See
  171:  * https://daniel.haxx.se/blog/2008/10/15/strcasecmp-in-turkish/ for some
  172:  * further explanation to why this function is necessary.
  173:  *
  174:  * The function is capable of comparing a-z case insensitively even for
  175:  * non-ascii.
  176:  *
  177:  * @unittest: 1301
  178:  */
  179: 
  180: int Curl_strcasecompare(const char *first, const char *second)
  181: {
  182:   while(*first && *second) {
  183:     if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second))
  184:       /* get out of the loop as soon as they don't match */
  185:       break;
  186:     first++;
  187:     second++;
  188:   }
  189:   /* we do the comparison here (possibly again), just to make sure that if the
  190:      loop above is skipped because one of the strings reached zero, we must not
  191:      return this as a successful match */
  192:   return (Curl_raw_toupper(*first) == Curl_raw_toupper(*second));
  193: }
  194: 
  195: int Curl_safe_strcasecompare(const char *first, const char *second)
  196: {
  197:   if(first && second)
  198:     /* both pointers point to something then compare them */
  199:     return Curl_strcasecompare(first, second);
  200: 
  201:   /* if both pointers are NULL then treat them as equal */
  202:   return (NULL == first && NULL == second);
  203: }
  204: 
  205: /*
  206:  * @unittest: 1301
  207:  */
  208: int Curl_strncasecompare(const char *first, const char *second, size_t max)
  209: {
  210:   while(*first && *second && max) {
  211:     if(Curl_raw_toupper(*first) != Curl_raw_toupper(*second)) {
  212:       break;
  213:     }
  214:     max--;
  215:     first++;
  216:     second++;
  217:   }
  218:   if(0 == max)
  219:     return 1; /* they are equal this far */
  220: 
  221:   return Curl_raw_toupper(*first) == Curl_raw_toupper(*second);
  222: }
  223: 
  224: /* Copy an upper case version of the string from src to dest.  The
  225:  * strings may overlap.  No more than n characters of the string are copied
  226:  * (including any NUL) and the destination string will NOT be
  227:  * NUL-terminated if that limit is reached.
  228:  */
  229: void Curl_strntoupper(char *dest, const char *src, size_t n)
  230: {
  231:   if(n < 1)
  232:     return;
  233: 
  234:   do {
  235:     *dest++ = Curl_raw_toupper(*src);
  236:   } while(*src++ && --n);
  237: }
  238: 
  239: /* Copy a lower case version of the string from src to dest.  The
  240:  * strings may overlap.  No more than n characters of the string are copied
  241:  * (including any NUL) and the destination string will NOT be
  242:  * NUL-terminated if that limit is reached.
  243:  */
  244: void Curl_strntolower(char *dest, const char *src, size_t n)
  245: {
  246:   if(n < 1)
  247:     return;
  248: 
  249:   do {
  250:     *dest++ = raw_tolower(*src);
  251:   } while(*src++ && --n);
  252: }
  253: 
  254: /* --- public functions --- */
  255: 
  256: int curl_strequal(const char *first, const char *second)
  257: {
  258:   return Curl_strcasecompare(first, second);
  259: }
  260: int curl_strnequal(const char *first, const char *second, size_t max)
  261: {
  262:   return Curl_strncasecompare(first, second, max);
  263: }

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>