strtoul, strtol
This commit is contained in:
parent
0c5b34b8d0
commit
f7c3154b8a
3 changed files with 129 additions and 2 deletions
|
@ -1,7 +1,13 @@
|
||||||
|
#define _STDLIB_DEBUG
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
int main(void) {
|
int main(void) {
|
||||||
|
char s[] = " -0XAh.\n";
|
||||||
|
char *end;
|
||||||
|
errno = 0;
|
||||||
|
printf("%ld\n", strtol(s, &end, 0));
|
||||||
|
printf("%d:%s",errno,end);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
12
05/parse.b
12
05/parse.b
|
@ -802,7 +802,9 @@ function parse_statement
|
||||||
|
|
||||||
:local_decl_initializer
|
:local_decl_initializer
|
||||||
token += 16
|
token += 16
|
||||||
if *1token == SYMBOL_LBRACE goto local_init_lbrace
|
if *1token == SYMBOL_LBRACE goto local_const_init
|
||||||
|
if *1token == TOKEN_STRING_LITERAL goto maybe_string_init
|
||||||
|
:not_string_init
|
||||||
n = token_next_semicolon_comma_rbracket(token)
|
n = token_next_semicolon_comma_rbracket(token)
|
||||||
out += 24
|
out += 24
|
||||||
p = expressions_end
|
p = expressions_end
|
||||||
|
@ -813,7 +815,13 @@ function parse_statement
|
||||||
type_decay_array_to_pointer_in_place(*4p) ; fix typing for `int[] x = {5,6}; int *y = x;`
|
type_decay_array_to_pointer_in_place(*4p) ; fix typing for `int[] x = {5,6}; int *y = x;`
|
||||||
token = n
|
token = n
|
||||||
goto local_decl_continue
|
goto local_decl_continue
|
||||||
:local_init_lbrace
|
:maybe_string_init
|
||||||
|
; check if we have char x[] = "hello"; or char *x = "hello"; (we'll use parse_constant_initializer for that)
|
||||||
|
p = token + 16
|
||||||
|
if *1p == SYMBOL_SEMICOLON goto local_const_init
|
||||||
|
if *1p == SYMBOL_COMMA goto local_const_init
|
||||||
|
goto not_string_init
|
||||||
|
:local_const_init
|
||||||
rwdata_end_addr += 7
|
rwdata_end_addr += 7
|
||||||
rwdata_end_addr >= 3
|
rwdata_end_addr >= 3
|
||||||
rwdata_end_addr <= 3
|
rwdata_end_addr <= 3
|
||||||
|
|
113
05/stdc_common.h
113
05/stdc_common.h
|
@ -1,6 +1,11 @@
|
||||||
#ifndef _STDC_COMMON_H
|
#ifndef _STDC_COMMON_H
|
||||||
#define _STDC_COMMON_H
|
#define _STDC_COMMON_H
|
||||||
|
|
||||||
|
#ifdef _STDLIB_DEBUG
|
||||||
|
int printf(char *);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#define signed
|
#define signed
|
||||||
#define volatile
|
#define volatile
|
||||||
#define register
|
#define register
|
||||||
|
@ -20,6 +25,35 @@ typedef long ptrdiff_t;
|
||||||
typedef unsigned long uintptr_t;
|
typedef unsigned long uintptr_t;
|
||||||
typedef long intptr_t;
|
typedef long intptr_t;
|
||||||
|
|
||||||
|
#define INT8_MAX 0x7f
|
||||||
|
#define INT8_MIN (-0x80)
|
||||||
|
#define INT16_MAX 0x7fff
|
||||||
|
#define INT16_MIN (-0x8000)
|
||||||
|
#define INT32_MAX 0x7fffffff
|
||||||
|
#define INT32_MIN (-0x80000000)
|
||||||
|
#define INT64_MAX 0x7fffffffffffffff
|
||||||
|
#define INT64_MIN (-0x8000000000000000)
|
||||||
|
#define UINT8_MAX 0xff
|
||||||
|
#define UINT16_MAX 0xffff
|
||||||
|
#define UINT32_MAX 0xffffffff
|
||||||
|
#define UINT64_MAX 0xffffffffffffffff
|
||||||
|
#define CHAR_BIT 8
|
||||||
|
#define MB_LEN_MAX 4
|
||||||
|
#define CHAR_MIN INT8_MIN
|
||||||
|
#define CHAR_MAX INT8_MAX
|
||||||
|
#define SCHAR_MIN INT8_MIN
|
||||||
|
#define SCHAR_MAX INT8_MAX
|
||||||
|
#define INT_MIN INT32_MIN
|
||||||
|
#define INT_MAX INT32_MAX
|
||||||
|
#define LONG_MIN INT64_MIN
|
||||||
|
#define LONG_MAX INT64_MAX
|
||||||
|
#define SHRT_MIN INT16_MIN
|
||||||
|
#define SHRT_MAX INT16_MAX
|
||||||
|
#define UCHAR_MAX UINT8_MAX
|
||||||
|
#define USHRT_MAX UINT16_MAX
|
||||||
|
#define UINT_MAX UINT32_MAX
|
||||||
|
#define ULONG_MAX UINT64_MAX
|
||||||
|
|
||||||
static unsigned char __syscall_data[] = {
|
static unsigned char __syscall_data[] = {
|
||||||
// mov rax, [rsp+24]
|
// mov rax, [rsp+24]
|
||||||
0x48, 0x8b, 0x84, 0x24, 24, 0, 0, 0,
|
0x48, 0x8b, 0x84, 0x24, 24, 0, 0, 0,
|
||||||
|
@ -141,6 +175,85 @@ size_t strlen(char *s) {
|
||||||
return t - s;
|
return t - s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int isspace(int c) {
|
||||||
|
return c == ' ' || c == '\f' || c == '\n' || c == '\r' || c == '\t' || c == '\v';
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned long strtoul(const char *nptr, char **endptr, int base) {
|
||||||
|
unsigned long value = 0, newvalue;
|
||||||
|
int overflow = 0;
|
||||||
|
|
||||||
|
while (isspace(*nptr)) ++nptr;
|
||||||
|
if (*nptr == '+') ++nptr;
|
||||||
|
if (base == 0) {
|
||||||
|
if (*nptr == '0') {
|
||||||
|
++nptr;
|
||||||
|
switch (*nptr) {
|
||||||
|
case 'x':
|
||||||
|
case 'X':
|
||||||
|
base = 16;
|
||||||
|
++nptr;
|
||||||
|
break;
|
||||||
|
case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7':
|
||||||
|
base = 8;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// this must just be the number 0.
|
||||||
|
if (endptr) *endptr = nptr;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
base = 10;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
int c = *nptr;
|
||||||
|
unsigned v;
|
||||||
|
if (c >= '0' && c <= '9')
|
||||||
|
v = c - '0';
|
||||||
|
else if (c >= 'a' && c <= 'z')
|
||||||
|
v = c - 'a' + 10;
|
||||||
|
else if (c >= 'A' && c <= 'Z')
|
||||||
|
v = c - 'A' + 10;
|
||||||
|
else break;
|
||||||
|
if (v >= base) break;
|
||||||
|
unsigned long newvalue = value * base + v;
|
||||||
|
if (newvalue < value) overflow = 1;
|
||||||
|
value = newvalue;
|
||||||
|
++nptr;
|
||||||
|
}
|
||||||
|
*endptr = nptr;
|
||||||
|
if (overflow) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return ULONG_MAX;
|
||||||
|
} else {
|
||||||
|
return value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
long strtol(const char *nptr, char **endptr, int base) {
|
||||||
|
int sign = 1;
|
||||||
|
while (isspace(*nptr)) ++nptr;
|
||||||
|
if (*nptr == '-') {
|
||||||
|
sign = -1;
|
||||||
|
++nptr;
|
||||||
|
}
|
||||||
|
unsigned long mag = strtoul(nptr, endptr, base);
|
||||||
|
if (sign > 0) {
|
||||||
|
if (mag > LONG_MAX) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return LONG_MIN;
|
||||||
|
}
|
||||||
|
return (long)mag;
|
||||||
|
} else {
|
||||||
|
if (mag > (unsigned long)LONG_MAX + 1) {
|
||||||
|
errno = ERANGE;
|
||||||
|
return LONG_MIN;
|
||||||
|
}
|
||||||
|
return -(long)mag;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int fd;
|
int fd;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue