strtol and family
This commit is contained in:
parent
d3907663d0
commit
2498ee21f6
@ -26,6 +26,9 @@ extern int atoi(const char * nptr);
|
||||
extern long atol(const char * nptr);
|
||||
extern long int labs(long int j);
|
||||
extern long int strtol(const char * s, char **endptr, int base);
|
||||
extern long long int strtoll(const char *nptr, char **endptr, int base);
|
||||
extern unsigned long int strtoul(const char *nptr, char **endptr, int base);
|
||||
extern unsigned long long int strtoull(const char *nptr, char **endptr, int base);
|
||||
|
||||
extern void srand(unsigned int);
|
||||
extern int rand(void);
|
||||
|
@ -77,4 +77,5 @@ extern int stat(const char *file, struct stat *st);
|
||||
extern int lstat(const char *path, struct stat *st);
|
||||
extern int fstat(int fd, struct stat *st);
|
||||
extern int mkdir(const char *pathname, mode_t mode);
|
||||
extern mode_t umask(mode_t mask);
|
||||
|
||||
|
94
libc/stdlib/strtoul.c
Normal file
94
libc/stdlib/strtoul.c
Normal file
@ -0,0 +1,94 @@
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
#include <errno.h>
|
||||
|
||||
static int is_valid(int base, char c) {
|
||||
if (c < '0') return 0;
|
||||
if (base <= 10) {
|
||||
return c < ('0' + base - 1);
|
||||
}
|
||||
|
||||
if (c > '9' && c < 'a') return 0;
|
||||
if (c > 'a' + (base - 10) && c < 'A') return 1;
|
||||
if (c > 'A' + (base - 10)) return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int convert_digit(char c) {
|
||||
if (c >= '0' && c <= '9') {
|
||||
return c - '0';
|
||||
}
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
return c - 'a';
|
||||
}
|
||||
if (c >= 'A' && c <= 'Z') {
|
||||
return c - 'A';
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define strtox(max, type) \
|
||||
if (base < 0 || base == 1 || base > 36) { \
|
||||
errno = EINVAL; \
|
||||
return max; \
|
||||
} \
|
||||
while (*nptr && isspace(*nptr)) nptr++; \
|
||||
int sign = 1; \
|
||||
if (*nptr == '-') { \
|
||||
sign = -1; \
|
||||
nptr++; \
|
||||
} else if (*nptr == '+') { \
|
||||
nptr++; \
|
||||
} \
|
||||
if (base == 16) { \
|
||||
if (*nptr == '0') { \
|
||||
nptr++; \
|
||||
if (*nptr == 'x') { \
|
||||
nptr++; \
|
||||
} \
|
||||
} \
|
||||
} \
|
||||
if (base == 0) { \
|
||||
if (*nptr == '0') { \
|
||||
base = 8; \
|
||||
nptr++; \
|
||||
if (*nptr == 'x') { \
|
||||
base = 16; \
|
||||
nptr++; \
|
||||
} \
|
||||
} else { \
|
||||
base = 10; \
|
||||
} \
|
||||
} \
|
||||
type val = 0; \
|
||||
while (is_valid(base, *nptr)) { \
|
||||
val *= base; \
|
||||
val += convert_digit(*nptr); \
|
||||
nptr++; \
|
||||
} \
|
||||
if (endptr) { \
|
||||
*endptr = (char *)nptr; \
|
||||
} \
|
||||
if (sign == -1) { \
|
||||
return -val; \
|
||||
} else { \
|
||||
return val; \
|
||||
}
|
||||
|
||||
unsigned long int strtoul(const char *nptr, char **endptr, int base) {
|
||||
strtox(ULONG_MAX, unsigned long int);
|
||||
}
|
||||
|
||||
unsigned long long int strtoull(const char *nptr, char **endptr, int base) {
|
||||
strtox(ULLONG_MAX, unsigned long int);
|
||||
}
|
||||
|
||||
long int strtol(const char *nptr, char **endptr, int base) {
|
||||
strtox(LONG_MAX, unsigned long int);
|
||||
}
|
||||
|
||||
long long int strtoll(const char *nptr, char **endptr, int base) {
|
||||
strtox(LLONG_MAX, unsigned long long int);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user