Replaces assertion of user input to validation.

This commit is contained in:
falsycat 2021-01-03 00:00:00 +00:00
parent fb43a77ec6
commit 967dc2cf3f
2 changed files with 18 additions and 17 deletions

29
biner.l
View File

@ -4,6 +4,7 @@
#include <assert.h> #include <assert.h>
#include <errno.h> #include <errno.h>
#include <inttypes.h> #include <inttypes.h>
#include <stdbool.h>
#include "./tree.h" #include "./tree.h"
#include "./zone.h" #include "./zone.h"
@ -11,7 +12,7 @@
#include "generated/biner.y.h" #include "generated/biner.y.h"
static inline biner_zone_ptr(char) strnew_(void); static inline biner_zone_ptr(char) strnew_(void);
static inline intmax_t parse_int_(int base); static inline bool parse_int_(intmax_t* v, int base);
static inline void count_(void); static inline void count_(void);
%} %}
@ -21,6 +22,7 @@ H [0-9A-Fa-f]
%% %%
[ \t\r\n]+ count_();
"//".* count_(); "//".* count_();
[/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] count_(); /* TODO: detect unterminated comment */ [/][*][^*]*[*]+([^*/][^*]*[*]+)*[/] count_(); /* TODO: detect unterminated comment */
@ -40,27 +42,24 @@ H [0-9A-Fa-f]
{I}({I}|{D})* { yylval.ptr = strnew_(); count_(); return IDENT; } {I}({I}|{D})* { yylval.ptr = strnew_(); count_(); return IDENT; }
{D}+ { yylval.i = parse_int_(10); count_(); return INTEGER; } {D}+ { return parse_int_(&yylval.i, 10)? INTEGER: OVERFLOWN_INTEGER; }
0[xX]{H}+ { yylval.i = parse_int_(16); count_(); return INTEGER; } 0[xX]{H}+ { return parse_int_(&yylval.i, 16)? INTEGER: OVERFLOWN_INTEGER; }
[\+\-\*\/\!\=\<\>\.\(\)[\]\{\}\;\,\&\|\~\^] { count_(); return yytext[0]; } . { count_(); return yytext[0]; }
(.|\n) count_();
%% %%
static inline uintptr_t strnew_(void) { static inline uintptr_t strnew_(void) {
return biner_zone_strnew(&biner_tree_parse_context_.zone, yytext); return biner_zone_strnew(&biner_tree_parse_context_.zone, yytext);
} }
static inline intmax_t parse_int_(int base) { static inline bool parse_int_(intmax_t* v, int base) {
assert(v != NULL);
char* end = NULL; char* end = NULL;
const intmax_t v = strtoimax(yytext, &end, base); *v = strtoimax(yytext, &end, base);
return
/* TODO: replace asserts with throwing error */ ((*v != INTMAX_MIN && *v != INTMAX_MAX) || errno != ERANGE) &&
assert((v != INTMAX_MIN && v != INTMAX_MAX) || errno != ERANGE); (INT64_MIN <= *v && *v <= INT64_MAX) &&
assert(INT64_MIN <= v && v <= INT64_MAX); (end != NULL && *end == 0);
assert(end != NULL && *end == 0);
return v;
} }
static inline void count_(void) { static inline void count_(void) {
const char* s = yytext; const char* s = yytext;

View File

@ -90,10 +90,12 @@ resolve_constant_(
uintptr_t ptr; uintptr_t ptr;
} }
%token OVERFLOWN_INTEGER
%token EQUAL NEQUAL LESS_EQUAL GREATER_EQUAL AND OR BIT_LSHIFT BIT_RSHIFT %token EQUAL NEQUAL LESS_EQUAL GREATER_EQUAL AND OR BIT_LSHIFT BIT_RSHIFT
%token CONST ENUM STRUCT UNION %token CONST ENUM STRUCT UNION
%token <ptr> IDENT %token <ptr> IDENT
%token <i> INTEGER; %token <i> INTEGER
%type <ptr> decl_list decl %type <ptr> decl_list decl
%type <ptr> enum_member_list enum_member %type <ptr> enum_member_list enum_member