From dd3852fdb1d8c4169b5a0de405dd95d8442dcbba Mon Sep 17 00:00:00 2001 From: "Meredith L. Patterson" <clonearmy@gmail.com> Date: Tue, 22 May 2012 02:40:48 +0200 Subject: [PATCH] Added length_value parser to use with DNS --- src/hammer.c | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/src/hammer.c b/src/hammer.c index 0d9cf8cc..136a07c8 100644 --- a/src/hammer.c +++ b/src/hammer.c @@ -846,6 +846,41 @@ const parser_t* attr_bool(const parser_t* p, predicate_t pred) { return res; } +typedef struct { + parser_t *length; + parser_t *value; +} lv_t; + +static parse_result_t* parse_length_value(void *env, parse_state_t *state) { + lv_t *lv = (lv_t*)env; + parse_result_t *len = do_parse(lv->length, state); + if (!len) + return NULL; + if (len->ast->token_type != TT_UINT) + errx(1, "Length parser must return an unsigned integer"); + parser_t epsilon_local = { + .fn = parse_epsilon, + .env = NULL + }; + repeat_t repeat = { + .p = lv->value, + .sep = &epsilon_local, + .count = len->ast->uint, + .min_p = false + } + return parse_many((void*)repeat, state); +} + +const parser_t* length_value(const parser_t* length, const parser_t* value) { + parser_t *res = g_new(parser_t, 1); + res->fn = parse_length_value; + lv_t *env = g_new(lv_t, 1); + env->length = length; + env->value = value; + res->env = (void*)env; + return res; +} + const parser_t* and(const parser_t* p) { return &unimplemented; } static parse_result_t* parse_not(void* env, parse_state_t* state) { @@ -1010,7 +1045,17 @@ static void test_whitespace(void) { } parsed_token_t* upcase(parse_result_t *p) { - return NULL; // shut compiler up + switch(p->ast->token_type) { + case TT_SEQUENCE: + for (size_t i=0; i<p->ast->seq->used; ++i) { + upcase((parse_result_t*)p->ast->seq->elements[i]); + return p->ast; + } + case TT_UINT: + // if i'm a char, upcase me + default: + return p->ast; + } } static void test_action(void) { -- GitLab