From 2ff51ab9c36dfc0fc723c38d26009048413e9e37 Mon Sep 17 00:00:00 2001 From: "Sven M. Hallberg" Date: Mon, 14 Jan 2013 21:25:46 +0100 Subject: [PATCH] rework dns example syntax into H_RULE style --- examples/dns.c | 119 +++++++++++++++++++++++++------------------------ 1 file changed, 61 insertions(+), 58 deletions(-) diff --git a/examples/dns.c b/examples/dns.c index 676855e..010c462 100644 --- a/examples/dns.c +++ b/examples/dns.c @@ -10,6 +10,10 @@ #define false 0 #define true 1 +#define H_RULE(rule, def) const HParser *rule = def +#define H_ARULE(rule, def) const HParser *rule = h_action(def, act_ ## rule) + + bool is_zero(HParseResult *p) { if (TT_UINT != p->ast->token_type) return false; @@ -283,7 +287,7 @@ void set_rr(struct dns_rr rr, HCountedArray *rdata) { } } -const HParsedToken* pack_dns_struct(const HParseResult *p) { +const HParsedToken* act_dns_message(const HParseResult *p) { h_pprint(stdout, p->ast, 0, 2); HParsedToken *ret = h_arena_malloc(p->arena, sizeof(HParsedToken)); ret->token_type = TT_DNS_MESSAGE; @@ -360,66 +364,65 @@ const HParsedToken* pack_dns_struct(const HParseResult *p) { return ret; } +// The action equivalent of h_ignore. +const HParsedToken *act_ignore(const HParseResult *p) +{ + return NULL; +} + +#define act_dns_hdzero act_ignore + const HParser* init_parser() { - static HParser *dns_message = NULL; - if (dns_message) - return dns_message; + static const HParser *ret = NULL; + if (ret) + return ret; - const HParser *domain = init_domain(); + H_RULE (domain, init_domain()); + H_ARULE(dns_hdzero, h_attr_bool(h_bits(3, false), is_zero)); + H_RULE (dns_header, h_sequence(h_bits(16, false), // ID + h_bits(1, false), // QR + h_bits(4, false), // opcode + h_bits(1, false), // AA + h_bits(1, false), // TC + h_bits(1, false), // RD + h_bits(1, false), // RA + dns_hdzero, // Z + h_bits(4, false), // RCODE + h_uint16(), // QDCOUNT + h_uint16(), // ANCOUNT + h_uint16(), // NSCOUNT + h_uint16(), // ARCOUNT + NULL)); + H_RULE (type, h_int_range(h_uint16(), 1, 16)); + H_RULE (qtype, h_choice(type, + h_int_range(h_uint16(), 252, 255), + NULL)); + H_RULE (class, h_int_range(h_uint16(), 1, 4)); + H_RULE (qclass, h_choice(class, + h_int_range(h_uint16(), 255, 255), + NULL)); + H_RULE (dns_question, h_sequence(h_sequence(h_many1(h_length_value(h_int_range(h_uint8(), 1, 255), + h_uint8())), + h_ch('\x00'), + NULL), // QNAME + qtype, // QTYPE + qclass, // QCLASS + NULL)); + H_RULE (dns_rr, h_sequence(domain, // NAME + type, // TYPE + class, // CLASS + h_uint32(), // TTL + h_length_value(h_uint16(), h_uint8()), // RDLENGTH+RDATA + NULL)); + H_ARULE(dns_message, h_attr_bool(h_sequence(dns_header, + h_many(dns_question), + h_many(dns_rr), + h_end_p(), + NULL), + validate_dns)); - const HParser *dns_header = h_sequence(h_bits(16, false), // ID - h_bits(1, false), // QR - h_bits(4, false), // opcode - h_bits(1, false), // AA - h_bits(1, false), // TC - h_bits(1, false), // RD - h_bits(1, false), // RA - h_ignore(h_attr_bool(h_bits(3, false), is_zero)), // Z - h_bits(4, false), // RCODE - h_uint16(), // QDCOUNT - h_uint16(), // ANCOUNT - h_uint16(), // NSCOUNT - h_uint16(), // ARCOUNT - NULL); - - const HParser *type = h_int_range(h_uint16(), 1, 16); - - const HParser *qtype = h_choice(type, - h_int_range(h_uint16(), 252, 255), - NULL); - - const HParser *class = h_int_range(h_uint16(), 1, 4); - - const HParser *qclass = h_choice(class, - h_int_range(h_uint16(), 255, 255), - NULL); - - const HParser *dns_question = h_sequence(h_sequence(h_many1(h_length_value(h_int_range(h_uint8(), 1, 255), - h_uint8())), - h_ch('\x00'), - NULL), // QNAME - qtype, // QTYPE - qclass, // QCLASS - NULL); - - - const HParser *dns_rr = h_sequence(domain, // NAME - type, // TYPE - class, // CLASS - h_uint32(), // TTL - h_length_value(h_uint16(), h_uint8()), // RDLENGTH+RDATA - NULL); - - - dns_message = (HParser*)h_action(h_attr_bool(h_sequence(dns_header, - h_many(dns_question), - h_many(dns_rr), - h_end_p(), - NULL), - validate_dns), - pack_dns_struct); - - return dns_message; + ret = dns_message; + return ret; } int start_listening() {