summaryrefslogtreecommitdiff
path: root/ext/ripper/ripper_init.c.tmpl
diff options
context:
space:
mode:
Diffstat (limited to 'ext/ripper/ripper_init.c.tmpl')
-rw-r--r--ext/ripper/ripper_init.c.tmpl78
1 files changed, 61 insertions, 17 deletions
diff --git a/ext/ripper/ripper_init.c.tmpl b/ext/ripper/ripper_init.c.tmpl
index c9d381da5b..fc98c067b8 100644
--- a/ext/ripper/ripper_init.c.tmpl
+++ b/ext/ripper/ripper_init.c.tmpl
@@ -17,15 +17,40 @@
ID id_warn, id_warning, id_gets, id_assoc;
+enum lex_type {
+ lex_type_str,
+ lex_type_io,
+ lex_type_generic,
+};
+
struct ripper {
rb_parser_t *p;
+ enum lex_type type;
+ union {
+ struct lex_pointer_string ptr_str;
+ VALUE val;
+ } data;
};
static void
ripper_parser_mark2(void *ptr)
{
struct ripper *r = (struct ripper*)ptr;
- if (r->p) ripper_parser_mark(r->p);
+ if (r->p) {
+ ripper_parser_mark(r->p);
+
+ switch (r->type) {
+ case lex_type_str:
+ rb_gc_mark(r->data.ptr_str.str);
+ break;
+ case lex_type_io:
+ rb_gc_mark(r->data.val);
+ break;
+ case lex_type_generic:
+ rb_gc_mark(r->data.val);
+ break;
+ }
+ }
}
static void
@@ -53,16 +78,18 @@ static const rb_data_type_t parser_data_type = {
0, 0, RUBY_TYPED_FREE_IMMEDIATELY
};
-static VALUE
-ripper_lex_get_generic(struct parser_params *p, VALUE src)
+static rb_parser_string_t *
+ripper_lex_get_generic(struct parser_params *p, rb_parser_input_data input, int line_count)
{
+ VALUE src = (VALUE)input;
VALUE line = rb_funcallv_public(src, id_gets, 0, 0);
- if (!NIL_P(line) && !RB_TYPE_P(line, T_STRING)) {
+ if (NIL_P(line)) return 0;
+ if (!RB_TYPE_P(line, T_STRING)) {
rb_raise(rb_eTypeError,
"gets returned %"PRIsVALUE" (expected String or nil)",
rb_obj_class(line));
}
- return line;
+ return rb_str_to_parser_string(p, line);
}
void
@@ -78,10 +105,19 @@ ripper_compile_error(struct parser_params *p, const char *fmt, ...)
ripper_error(p);
}
-static VALUE
-ripper_lex_io_get(struct parser_params *p, VALUE src)
+static rb_parser_string_t *
+ripper_lex_io_get(struct parser_params *p, rb_parser_input_data input, int line_count)
{
- return rb_io_gets(src);
+ VALUE src = (VALUE)input;
+ VALUE line = rb_io_gets(src);
+ if (NIL_P(line)) return 0;
+ return rb_str_to_parser_string(p, line);
+}
+
+static rb_parser_string_t *
+ripper_lex_get_str(struct parser_params *p, rb_parser_input_data input, int line_count)
+{
+ return rb_parser_lex_get_str(p, (struct lex_pointer_string *)input);
}
static VALUE
@@ -155,7 +191,7 @@ ripper_parser_encoding(VALUE vparser)
{
struct parser_params *p = ripper_parser_params(vparser, false);
- return rb_ruby_parser_encoding(p);
+ return rb_enc_from_encoding(rb_ruby_parser_encoding(p));
}
/*
@@ -294,26 +330,38 @@ parser_dedent_string(VALUE self, VALUE input, VALUE width)
static VALUE
ripper_initialize(int argc, VALUE *argv, VALUE self)
{
+ struct ripper *r;
struct parser_params *p;
VALUE src, fname, lineno;
- VALUE (*gets)(struct parser_params*,VALUE);
- VALUE input, sourcefile_string;
+ rb_parser_lex_gets_func *gets;
+ VALUE sourcefile_string;
const char *sourcefile;
int sourceline;
+ rb_parser_input_data input;
p = ripper_parser_params(self, false);
+ TypedData_Get_Struct(self, struct ripper, &parser_data_type, r);
rb_scan_args(argc, argv, "12", &src, &fname, &lineno);
if (RB_TYPE_P(src, T_FILE)) {
gets = ripper_lex_io_get;
+ r->type = lex_type_io;
+ r->data.val = src;
+ input = (rb_parser_input_data)src;
}
else if (rb_respond_to(src, id_gets)) {
gets = ripper_lex_get_generic;
+ r->type = lex_type_generic;
+ r->data.val = src;
+ input = (rb_parser_input_data)src;
}
else {
StringValue(src);
- gets = rb_ruby_ripper_lex_get_str;
+ gets = ripper_lex_get_str;
+ r->type = lex_type_str;
+ r->data.ptr_str.str = src;
+ r->data.ptr_str.ptr = 0;
+ input = (rb_parser_input_data)&r->data.ptr_str;
}
- input = src;
if (NIL_P(fname)) {
fname = STR_NEW2("(ripper)");
OBJ_FREEZE(fname);
@@ -617,8 +665,4 @@ InitVM_ripper(void)
*/
rb_define_global_const("SCRIPT_LINES__", Qnil);
#endif
- rb_ripper_none = rb_obj_alloc(rb_cObject);
- rb_obj_freeze(rb_ripper_none);
- rb_gc_register_mark_object(rb_ripper_none);
-
}