Mercurial > vim
diff src/if_ruby.c @ 2077:d8983769c9dd v7.2.361
updated for version 7.2.361
Problem: Ruby 1.9 is not supported.
Solution: Add Ruby 1.9 support. (Msaki Suketa)
author | Bram Moolenaar <bram@zimbu.org> |
---|---|
date | Wed, 17 Feb 2010 16:23:09 +0100 |
parents | 1c7a66d820e4 |
children | 4bac7ed34007 |
line wrap: on
line diff
--- a/src/if_ruby.c +++ b/src/if_ruby.c @@ -54,6 +54,9 @@ #endif #include <ruby.h> +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 +# include <ruby/encoding.h> +#endif #undef EXTERN #undef _ @@ -65,6 +68,28 @@ # define __OPENTRANSPORTPROVIDERS__ #endif +/* + * Backward compatiblity for Ruby 1.8 and earlier. + * Ruby 1.9 does not provide STR2CSTR, instead StringValuePtr is provided. + * Ruby 1.9 does not provide RXXX(s)->len and RXXX(s)->ptr, instead + * RXXX_LEN(s) and RXXX_PTR(s) are provided. + */ +#ifndef StringValuePtr +# define StringValuePtr(s) STR2CSTR(s) +#endif +#ifndef RARRAY_LEN +# define RARRAY_LEN(s) RARRAY(s)->len +#endif +#ifndef RARRAY_PTR +# define RARRAY_PTR(s) RARRAY(s)->ptr +#endif +#ifndef RSTRING_LEN +# define RSTRING_LEN(s) RSTRING(s)->len +#endif +#ifndef RSTRING_PTR +# define RSTRING_PTR(s) RSTRING(s)->ptr +#endif + #include "vim.h" #include "version.h" @@ -134,7 +159,11 @@ static void ruby_vim_init(void); #define rb_str_concat dll_rb_str_concat #define rb_str_new dll_rb_str_new #define rb_str_new2 dll_rb_str_new2 -#define ruby_errinfo (*dll_ruby_errinfo) +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 +# define rb_errinfo dll_rb_errinfo +#else +# define ruby_errinfo (*dll_ruby_errinfo) +#endif #define ruby_init dll_ruby_init #define ruby_init_loadpath dll_ruby_init_loadpath #define NtInitialize dll_NtInitialize @@ -142,6 +171,14 @@ static void ruby_vim_init(void); # define rb_w32_snprintf dll_rb_w32_snprintf #endif +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 +# define ruby_script dll_ruby_script +# define rb_enc_find_index dll_rb_enc_find_index +# define rb_enc_find dll_rb_enc_find +# define rb_enc_str_new dll_rb_enc_str_new +# define rb_sprintf dll_rb_sprintf +#endif + /* * Pointers for dynamic link */ @@ -189,7 +226,11 @@ static VALUE (*dll_rb_str_cat) (VALUE, c static VALUE (*dll_rb_str_concat) (VALUE, VALUE); static VALUE (*dll_rb_str_new) (const char*, long); static VALUE (*dll_rb_str_new2) (const char*); +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 +static VALUE (*dll_rb_errinfo) (void); +#else static VALUE *dll_ruby_errinfo; +#endif static void (*dll_ruby_init) (void); static void (*dll_ruby_init_loadpath) (void); static void (*dll_NtInitialize) (int*, char***); @@ -197,6 +238,14 @@ static void (*dll_NtInitialize) (int*, c static int (*dll_rb_w32_snprintf)(char*, size_t, const char*, ...); #endif +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 +static void (*dll_ruby_script) (const char*); +static int (*dll_rb_enc_find_index) (const char*); +static rb_encoding* (*dll_rb_enc_find) (const char*); +static VALUE (*dll_rb_enc_str_new) (const char*, long, rb_encoding*); +static VALUE (*dll_rb_sprintf) (const char*, ...); +#endif + static HINSTANCE hinstRuby = 0; /* Instance of ruby.dll */ /* @@ -252,13 +301,24 @@ static struct {"rb_str_concat", (RUBY_PROC*)&dll_rb_str_concat}, {"rb_str_new", (RUBY_PROC*)&dll_rb_str_new}, {"rb_str_new2", (RUBY_PROC*)&dll_rb_str_new2}, +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 + {"rb_errinfo", (RUBY_PROC*)&dll_rb_errinfo}, +#else {"ruby_errinfo", (RUBY_PROC*)&dll_ruby_errinfo}, +#endif {"ruby_init", (RUBY_PROC*)&dll_ruby_init}, {"ruby_init_loadpath", (RUBY_PROC*)&dll_ruby_init_loadpath}, {"NtInitialize", (RUBY_PROC*)&dll_NtInitialize}, #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18 {"rb_w32_snprintf", (RUBY_PROC*)&dll_rb_w32_snprintf}, #endif +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 + {"ruby_script", (RUBY_PROC*)&dll_ruby_script}, + {"rb_enc_find_index", (RUBY_PROC*)&dll_rb_enc_find_index}, + {"rb_enc_find", (RUBY_PROC*)&dll_rb_enc_find}, + {"rb_enc_str_new", (RUBY_PROC*)&dll_rb_enc_str_new}, + {"rb_sprintf", (RUBY_PROC*)&dll_rb_sprintf}, +#endif {"", NULL}, }; @@ -348,6 +408,58 @@ void ex_ruby(exarg_T *eap) vim_free(script); } +/* + * In Ruby 1.9 or later, ruby String object has encoding. + * conversion buffer string of vim to ruby String object using + * VIM encoding option. + */ + static VALUE +vim_str2rb_enc_str(const char *s) +{ +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 + int isnum; + long lval; + char_u *sval; + rb_encoding *enc; + + isnum = get_option_value((char_u *)"enc", &lval, &sval, 0); + if (isnum == 0) + { + enc = rb_enc_find((char *)sval); + vim_free(sval); + if (enc) { + return rb_enc_str_new(s, strlen(s), enc); + } + } +#endif + return rb_str_new2(s); +} + + static VALUE +eval_enc_string_protect(const char *str, int *state) +{ +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 + int isnum; + long lval; + char_u *sval; + rb_encoding *enc; + VALUE v; + + isnum = get_option_value((char_u *)"enc", &lval, &sval, 0); + if (isnum == 0) + { + enc = rb_enc_find((char *)sval); + vim_free(sval); + if (enc) + { + v = rb_sprintf("#-*- coding:%s -*-\n%s", rb_enc_name(enc), str); + return rb_eval_string_protect(StringValuePtr(v), state); + } + } +#endif + return rb_eval_string_protect(str, state); +} + void ex_rubydo(exarg_T *eap) { int state; @@ -360,9 +472,9 @@ void ex_rubydo(exarg_T *eap) for (i = eap->line1; i <= eap->line2; i++) { VALUE line, oldline; - line = oldline = rb_str_new2((char *)ml_get(i)); + line = oldline = vim_str2rb_enc_str((char *)ml_get(i)); rb_lastline_set(line); - rb_eval_string_protect((char *) eap->arg, &state); + eval_enc_string_protect((char *) eap->arg, &state); if (state) { error_print(state); break; @@ -373,7 +485,7 @@ void ex_rubydo(exarg_T *eap) EMSG(_("E265: $_ must be an instance of String")); return; } - ml_replace(i, (char_u *) STR2CSTR(line), 1); + ml_replace(i, (char_u *) StringValuePtr(line), 1); changed(); #ifdef SYNTAX_HL syn_changed(i); /* recompute syntax hl. for this line */ @@ -428,9 +540,18 @@ static int ensure_ruby_initialized(void) char *argv[] = {"gvim.exe"}; NtInitialize(&argc, &argv); #endif +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 + RUBY_INIT_STACK; +#endif ruby_init(); +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 + ruby_script("vim-ruby"); +#endif ruby_init_loadpath(); ruby_io_init(); +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 + rb_enc_find_index("encdb"); +#endif ruby_vim_init(); ruby_initialized = 1; #ifdef DYNAMIC_RUBY @@ -448,8 +569,10 @@ static int ensure_ruby_initialized(void) static void error_print(int state) { #ifndef DYNAMIC_RUBY +#if !(defined(RUBY_VERSION) && RUBY_VERSION >= 19) RUBYEXTERN VALUE ruby_errinfo; #endif +#endif VALUE eclass; VALUE einfo; char buff[BUFSIZ]; @@ -482,9 +605,14 @@ static void error_print(int state) break; case TAG_RAISE: case TAG_FATAL: +#if defined(RUBY_VERSION) && RUBY_VERSION >= 19 + eclass = CLASS_OF(rb_errinfo()); + einfo = rb_obj_as_string(rb_errinfo()); +#else eclass = CLASS_OF(ruby_errinfo); einfo = rb_obj_as_string(ruby_errinfo); - if (eclass == rb_eRuntimeError && RSTRING(einfo)->len == 0) { +#endif + if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) { EMSG(_("E272: unhandled exception")); } else { @@ -493,7 +621,7 @@ static void error_print(int state) epath = rb_class_path(eclass); vim_snprintf(buff, BUFSIZ, "%s: %s", - RSTRING(epath)->ptr, RSTRING(einfo)->ptr); + RSTRING_PTR(epath), RSTRING_PTR(einfo)); p = strchr(buff, '\n'); if (p) *p = '\0'; EMSG(buff); @@ -511,8 +639,8 @@ static VALUE vim_message(VALUE self UNUS char *buff, *p; str = rb_obj_as_string(str); - buff = ALLOCA_N(char, RSTRING(str)->len); - strcpy(buff, RSTRING(str)->ptr); + buff = ALLOCA_N(char, RSTRING_LEN(str)); + strcpy(buff, RSTRING_PTR(str)); p = strchr(buff, '\n'); if (p) *p = '\0'; MSG(buff); @@ -521,21 +649,21 @@ static VALUE vim_message(VALUE self UNUS static VALUE vim_set_option(VALUE self UNUSED, VALUE str) { - do_set((char_u *)STR2CSTR(str), 0); + do_set((char_u *)StringValuePtr(str), 0); update_screen(NOT_VALID); return Qnil; } static VALUE vim_command(VALUE self UNUSED, VALUE str) { - do_cmdline_cmd((char_u *)STR2CSTR(str)); + do_cmdline_cmd((char_u *)StringValuePtr(str)); return Qnil; } static VALUE vim_evaluate(VALUE self UNUSED, VALUE str) { #ifdef FEAT_EVAL - char_u *value = eval_to_string((char_u *)STR2CSTR(str), NULL, TRUE); + char_u *value = eval_to_string((char_u *)StringValuePtr(str), NULL, TRUE); if (value != NULL) { @@ -640,9 +768,9 @@ static VALUE get_buffer_line(buf_T *buf, if (n > 0 && n <= buf->b_ml.ml_line_count) { char *line = (char *)ml_get_buf(buf, n, FALSE); - return line ? rb_str_new2(line) : Qnil; + return line ? vim_str2rb_enc_str(line) : Qnil; } - rb_raise(rb_eIndexError, "index %d out of buffer", n); + rb_raise(rb_eIndexError, "line number %ld out of range", (long)n); #ifndef __GNUC__ return Qnil; /* For stop warning */ #endif @@ -659,7 +787,7 @@ static VALUE buffer_aref(VALUE self, VAL static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str) { - char *line = STR2CSTR(str); + char *line = StringValuePtr(str); aco_save_T aco; if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL) @@ -683,7 +811,7 @@ static VALUE set_buffer_line(buf_T *buf, } else { - rb_raise(rb_eIndexError, "index %d out of buffer", n); + rb_raise(rb_eIndexError, "line number %ld out of range", (long)n); #ifndef __GNUC__ return Qnil; /* For stop warning */ #endif @@ -729,7 +857,7 @@ static VALUE buffer_delete(VALUE self, V } else { - rb_raise(rb_eIndexError, "index %d out of buffer", n); + rb_raise(rb_eIndexError, "line number %ld out of range", n); } return Qnil; } @@ -737,11 +865,14 @@ static VALUE buffer_delete(VALUE self, V static VALUE buffer_append(VALUE self, VALUE num, VALUE str) { buf_T *buf = get_buf(self); - char *line = STR2CSTR(str); + char *line = StringValuePtr(str); long n = NUM2LONG(num); aco_save_T aco; - if (n >= 0 && n <= buf->b_ml.ml_line_count && line != NULL) + if (line != NULL) { + rb_raise(rb_eIndexError, "NULL line"); + } + else if (n >= 0 && n <= buf->b_ml.ml_line_count) { /* set curwin/curbuf for "buf" and save some things */ aucmd_prepbuf(&aco, buf); @@ -763,7 +894,7 @@ static VALUE buffer_append(VALUE self, V update_curbuf(NOT_VALID); } else { - rb_raise(rb_eIndexError, "index %d out of buffer", n); + rb_raise(rb_eIndexError, "line number %ld out of range", n); } return str; } @@ -904,10 +1035,10 @@ static VALUE window_set_cursor(VALUE sel win_T *win = get_win(self); Check_Type(pos, T_ARRAY); - if (RARRAY(pos)->len != 2) + if (RARRAY_LEN(pos) != 2) rb_raise(rb_eArgError, "array length must be 2"); - lnum = RARRAY(pos)->ptr[0]; - col = RARRAY(pos)->ptr[1]; + lnum = RARRAY_PTR(pos)[0]; + col = RARRAY_PTR(pos)[1]; win->w_cursor.lnum = NUM2LONG(lnum); win->w_cursor.col = NUM2UINT(col); check_cursor(); /* put cursor on an existing line */ @@ -924,7 +1055,7 @@ static VALUE f_p(int argc, VALUE *argv, if (i > 0) rb_str_cat(str, ", ", 2); rb_str_concat(str, rb_inspect(argv[i])); } - MSG(RSTRING(str)->ptr); + MSG(RSTRING_PTR(str)); return Qnil; }