redesign parse function to take a dice as parameter

Otherwise we couldn't fetch any error message or code if the dice
object is never visible to the user.
This commit is contained in:
Florian Stinglmayr 2018-02-21 10:19:24 +01:00
parent 82431e7814
commit 6a0abd810f
4 changed files with 27 additions and 23 deletions

View File

@ -44,7 +44,7 @@ struct dice_
char *error; char *error;
}; };
static dice_t dice_new(void) dice_t dice_new(void)
{ {
dice_t tmp = calloc(1, sizeof(struct dice_)); dice_t tmp = calloc(1, sizeof(struct dice_));
@ -101,16 +101,14 @@ dice_t dice_simple(uint32_t amount, uint32_t sides)
return tmp; return tmp;
} }
dice_t dice_parse(char const *s) bool dice_parse(dice_t d, char const *s)
{ {
void *scanner = NULL; void *scanner = NULL;
dice_t d = NULL;
void *buffer = NULL; void *buffer = NULL;
int ret = 0; int ret = 0;
d = dice_new(); if (d == NULL || s == NULL) {
if (d == NULL) { return false;
return NULL;
} }
yylex_init_extra(d, &scanner); yylex_init_extra(d, &scanner);
@ -123,11 +121,10 @@ dice_t dice_parse(char const *s)
yylex_destroy(scanner); yylex_destroy(scanner);
if (ret) { if (ret) {
dice_free(d); return false;
return NULL;
} }
return d; return true;
} }
bool dice_set(dice_t d, dice_option_t opt, ...) bool dice_set(dice_t d, dice_option_t opt, ...)

View File

@ -44,9 +44,10 @@ typedef enum {
void dice_result_free(dice_result_t *r); void dice_result_free(dice_result_t *r);
void dice_result_freev(dice_result_t *r, size_t len); void dice_result_freev(dice_result_t *r, size_t len);
dice_t dice_new(void);
void dice_free(dice_t t); void dice_free(dice_t t);
dice_t dice_simple(uint32_t amount, uint32_t sides); dice_t dice_simple(uint32_t amount, uint32_t sides);
dice_t dice_parse(char const *s); bool dice_parse(dice_t d, char const *s);
bool dice_set(dice_t d, dice_option_t opt, ...); bool dice_set(dice_t d, dice_option_t opt, ...);
bool dice_get(dice_t d, dice_option_t opt, ...); bool dice_get(dice_t d, dice_option_t opt, ...);

View File

@ -279,13 +279,15 @@ void next_token(state *s) {
if (isdigit(s->next[0]) || s->next[0] == '.' || s->next[0] == 'd') { if (isdigit(s->next[0]) || s->next[0] == '.' || s->next[0] == 'd') {
/* first try reading a dice expression, if that fails, we go /* first try reading a dice expression, if that fails, we go
back to trying a number instead */ back to trying a number instead */
dice_t d = dice_parse(s->next); dice_t d = dice_new();
if (d != NULL) {
if (dice_parse(d, s->next)) {
int consumed = dice_consumed(d); int consumed = dice_consumed(d);
s->type = TOK_DICE; s->type = TOK_DICE;
s->dice = d; s->dice = d;
s->next += consumed; s->next += consumed;
} else if (d == NULL) { } else {
dice_free(d);
/* Try reading a number. */ /* Try reading a number. */
s->value = strtod(s->next, (char**)&s->next); s->value = strtod(s->next, (char**)&s->next);
s->type = TOK_NUMBER; s->type = TOK_NUMBER;

View File

@ -31,22 +31,26 @@ int dice_consumed(dice_t d);
static void test_dice_parse_none(void **data) static void test_dice_parse_none(void **data)
{ {
dice_t d = dice_parse(""); dice_t d = dice_new();
assert_null(d);
assert_false(dice_parse(d, ""));
dice_free(d);
} }
static void test_dice_parse_amount(void **data) static void test_dice_parse_amount(void **data)
{ {
dice_t d = dice_parse("3d"); dice_t d = dice_new();
assert_null(d);
assert_false(dice_parse(d, "3d"));
dice_free(d);
} }
static void test_dice_parse_amount_sides(void **data) static void test_dice_parse_amount_sides(void **data)
{ {
dice_t d = dice_parse("5d10"); dice_t d = dice_new();
int i = 0; int i = 0;
assert_non_null(d); assert_true(dice_parse(d, "5d10"));
assert_true(dice_get(d, DICEOPTION_AMOUNT, &i)); assert_true(dice_get(d, DICEOPTION_AMOUNT, &i));
assert_int_equal(i, 5); assert_int_equal(i, 5);
@ -61,10 +65,10 @@ static void test_dice_parse_amount_sides(void **data)
static void test_dice_parse_sides(void **data) static void test_dice_parse_sides(void **data)
{ {
dice_t d = dice_parse("d12"); dice_t d = dice_new();
int i = 0; int i = 0;
assert_non_null(d); assert_true(dice_parse(d, "d12"));
assert_true(dice_get(d, DICEOPTION_SIDES, &i)); assert_true(dice_get(d, DICEOPTION_SIDES, &i));
assert_int_equal(i, 12); assert_int_equal(i, 12);
@ -77,10 +81,10 @@ static void test_dice_parse_sides(void **data)
static void test_dice_parse_big(void **data) static void test_dice_parse_big(void **data)
{ {
char const *dice_str = "1000d120000"; char const *dice_str = "1000d120000";
dice_t d = dice_parse(dice_str); dice_t d = dice_new();
int i = 0; int i = 0;
assert_non_null(d); assert_true(dice_parse(d, dice_str));
assert_true(dice_get(d, DICEOPTION_SIDES, &i)); assert_true(dice_get(d, DICEOPTION_SIDES, &i));
assert_int_equal(i, 120000); assert_int_equal(i, 120000);