blob: 7c5ac0fe28e7ae01d09b1340ce9da813bdce457d [file]
//
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
//
/*++
Module Name:
wchartls.c
Abstract:
Implementation of wide char string functions that depend on per-thread data
--*/
#include "pal/palinternal.h"
#include "pal/thread.hpp"
#include "pal/dbgmsg.h"
#include "pal/unicode_data.h"
using namespace CorUnix;
SET_DEFAULT_DEBUG_CHANNEL(CRT);
/*++
Function:
PAL_wcstok
Finds the next token in a wide character string.
Return value:
A pointer to the next token found in strToken. Returns NULL when no more
tokens are found. Each call modifies strToken by substituting a NULL
character for each delimiter that is encountered.
Parameters:
strToken String containing token(s)
strDelimit Set of delimiter characters
--*/
WCHAR *
__cdecl
PAL_wcstok(WCHAR *strToken, const WCHAR *strDelimit)
{
CPalThread *pThread = NULL;
WCHAR *retval = NULL;
WCHAR *delim_ptr;
WCHAR *next_context; /* string to save in TLS for future calls */
PERF_ENTRY(wcstok);
ENTRY("PAL_wcstok (strToken=%p (%S), strDelimit=%p (%S))\n",
strToken?strToken:W16_NULLSTRING,
strToken?strToken:W16_NULLSTRING,
strDelimit?strDelimit:W16_NULLSTRING,
strDelimit?strDelimit:W16_NULLSTRING);
/* Get the per-thread buffer from the thread structure. */
pThread = InternalGetCurrentThread();
if(NULL == strDelimit)
{
ERROR("delimiter string is NULL\n");
goto done;
}
/* get token string from TLS if none is provided */
if(NULL == strToken)
{
TRACE("wcstok() called with NULL string, using previous string\n");
strToken = pThread->crtInfo.wcstokContext;
if(NULL == strToken)
{
ERROR("wcstok called with NULL string without a previous call\n");
goto done;
}
}
/* first, skip all leading delimiters */
while ((*strToken != '\0') && (PAL_wcschr(strDelimit,*strToken)))
{
strToken++;
}
/* if there were only delimiters, there's no string */
if('\0' == strToken[0])
{
TRACE("end of string already reached, returning NULL\n");
goto done;
}
/* we're now at the beginning of the token; look for the first delimiter */
delim_ptr = PAL_wcspbrk(strToken,strDelimit);
if(NULL == delim_ptr)
{
TRACE("no delimiters found, this is the last token\n");
/* place the next context at the end of the string, so that subsequent
calls will return NULL */
next_context = strToken+PAL_wcslen(strToken);
retval = strToken;
}
else
{
/* null-terminate current token */
*delim_ptr=0;
/* place the next context right after the delimiter */
next_context = delim_ptr+1;
retval = strToken;
TRACE("found delimiter; next token will be %p\n",next_context);
}
pThread->crtInfo.wcstokContext = next_context;
done:
LOGEXIT("PAL_wcstok() returns %p (%S)\n", retval?retval:W16_NULLSTRING, retval?retval:W16_NULLSTRING);
PERF_EXIT(wcstok);
return(retval);
}