os/ossrv/genericopenlibs/cstdlib/LCHAR/STRTOK.C
author sl
Tue, 10 Jun 2014 14:32:02 +0200
changeset 1 260cb5ec6c19
permissions -rw-r--r--
Update contrib.
     1 /*
     2 * FUNCTION
     3 * <<strtok>>---get next token from a string
     4 * INDEX
     5 * strtok
     6 * INDEX
     7 * strtok_r
     8 * ANSI_SYNOPSIS
     9 * #include <string.h>
    10 * char *strtok(char *<[source]>, const char *<[delimiters]>)
    11 * char *strtok_r(char *<[source]>, const char *<[delimiters]>,
    12 * char **<[lasts]>)
    13 * TRAD_SYNOPSIS
    14 * #include <string.h>
    15 * char *strtok(<[source]>, <[delimiters]>)
    16 * char *<[source]>;
    17 * char *<[delimiters]>;
    18 * char *strtok_r(<[source]>, <[delimiters]>, <[lasts]>)
    19 * char *<[source]>;
    20 * char *<[delimiters]>;
    21 * char **<[lasts]>;
    22 * A series of calls to <<strtok>> break the string starting at
    23 * <<*<[source]>>> into a sequence of tokens.  The tokens are
    24 * delimited from one another by characters from the string at
    25 * <<*<[delimiters]>>>, at the outset.
    26 * The first call to <<strtok>> normally has a string address as
    27 * the first argument; subsequent calls can use <<NULL>> as the
    28 * first argument, to continue searching the same string.  You
    29 * can continue searching a single string with different
    30 * delimiters by using a different delimiter string on each call.
    31 * <<strtok>> begins by searching for any character not in the
    32 * <[delimiters]> string: the first such character is the
    33 * beginning of a token (and its address will be the result of
    34 * the <<strtok>> call). <<strtok>> then continues searching
    35 * until it finds another delimiter character; it replaces that
    36 * character by <<NULL>> and returns.  (If <<strtok>> comes to
    37 * the end of the <<*<[source]>>> string without finding any more
    38 * delimiters, the entire remainder of the string is treated as
    39 * the next token).
    40 * <<strtok>> starts its search at <<*<[source]>>>, unless you
    41 * pass <<NULL>> as the first argument;  if <[source]> is
    42 * <<NULL>>, <<strtok>> continues searching from the end of the
    43 * last search. Exploiting the <<NULL>> first argument leads to
    44 * non-reentrant code. You can easily circumvent this problem by
    45 * saving the last delimiter address in your application, and
    46 * always using it to pass a non-null <[source]> argument.
    47 * RETURNS
    48 * <<strtok>> returns a pointer to the next token, or <<NULL>> if
    49 * no more tokens can be found.
    50 * PORTABILITY
    51 * <<strtok>> is ANSI C.
    52 * <<strtok>> requires no supporting OS subroutines.
    53 * QUICKREF
    54 * strtok ansi impure
    55 * 
    56 *
    57 */
    58 
    59 
    60 
    61 #include <sys/reent.h>
    62 #include <string.h>
    63 
    64 /**
    65 Sequentially truncate string if delimiter is found.
    66 If string is not NULL, the function scans string for the first occurrence of 
    67 any character included in delimiters. If it is found, the function overwrites 
    68 the delimiter in string by a null-character and returns a pointer to the token,
    69 i.e. the part of the scanned string previous to the delimiter.
    70 After a first call to strtok, the function may be called with NULL as string parameter,
    71 and it will follow by where the last call to strtok found a delimiter.
    72 @return A pointer to the last token found in string.
    73 NULL is returned when there are no more tokens to be found.
    74 @param s Null-terminated string to scan. 
    75 @param delim Null-terminated string containing the separators.
    76 */
    77 EXPORT_C char *
    78 strtok (register char *s, register const char *delim)
    79 {
    80     return strtok_r (s, delim, &(_REENT->_scanpoint));
    81 }
    82 
    83 /*
    84  * Copyright (c) 1988 Regents of the University of California.
    85  * All rights reserved.
    86  *
    87  * Redistribution and use in source and binary forms, with or without
    88  * modification, are permitted provided that the following conditions
    89  * are met:
    90  * 1. Redistributions of source code must retain the above copyright
    91  *    notice, this list of conditions and the following disclaimer.
    92  * 2. Redistributions in binary form must reproduce the above copyright
    93  *    notice, this list of conditions and the following disclaimer in the
    94  *    documentation and/or other materials provided with the distribution.
    95  * 3. All advertising materials mentioning features or use of this software
    96  *    must display the following acknowledgement:
    97  *	This product includes software developed by the University of
    98  *	California, Berkeley and its contributors.
    99  * 4. Neither the name of the University nor the names of its contributors
   100  *    may be used to endorse or promote products derived from this software
   101  *    without specific prior written permission.
   102  *
   103  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
   104  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   105  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
   106  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
   107  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
   108  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
   109  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
   110  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
   111  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
   112  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
   113  * SUCH DAMAGE.
   114  */
   115 
   116 EXPORT_C char *
   117 strtok_r (register char *s, register const char *delim, char **lasts)
   118 {
   119 	register char *spanp;
   120 	register int c, sc;
   121 	char *tok;
   122 
   123 
   124 	if (s == NULL && (s = *lasts) == NULL)
   125 		return (NULL);
   126 
   127 	/*
   128 	 * Skip (span) leading delimiters (s += strspn(s, delim), sort of).
   129 	 */
   130 cont:
   131 	c = *s++;
   132 	for (spanp = (char *)delim; (sc = *spanp++) != 0;) {
   133 		if (c == sc)
   134 			goto cont;
   135 	}
   136 
   137 	if (c == 0) {		/* no non-delimiter characters */
   138 		*lasts = NULL;
   139 		return (NULL);
   140 	}
   141 	tok = s - 1;
   142 
   143 	/*
   144 	 * Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
   145 	 * Note that delim must have one NUL; we stop if we see that, too.
   146 	 */
   147 	for (;;) {
   148 		c = *s++;
   149 		spanp = (char *)delim;
   150 		do {
   151 			if ((sc = *spanp++) == c) {
   152 				if (c == 0)
   153 					s = NULL;
   154 				else
   155 					s[-1] = 0;
   156 				*lasts = s;
   157 				return (tok);
   158 			}
   159 		} while (sc != 0);
   160 	}
   161 	/* NOTREACHED */
   162 }