/*--------------------------------------------------------------------------*/ /* */ /* File: STRTOK_R.C */ /* Created: 20-September-2002 */ /* Author: Peter Scandrett */ /* Description: Module to provide a reentrant version of the 'C' */ /* function STRTOK. */ /* */ /*--------------------------------------------------------------------------*/ /* */ /* Copyright (C) 2002 by ALSTOM Australia Limited. All rights reserved. */ /* */ /* Redistribution and use in source and binary forms, with or without */ /* modification, are permitted provided that the following conditions */ /* are met: */ /* 1. Redistributions of source code must retain the above copyright */ /* notice and this list of conditions. */ /* 2. Neither the name of ALSTOM Australia Limited nor the names of its */ /* contributors may be used to endorse or promote products derived */ /* from this software. */ /* */ /* THIS SOFTWARE IS PROVIDED BY ALSTOM AUSTRALIA LIMITED AND CONTRIBUTORS */ /* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT */ /* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS */ /* FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ALSTOM */ /* AUSTRALIA LIMITED OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, */ /* INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, */ /* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS */ /* OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED */ /* AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, */ /* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF */ /* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH */ /* DAMAGE. */ /* */ /*--------------------------------------------------------------------------*/ /* * $Log$ * Revision 1.7 2008/02/15 17:13:16 haraldkipp * Use configurable constant attribute. * * Revision 1.6 2006/10/08 16:48:08 haraldkipp * Documentation fixed * * Revision 1.5 2004/07/27 19:28:51 drsung * Implementation of strtok_r adjusted to the POSIX 1c standard. * * Revision 1.4 2003/12/16 22:34:41 drsung * Portability issues * */ #include #include #include "strtok_r.h" /*! * \addtogroup xgCrtMisc * * The functions strtok_r(), strsep_r() and strsep_rs() are intended as a * replacement for the strtok() function. While the strtok() function should * be preferred for portability reasons (it conforms to ISO/IEC 9899:1990 * ("ISO C89")) it may not be able to be used in a multi-threaded environment * (that is it is not reentrant). Functions strsep_r() and strsep_rs() can * handle empty fields, (i.e. detect fields delimited by two adjacent * delimiter characters). Function strsep() first appeared in 4.4BSD. */ /*@{*/ /*--------------------------------------------------------------------------*/ static char *end_tok(char **pp_str, const char *p_delim, char *p_sep) { register const char *sp; char *p_tok; char *p_ch; /* Use a local pointer. */ p_ch = *pp_str; /* Scan for next deliminator. */ p_tok = p_ch; while (*p_ch != 0) { for (sp = p_delim; *sp != 0; sp++) { if (*sp == *p_ch) { if (p_sep != NULL) { /* Save terminator. */ *p_sep = *p_ch; } *p_ch++ = 0; *pp_str = p_ch; return p_tok; } } p_ch++; } /* At end of string, so exit, but return last token. */ *pp_str = p_ch; return p_tok; } /*--------------------------------------------------------------------------*/ /*! * \brief Thread safe variant of strsep. * * This function is identical in operation to strsep_r(), except it returns the * deliminating character. */ char *strsep_rs(char **pp_str, const char *p_delim, char *p_sep) { char *p_ch; /* Assume terminator was end of string. */ if (p_sep != NULL) *p_sep = 0; /* Check not passed a NULL. */ if (pp_str == NULL) return NULL; /* Use a local pointer. */ p_ch = *pp_str; if (p_ch == NULL) return NULL; if (*p_ch == 0) return NULL; /* Check a valid delimiter string. */ if ((p_delim == NULL) || (*p_delim == 0)) { *pp_str = NULL; return p_ch; } /* Scan for next deliminator. */ return end_tok(pp_str, p_delim, p_sep); } /*--------------------------------------------------------------------------*/ /*! * \brief Thread safe version of strsep. * * This function locates, in the string referenced by *str, the first occurrence of * any character in the string delim (or the terminating `\\0' character) and * replaces it with a `\\0'. The location of the next character after the delimiter * character (or NULL, if the end of the string was reached) is stored in *str. * The original value of *str is returned. * * An "empty" field, i.e. one caused by two adjacent delimiter characters, can be * detected by comparing the location referenced by the pointer returned in *str * to `\\0'. * * If *str is initially NULL, strsep_r() returns NULL. * * If delim is NULL or the empty string, strsep_r() returns *str. */ char *strsep_r(char **pp_str, const char *p_delim) { return strsep_rs(pp_str, p_delim, NULL); } /*--------------------------------------------------------------------------*/ /*! * \brief Thread safe version of strtok. * * This function locates, in the string referenced by *s, the occurrence of * any character in the string delim (or the terminating `\\0' character) and * replaces them with a `\\0'. The location of the next character after the * delimiter character (or NULL, if the end of the string was reached) is * stored in *save_ptr. The first character not a delimiter character from * the original value of *s is returned. * * \deprecated This function is supported by avrlibc, which uses different * parameters. It's still available for ICCAVR, but should be * avoided for portability reasons. */ #ifdef __IMAGECRAFT__ /* Parse S into tokens separated by characters in DELIM. If S is NULL, the saved pointer in SAVE_PTR is used as the next starting point. For example: char s[] = "-abc-=-def"; char *sp; x = strtok_r(s, "-", &sp); // x = "abc", sp = "=-def" x = strtok_r(NULL, "-=", &sp); // x = "def", sp = NULL x = strtok_r(NULL, "=", &sp); // x = NULL // s = "abc\\0-def\\0" */ char *strtok_r(char *s, const char *delim, char **save_ptr) { char *token; if (s == NULL) s = *save_ptr; /* Scan leading delimiters. */ s += strspn(s, delim); if (*s == '\0') return NULL; /* Find the end of the token. */ token = s; s = strpbrk(token, delim); if (s == NULL) /* This token finishes the string. */ *save_ptr = strchr(token, '\0'); else { /* Terminate the token and make *SAVE_PTR point past it. */ *s = '\0'; *save_ptr = s + 1; } return token; } #endif /*__IMAGECRAFT__ */ /*@}*/ /*-------------------------- end of file STRTOK_R.C ------------------------*/