Reactos
at master 170 lines 5.0 kB view raw
1/*** 2*strspn.c - find length of initial substring of chars from a control string 3* 4* Copyright (c) Microsoft Corporation. All rights reserved. 5* 6*Purpose: 7* defines strspn() - finds the length of the initial substring of 8* a string consisting entirely of characters from a control string. 9* 10* defines strcspn()- finds the length of the initial substring of 11* a string consisting entirely of characters not in a control string. 12* 13* defines strpbrk()- finds the index of the first character in a string 14* that is not in a control string 15* 16*******************************************************************************/ 17 18#include <string.h> 19 20#pragma warning(disable:__WARNING_POTENTIAL_BUFFER_OVERFLOW_NULLTERMINATED) // 26018 Prefast doesn't understand reading past buffer but staying on same page. 21#pragma warning(disable:__WARNING_RETURNING_BAD_RESULT) // 28196 22 23/* Determine which routine we're compiling for (default to STRSPN) */ 24#define _STRSPN 1 25#define _STRCSPN 2 26#define _STRPBRK 3 27 28#if defined (SSTRCSPN) 29 #define ROUTINE _STRCSPN 30#elif defined (SSTRPBRK) 31 #define ROUTINE _STRPBRK 32#else 33 #define ROUTINE _STRSPN 34#endif 35 36/*** 37*int strspn(string, control) - find init substring of control chars 38* 39*Purpose: 40* Finds the index of the first character in string that does belong 41* to the set of characters specified by control. This is 42* equivalent to the length of the initial substring of string that 43* consists entirely of characters from control. The '\0' character 44* that terminates control is not considered in the matching process. 45* 46*Entry: 47* char *string - string to search 48* char *control - string containing characters not to search for 49* 50*Exit: 51* returns index of first char in string not in control 52* 53*Exceptions: 54* 55*******************************************************************************/ 56 57/*** 58*int strcspn(string, control) - search for init substring w/o control chars 59* 60*Purpose: 61* returns the index of the first character in string that belongs 62* to the set of characters specified by control. This is equivalent 63* to the length of the length of the initial substring of string 64* composed entirely of characters not in control. Null chars not 65* considered. 66* 67*Entry: 68* char *string - string to search 69* char *control - set of characters not allowed in init substring 70* 71*Exit: 72* returns the index of the first char in string 73* that is in the set of characters specified by control. 74* 75*Exceptions: 76* 77*******************************************************************************/ 78 79/*** 80*char *strpbrk(string, control) - scans string for a character from control 81* 82*Purpose: 83* Finds the first occurence in string of any character from 84* the control string. 85* 86*Entry: 87* char *string - string to search in 88* char *control - string containing characters to search for 89* 90*Exit: 91* returns a pointer to the first character from control found 92* in string. 93* returns NULL if string and control have no characters in common. 94* 95*Exceptions: 96* 97*******************************************************************************/ 98 99 100 101/* Routine prototype */ 102#if ROUTINE == _STRSPN 103size_t __cdecl strspn ( 104#elif ROUTINE == _STRCSPN 105size_t __cdecl strcspn ( 106#else /* ROUTINE == _STRCSPN */ 107char * __cdecl strpbrk ( 108#endif /* ROUTINE == _STRCSPN */ 109 const char * string, 110 const char * control 111 ) 112{ 113 const unsigned char *str = (unsigned char const*)string; 114 const unsigned char *ctrl = (unsigned char const*)control; 115 116 unsigned char map[32]; 117 int count; 118 119 /* Clear out bit map */ 120 for (count=0; count<32; count++) 121 map[count] = 0; 122 123 /* Set bits in control map */ 124 while (*ctrl) 125 { 126 map[*ctrl >> 3] |= (1 << (*ctrl & 7)); 127 ctrl++; 128 } 129 130#if ROUTINE == _STRSPN 131 132 /* 1st char NOT in control map stops search */ 133 if (*str) 134 { 135 count=0; 136 while (map[*str >> 3] & (1 << (*str & 7))) 137 { 138 count++; 139 str++; 140 } 141 return(count); 142 } 143 return(0); 144 145#elif ROUTINE == _STRCSPN 146 147 /* 1st char in control map stops search */ 148 count=0; 149 map[0] |= 1; /* null chars not considered */ 150 while (!(map[*str >> 3] & (1 << (*str & 7)))) 151 { 152 count++; 153 str++; 154 } 155 return(count); 156 157#else /* ROUTINE == _STRCSPN */ 158 159 /* 1st char in control map stops search */ 160 while (*str) 161 { 162 if (map[*str >> 3] & (1 << (*str & 7))) 163 return((char *)str); 164 str++; 165 } 166 return(NULL); 167 168#endif /* ROUTINE == _STRCSPN */ 169 170}