Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | RSS feed

  1. /*
  2. FUNCTION
  3.         <<wcstok>>---get next token from a string
  4.  
  5. INDEX
  6.         wcstok
  7.  
  8.  
  9. ANSI_SYNOPSIS
  10.         #include <wchar.h>
  11.         wchar_t *wcstok(wchar_t *__restrict <[source]>,
  12.                         const wchar_t *__restrict <[delimiters]>,
  13.                         wchar_t **__restrict <[lasts]>);
  14.  
  15. TRAD_SYNOPSIS
  16.         #include <wchar.h>
  17.         wchar_t *wcstok(<[source]>, <[delimiters]>, <[lasts]>);
  18.         wchar_t *__restrict <[source]>;
  19.         wchar_t *__restrict <[delimiters]>;
  20.         wchar_t **__restrict <[lasts]>;
  21.  
  22. DESCRIPTION
  23.         The <<wcstok>> function is the wide-character equivalent of the
  24.         <<strtok_r>> function (which in turn is the same as the <<strtok>>
  25.         function with an added argument to make it thread-safe).
  26.  
  27.         The <<wcstok>> function is used to isolate (one at a time)
  28.         sequential tokens in a null-terminated wide-character string,
  29.         <<*<[source]>>>.  A token is defined as a substring not containing
  30.         any wide-characters from <<*<[delimiters]>>>.
  31.  
  32.         The first time that <<wcstok>> is called, <<*<[source]>>> should
  33.         be specified with the wide-character string to be searched, and
  34.         <<*<[lasts]>>>--but not <<lasts>>, which must be non-NULL--may be
  35.         random; subsequent calls, wishing to obtain further tokens from
  36.         the same string, should pass a null pointer for <<*<[source]>>>
  37.         instead but must supply <<*<[lasts]>>> unchanged from the last
  38.         call.  The separator wide-character string, <<*<[delimiters]>>>,
  39.         must be supplied each time and may change between calls.
  40.         A pointer to placeholder <<*<[lasts]>>> must be supplied by
  41.         the caller, and is set each time as needed to save the state
  42.         by <<wcstok>>.  Every call to <<wcstok>> with <<*<[source]>>>
  43.         == <<NULL>> must pass the value of <<*<[lasts]>>> as last set
  44.         by <<wcstok>>.
  45.  
  46.         The <<wcstok>> function returns a pointer to the beginning of each
  47.         subsequent token in the string, after replacing the separator
  48.         wide-character itself with a null wide-character.  When no more tokens
  49.         remain, a null pointer is returned.
  50.  
  51. RETURNS
  52.         <<wcstok>> returns a pointer to the first wide character of a token, or
  53.         <<NULL>> if there is no token.
  54.  
  55. NOTES
  56.         <<wcstok>> is thread-safe (unlike <<strtok>>, but like <<strtok_r>>).
  57.         <<wcstok>> writes into the string being searched.
  58.  
  59. PORTABILITY
  60. <<wcstok>> is C99 and POSIX.1-2001.
  61.  
  62. <<wcstok>> requires no supporting OS subroutines.
  63.  
  64. QUICKREF
  65.         strtok ansi pure
  66. */
  67. /* wcstok for Newlib created by adapting strtok_r, 2008.  */
  68. /*
  69.  * Copyright (c) 1988 Regents of the University of California.
  70.  * All rights reserved.
  71.  *
  72.  * Redistribution and use in source and binary forms, with or without
  73.  * modification, are permitted provided that the following conditions
  74.  * are met:
  75.  * 1. Redistributions of source code must retain the above copyright
  76.  *    notice, this list of conditions and the following disclaimer.
  77.  * 2. Redistributions in binary form must reproduce the above copyright
  78.  *    notice, this list of conditions and the following disclaimer in the
  79.  *    documentation and/or other materials provided with the distribution.
  80.  * 3. Neither the name of the University nor the names of its contributors
  81.  *    may be used to endorse or promote products derived from this software
  82.  *    without specific prior written permission.
  83.  *
  84.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  85.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  86.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  87.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  88.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  89.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  90.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  91.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  92.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  93.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  94.  * SUCH DAMAGE.
  95.  */
  96.  
  97. #include <wchar.h>
  98.  
  99. wchar_t *
  100. _DEFUN (wcstok, (s, delim, lasts),
  101.         register wchar_t *__restrict s _AND
  102.         register const wchar_t *__restrict delim _AND
  103.         wchar_t **__restrict lasts)
  104. {
  105.         register const wchar_t *spanp;
  106.         register int c, sc;
  107.         wchar_t *tok;
  108.  
  109.  
  110.         if (s == NULL && (s = *lasts) == NULL)
  111.                 return (NULL);
  112.  
  113.         /*
  114.          * Skip (span) leading delimiters (s += wcsspn(s, delim), sort of).
  115.          */
  116. cont:
  117.         c = *s++;
  118.         for (spanp = delim; (sc = *spanp++) != L'\0';) {
  119.                 if (c == sc)  goto cont;
  120.         }
  121.  
  122.         if (c == L'\0') {               /* no non-delimiter characters */
  123.                 *lasts = NULL;
  124.                 return (NULL);
  125.         }
  126.         tok = s - 1;
  127.  
  128.         /*
  129.          * Scan token (scan for delimiters: s += wcscspn(s, delim), sort of).
  130.          * Note that delim must have one NUL; we stop if we see that, too.
  131.          */
  132.         for (;;) {
  133.                 c = *s++;
  134.                 spanp = delim;
  135.                 do {
  136.                         if ((sc = *spanp++) == c) {
  137.                                 if (c == L'\0')
  138.                                         s = NULL;
  139.                                 else
  140.                                         s[-1] = L'\0';
  141.                                 *lasts = s;
  142.                                 return (tok);
  143.                         }
  144.                 } while (sc != L'\0');
  145.         }
  146.         /* NOTREACHED */
  147. }
  148.  
  149. /* The remainder of this file can serve as a regression test.  Compile
  150.  *  with -D_REGRESSION_TEST.  */
  151. #if defined(_REGRESSION_TEST)   /* [Test code:  example from C99 standard */
  152. #include <stdio.h>
  153. #include <wchar.h>
  154.  
  155. /* example from C99 standard with minor additions to be a test */
  156. int
  157. main(void)
  158. {
  159. int  errs=0;
  160. static wchar_t str1[] = L"?a???b,,,#c";
  161. static wchar_t str2[] = L"\t \t";
  162. wchar_t *t, *ptr1, *ptr2;
  163.  
  164. t = wcstok(str1, L"?", &ptr1); // t points to the token L"a"
  165. if(wcscmp(t,L"a")) errs++;
  166. t = wcstok(NULL, L",", &ptr1); // t points to the token L"??b"
  167. if(wcscmp(t,L"??b")) errs++;
  168. t = wcstok(str2, L" \t", &ptr2); // t is a null pointer
  169. if(t != NULL) errs++;
  170. t = wcstok(NULL, L"#,", &ptr1); // t points to the token L"c"
  171. if(wcscmp(t,L"c")) errs++;
  172. t = wcstok(NULL, L"?", &ptr1); // t is a null pointer
  173. if(t != NULL) errs++;
  174.  
  175. printf("wcstok() test ");
  176. if(errs)  printf("FAILED %d test cases", errs);
  177.   else    printf("passed");
  178. printf(".\n");
  179.  
  180. return(errs);
  181. }
  182. #endif /* defined(_REGRESSION_TEST) ] */
  183.