add "VRULE" family of macros to attach validations like actions

This commit is contained in:
Sven M. Hallberg 2013-01-17 17:44:41 +01:00
parent 6515a80c3a
commit e875dcd19a
2 changed files with 55 additions and 46 deletions

View file

@ -12,10 +12,10 @@
/// ///
// Semantic Actions and Validations // Validations
/// ///
bool is_zero(HParseResult *p) { bool validate_hdzero(HParseResult *p) {
if (TT_UINT != p->ast->token_type) if (TT_UINT != p->ast->token_type)
return false; return false;
return (0 == p->ast->uint); return (0 == p->ast->uint);
@ -25,7 +25,7 @@ bool is_zero(HParseResult *p) {
* Every DNS message should have QDCOUNT entries in the question * Every DNS message should have QDCOUNT entries in the question
* section, and ANCOUNT+NSCOUNT+ARCOUNT resource records. * section, and ANCOUNT+NSCOUNT+ARCOUNT resource records.
*/ */
bool validate_dns(HParseResult *p) { bool validate_message(HParseResult *p) {
if (TT_SEQUENCE != p->ast->token_type) if (TT_SEQUENCE != p->ast->token_type)
return false; return false;
dns_header_t *header = H_FIELD(dns_header_t, 0); dns_header_t *header = H_FIELD(dns_header_t, 0);
@ -42,6 +42,10 @@ bool validate_dns(HParseResult *p) {
return true; return true;
} }
///
// Semantic Actions
///
uint8_t* get_cs(const HCountedArray *arr) { uint8_t* get_cs(const HCountedArray *arr) {
uint8_t *ret = h_arena_malloc(arr->arena, sizeof(uint8_t)*arr->used); uint8_t *ret = h_arena_malloc(arr->arena, sizeof(uint8_t)*arr->used);
for (size_t i=0; i<arr->used; ++i) for (size_t i=0; i<arr->used; ++i)
@ -272,8 +276,8 @@ const HParser* init_parser() {
return ret; return ret;
H_RULE (domain, init_domain()); H_RULE (domain, init_domain());
H_ARULE(hdzero, h_attr_bool(h_bits(3, false), is_zero)); H_AVRULE(hdzero, h_bits(3, false));
H_ARULE(header, h_sequence(h_bits(16, false), // ID H_ARULE (header, h_sequence(h_bits(16, false), // ID
h_bits(1, false), // QR h_bits(1, false), // QR
h_bits(4, false), // opcode h_bits(4, false), // opcode
h_bits(1, false), // AA h_bits(1, false), // AA
@ -296,11 +300,11 @@ const HParser* init_parser() {
h_int_range(h_uint16(), 255, 255), h_int_range(h_uint16(), 255, 255),
NULL)); NULL));
H_RULE (len, h_int_range(h_uint8(), 1, 255)); H_RULE (len, h_int_range(h_uint8(), 1, 255));
H_ARULE(label, h_length_value(len, h_uint8())); H_ARULE (label, h_length_value(len, h_uint8()));
H_ARULE(qname, h_sequence(h_many1(label), H_ARULE (qname, h_sequence(h_many1(label),
h_ch('\x00'), h_ch('\x00'),
NULL)); NULL));
H_ARULE(question, h_sequence(qname, qtype, qclass, NULL)); H_ARULE (question, h_sequence(qname, qtype, qclass, NULL));
H_RULE (rdata, h_length_value(h_uint16(), h_uint8())); H_RULE (rdata, h_length_value(h_uint16(), h_uint8()));
H_ARULE (rr, h_sequence(domain, // NAME H_ARULE (rr, h_sequence(domain, // NAME
type, // TYPE type, // TYPE
@ -308,12 +312,11 @@ const HParser* init_parser() {
h_uint32(), // TTL h_uint32(), // TTL
rdata, // RDLENGTH+RDATA rdata, // RDLENGTH+RDATA
NULL)); NULL));
H_ARULE(message, h_attr_bool(h_sequence(header, H_AVRULE(message, h_sequence(header,
h_many(question), h_many(question),
h_many(rr), h_many(rr),
h_end_p(), h_end_p(),
NULL), NULL));
validate_dns));
ret = message; ret = message;
return ret; return ret;

View file

@ -10,6 +10,12 @@
#define H_RULE(rule, def) const HParser *rule = def #define H_RULE(rule, def) const HParser *rule = def
#define H_ARULE(rule, def) const HParser *rule = h_action(def, act_ ## rule) #define H_ARULE(rule, def) const HParser *rule = h_action(def, act_ ## rule)
#define H_VRULE(rule, def) const HParser *rule = \
h_attr_bool(def, validate_ ## rule)
#define H_VARULE(rule, def) const HParser *rule = \
h_attr_bool(h_action(def, act_ ## rule), validate_ ## rule)
#define H_AVRULE(rule, def) const HParser *rule = \
h_action(h_attr_bool(def, validate_ ## rule), act_ ## rule)
const HParsedToken *act_ignore(const HParseResult *p); const HParsedToken *act_ignore(const HParseResult *p);
const HParsedToken *act_index(int i, const HParseResult *p); const HParsedToken *act_index(int i, const HParseResult *p);