From 03d586aafe8bb64fa623be0852d644cfa26ef4a8 Mon Sep 17 00:00:00 2001 From: Dylan Thacker-Smith Date: Fri, 28 Feb 2014 10:08:21 -0500 Subject: [PATCH] Add convenience methods for getting a struct from a ruby object. If we are trying to get the struct from something other than self, then we should make sure to check the class of the object. This util functions make this easier. --- ext/liquid/block.c | 10 +--------- ext/liquid/block.h | 2 ++ ext/liquid/liquid_ext.h | 4 ++++ ext/liquid/tokenizer.c | 1 - ext/liquid/tokenizer.h | 4 ++++ ext/liquid/utils.c | 21 +++++++++++++++++++++ ext/liquid/utils.h | 8 ++++++++ 7 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 ext/liquid/utils.c create mode 100644 ext/liquid/utils.h diff --git a/ext/liquid/block.c b/ext/liquid/block.c index 18927a3..2ffeddd 100644 --- a/ext/liquid/block.c +++ b/ext/liquid/block.c @@ -1,6 +1,5 @@ #include "liquid_ext.h" -extern VALUE mLiquid, cLiquidTokenizer, cLiquidTag, cLiquidTemplate, cLiquidVariable; VALUE cLiquidBlock; ID intern_assert_missing_delimitation, intern_block_delimiter, intern_is_blank, intern_new, intern_new_with_options, intern_tags, intern_unknown_tag, intern_unterminated_tag, @@ -46,14 +45,7 @@ static bool parse_tag(struct liquid_tag *tag, char *token, long token_length) static VALUE rb_parse_body(VALUE self, VALUE tokenizerObj) { - Check_Type(tokenizerObj, T_DATA); - if (RBASIC_CLASS(tokenizerObj) != cLiquidTokenizer) { - rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", - rb_obj_classname(tokenizerObj), - rb_class2name(cLiquidTokenizer)); - } - struct liquid_tokenizer *tokenizer; - Data_Get_Struct(tokenizerObj, struct liquid_tokenizer, tokenizer); + struct liquid_tokenizer *tokenizer = LIQUID_TOKENIZER_GET_STRUCT(tokenizerObj); bool blank = true; VALUE nodelist = rb_iv_get(self, "@nodelist"); diff --git a/ext/liquid/block.h b/ext/liquid/block.h index ab4273c..ddb8a08 100644 --- a/ext/liquid/block.h +++ b/ext/liquid/block.h @@ -3,4 +3,6 @@ void init_liquid_block(); +extern VALUE cLiquidBlock; + #endif diff --git a/ext/liquid/liquid_ext.h b/ext/liquid/liquid_ext.h index 796ae99..3eba3ae 100644 --- a/ext/liquid/liquid_ext.h +++ b/ext/liquid/liquid_ext.h @@ -7,5 +7,9 @@ #include "tokenizer.h" #include "block.h" +#include "utils.h" + +extern VALUE mLiquid; +extern VALUE cLiquidTemplate, cLiquidTag, cLiquidVariable; #endif diff --git a/ext/liquid/tokenizer.c b/ext/liquid/tokenizer.c index 26e2368..a70efa3 100644 --- a/ext/liquid/tokenizer.c +++ b/ext/liquid/tokenizer.c @@ -1,7 +1,6 @@ #include "liquid_ext.h" VALUE cLiquidTokenizer; -extern VALUE mLiquid; static void free_tokenizer(void *ptr) { diff --git a/ext/liquid/tokenizer.h b/ext/liquid/tokenizer.h index 83b7351..530c5e4 100644 --- a/ext/liquid/tokenizer.h +++ b/ext/liquid/tokenizer.h @@ -1,6 +1,8 @@ #ifndef LIQUID_TOKENIZER_H #define LIQUID_TOKENIZER_H +extern VALUE cLiquidTokenizer; + enum token_type { TOKEN_NONE, TOKEN_INVALID, @@ -23,4 +25,6 @@ struct liquid_tokenizer { void init_liquid_tokenizer(); void liquid_tokenizer_next(struct liquid_tokenizer *tokenizer, struct token *token); +#define LIQUID_TOKENIZER_GET_STRUCT(obj) ((struct liquid_tokenizer *)obj_get_data_ptr(obj, cLiquidTokenizer)) + #endif diff --git a/ext/liquid/utils.c b/ext/liquid/utils.c new file mode 100644 index 0000000..c68cbfa --- /dev/null +++ b/ext/liquid/utils.c @@ -0,0 +1,21 @@ +#include + +void raise_type_error(VALUE expected, VALUE got) +{ + rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)", + rb_class2name(got), rb_class2name(expected)); +} + +void check_class(VALUE obj, int type, VALUE klass) +{ + Check_Type(obj, type); + VALUE obj_klass = RBASIC_CLASS(obj); + if (obj_klass != klass) + raise_type_error(klass, obj_klass); +} + +void *obj_get_data_ptr(VALUE obj, VALUE klass) +{ + check_class(obj, T_DATA, klass); + return DATA_PTR(obj); +} diff --git a/ext/liquid/utils.h b/ext/liquid/utils.h new file mode 100644 index 0000000..675a1e3 --- /dev/null +++ b/ext/liquid/utils.h @@ -0,0 +1,8 @@ +#ifndef LIQUID_UTILS_H +#define LIQUID_UTILS_H + +void raise_type_error(VALUE expected, VALUE got); +void check_class(VALUE klass); +void *obj_get_data_ptr(VALUE obj, VALUE klass); + +#endif