Reactos
at master 129 lines 3.7 kB view raw
1/*** 2*strnicmp.cpp - compare n chars of strings, ignoring case 3* 4* Copyright (c) Microsoft Corporation. All rights reserved. 5* 6*Purpose: 7* defines _strnicmp() - Compares at most n characters of two strings, 8* without regard to case. 9* 10*******************************************************************************/ 11#include <corecrt_internal.h> 12#include <ctype.h> 13#include <locale.h> 14#include <string.h> 15 16/*** 17*int _strnicmp(lhs, rhs, count) - compares count char of strings, ignore case 18* 19*Purpose: 20* Compare the two strings for ordinal order. Stops the comparison 21* when the following occurs: (1) strings differ, (2) the end of the 22* strings is reached, or (3) count characters have been compared. 23* For the purposes of the comparison, upper case characters are 24* converted to lower case. 25* 26*Entry: 27* char *lhs, *rhs - strings to compare 28* size_t count - maximum number of characters to compare 29* 30*Exit: 31* returns <0 if lhs < rhs 32* returns 0 if lhs == rhs 33* returns >0 if lhs > rhs 34* Returns _NLSCMPERROR if something went wrong 35* 36*Exceptions: 37* Input parameters are validated. Refer to the validation section of the function. 38* 39*******************************************************************************/ 40 41extern "C" int __cdecl _strnicmp_l ( 42 char const * const lhs, 43 char const * const rhs, 44 size_t const count, 45 _locale_t const plocinfo 46 ) 47{ 48 /* validation section */ 49 _VALIDATE_RETURN(lhs != nullptr, EINVAL, _NLSCMPERROR); 50 _VALIDATE_RETURN(rhs != nullptr, EINVAL, _NLSCMPERROR); 51 _VALIDATE_RETURN(count <= INT_MAX, EINVAL, _NLSCMPERROR); 52 53 if (count == 0) 54 { 55 return 0; 56 } 57 58 unsigned char const * lhs_ptr = reinterpret_cast<unsigned char const *>(lhs); 59 unsigned char const * rhs_ptr = reinterpret_cast<unsigned char const *>(rhs); 60 61 _LocaleUpdate _loc_update(plocinfo); 62 63 int result; 64 int lhs_value; 65 int rhs_value; 66 size_t remaining = count; 67 do 68 { 69 lhs_value = _tolower_fast_internal(*lhs_ptr++, _loc_update.GetLocaleT()); 70 rhs_value = _tolower_fast_internal(*rhs_ptr++, _loc_update.GetLocaleT()); 71 result = lhs_value - rhs_value; 72 } 73 while (result == 0 && lhs_value != 0 && --remaining != 0); 74 75 return result; 76} 77 78 79#if !defined(_M_IX86) || defined(_M_HYBRID_X86_ARM64) 80 81extern "C" int __cdecl __ascii_strnicmp ( 82 char const * const lhs, 83 char const * const rhs, 84 size_t const count 85 ) 86{ 87 if (count == 0) 88 { 89 return 0; 90 } 91 92 unsigned char const * lhs_ptr = reinterpret_cast<unsigned char const *>(lhs); 93 unsigned char const * rhs_ptr = reinterpret_cast<unsigned char const *>(rhs); 94 95 int result; 96 int lhs_value; 97 int rhs_value; 98 size_t remaining = count; 99 do 100 { 101 lhs_value = __ascii_tolower(*lhs_ptr++); 102 rhs_value = __ascii_tolower(*rhs_ptr++); 103 result = lhs_value - rhs_value; 104 } 105 while (result == 0 && lhs_value != 0 && --remaining != 0); 106 107 return result; 108} 109 110#endif /* !_M_IX86 || _M_HYBRID_X86_ARM64 */ 111 112extern "C" int __cdecl _strnicmp ( 113 char const * const lhs, 114 char const * const rhs, 115 size_t const count 116 ) 117{ 118 if (!__acrt_locale_changed()) 119 { 120 /* validation section */ 121 _VALIDATE_RETURN(lhs != nullptr, EINVAL, _NLSCMPERROR); 122 _VALIDATE_RETURN(rhs != nullptr, EINVAL, _NLSCMPERROR); 123 _VALIDATE_RETURN(count <= INT_MAX, EINVAL, _NLSCMPERROR); 124 125 return __ascii_strnicmp(lhs, rhs, count); 126 } 127 128 return _strnicmp_l(lhs, rhs, count, nullptr); 129}