source: SVN/cambria/redboot/packages/language/c/libc/string/current/src/strtok.cxx @ 1

Last change on this file since 1 was 1, checked in by Tim Harvey, 2 years ago

restored latest version of files from server backup

Signed-off-by: Tim Harvey <tharvey@…>

File size: 8.1 KB
Line 
1//===========================================================================
2//
3//      strtok.cxx
4//
5//      ISO standard strtok() routine
6//
7//===========================================================================
8//####ECOSGPLCOPYRIGHTBEGIN####
9// -------------------------------------------
10// This file is part of eCos, the Embedded Configurable Operating System.
11// Copyright (C) 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.
12//
13// eCos is free software; you can redistribute it and/or modify it under
14// the terms of the GNU General Public License as published by the Free
15// Software Foundation; either version 2 or (at your option) any later version.
16//
17// eCos is distributed in the hope that it will be useful, but WITHOUT ANY
18// WARRANTY; without even the implied warranty of MERCHANTABILITY or
19// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
20// for more details.
21//
22// You should have received a copy of the GNU General Public License along
23// with eCos; if not, write to the Free Software Foundation, Inc.,
24// 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
25//
26// As a special exception, if other files instantiate templates or use macros
27// or inline functions from this file, or you compile this file and link it
28// with other works to produce a work based on this file, this file does not
29// by itself cause the resulting work to be covered by the GNU General Public
30// License. However the source code for this file must still be made available
31// in accordance with section (3) of the GNU General Public License.
32//
33// This exception does not invalidate any other reasons why a work based on
34// this file might be covered by the GNU General Public License.
35//
36// Alternative licenses for eCos may be arranged by contacting Red Hat, Inc.
37// at http://sources.redhat.com/ecos/ecos-license/
38// -------------------------------------------
39//####ECOSGPLCOPYRIGHTEND####
40//===========================================================================
41//#####DESCRIPTIONBEGIN####
42//
43// Author(s):     jlarmour
44// Contributors:  jlarmour
45// Date:          2000-04-14
46// Purpose:       Provide ISO C strtok() and POSIX strtok_r() routines
47// Description:
48// Usage:       
49//
50//####DESCRIPTIONEND####
51//
52//===========================================================================
53//
54// This code is based on original code with the following copyright:
55//
56/*
57 * Copyright (c) 1988 Regents of the University of California.
58 * All rights reserved.
59 *
60 * Redistribution and use in source and binary forms, with or without
61 * modification, are permitted provided that the following conditions
62 * are met:
63 * 1. Redistributions of source code must retain the above copyright
64 *    notice, this list of conditions and the following disclaimer.
65 * 2. Redistributions in binary form must reproduce the above copyright
66 *    notice, this list of conditions and the following disclaimer in the
67 *    documentation and/or other materials provided with the distribution.
68 * 3. Neither the name of the University nor the names of its contributors
69 *    may be used to endorse or promote products derived from this software
70 *    without specific prior written permission.
71 *
72 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
73 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
74 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
75 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
76 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
77 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
78 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
79 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
80 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
81 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
82 * SUCH DAMAGE.
83 */
84
85
86// CONFIGURATION
87
88#include <pkgconf/libc_string.h>   // Configuration header
89
90// INCLUDES
91
92#include <cyg/infra/cyg_type.h>    // Common type definitions
93#include <cyg/infra/cyg_trac.h>    // Tracing support
94#include <cyg/infra/cyg_ass.h>     // Assertion support
95#include <string.h>                // Header for this file
96#include <stddef.h>         // Compiler definitions such as size_t, NULL etc.
97#include <cyg/libc/string/stringsupp.hxx> // Useful string function support and
98                                          // prototypes
99
100#ifdef CYGSEM_LIBC_STRING_PER_THREAD_STRTOK
101# include <pkgconf/kernel.h>       // kernel configuration
102# include <cyg/kernel/thread.hxx>  // per-thread data
103# include <cyg/kernel/thread.inl>  // per-thread data
104# include <cyg/kernel/mutex.hxx>   // mutexes
105#endif
106
107// TRACE
108
109#if defined(CYGDBG_USE_TRACING) && defined(CYGNUM_LIBC_STRING_STRTOK_TRACE_LEVEL)
110static int strtok_trace = CYGNUM_LIBC_STRING_STRTOK_TRACE_LEVEL;
111# define TL1 (0 < strtok_trace)
112#else
113# define TL1 (0)
114#endif
115
116// STATICS
117
118#ifdef CYGSEM_LIBC_STRING_PER_THREAD_STRTOK
119static Cyg_Thread::cyg_data_index
120strtok_data_index=CYGNUM_KERNEL_THREADS_DATA_MAX;
121
122static Cyg_Mutex strtok_data_mutex CYG_INIT_PRIORITY(LIBC);
123#else
124static char *cyg_libc_strtok_last;
125#endif
126
127// FUNCTIONS
128
129char *
130strtok( char *s1, const char *s2 )
131{
132    char **lasts;
133    char *retval;
134
135    CYG_REPORT_FUNCNAMETYPE( "strtok", "returning %08x" );
136    CYG_REPORT_FUNCARG2( "s1=%08x, s2=%08x", s1, s2 );
137   
138    if (s1 != NULL)
139        CYG_CHECK_DATA_PTR( s1, "s1 is not a valid pointer!" );
140    CYG_CHECK_DATA_PTR( s2, "s2 is not a valid pointer!" );
141
142#ifdef CYGSEM_LIBC_STRING_PER_THREAD_STRTOK
143    Cyg_Thread *self = Cyg_Thread::self();
144
145    // Get a per-thread data slot if we haven't got one already
146    // Do a simple test before locking and retrying test, as this is a
147    // rare situation
148    if (CYGNUM_KERNEL_THREADS_DATA_MAX==strtok_data_index) {
149        strtok_data_mutex.lock();
150        if (CYGNUM_KERNEL_THREADS_DATA_MAX==strtok_data_index) {
151
152            // FIXME: Should use real CDL to pre-allocate a slot at compile
153            // time to ensure there are enough slots
154            strtok_data_index = self->new_data_index();
155            CYG_ASSERT(strtok_data_index >= 0,
156                       "failed to allocate data index" );
157        }
158        strtok_data_mutex.unlock();
159    } // if
160
161    // we have a valid index now
162
163    lasts = (char **)self->get_data_ptr(strtok_data_index);
164#else
165    lasts = &cyg_libc_strtok_last;
166#endif
167
168    CYG_TRACE2( TL1, "Retrieved strtok_last address %08x containing %s",
169                lasts, *lasts );
170
171    retval = strtok_r( s1, s2, lasts );
172   
173    CYG_REPORT_RETVAL( retval );
174
175    return retval;
176} // strtok()
177
178char *
179strtok_r( char *s1, const char *s2, char **lasts )
180{
181    char *spanp;
182    int c, sc;
183    char *tok;
184   
185    CYG_REPORT_FUNCNAMETYPE( "strtok_r", "returning %08x" );
186    CYG_REPORT_FUNCARG3( "s1=%08x, s2=%08x, lasts=%08x", s1, s2, lasts );
187   
188    if (s1 != NULL)
189        CYG_CHECK_DATA_PTR( s1, "s1 is not a valid pointer!" );
190    CYG_CHECK_DATA_PTR( s2, "s2 is not a valid pointer!" );
191    CYG_CHECK_DATA_PTR( lasts, "lasts is not a valid pointer!" );
192
193
194    if (s1 == NULL && (s1 = *lasts) == NULL)
195    {
196        CYG_REPORT_RETVAL( NULL );
197        return NULL;
198    } // if
199   
200    //
201    // Skip (span) leading delimiters (s += strspn(s, delim), sort of).
202    //
203cont:
204    c = *s1++;
205    for (spanp = (char *)s2; (sc = *spanp++) != 0;) {
206        if (c == sc)
207            goto cont;
208    } // for
209   
210    if (c == 0) {               // no non-delimiter characters
211        *lasts = NULL;
212
213        CYG_REPORT_RETVAL( NULL );
214        return NULL;
215    } // if
216    tok = s1 - 1;
217   
218    //
219    // Scan token (scan for delimiters: s += strcspn(s, delim), sort of).
220    // Note that delim must have one NUL; we stop if we see that, too.
221    //
222    for (;;) {
223        c = *s1++;
224        spanp = (char *)s2;
225        do {
226            if ((sc = *spanp++) == c) {
227                if (c == 0)
228                    s1 = NULL;
229                else
230                    s1[-1] = 0;
231                *lasts = s1;
232
233                CYG_REPORT_RETVAL( tok );
234
235                return (tok);
236            } // if
237        } while (sc != 0);
238    } // for
239    // NOTREACHED
240} // strtok_r()
241
242// EOF strtok.cxx
Note: See TracBrowser for help on using the repository browser.