diff --git a/libc/Makefile b/libc/Makefile index 4b20911c..202b188b 100644 --- a/libc/Makefile +++ b/libc/Makefile @@ -210,6 +210,7 @@ string/strdup.o \ string/strerror_l.o \ string/strerror.o \ string/strerror_r.o \ +string/stresep.o \ string/strlcat.o \ string/strlcpy.o \ string/strlen.o \ diff --git a/libc/include/string.h b/libc/include/string.h index e618e6f6..e55bc1f1 100644 --- a/libc/include/string.h +++ b/libc/include/string.h @@ -129,6 +129,7 @@ int ffsl(long int); void* memrchr(const void*, int, size_t); /* TODO: strcasecmp_l */ char* strchrnul(const char* str, int c); +char* stresep(char**, const char*, int); size_t strlcat(char* __restrict, const char* __restrict, size_t); size_t strlcpy(char* __restrict, const char* __restrict, size_t); /* TODO: strncasecmp_l */ diff --git a/libc/string/stresep.cpp b/libc/string/stresep.cpp new file mode 100644 index 00000000..432f0ca3 --- /dev/null +++ b/libc/string/stresep.cpp @@ -0,0 +1,63 @@ +/******************************************************************************* + + Copyright(C) Jonas 'Sortie' Termansen 2014. + + This file is part of the Sortix C Library. + + The Sortix C Library is free software: you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation, either version 3 of the License, or (at your + option) any later version. + + The Sortix C Library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY + or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public + License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with the Sortix C Library. If not, see . + + string/stresep.cpp + Extract a token from a string while handling escape characters. + +*******************************************************************************/ + +#include + +extern "C" char* stresep(char** string_ptr, const char* delim, int escape) +{ + char* token = *string_ptr; + if ( !token ) + return NULL; + size_t consumed_length = 0; + size_t token_length = 0; + bool escaped = false; + while ( true ) + { + char c = token[consumed_length++]; + bool true_nul = c == '\0'; + if ( !escaped && escape && (unsigned char) c == (unsigned char) escape ) + { + escaped = true; + continue; + } + if ( !escaped && c != '\0' ) + { + for ( size_t i = 0; delim[i]; i++ ) + { + if ( c != delim[i] ) + { + c = '\0'; + break; + } + } + } + token[token_length++] = c; + escaped = false; + if ( c == '\0' ) + { + *string_ptr = true_nul ? (char*) NULL : token + consumed_length; + return token; + } + } +}