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