diff --git a/examples/dns.c b/examples/dns.c index 4174206..81c2488 100644 --- a/examples/dns.c +++ b/examples/dns.c @@ -69,7 +69,7 @@ void set_rdata(struct dns_rr rr, HCountedArray *rdata) { const HParser *parser = init_rdata(rr.type); if (parser) p = h_parse(parser, (const uint8_t*)data, rdata->used); - + // If the RR doesn't parse, set its type to 0. if (!p) rr.type = 0; diff --git a/examples/rr.c b/examples/rr.c index 5feaf37..84022ab 100644 --- a/examples/rr.c +++ b/examples/rr.c @@ -5,248 +5,79 @@ #define false 0 #define true 1 -#define RDATA_TYPE_MAX 16 -const HParser* init_rdata(uint16_t type) { - static const HParser *parsers[RDATA_TYPE_MAX+1]; - static int inited = 0; - - if (type > RDATA_TYPE_MAX) - return NULL; - - if (inited) - return parsers[type]; - - parsers[ 0] = NULL; // there is no type 0 - parsers[ 1] = init_a(); - parsers[ 2] = init_ns(); - parsers[ 3] = init_md(); - parsers[ 4] = init_mf(); - parsers[ 5] = init_cname(); - parsers[ 6] = init_soa(); - parsers[ 7] = init_mb(); - parsers[ 8] = init_mg(); - parsers[ 9] = init_mr(); - parsers[10] = init_null(); - parsers[11] = init_wks(); - parsers[12] = init_ptr(); - parsers[13] = init_hinfo(); - parsers[14] = init_minfo(); - parsers[15] = init_mx(); - parsers[16] = init_txt(); - - inited = 1; - return parsers[type]; -} - -const HParser* init_cname() { - static const HParser *cname = NULL; - if (cname) - return cname; - - cname = h_sequence(init_domain(), - h_end_p(), - NULL); - - return cname; -} - -const HParser* init_hinfo() { - static const HParser *hinfo = NULL; - if (hinfo) - return hinfo; - - const HParser* cstr = init_character_string(); - - hinfo = h_sequence(cstr, - cstr, - h_end_p(), - NULL); - - return hinfo; -} - -const HParser* init_mb() { - static const HParser *mb = NULL; - if (mb) - return mb; - - mb = h_sequence(init_domain(), - h_end_p(), - NULL); - - return mb; -} - -const HParser* init_md() { - static const HParser *md = NULL; - if (md) - return md; - - md = h_sequence(init_domain(), - h_end_p, - NULL); - - return md; -} - -const HParser* init_mf() { - static const HParser *mf = NULL; - if (mf) - return mf; - - mf = h_sequence(init_domain(), - h_end_p(), - NULL); - - return mf; -} - -const HParser* init_mg() { - static const HParser *mg = NULL; - if (mg) - return mg; - - mg = h_sequence(init_domain(), - h_end_p(), - NULL); - - return mg; -} - -const HParser* init_minfo() { - static const HParser *minfo = NULL; - if (minfo) - return minfo; - - const HParser* domain = init_domain(); - - minfo = h_sequence(domain, - domain, - h_end_p(), - NULL); - - return minfo; -} - -const HParser* init_mr() { - static const HParser *mr = NULL; - if (mr) - return mr; - - mr = h_sequence(init_domain(), - h_end_p(), - NULL); - - return mr; -} - -const HParser* init_mx() { - static const HParser *mx = NULL; - if (mx) - return mx; - - mx = h_sequence(h_uint16(), - init_domain(), - h_end_p(), - NULL); - - return mx; -} - bool validate_null(HParseResult *p) { if (TT_SEQUENCE != p->ast->token_type) return false; return (65536 > p->ast->seq->used); } -const HParser* init_null() { - static const HParser *null_ = NULL; - if (null_) - return null_; +#define RDATA_TYPE_MAX 16 +const HParser* init_rdata(uint16_t type) { + static const HParser *parsers[RDATA_TYPE_MAX+1]; + static int inited = 0; - null_ = h_attr_bool(h_many(h_uint8()), validate_null); - - return null_; -} - -const HParser* init_ns() { - static const HParser *ns = NULL; - if (ns) - return ns; - - ns = h_sequence(init_domain(), - h_end_p(), - NULL); - - return ns; -} - -const HParser* init_ptr() { - static const HParser *ptr = NULL; - if (ptr) - return ptr; + if (type >= sizeof(parsers)) + return NULL; - ptr = h_sequence(init_domain(), - h_end_p(), - NULL); + if (inited) + return parsers[type]; - return ptr; -} - -const HParser* init_soa() { - static const HParser *soa = NULL; - if (soa) - return soa; - - const HParser *domain = init_domain(); - - soa = h_sequence(domain, // MNAME - domain, // RNAME - h_uint32(), // SERIAL - h_uint32(), // REFRESH - h_uint32(), // RETRY - h_uint32(), // EXPIRE - h_uint32(), // MINIMUM - h_end_p(), - NULL); - - return soa; -} - -const HParser* init_txt() { - static const HParser *txt = NULL; - if (txt) - return txt; - - txt = h_sequence(h_many1(init_character_string()), - h_end_p(), - NULL); - - return txt; -} - -const HParser* init_a() { - static const HParser *a = NULL; - if (a) - return a; - - a = h_sequence(h_uint32(), - h_end_p(), - NULL); - - return a; -} - -const HParser* init_wks() { - static const HParser *wks = NULL; - if (wks) - return wks; - - wks = h_sequence(h_uint32(), - h_uint8(), - h_many(h_uint8()), - h_end_p(), - NULL); - - return wks; + + H_RULE (domain, init_domain()); + H_RULE (cstr, init_character_string()); + + H_RULE (a, h_uint32()); + H_RULE (ns, domain); + H_RULE (md, domain); + H_RULE (mf, domain); + H_RULE (cname, domain); + H_RULE (soa, h_sequence(domain, // MNAME + domain, // RNAME + h_uint32(), // SERIAL + h_uint32(), // REFRESH + h_uint32(), // RETRY + h_uint32(), // EXPIRE + h_uint32(), // MINIMUM + NULL)); + H_RULE (mb, domain); + H_RULE (mg, domain); + H_RULE (mr, domain); + H_RULE (null_, h_attr_bool(h_many(h_uint8()), validate_null)); + H_RULE (wks, h_sequence(h_uint32(), + h_uint8(), + h_many(h_uint8()), + NULL)); + H_RULE (ptr, domain); + H_RULE (hinfo, h_sequence(cstr, cstr, NULL)); + H_RULE (minfo, h_sequence(domain, domain, NULL)); + H_RULE (mx, h_sequence(h_uint16(), domain, NULL)); + H_RULE (txt, h_many1(cstr)); + + + parsers[ 0] = NULL; // there is no type 0 + parsers[ 1] = a; + parsers[ 2] = ns; + parsers[ 3] = md; + parsers[ 4] = mf; + parsers[ 5] = cname; + parsers[ 6] = soa; + parsers[ 7] = mb; + parsers[ 8] = mg; + parsers[ 9] = mr; + parsers[10] = null_; + parsers[11] = wks; + parsers[12] = ptr; + parsers[13] = hinfo; + parsers[14] = minfo; + parsers[15] = mx; + parsers[16] = txt; + + // All parsers must consume their input exactly. + for(uint16_t i; i