Subversion Repositories HelenOS-historic

Rev

Rev 1197 | Rev 1319 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 1197 Rev 1314
Line 25... Line 25...
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27
 */
27
 */
28
 
28
 
29
#include <string.h>
29
#include <string.h>
-
 
30
#include <unistd.h>
-
 
31
#include <ctype.h>
-
 
32
#include <limits.h>
-
 
33
 
30
 
34
 
31
/* Dummy implementation of mem/ functions */
35
/* Dummy implementation of mem/ functions */
32
 
36
 
33
void * memset(void *s, int c, size_t n)
37
void * memset(void *s, int c, size_t n)
34
{
38
{
Line 45... Line 49...
45
    while (n--)
49
    while (n--)
46
        *(odst++) = *(os++);
50
        *(odst++) = *(os++);
47
    return dest;
51
    return dest;
48
}
52
}
49
 
53
 
-
 
54
/** Count the number of characters in the string, not including terminating 0.
-
 
55
 * @param str string
-
 
56
 * @return number of characters in string.
-
 
57
 */
50
size_t strlen(const char *str)
58
size_t strlen(const char *str)
51
{
59
{
52
    size_t counter = 0;
60
    size_t counter = 0;
53
 
61
 
54
    while (str[counter] != 0) {
62
    while (str[counter] != 0) {
55
        counter++;
63
        counter++;
56
    }
64
    }
57
 
65
 
58
    return counter;
66
    return counter;
59
}
67
}
-
 
68
 
-
 
69
/** Return pointer to the first occurence of character c in string
-
 
70
 * @param str scanned string
-
 
71
 * @param c searched character (taken as one byte)
-
 
72
 * @return pointer to the matched character or NULL if it is not found in given string.
-
 
73
 */
-
 
74
char *strchr(const char *str, int c)
-
 
75
{
-
 
76
    while (*str != '\0') {
-
 
77
        if (*str == (char)c)
-
 
78
            return (char *)str;
-
 
79
        str++;
-
 
80
    }
-
 
81
 
-
 
82
    return NULL;
-
 
83
}
-
 
84
 
-
 
85
/** Return pointer to the last occurence of character c in string
-
 
86
 * @param str scanned string
-
 
87
 * @param c searched character (taken as one byte)
-
 
88
 * @return pointer to the matched character or NULL if it is not found in given string.
-
 
89
 */
-
 
90
char *strrchr(const char *str, int c)
-
 
91
{
-
 
92
    char *retval = NULL;
-
 
93
 
-
 
94
    while (*str != '\0') {
-
 
95
        if (*str == (char)c)
-
 
96
            retval = (char *)str;
-
 
97
        str++;
-
 
98
    }
-
 
99
 
-
 
100
    return (char *)retval;
-
 
101
}
-
 
102
 
-
 
103
/** Convert string to a number.
-
 
104
 * Core of strtol and strtoul functions.
-
 
105
 * @param nptr pointer to string
-
 
106
 * @param endptr if not NULL, function stores here pointer to the first invalid character
-
 
107
 * @param base zero or number between 2 and 36 inclusive
-
 
108
 * @param sgn its set to 1 if minus found
-
 
109
 * @return result of conversion.
-
 
110
 */
-
 
111
static unsigned long _strtoul(const char *nptr, char **endptr, int base, char *sgn)
-
 
112
{
-
 
113
    unsigned char c;
-
 
114
    unsigned long result = 0;
-
 
115
    unsigned long a, b;
-
 
116
    const char *str = nptr;
-
 
117
    const char *tmpptr;
-
 
118
   
-
 
119
    while (isspace(*str))
-
 
120
        str++;
-
 
121
   
-
 
122
    if (*str == '-') {
-
 
123
        *sgn = 1;
-
 
124
        ++str;
-
 
125
    } else if (*str == '+')
-
 
126
        ++str;
-
 
127
   
-
 
128
    if (base) {
-
 
129
        if ((base == 1) || (base > 36)) {
-
 
130
            /* FIXME: set errno to EINVAL */
-
 
131
            return 0;
-
 
132
        }
-
 
133
        if ((base == 16) && (*str == '0') && ((str[1] == 'x') || (str[1] == 'X'))) {
-
 
134
            str += 2;
-
 
135
        }
-
 
136
    } else {
-
 
137
        base = 10;
-
 
138
       
-
 
139
        if (*str == '0') {
-
 
140
            base = 8;
-
 
141
            if ((str[1] == 'X') || (str[1] == 'x'))  {
-
 
142
                base = 16;
-
 
143
                str += 2;
-
 
144
            }
-
 
145
        }
-
 
146
    }
-
 
147
   
-
 
148
    tmpptr = str;
-
 
149
 
-
 
150
    while (*str) {
-
 
151
        c = *str;
-
 
152
        c = ( c >= 'a'? c-'a'+10:(c >= 'A'?c-'A'+10:(c <= '9'?c-'0':0xff)));
-
 
153
        if (c > base) {
-
 
154
            break;
-
 
155
        }
-
 
156
       
-
 
157
        a = (result & 0xff) * base + c;
-
 
158
        b = (result >> 8) * base + (a >> 8);
-
 
159
       
-
 
160
        if (b > (ULONG_MAX >> 8)) {
-
 
161
            /* overflow */
-
 
162
            /* FIXME: errno = ERANGE*/
-
 
163
            return ULONG_MAX;
-
 
164
        }
-
 
165
   
-
 
166
        result = (b << 8) + (a & 0xff);
-
 
167
        ++str;
-
 
168
    }
-
 
169
   
-
 
170
    if (str == tmpptr) {
-
 
171
        /* no number was found => first invalid character is the first character of the string */
-
 
172
        /* FIXME: set errno to EINVAL */
-
 
173
        str = nptr;
-
 
174
        result = 0;
-
 
175
    }
-
 
176
   
-
 
177
    if (endptr)
-
 
178
        *endptr = (char *)str;
-
 
179
 
-
 
180
    if (nptr == str) {
-
 
181
        /*FIXME: errno = EINVAL*/
-
 
182
        return 0;
-
 
183
    }
-
 
184
 
-
 
185
    return result;
-
 
186
}
-
 
187
 
-
 
188
/** Convert initial part of string to long int according to given base.
-
 
189
 * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
-
 
190
 * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
-
 
191
 * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
-
 
192
 * Otherwise the base 0 is taken as decimal.
-
 
193
 * @param nptr pointer to string
-
 
194
 * @param endptr if not NULL, function stores here pointer to the first invalid character
-
 
195
 * @param base zero or number between 2 and 36 inclusive
-
 
196
 * @return result of conversion.
-
 
197
 */
-
 
198
long int strtol(const char *nptr, char **endptr, int base)
-
 
199
{
-
 
200
    char sgn = 0;
-
 
201
    unsigned long number = 0;
-
 
202
   
-
 
203
    number = _strtoul(nptr, endptr, base, &sgn);
-
 
204
 
-
 
205
    if (number > LONG_MAX) {
-
 
206
        if ((sgn) && (number == (unsigned long)(LONG_MAX) + 1)) {
-
 
207
            /* FIXME: set 0 to errno */
-
 
208
            return number;     
-
 
209
        }
-
 
210
        /* FIXME: set ERANGE to errno */
-
 
211
        return (sgn?LONG_MIN:LONG_MAX);
-
 
212
    }
-
 
213
   
-
 
214
    return (sgn?-number:number);
-
 
215
}
-
 
216
 
-
 
217
 
-
 
218
/** Convert initial part of string to unsigned long according to given base.
-
 
219
 * The number may begin with an arbitrary number of whitespaces followed by optional sign (`+' or `-').
-
 
220
 * If the base is 0 or 16, the prefix `0x' may be inserted and the number will be taken as hexadecimal one.
-
 
221
 * If the base is 0 and the number begin with a zero, number will be taken as octal one (as with base 8).
-
 
222
 * Otherwise the base 0 is taken as decimal.
-
 
223
 * @param nptr pointer to string
-
 
224
 * @param endptr if not NULL, function stores here pointer to the first invalid character
-
 
225
 * @param base zero or number between 2 and 36 inclusive
-
 
226
 * @return result of conversion.
-
 
227
 */
-
 
228
unsigned long strtoul(const char *nptr, char **endptr, int base)
-
 
229
{
-
 
230
    char sgn = 0;
-
 
231
    unsigned long number = 0;
-
 
232
   
-
 
233
    number = _strtoul(nptr, endptr, base, &sgn);
-
 
234
 
-
 
235
    return (sgn?-number:number);
-
 
236
}