Subversion Repositories Kolibri OS

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
553 serge 1
/****************************************************************************
2
*
3
*                            Open Watcom Project
4
*
5
*    Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
6
*
7
*  ========================================================================
8
*
9
*    This file contains Original Code and/or Modifications of Original
10
*    Code as defined in and that are subject to the Sybase Open Watcom
11
*    Public License version 1.0 (the 'License'). You may not use this file
12
*    except in compliance with the License. BY USING THIS FILE YOU AGREE TO
13
*    ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
14
*    provided with the Original Code and Modifications, and is also
15
*    available at www.sybase.com/developer/opensource.
16
*
17
*    The Original Code and all software distributed under the License are
18
*    distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
19
*    EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
20
*    ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
21
*    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
22
*    NON-INFRINGEMENT. Please see the License for the specific language
23
*    governing rights and limitations under the License.
24
*
25
*  ========================================================================
26
*
27
* Description:  Implementation of strtok_s() - bounds-checking strtok().
28
*
29
****************************************************************************/
30
 
31
 
32
#include "variety.h"
33
#include "saferlib.h"
34
#include "widechar.h"
35
#include 
36
#include 
37
#include "setbits.h"
38
 
39
 
40
_WCRTLINK CHAR_TYPE *__F_NAME(strtok_s,wcstok_s)( CHAR_TYPE * __restrict s1,
41
                rsize_t * __restrict s1max, const CHAR_TYPE * __restrict s2,
42
                                                 CHAR_TYPE ** __restrict ptr )
43
/****************************************************************************/
44
{
45
#ifdef __WIDECHAR__
46
    const CHAR_TYPE   *p2;
47
    CHAR_TYPE         tc2;
48
#else
49
    char              vector[32];
50
#endif
51
    char              *msg = NULL;
52
    CHAR_TYPE         *p1 = s1;
53
    CHAR_TYPE         *str;
54
    rsize_t           m;
55
    CHAR_TYPE         tc1;
56
 
57
    // Verify runtime-constraints
58
    // s1max not NULL
59
    // s2    not NULL
60
    // ptr   not NULL
61
    // *s1max <= RSIZE_MAX
62
    // if s1 == NULL then *ptr != NULL
63
    if( __check_constraint_nullptr_msg( msg, s1max ) &&
64
        __check_constraint_nullptr_msg( msg, s2 ) &&
65
        __check_constraint_nullptr_msg( msg, ptr ) &&
66
        __check_constraint_maxsize_msg( msg, *s1max ) &&
67
       ((s1 != NULL) || __check_constraint_nullptr_msg( msg, *ptr )) ) {
68
 
69
        /* if necessary, continue from where we left off */
70
        if( s1 == NULL ) {
71
            p1 = *ptr;                                  /* use previous value */
72
        }
73
#ifndef __WIDECHAR__
74
        __setbits( vector, s2 );
75
#endif
76
        m = *s1max;
77
        for( ; tc1 = *p1; ++p1 ) {
78
            if( ! ((m == 0) ? ( msg = "no start of token found" ), 0 : 1 ) ) {
79
               break;                                   /* limit reached, quit */
80
            }
81
 
82
#ifdef __WIDECHAR__
83
            for( p2 = s2; tc2 = *p2; p2++ ) {
84
                if( tc1 == tc2 ) break;
85
            }
86
            if( tc2 == NULLCHAR ) break;
87
#else
88
            /* quit if we find any char not in charset */
89
            if( ( vector[ tc1 >> 3 ] & _Bits[ tc1 & 0x07 ] ) == 0 )  break;
90
#endif
91
            --m;
92
        }
93
 
94
        if( msg == NULL ) {                             /* no rt-constraint violated */
95
            if( tc1 == NULLCHAR ) return( NULL );       /* no (more) tokens */
96
        } else {
97
            /* Now call the handler */
98
            __rtct_fail( __func__, msg, NULL );
99
            return( NULL );
100
        }
101
 
102
        str = p1++;                                     /* start of token */
103
 
104
        for( ; tc1 = *p1; p1++ ) {
105
            if( ! ((m == 0) ? ( msg = "no closing token delimiter found" ), 0 : 1 ) ) {
106
               break;                                   /* limit reached, quit */
107
            }
108
 
109
            --m;
110
 
111
            /* skip characters until we reach one in delimiterset */
112
#ifdef __WIDECHAR__
113
            for( p2 = s2; tc2 = *p2; p2++ ) {
114
                if( tc1 == tc2 ) break;
115
            }
116
            if( tc2 != NULLCHAR ) {
117
#else
118
            if( ( vector[ tc1 >> 3 ] & _Bits[ tc1 & 0x07 ] ) != 0 ) {
119
#endif
120
                *p1 = NULLCHAR;                         /* terminate the token  */
121
                p1++;                                   /* start of next token  */
122
                *ptr = p1;
123
                *s1max = m;
124
                return( str );
125
            }
126
        }
127
    }
128
    if( msg != NULL ) {                                 /* rt-constraint violated */
129
        /* Now call the handler */
130
        __rtct_fail( __func__, msg, NULL );
131
        return( NULL );
132
    } else {
133
        *ptr = NULL;                                    /* last token reached */
134
        *s1max = 0;
135
    }
136
    return( str );
137
}