diff --git a/examples/dns.c b/examples/dns.c index c404f6c526bf52b87b65c254e26a4dff8636cf6a..6c572a00b4417f6e636331a12b404a5f2abb2681 100644 --- a/examples/dns.c +++ b/examples/dns.c @@ -52,7 +52,7 @@ bool validate_message(HParseResult *p) { void set_rdata(struct dns_rr rr, HCountedArray *rdata) { uint8_t *data = h_arena_malloc(rdata->arena, sizeof(uint8_t)*rdata->used); for (size_t i=0; i<rdata->used; ++i) - data[i] = h_cast_uint(rdata->elements[i]); + data[i] = H_CAST_UINT(rdata->elements[i]); // Parse RDATA if possible. const HParseResult *p = NULL; @@ -66,7 +66,7 @@ void set_rdata(struct dns_rr rr, HCountedArray *rdata) { // Pack the parsed rdata into rr. switch(rr.type) { - case 1: rr.a = h_cast_uint(p->ast); break; + case 1: rr.a = H_CAST_UINT(p->ast); break; case 2: rr.ns = *H_CAST(dns_domain_t, p->ast); break; case 3: rr.md = *H_CAST(dns_domain_t, p->ast); break; case 4: rr.md = *H_CAST(dns_domain_t, p->ast); break; @@ -89,18 +89,18 @@ void set_rdata(struct dns_rr rr, HCountedArray *rdata) { const HParsedToken* act_header(const HParseResult *p) { HParsedToken **fields = h_seq_elements(p->ast); dns_header_t header_ = { - .id = h_cast_uint(fields[0]), - .qr = h_cast_uint(fields[1]), - .opcode = h_cast_uint(fields[2]), - .aa = h_cast_uint(fields[3]), - .tc = h_cast_uint(fields[4]), - .rd = h_cast_uint(fields[5]), - .ra = h_cast_uint(fields[6]), - .rcode = h_cast_uint(fields[7]), - .question_count = h_cast_uint(fields[8]), - .answer_count = h_cast_uint(fields[9]), - .authority_count = h_cast_uint(fields[10]), - .additional_count = h_cast_uint(fields[11]) + .id = H_CAST_UINT(fields[0]), + .qr = H_CAST_UINT(fields[1]), + .opcode = H_CAST_UINT(fields[2]), + .aa = H_CAST_UINT(fields[3]), + .tc = H_CAST_UINT(fields[4]), + .rd = H_CAST_UINT(fields[5]), + .ra = H_CAST_UINT(fields[6]), + .rcode = H_CAST_UINT(fields[7]), + .question_count = H_CAST_UINT(fields[8]), + .answer_count = H_CAST_UINT(fields[9]), + .authority_count = H_CAST_UINT(fields[10]), + .additional_count = H_CAST_UINT(fields[11]) }; dns_header_t *header = H_ALLOC(dns_header_t); @@ -147,8 +147,8 @@ const HParsedToken* act_question(const HParseResult *p) { q->qname.labels[i] = *H_INDEX(dns_label_t, fields[0], i); } - q->qtype = h_cast_uint(fields[1]); - q->qclass = h_cast_uint(fields[2]); + q->qtype = H_CAST_UINT(fields[1]); + q->qclass = H_CAST_UINT(fields[2]); return H_MAKE(dns_question_t, q); } diff --git a/examples/glue.c b/examples/glue.c index 3a8f6cb6073e98b2d5ba108e74765b2e214e9f0f..7f9c6fa4b1f2cd0f9ecc28bdfa591aa9bec5914c 100644 --- a/examples/glue.c +++ b/examples/glue.c @@ -77,36 +77,6 @@ HParsedToken *h_make_uint(HArena *arena, uint64_t val) return ret; } -void * h_cast(HTokenType type, const HParsedToken *p) -{ - assert(p->token_type == type); - return p->user; -} - -HCountedArray *h_cast_seq(const HParsedToken *p) -{ - assert(p->token_type == TT_SEQUENCE); - return p->seq; -} - -HBytes h_cast_bytes(const HParsedToken *p) -{ - assert(p->token_type == TT_BYTES); - return p->bytes; -} - -int64_t h_cast_sint(const HParsedToken *p) -{ - assert(p->token_type == TT_SINT); - return p->sint; -} - -uint64_t h_cast_uint(const HParsedToken *p) -{ - assert(p->token_type == TT_UINT); - return p->uint; -} - // XXX -> internal HParsedToken *h_carray_index(const HCountedArray *a, size_t i) { diff --git a/examples/glue.h b/examples/glue.h index 1dc2fbd8c00526c3c07eed4585626390c5c23fc1..addcf18df2350ec076377728ae68c9c5e837c77d 100644 --- a/examples/glue.h +++ b/examples/glue.h @@ -61,16 +61,24 @@ HParsedToken *h_make_uint(HArena *arena, uint64_t val); #define H_MAKE_SINT(VAL) h_make_sint(p->arena, VAL) #define H_MAKE_UINT(VAL) h_make_uint(p->arena, VAL) -// Extract type-specific value back from HParsedTokens... +// Extract (cast) type-specific value back from HParsedTokens... -void * h_cast (HTokenType type, const HParsedToken *p); -HCountedArray *h_cast_seq (const HParsedToken *p); -HBytes h_cast_bytes(const HParsedToken *p); -int64_t h_cast_sint (const HParsedToken *p); -uint64_t h_cast_uint (const HParsedToken *p); +// Pass-through assertion that a given token has the expected type. +#define h_assert_type(T,P) (assert(P->token_type == (HTokenType)T), P) -// Standard short-hand to cast to a user type. -#define H_CAST(TYP, TOK) ((TYP *) h_cast(TT_ ## TYP, TOK)) +// Convenience short-hand forms of h_assert_type. +#define H_ASSERT(TYP, TOK) h_assert_type(TT_ ## TYP, TOK) +#define H_ASSERT_SEQ(TOK) h_assert_type(TT_SEQUENCE, TOK) +#define H_ASSERT_BYTES(TOK) h_assert_type(TT_BYTES, TOK) +#define H_ASSERT_SINT(TOK) h_assert_type(TT_SINT, TOK) +#define H_ASSERT_UINT(TOK) h_assert_type(TT_UINT, TOK) + +// Assert expected type and return contained value. +#define H_CAST(TYP, TOK) ((TYP *) H_ASSERT(TYP, TOK)->user) +#define H_CAST_SEQ(TOK) (H_ASSERT_SEQ(TOK)->seq) +#define H_CAST_BYTES(TOK) (H_ASSERT_BYTES(TOK)->bytes) +#define H_CAST_SINT(TOK) (H_ASSERT_SINT(TOK)->sint) +#define H_CAST_UINT(TOK) (H_ASSERT_UINT(TOK)->uint) // Sequence access... @@ -88,12 +96,11 @@ HParsedToken *h_seq_index_path(const HParsedToken *p, size_t i, ...); HParsedToken *h_seq_index_vpath(const HParsedToken *p, size_t i, va_list va); // Convenience macros combining (nested) index access and h_cast. -#define H_INDEX(TYP, SEQ, ...) \ - ((TYP *) h_cast(TT_ ## TYP, H_INDEX_TOKEN(SEQ, __VA_ARGS__))) -#define H_INDEX_SEQ(SEQ, ...) h_cast_seq(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) -#define H_INDEX_BYTES(SEQ, ...) h_cast_bytes(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) -#define H_INDEX_SINT(SEQ, ...) h_cast_sint(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) -#define H_INDEX_UINT(SEQ, ...) h_cast_uint(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) +#define H_INDEX(TYP, SEQ, ...) H_CAST(TYP, H_INDEX_TOKEN(SEQ, __VA_ARGS__)) +#define H_INDEX_SEQ(SEQ, ...) H_CAST_SEQ(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) +#define H_INDEX_BYTES(SEQ, ...) H_CAST_BYTES(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) +#define H_INDEX_SINT(SEQ, ...) H_CAST_SINT(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) +#define H_INDEX_UINT(SEQ, ...) H_CAST_UINT(H_INDEX_TOKEN(SEQ, __VA_ARGS__)) #define H_INDEX_TOKEN(SEQ, ...) h_seq_index_path(SEQ, __VA_ARGS__, -1) // Standard short-hand to access and cast elements on a sequence token. diff --git a/examples/rr.c b/examples/rr.c index 1e74370c03044d47c0d9dbb8f9e5b54efa441ab3..8c14e0aec8e678f86dfdbc54dc0499dd3a828d8e 100644 --- a/examples/rr.c +++ b/examples/rr.c @@ -31,7 +31,7 @@ const HParsedToken *act_null(const HParseResult *p) { const HParsedToken *act_txt(const HParseResult *p) { dns_rr_txt_t *txt = H_ALLOC(dns_rr_txt_t); - const HCountedArray *arr = h_cast_seq(p->ast); + const HCountedArray *arr = H_CAST_SEQ(p->ast); uint8_t **ret = h_arena_malloc(arr->arena, sizeof(uint8_t*)*arr->used); for (size_t i=0; i<arr->used; ++i) { size_t len = h_seq_len(arr->elements[i]); @@ -50,10 +50,10 @@ const HParsedToken *act_txt(const HParseResult *p) { const HParsedToken* act_cstr(const HParseResult *p) { dns_cstr_t *cs = H_ALLOC(dns_cstr_t); - const HCountedArray *arr = h_cast_seq(p->ast); + const HCountedArray *arr = H_CAST_SEQ(p->ast); uint8_t *ret = h_arena_malloc(arr->arena, sizeof(uint8_t)*arr->used); for (size_t i=0; i<arr->used; ++i) - ret[i] = h_cast_uint(arr->elements[i]); + ret[i] = H_CAST_UINT(arr->elements[i]); assert(ret[arr->used-1] == '\0'); // XXX Is this right?! If so, shouldn't it be a validation? *cs = ret;