const HParser* init_domain() { static const HParser *domain = NULL; if (domain) return domain; const HParser *letter = h_choice(h_ch_range('a', 'z'), h_ch_range('A', 'Z'), NULL); const HParser *let_dig = h_choice(letter, h_ch_range('0', '9'), NULL); const HParser *ldh_str = h_many1(h_choice(let_dig, h_ch('-'), NULL)); const HParser *label = h_attr_bool(h_sequence(letter, h_optional(h_sequence(h_optional(ldh_str), let_dig, NULL)), NULL), validate_label); /** * You could write it like this ... * HParser *indirect_subdomain = h_indirect(); * const HParser *subdomain = h_choice(label, * h_sequence(indirect_subdomain, * h_ch('.'), * label, * NULL), * NULL); * h_bind_indirect(indirect_subdomain, subdomain); * * ... but this is easier and equivalent */ const HParser *subdomain = h_sepBy1(label, h_ch('.')); domain = h_choice(subdomain, h_ch(' '), NULL); return domain; }
HParser* init_domain() { static HParser *ret = NULL; if (ret) return ret; H_RULE (letter, h_choice(h_ch_range('a','z'), h_ch_range('A','Z'), NULL)); H_RULE (let_dig, h_choice(letter, h_ch_range('0','9'), NULL)); H_RULE (ldh_str, h_many1(h_choice(let_dig, h_ch('-'), NULL))); H_VARULE(label, h_sequence(letter, h_optional(h_sequence(h_optional(ldh_str), let_dig, NULL)), NULL)); H_RULE (subdomain, h_sepBy1(label, h_ch('.'))); H_ARULE (domain, h_choice(subdomain, h_ch(' '), NULL)); ret = domain; return ret; }
const HParser* init_rdata(uint16_t type) { static const HParser *parsers[RDATA_TYPE_MAX+1]; static int inited = 0; if (type >= sizeof(parsers)) return NULL; if (inited) return parsers[type]; H_RULE (domain, init_domain()); H_ARULE(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_ARULE(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_VRULE(null, h_many(h_uint8())); 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_ARULE(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<sizeof(parsers); i++) { if(parsers[i]) { parsers[i] = h_action(h_sequence(parsers[i], h_end_p(), NULL), act_index0); } } inited = 1; return parsers[type]; }