From 8a93a7ff556b9c5d1b4621d5d5f7dc570a4cdaac 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 18927a36..2ffeddd7 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 ab4273c6..ddb8a088 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 796ae99a..3eba3aec 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 26e23689..a70efa37 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 83b73516..530c5e40 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 00000000..c68cbfae --- /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 00000000..675a1e3e --- /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