forked from Bananymous/banan-os
				
			LibC: optimize strpbrk, str{,c}spn, strtok{,_r}
These matches are now detected with bitmasks instead of looping over the second string
This commit is contained in:
		
							parent
							
								
									418678466c
								
							
						
					
					
						commit
						006a196e4a
					
				|  | @ -282,37 +282,39 @@ char* strstr(const char* haystack, const char* needle) | ||||||
| 	return nullptr; | 	return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| size_t strcspn(const char* s1, const char* s2) | #define CHAR_UCHAR(ch) \ | ||||||
| { | 	static_cast<unsigned char>(ch) | ||||||
| 	size_t i = 0; | 
 | ||||||
| 	for (; s1[i]; i++) | #define CHAR_BITMASK(str) \ | ||||||
| 		for (size_t j = 0; s2[j]; j++) | 	uint32_t bitmask[0x100 / 32] {}; \ | ||||||
| 			if (s1[i] == s2[j]) | 	for (size_t i = 0; str[i]; i++) \ | ||||||
| 				return i; | 		bitmask[CHAR_UCHAR(str[i]) / 32] |= (1 << (CHAR_UCHAR(str[i]) % 32)) | ||||||
| 	return i; | 
 | ||||||
| } | #define CHAR_BITMASK_TEST(ch) \ | ||||||
|  | 	(bitmask[CHAR_UCHAR(ch) / 32] & (1 << (CHAR_UCHAR(ch) % 32))) | ||||||
| 
 | 
 | ||||||
| char* strpbrk(const char* s1, const char* s2) | char* strpbrk(const char* s1, const char* s2) | ||||||
| { | { | ||||||
|  | 	CHAR_BITMASK(s2); | ||||||
| 	for (size_t i = 0; s1[i]; i++) | 	for (size_t i = 0; s1[i]; i++) | ||||||
| 		for (size_t j = 0; s2[j]; j++) | 		if (CHAR_BITMASK_TEST(s1[i])) | ||||||
| 			if (s1[i] == s2[j]) | 			return const_cast<char*>(&s1[i]); | ||||||
| 				return const_cast<char*>(s1 + i); |  | ||||||
| 	return nullptr; | 	return nullptr; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| size_t strspn(const char* s1, const char* s2) | size_t strspn(const char* s1, const char* s2) | ||||||
| { | { | ||||||
| 	size_t i = 0; | 	CHAR_BITMASK(s2); | ||||||
| 	for (; s1[i]; i++) | 	for (size_t i = 0;; i++) | ||||||
| 	{ | 		if (s1[i] == '\0' || !CHAR_BITMASK_TEST(s1[i])) | ||||||
| 		bool found = false; | 			return i; | ||||||
| 		for (size_t j = 0; s2[j] && !found; j++) | } | ||||||
| 			if (s1[i] == s2[j]) | 
 | ||||||
| 				found = true; | size_t strcspn(const char* s1, const char* s2) | ||||||
| 		if (!found) | { | ||||||
| 			break; | 	CHAR_BITMASK(s2); | ||||||
| 	} | 	for (size_t i = 0;; i++) | ||||||
|  | 		if (s1[i] == '\0' || CHAR_BITMASK_TEST(s1[i])) | ||||||
| 			return i; | 			return i; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | @ -324,49 +326,43 @@ char* strtok(char* __restrict s, const char* __restrict sep) | ||||||
| 
 | 
 | ||||||
| char* strtok_r(char* __restrict str, const char* __restrict sep, char** __restrict state) | char* strtok_r(char* __restrict str, const char* __restrict sep, char** __restrict state) | ||||||
| { | { | ||||||
| 	if (str) | 	CHAR_BITMASK(sep); | ||||||
| 	{ |  | ||||||
| 		while (*str) |  | ||||||
| 		{ |  | ||||||
| 			bool found = false; |  | ||||||
| 			for (size_t i = 0; sep[i] && !found; i++) |  | ||||||
| 				if (*str == sep[i]) |  | ||||||
| 					found = true; |  | ||||||
| 			if (!found) |  | ||||||
| 				break; |  | ||||||
| 			str++; |  | ||||||
| 		} |  | ||||||
| 
 | 
 | ||||||
| 		if (!*str) | 	if (str) | ||||||
|  | 		*state = str; | ||||||
|  | 
 | ||||||
|  | 	if (*state == nullptr) | ||||||
|  | 		return nullptr; | ||||||
|  | 
 | ||||||
|  | 	str = *state; | ||||||
|  | 
 | ||||||
|  | 	for (; *str; str++) | ||||||
|  | 		if (!CHAR_BITMASK_TEST(*str)) | ||||||
|  | 			break; | ||||||
|  | 
 | ||||||
|  | 	if (*str == '\0') | ||||||
| 	{ | 	{ | ||||||
| 		*state = nullptr; | 		*state = nullptr; | ||||||
| 		return nullptr; | 		return nullptr; | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 		*state = str; |  | ||||||
| 	} |  | ||||||
| 
 |  | ||||||
| 	if (!*state) |  | ||||||
| 		return nullptr; |  | ||||||
| 
 |  | ||||||
| 	str = *state; |  | ||||||
| 	for (size_t i = 0; str[i]; i++) | 	for (size_t i = 0; str[i]; i++) | ||||||
| 	{ | 	{ | ||||||
| 		for (size_t j = 0; sep[j]; j++) | 		if (!CHAR_BITMASK_TEST(str[i])) | ||||||
| 		{ | 			continue; | ||||||
| 			if (str[i] == sep[j]) |  | ||||||
| 			{ |  | ||||||
| 		str[i] = '\0'; | 		str[i] = '\0'; | ||||||
| 		*state = str + i + 1; | 		*state = str + i + 1; | ||||||
| 		return str; | 		return str; | ||||||
| 	} | 	} | ||||||
| 		} |  | ||||||
| 	} |  | ||||||
| 
 | 
 | ||||||
| 	*state = nullptr; | 	*state = nullptr; | ||||||
| 	return str; | 	return str; | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #undef CHAR_UCHAR | ||||||
|  | #undef CHAR_BITMASK | ||||||
|  | #undef CHAR_BITMASK_TEST | ||||||
|  | 
 | ||||||
| char* strsignal(int signum) | char* strsignal(int signum) | ||||||
| { | { | ||||||
| 	static char buffer[128]; | 	static char buffer[128]; | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue