1 /* vi:set ts=8 sts=4 sw=4 noet: 2 * 3 * VIM - Vi IMproved by Bram Moolenaar 4 * 5 * Ruby interface by Shugo Maeda 6 * with improvements by SegPhault (Ryan Paul) 7 * with improvements by Jon Maken 8 * 9 * Do ":help uganda" in Vim to read copying and usage conditions. 10 * Do ":help credits" in Vim to see a list of people who contributed. 11 * See README.txt for an overview of the Vim source code. 12 */ 13 14 #include "protodef.h" 15 #ifdef HAVE_CONFIG_H 16 # include "auto/config.h" 17 #endif 18 19 #include <stdio.h> 20 #include <string.h> 21 22 #ifdef _WIN32 23 # if !defined(DYNAMIC_RUBY) || (RUBY_VERSION < 18) 24 # define NT 25 # endif 26 # ifndef DYNAMIC_RUBY 27 # define IMPORT // For static dll usage __declspec(dllimport) 28 # define RUBYEXTERN __declspec(dllimport) 29 # endif 30 #endif 31 #ifndef RUBYEXTERN 32 # define RUBYEXTERN extern 33 #endif 34 35 // suggested by Ariya Mizutani 36 #if (_MSC_VER == 1200) 37 # undef _WIN32_WINNT 38 #endif 39 40 #ifdef DYNAMIC_RUBY 41 /* 42 * This is tricky. In ruby.h there is (inline) function rb_class_of() 43 * definition. This function use these variables. But we want function to 44 * use dll_* variables. 45 */ 46 # if RUBY_VERSION >= 24 47 # define USE_RUBY_INTEGER 48 # endif 49 50 # define rb_cFalseClass (*dll_rb_cFalseClass) 51 # define rb_cFixnum (*dll_rb_cFixnum) 52 # if defined(USE_RUBY_INTEGER) 53 # define rb_cInteger (*dll_rb_cInteger) 54 # endif 55 # if RUBY_VERSION >= 20 56 # define rb_cFloat (*dll_rb_cFloat) 57 # endif 58 # define rb_cNilClass (*dll_rb_cNilClass) 59 # define rb_cString (*dll_rb_cString) 60 # define rb_cSymbol (*dll_rb_cSymbol) 61 # define rb_cTrueClass (*dll_rb_cTrueClass) 62 63 # if RUBY_VERSION >= 18 64 /* 65 * On ver 1.8, all Ruby functions are exported with "__declspec(dllimport)" 66 * in ruby.h. But it causes trouble for these variables, because it is 67 * defined in this file. When defined this RUBY_EXPORT it modified to 68 * "extern" and be able to avoid this problem. 69 */ 70 # define RUBY_EXPORT 71 # endif 72 73 # if RUBY_VERSION >= 19 74 // Ruby 1.9 defines a number of static functions which use rb_num2long and 75 // rb_int2big 76 # define rb_num2long rb_num2long_stub 77 # define rb_int2big rb_int2big_stub 78 79 # if RUBY_VERSION >= 30 || VIM_SIZEOF_INT < VIM_SIZEOF_LONG 80 // Ruby 1.9 defines a number of static functions which use rb_fix2int and 81 // rb_num2int if VIM_SIZEOF_INT < VIM_SIZEOF_LONG (64bit) 82 # define rb_fix2int rb_fix2int_stub 83 # define rb_num2int rb_num2int_stub 84 # endif 85 # endif 86 87 # if RUBY_VERSION == 21 88 // Ruby 2.1 adds new GC called RGenGC and RARRAY_PTR uses 89 // rb_gc_writebarrier_unprotect_promoted if USE_RGENGC 90 # define rb_gc_writebarrier_unprotect_promoted rb_gc_writebarrier_unprotect_promoted_stub 91 # endif 92 93 # if RUBY_VERSION >= 22 94 # define rb_gc_writebarrier_unprotect rb_gc_writebarrier_unprotect_stub 95 # endif 96 97 # if RUBY_VERSION >= 26 98 # define rb_ary_detransient rb_ary_detransient_stub 99 # endif 100 101 # if RUBY_VERSION >= 30 102 # define rb_check_type rb_check_type_stub 103 # define rb_num2uint rb_num2uint_stub 104 # define ruby_malloc_size_overflow ruby_malloc_size_overflow_stub 105 # endif 106 107 #endif // ifdef DYNAMIC_RUBY 108 109 // On macOS pre-installed Ruby defines "SIZEOF_TIME_T" as "SIZEOF_LONG" so it 110 // conflicts with the definition in config.h then causes a macro-redefined 111 // warning. 112 #ifdef SIZEOF_TIME_T 113 # undef SIZEOF_TIME_T 114 #endif 115 116 #include <ruby.h> 117 #if RUBY_VERSION >= 19 118 # include <ruby/encoding.h> 119 #endif 120 #if RUBY_VERSION <= 18 121 # include <st.h> // for ST_STOP and ST_CONTINUE 122 #endif 123 124 // See above. 125 #ifdef SIZEOF_TIME_T 126 # undef SIZEOF_TIME_T 127 #endif 128 129 #undef off_t // ruby defines off_t as _int64, Mingw uses long 130 #undef EXTERN 131 #undef _ 132 133 // T_DATA defined both by Ruby and Mac header files, hack around it... 134 #if defined(MACOS_X) 135 # define __OPENTRANSPORT__ 136 # define __OPENTRANSPORTPROTOCOL__ 137 # define __OPENTRANSPORTPROVIDERS__ 138 #endif 139 140 /* 141 * The TypedData_XXX macro family can be used since Ruby 1.9.2 but 142 * rb_data_type_t changed in 1.9.3, therefore require at least 2.0. 143 * The old Data_XXX macro family was deprecated on Ruby 2.2. 144 * Use TypedData_XXX if available. 145 */ 146 #if defined(TypedData_Wrap_Struct) && (RUBY_VERSION >= 20) 147 # define USE_TYPEDDATA 1 148 #endif 149 150 /* 151 * Backward compatibility for Ruby 1.8 and earlier. 152 * Ruby 1.9 does not provide STR2CSTR, instead StringValuePtr is provided. 153 * Ruby 1.9 does not provide RXXX(s)->len and RXXX(s)->ptr, instead 154 * RXXX_LEN(s) and RXXX_PTR(s) are provided. 155 */ 156 #ifndef StringValuePtr 157 # define StringValuePtr(s) STR2CSTR(s) 158 #endif 159 #ifndef RARRAY_LEN 160 # define RARRAY_LEN(s) RARRAY(s)->len 161 #endif 162 #ifndef RARRAY_PTR 163 # define RARRAY_PTR(s) RARRAY(s)->ptr 164 #endif 165 #ifndef RSTRING_LEN 166 # define RSTRING_LEN(s) RSTRING(s)->len 167 #endif 168 #ifndef RSTRING_PTR 169 # define RSTRING_PTR(s) RSTRING(s)->ptr 170 #endif 171 172 #ifdef HAVE_DUP 173 # undef HAVE_DUP 174 #endif 175 176 #include "vim.h" 177 #include "version.h" 178 179 #ifdef DYNAMIC_RUBY 180 # if !defined(MSWIN) // must come after including vim.h, where it is defined 181 # include <dlfcn.h> 182 # define HINSTANCE void* 183 # define RUBY_PROC void* 184 # define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL) 185 # define symbol_from_dll dlsym 186 # define close_dll dlclose 187 # define load_dll_error dlerror 188 # else 189 # define RUBY_PROC FARPROC 190 # define load_dll vimLoadLib 191 # define symbol_from_dll GetProcAddress 192 # define close_dll FreeLibrary 193 # define load_dll_error GetWin32Error 194 # endif 195 #endif 196 197 #if defined(PROTO) && !defined(FEAT_RUBY) 198 // Define these to be able to generate the function prototypes. 199 # define VALUE int 200 # define RUBY_DATA_FUNC int 201 #endif 202 203 static int ruby_initialized = 0; 204 static void *ruby_stack_start; 205 static VALUE objtbl; 206 207 static VALUE mVIM; 208 static VALUE cBuffer; 209 static VALUE cVimWindow; 210 static VALUE eDeletedBufferError; 211 static VALUE eDeletedWindowError; 212 213 static int ensure_ruby_initialized(void); 214 static void error_print(int); 215 static void ruby_io_init(void); 216 static void ruby_vim_init(void); 217 static int ruby_convert_to_vim_value(VALUE val, typval_T *rettv); 218 219 #if (RUBY_VERSION >= 19) || defined(RUBY_INIT_STACK) 220 # if defined(__ia64) && !defined(ruby_init_stack) 221 # define ruby_init_stack(addr) ruby_init_stack((addr), rb_ia64_bsp()) 222 # endif 223 #endif 224 225 #if defined(DYNAMIC_RUBY) || defined(PROTO) 226 # if defined(PROTO) && !defined(HINSTANCE) 227 # define HINSTANCE int // for generating prototypes 228 # endif 229 230 /* 231 * Wrapper defines 232 */ 233 // Ruby 2.7 actually expands the following symbols as macro. 234 # if RUBY_VERSION >= 27 235 # undef rb_define_global_function 236 # undef rb_define_method 237 # undef rb_define_module_function 238 # undef rb_define_singleton_method 239 # endif 240 241 # define rb_assoc_new dll_rb_assoc_new 242 # define rb_cObject (*dll_rb_cObject) 243 # define rb_class_new_instance dll_rb_class_new_instance 244 # if RUBY_VERSION < 30 245 # define rb_check_type dll_rb_check_type 246 # endif 247 # ifdef USE_TYPEDDATA 248 # define rb_check_typeddata dll_rb_check_typeddata 249 # endif 250 # define rb_class_path dll_rb_class_path 251 # ifdef USE_TYPEDDATA 252 # if RUBY_VERSION >= 23 253 # define rb_data_typed_object_wrap dll_rb_data_typed_object_wrap 254 # else 255 # define rb_data_typed_object_alloc dll_rb_data_typed_object_alloc 256 # endif 257 # else 258 # define rb_data_object_alloc dll_rb_data_object_alloc 259 # endif 260 # define rb_define_class_under dll_rb_define_class_under 261 # define rb_define_const dll_rb_define_const 262 # define rb_define_global_function dll_rb_define_global_function 263 # define rb_define_method dll_rb_define_method 264 # define rb_define_module dll_rb_define_module 265 # define rb_define_module_function dll_rb_define_module_function 266 # define rb_define_singleton_method dll_rb_define_singleton_method 267 # define rb_define_virtual_variable dll_rb_define_virtual_variable 268 # define rb_stdout (*dll_rb_stdout) 269 # define rb_stderr (*dll_rb_stderr) 270 # define rb_eArgError (*dll_rb_eArgError) 271 # define rb_eIndexError (*dll_rb_eIndexError) 272 # define rb_eRuntimeError (*dll_rb_eRuntimeError) 273 # define rb_eStandardError (*dll_rb_eStandardError) 274 # define rb_eval_string_protect dll_rb_eval_string_protect 275 # if RUBY_VERSION >= 21 276 # define rb_funcallv dll_rb_funcallv 277 # else 278 # define rb_funcall2 dll_rb_funcall2 279 # endif 280 # define rb_global_variable dll_rb_global_variable 281 # define rb_hash_aset dll_rb_hash_aset 282 # define rb_hash_foreach dll_rb_hash_foreach 283 # define rb_hash_new dll_rb_hash_new 284 # define rb_inspect dll_rb_inspect 285 # define rb_int2inum dll_rb_int2inum 286 287 // ruby.h may redefine rb_intern to use RUBY_CONST_ID_CACHE(), but that won't 288 // work. Not using the cache appears to be the best solution. 289 # undef rb_intern 290 # define rb_intern dll_rb_intern 291 292 # if VIM_SIZEOF_INT < VIM_SIZEOF_LONG // 64 bits only 293 # if RUBY_VERSION <= 18 294 # define rb_fix2int dll_rb_fix2int 295 # define rb_num2int dll_rb_num2int 296 # endif 297 # if RUBY_VERSION < 30 298 # define rb_num2uint dll_rb_num2uint 299 # endif 300 # endif 301 # define rb_num2dbl dll_rb_num2dbl 302 # define rb_lastline_get dll_rb_lastline_get 303 # define rb_lastline_set dll_rb_lastline_set 304 # define rb_protect dll_rb_protect 305 # define rb_load dll_rb_load 306 # if RUBY_VERSION <= 18 307 # define rb_num2long dll_rb_num2long 308 # endif 309 # if RUBY_VERSION <= 19 310 # define rb_num2ulong dll_rb_num2ulong 311 # endif 312 # define rb_obj_alloc dll_rb_obj_alloc 313 # define rb_obj_as_string dll_rb_obj_as_string 314 # define rb_obj_id dll_rb_obj_id 315 # define rb_raise dll_rb_raise 316 # define rb_str_cat dll_rb_str_cat 317 # define rb_str_concat dll_rb_str_concat 318 # undef rb_str_new 319 # define rb_str_new dll_rb_str_new 320 # ifdef rb_str_new2 321 // Ruby may #define rb_str_new2 to use rb_str_new_cstr. 322 # define need_rb_str_new_cstr 1 323 // Ruby's headers #define rb_str_new_cstr to make use of GCC's 324 // __builtin_constant_p extension. 325 # undef rb_str_new_cstr 326 # define rb_str_new_cstr dll_rb_str_new_cstr 327 # else 328 # define rb_str_new2 dll_rb_str_new2 329 # endif 330 # if RUBY_VERSION >= 18 331 # define rb_string_value dll_rb_string_value 332 # define rb_string_value_ptr dll_rb_string_value_ptr 333 # define rb_float_new dll_rb_float_new 334 # define rb_ary_new dll_rb_ary_new 335 # ifdef rb_ary_new4 336 # define RB_ARY_NEW4_MACRO 1 337 # undef rb_ary_new4 338 # endif 339 # define rb_ary_new4 dll_rb_ary_new4 340 # define rb_ary_push dll_rb_ary_push 341 # if (RUBY_VERSION >= 19) || defined(RUBY_INIT_STACK) 342 # ifdef __ia64 343 # define rb_ia64_bsp dll_rb_ia64_bsp 344 # undef ruby_init_stack 345 # define ruby_init_stack(addr) dll_ruby_init_stack((addr), rb_ia64_bsp()) 346 # else 347 # define ruby_init_stack dll_ruby_init_stack 348 # endif 349 # endif 350 # else 351 # define rb_str2cstr dll_rb_str2cstr 352 # endif 353 # if RUBY_VERSION >= 19 354 # define rb_errinfo dll_rb_errinfo 355 # else 356 # define ruby_errinfo (*dll_ruby_errinfo) 357 # endif 358 # define ruby_init dll_ruby_init 359 # define ruby_init_loadpath dll_ruby_init_loadpath 360 # ifdef MSWIN 361 # if RUBY_VERSION >= 19 362 # define ruby_sysinit dll_ruby_sysinit 363 # else 364 # define NtInitialize dll_NtInitialize 365 # endif 366 # if RUBY_VERSION >= 18 367 # define rb_w32_snprintf dll_rb_w32_snprintf 368 # endif 369 # endif 370 371 # if RUBY_VERSION >= 19 372 # define ruby_script dll_ruby_script 373 # define rb_enc_find_index dll_rb_enc_find_index 374 # define rb_enc_find dll_rb_enc_find 375 # undef rb_enc_str_new 376 # define rb_enc_str_new dll_rb_enc_str_new 377 # define rb_sprintf dll_rb_sprintf 378 # define rb_require dll_rb_require 379 # define ruby_options dll_ruby_options 380 # endif 381 382 /* 383 * Pointers for dynamic link 384 */ 385 static VALUE (*dll_rb_assoc_new) (VALUE, VALUE); 386 VALUE *dll_rb_cFalseClass; 387 VALUE *dll_rb_cFixnum; 388 # if defined(USE_RUBY_INTEGER) 389 VALUE *dll_rb_cInteger; 390 # endif 391 # if RUBY_VERSION >= 20 392 VALUE *dll_rb_cFloat; 393 # endif 394 VALUE *dll_rb_cNilClass; 395 static VALUE *dll_rb_cObject; 396 VALUE *dll_rb_cString; 397 VALUE *dll_rb_cSymbol; 398 VALUE *dll_rb_cTrueClass; 399 static VALUE (*dll_rb_class_new_instance) (int,VALUE*,VALUE); 400 static void (*dll_rb_check_type) (VALUE,int); 401 # ifdef USE_TYPEDDATA 402 static void *(*dll_rb_check_typeddata) (VALUE,const rb_data_type_t *); 403 # endif 404 static VALUE (*dll_rb_class_path) (VALUE); 405 # ifdef USE_TYPEDDATA 406 # if RUBY_VERSION >= 23 407 static VALUE (*dll_rb_data_typed_object_wrap) (VALUE, void*, const rb_data_type_t *); 408 # else 409 static VALUE (*dll_rb_data_typed_object_alloc) (VALUE, void*, const rb_data_type_t *); 410 # endif 411 # else 412 static VALUE (*dll_rb_data_object_alloc) (VALUE, void*, RUBY_DATA_FUNC, RUBY_DATA_FUNC); 413 # endif 414 static VALUE (*dll_rb_define_class_under) (VALUE, const char*, VALUE); 415 static void (*dll_rb_define_const) (VALUE,const char*,VALUE); 416 static void (*dll_rb_define_global_function) (const char*,VALUE(*)(),int); 417 static void (*dll_rb_define_method) (VALUE,const char*,VALUE(*)(),int); 418 static VALUE (*dll_rb_define_module) (const char*); 419 static void (*dll_rb_define_module_function) (VALUE,const char*,VALUE(*)(),int); 420 static void (*dll_rb_define_singleton_method) (VALUE,const char*,VALUE(*)(),int); 421 static void (*dll_rb_define_virtual_variable) (const char*,VALUE(*)(),void(*)()); 422 static VALUE *dll_rb_stdout; 423 static VALUE *dll_rb_stderr; 424 static VALUE *dll_rb_eArgError; 425 static VALUE *dll_rb_eIndexError; 426 static VALUE *dll_rb_eRuntimeError; 427 static VALUE *dll_rb_eStandardError; 428 static VALUE (*dll_rb_eval_string_protect) (const char*, int*); 429 # if RUBY_VERSION >= 21 430 static VALUE (*dll_rb_funcallv) (VALUE, ID, int, const VALUE*); 431 # else 432 static VALUE (*dll_rb_funcall2) (VALUE, ID, int, const VALUE*); 433 # endif 434 static void (*dll_rb_global_variable) (VALUE*); 435 static VALUE (*dll_rb_hash_aset) (VALUE, VALUE, VALUE); 436 static VALUE (*dll_rb_hash_foreach) (VALUE, int (*)(VALUE, VALUE, VALUE), VALUE); 437 static VALUE (*dll_rb_hash_new) (void); 438 static VALUE (*dll_rb_inspect) (VALUE); 439 static VALUE (*dll_rb_int2inum) (long); 440 static ID (*dll_rb_intern) (const char*); 441 # if RUBY_VERSION >= 30 || VIM_SIZEOF_INT < VIM_SIZEOF_LONG 442 static long (*dll_rb_fix2int) (VALUE); 443 static long (*dll_rb_num2int) (VALUE); 444 static unsigned long (*dll_rb_num2uint) (VALUE); 445 # endif 446 static double (*dll_rb_num2dbl) (VALUE); 447 static VALUE (*dll_rb_lastline_get) (void); 448 static void (*dll_rb_lastline_set) (VALUE); 449 static VALUE (*dll_rb_protect) (VALUE (*)(VALUE), VALUE, int*); 450 static void (*dll_rb_load) (VALUE, int); 451 static long (*dll_rb_num2long) (VALUE); 452 static unsigned long (*dll_rb_num2ulong) (VALUE); 453 static VALUE (*dll_rb_obj_alloc) (VALUE); 454 static VALUE (*dll_rb_obj_as_string) (VALUE); 455 static VALUE (*dll_rb_obj_id) (VALUE); 456 static void (*dll_rb_raise) (VALUE, const char*, ...); 457 # if RUBY_VERSION >= 18 458 static VALUE (*dll_rb_string_value) (volatile VALUE*); 459 # else 460 static char *(*dll_rb_str2cstr) (VALUE,int*); 461 # endif 462 static VALUE (*dll_rb_str_cat) (VALUE, const char*, long); 463 static VALUE (*dll_rb_str_concat) (VALUE, VALUE); 464 static VALUE (*dll_rb_str_new) (const char*, long); 465 # ifdef need_rb_str_new_cstr 466 // Ruby may #define rb_str_new2 to use rb_str_new_cstr. 467 static VALUE (*dll_rb_str_new_cstr) (const char*); 468 # else 469 static VALUE (*dll_rb_str_new2) (const char*); 470 # endif 471 # if RUBY_VERSION >= 19 472 static VALUE (*dll_rb_errinfo) (void); 473 # else 474 static VALUE *dll_ruby_errinfo; 475 # endif 476 static void (*dll_ruby_init) (void); 477 static void (*dll_ruby_init_loadpath) (void); 478 # ifdef MSWIN 479 # if RUBY_VERSION >= 19 480 static void (*dll_ruby_sysinit) (int*, char***); 481 # else 482 static void (*dll_NtInitialize) (int*, char***); 483 # endif 484 # if RUBY_VERSION >= 18 485 static int (*dll_rb_w32_snprintf)(char*, size_t, const char*, ...); 486 # endif 487 # endif 488 # if RUBY_VERSION >= 18 489 static char * (*dll_rb_string_value_ptr) (volatile VALUE*); 490 static VALUE (*dll_rb_float_new) (double); 491 static VALUE (*dll_rb_ary_new) (void); 492 static VALUE (*dll_rb_ary_new4) (long n, const VALUE *elts); 493 static VALUE (*dll_rb_ary_push) (VALUE, VALUE); 494 # if RUBY_VERSION >= 26 495 static void (*dll_rb_ary_detransient) (VALUE); 496 # endif 497 # if (RUBY_VERSION >= 19) || defined(RUBY_INIT_STACK) 498 # ifdef __ia64 499 static void * (*dll_rb_ia64_bsp) (void); 500 static void (*dll_ruby_init_stack)(VALUE*, void*); 501 # else 502 static void (*dll_ruby_init_stack)(VALUE*); 503 # endif 504 # endif 505 # endif 506 # if RUBY_VERSION >= 19 507 static VALUE (*dll_rb_int2big)(SIGNED_VALUE); 508 # endif 509 510 # if RUBY_VERSION >= 19 511 static void (*dll_ruby_script) (const char*); 512 static int (*dll_rb_enc_find_index) (const char*); 513 static rb_encoding* (*dll_rb_enc_find) (const char*); 514 static VALUE (*dll_rb_enc_str_new) (const char*, long, rb_encoding*); 515 static VALUE (*dll_rb_sprintf) (const char*, ...); 516 static VALUE (*dll_rb_require) (const char*); 517 static void* (*dll_ruby_options)(int, char**); 518 # endif 519 520 # if defined(USE_RGENGC) && USE_RGENGC 521 # if RUBY_VERSION == 21 522 static void (*dll_rb_gc_writebarrier_unprotect_promoted)(VALUE); 523 # else 524 static void (*dll_rb_gc_writebarrier_unprotect)(VALUE obj); 525 # endif 526 # endif 527 528 # if RUBY_VERSION >= 30 529 # ifdef _MSC_VER 530 static void (*dll_ruby_malloc_size_overflow)(size_t, size_t); 531 # else 532 NORETURN(static void (*dll_ruby_malloc_size_overflow)(size_t, size_t)); 533 # endif 534 # endif 535 536 # if RUBY_VERSION >= 26 537 void rb_ary_detransient_stub(VALUE x); 538 # endif 539 540 // Do not generate a prototype here, VALUE isn't always defined. 541 # ifndef PROTO 542 # if RUBY_VERSION >= 19 543 # if RUBY_VERSION >= 22 544 long 545 rb_num2long_stub(VALUE x) 546 # else 547 SIGNED_VALUE 548 rb_num2long_stub(VALUE x) 549 # endif 550 { 551 return dll_rb_num2long(x); 552 } 553 # if RUBY_VERSION >= 26 554 VALUE 555 rb_int2big_stub(intptr_t x) 556 # else 557 VALUE 558 rb_int2big_stub(SIGNED_VALUE x) 559 # endif 560 { 561 return dll_rb_int2big(x); 562 } 563 # if RUBY_VERSION >= 30 || VIM_SIZEOF_INT < VIM_SIZEOF_LONG 564 long 565 rb_fix2int_stub(VALUE x) 566 { 567 return dll_rb_fix2int(x); 568 } 569 long 570 rb_num2int_stub(VALUE x) 571 { 572 return dll_rb_num2int(x); 573 } 574 # endif 575 # if RUBY_VERSION >= 20 576 VALUE 577 rb_float_new_in_heap(double d) 578 { 579 return dll_rb_float_new(d); 580 } 581 # if RUBY_VERSION >= 22 582 unsigned long 583 rb_num2ulong(VALUE x) 584 # else 585 VALUE 586 rb_num2ulong(VALUE x) 587 # endif 588 { 589 return (long)RSHIFT((SIGNED_VALUE)(x),1); 590 } 591 # endif 592 # endif 593 # if defined(USE_RGENGC) && USE_RGENGC 594 # if RUBY_VERSION == 21 595 void 596 rb_gc_writebarrier_unprotect_promoted_stub(VALUE obj) 597 { 598 dll_rb_gc_writebarrier_unprotect_promoted(obj); 599 } 600 # else 601 void 602 rb_gc_writebarrier_unprotect_stub(VALUE obj) 603 { 604 dll_rb_gc_writebarrier_unprotect(obj); 605 } 606 # endif 607 # endif 608 # if RUBY_VERSION >= 26 609 void 610 rb_ary_detransient_stub(VALUE x) 611 { 612 dll_rb_ary_detransient(x); 613 } 614 # endif 615 # if RUBY_VERSION >= 30 616 void 617 rb_check_type_stub(VALUE obj, int t) 618 { 619 dll_rb_check_type(obj, t); 620 } 621 unsigned long 622 rb_num2uint_stub(VALUE x) 623 { 624 return dll_rb_num2uint(x); 625 } 626 void 627 ruby_malloc_size_overflow_stub(size_t x, size_t y) 628 { 629 dll_ruby_malloc_size_overflow(x, y); 630 } 631 # endif 632 # endif // ifndef PROTO 633 634 static HINSTANCE hinstRuby = NULL; // Instance of ruby.dll 635 636 /* 637 * Table of name to function pointer of ruby. 638 */ 639 static struct 640 { 641 char *name; 642 RUBY_PROC *ptr; 643 } ruby_funcname_table[] = 644 { 645 {"rb_assoc_new", (RUBY_PROC*)&dll_rb_assoc_new}, 646 {"rb_cFalseClass", (RUBY_PROC*)&dll_rb_cFalseClass}, 647 # if defined(USE_RUBY_INTEGER) 648 {"rb_cInteger", (RUBY_PROC*)&dll_rb_cInteger}, 649 # else 650 {"rb_cFixnum", (RUBY_PROC*)&dll_rb_cFixnum}, 651 # endif 652 # if RUBY_VERSION >= 20 653 {"rb_cFloat", (RUBY_PROC*)&dll_rb_cFloat}, 654 # endif 655 {"rb_cNilClass", (RUBY_PROC*)&dll_rb_cNilClass}, 656 {"rb_cObject", (RUBY_PROC*)&dll_rb_cObject}, 657 {"rb_cString", (RUBY_PROC*)&dll_rb_cString}, 658 {"rb_cSymbol", (RUBY_PROC*)&dll_rb_cSymbol}, 659 {"rb_cTrueClass", (RUBY_PROC*)&dll_rb_cTrueClass}, 660 {"rb_class_new_instance", (RUBY_PROC*)&dll_rb_class_new_instance}, 661 {"rb_check_type", (RUBY_PROC*)&dll_rb_check_type}, 662 # ifdef USE_TYPEDDATA 663 {"rb_check_typeddata", (RUBY_PROC*)&dll_rb_check_typeddata}, 664 # endif 665 {"rb_class_path", (RUBY_PROC*)&dll_rb_class_path}, 666 # ifdef USE_TYPEDDATA 667 # if RUBY_VERSION >= 23 668 {"rb_data_typed_object_wrap", (RUBY_PROC*)&dll_rb_data_typed_object_wrap}, 669 # else 670 {"rb_data_typed_object_alloc", (RUBY_PROC*)&dll_rb_data_typed_object_alloc}, 671 # endif 672 # else 673 {"rb_data_object_alloc", (RUBY_PROC*)&dll_rb_data_object_alloc}, 674 # endif 675 {"rb_define_class_under", (RUBY_PROC*)&dll_rb_define_class_under}, 676 {"rb_define_const", (RUBY_PROC*)&dll_rb_define_const}, 677 {"rb_define_global_function", (RUBY_PROC*)&dll_rb_define_global_function}, 678 {"rb_define_method", (RUBY_PROC*)&dll_rb_define_method}, 679 {"rb_define_module", (RUBY_PROC*)&dll_rb_define_module}, 680 {"rb_define_module_function", (RUBY_PROC*)&dll_rb_define_module_function}, 681 {"rb_define_singleton_method", (RUBY_PROC*)&dll_rb_define_singleton_method}, 682 {"rb_define_virtual_variable", (RUBY_PROC*)&dll_rb_define_virtual_variable}, 683 {"rb_stdout", (RUBY_PROC*)&dll_rb_stdout}, 684 {"rb_stderr", (RUBY_PROC*)&dll_rb_stderr}, 685 {"rb_eArgError", (RUBY_PROC*)&dll_rb_eArgError}, 686 {"rb_eIndexError", (RUBY_PROC*)&dll_rb_eIndexError}, 687 {"rb_eRuntimeError", (RUBY_PROC*)&dll_rb_eRuntimeError}, 688 {"rb_eStandardError", (RUBY_PROC*)&dll_rb_eStandardError}, 689 {"rb_eval_string_protect", (RUBY_PROC*)&dll_rb_eval_string_protect}, 690 # if RUBY_VERSION >= 21 691 {"rb_funcallv", (RUBY_PROC*)&dll_rb_funcallv}, 692 # else 693 {"rb_funcall2", (RUBY_PROC*)&dll_rb_funcall2}, 694 # endif 695 {"rb_global_variable", (RUBY_PROC*)&dll_rb_global_variable}, 696 {"rb_hash_aset", (RUBY_PROC*)&dll_rb_hash_aset}, 697 {"rb_hash_foreach", (RUBY_PROC*)&dll_rb_hash_foreach}, 698 {"rb_hash_new", (RUBY_PROC*)&dll_rb_hash_new}, 699 {"rb_inspect", (RUBY_PROC*)&dll_rb_inspect}, 700 {"rb_int2inum", (RUBY_PROC*)&dll_rb_int2inum}, 701 {"rb_intern", (RUBY_PROC*)&dll_rb_intern}, 702 # if RUBY_VERSION >= 30 || VIM_SIZEOF_INT < VIM_SIZEOF_LONG 703 {"rb_fix2int", (RUBY_PROC*)&dll_rb_fix2int}, 704 {"rb_num2int", (RUBY_PROC*)&dll_rb_num2int}, 705 {"rb_num2uint", (RUBY_PROC*)&dll_rb_num2uint}, 706 # endif 707 {"rb_num2dbl", (RUBY_PROC*)&dll_rb_num2dbl}, 708 {"rb_lastline_get", (RUBY_PROC*)&dll_rb_lastline_get}, 709 {"rb_lastline_set", (RUBY_PROC*)&dll_rb_lastline_set}, 710 {"rb_protect", (RUBY_PROC*)&dll_rb_protect}, 711 {"rb_load", (RUBY_PROC*)&dll_rb_load}, 712 {"rb_num2long", (RUBY_PROC*)&dll_rb_num2long}, 713 {"rb_num2ulong", (RUBY_PROC*)&dll_rb_num2ulong}, 714 {"rb_obj_alloc", (RUBY_PROC*)&dll_rb_obj_alloc}, 715 {"rb_obj_as_string", (RUBY_PROC*)&dll_rb_obj_as_string}, 716 {"rb_obj_id", (RUBY_PROC*)&dll_rb_obj_id}, 717 {"rb_raise", (RUBY_PROC*)&dll_rb_raise}, 718 # if RUBY_VERSION >= 18 719 {"rb_string_value", (RUBY_PROC*)&dll_rb_string_value}, 720 # else 721 {"rb_str2cstr", (RUBY_PROC*)&dll_rb_str2cstr}, 722 # endif 723 {"rb_str_cat", (RUBY_PROC*)&dll_rb_str_cat}, 724 {"rb_str_concat", (RUBY_PROC*)&dll_rb_str_concat}, 725 {"rb_str_new", (RUBY_PROC*)&dll_rb_str_new}, 726 # ifdef need_rb_str_new_cstr 727 {"rb_str_new_cstr", (RUBY_PROC*)&dll_rb_str_new_cstr}, 728 # else 729 {"rb_str_new2", (RUBY_PROC*)&dll_rb_str_new2}, 730 # endif 731 # if RUBY_VERSION >= 19 732 {"rb_errinfo", (RUBY_PROC*)&dll_rb_errinfo}, 733 # else 734 {"ruby_errinfo", (RUBY_PROC*)&dll_ruby_errinfo}, 735 # endif 736 {"ruby_init", (RUBY_PROC*)&dll_ruby_init}, 737 {"ruby_init_loadpath", (RUBY_PROC*)&dll_ruby_init_loadpath}, 738 # ifdef MSWIN 739 # if RUBY_VERSION >= 19 740 {"ruby_sysinit", (RUBY_PROC*)&dll_ruby_sysinit}, 741 # else 742 {"NtInitialize", (RUBY_PROC*)&dll_NtInitialize}, 743 # endif 744 # if RUBY_VERSION >= 18 745 {"rb_w32_snprintf", (RUBY_PROC*)&dll_rb_w32_snprintf}, 746 # endif 747 # endif 748 # if RUBY_VERSION >= 18 749 {"rb_string_value_ptr", (RUBY_PROC*)&dll_rb_string_value_ptr}, 750 # if RUBY_VERSION <= 19 751 {"rb_float_new", (RUBY_PROC*)&dll_rb_float_new}, 752 # else 753 {"rb_float_new_in_heap", (RUBY_PROC*)&dll_rb_float_new}, 754 # endif 755 {"rb_ary_new", (RUBY_PROC*)&dll_rb_ary_new}, 756 # ifdef RB_ARY_NEW4_MACRO 757 {"rb_ary_new_from_values", (RUBY_PROC*)&dll_rb_ary_new4}, 758 # else 759 {"rb_ary_new4", (RUBY_PROC*)&dll_rb_ary_new4}, 760 # endif 761 {"rb_ary_push", (RUBY_PROC*)&dll_rb_ary_push}, 762 # if RUBY_VERSION >= 26 763 {"rb_ary_detransient", (RUBY_PROC*)&dll_rb_ary_detransient}, 764 # endif 765 # endif 766 # if RUBY_VERSION >= 19 767 {"rb_int2big", (RUBY_PROC*)&dll_rb_int2big}, 768 {"ruby_script", (RUBY_PROC*)&dll_ruby_script}, 769 {"rb_enc_find_index", (RUBY_PROC*)&dll_rb_enc_find_index}, 770 {"rb_enc_find", (RUBY_PROC*)&dll_rb_enc_find}, 771 {"rb_enc_str_new", (RUBY_PROC*)&dll_rb_enc_str_new}, 772 {"rb_sprintf", (RUBY_PROC*)&dll_rb_sprintf}, 773 {"rb_require", (RUBY_PROC*)&dll_rb_require}, 774 {"ruby_options", (RUBY_PROC*)&dll_ruby_options}, 775 # endif 776 # if (RUBY_VERSION >= 19) || defined(RUBY_INIT_STACK) 777 # ifdef __ia64 778 {"rb_ia64_bsp", (RUBY_PROC*)&dll_rb_ia64_bsp}, 779 # endif 780 {"ruby_init_stack", (RUBY_PROC*)&dll_ruby_init_stack}, 781 # endif 782 # if defined(USE_RGENGC) && USE_RGENGC 783 # if RUBY_VERSION == 21 784 {"rb_gc_writebarrier_unprotect_promoted", (RUBY_PROC*)&dll_rb_gc_writebarrier_unprotect_promoted}, 785 # else 786 {"rb_gc_writebarrier_unprotect", (RUBY_PROC*)&dll_rb_gc_writebarrier_unprotect}, 787 # endif 788 # endif 789 # if RUBY_VERSION >= 30 790 {"ruby_malloc_size_overflow", (RUBY_PROC*)&dll_ruby_malloc_size_overflow}, 791 # endif 792 {"", NULL}, 793 }; 794 795 /* 796 * Load library and get all pointers. 797 * Parameter 'libname' provides name of DLL. 798 * Return OK or FAIL. 799 */ 800 static int 801 ruby_runtime_link_init(char *libname, int verbose) 802 { 803 int i; 804 805 if (hinstRuby) 806 return OK; 807 hinstRuby = load_dll(libname); 808 if (!hinstRuby) 809 { 810 if (verbose) 811 semsg(_(e_loadlib), libname, load_dll_error()); 812 return FAIL; 813 } 814 815 for (i = 0; ruby_funcname_table[i].ptr; ++i) 816 { 817 if (!(*ruby_funcname_table[i].ptr = symbol_from_dll(hinstRuby, 818 ruby_funcname_table[i].name))) 819 { 820 close_dll(hinstRuby); 821 hinstRuby = NULL; 822 if (verbose) 823 semsg(_(e_loadfunc), ruby_funcname_table[i].name); 824 return FAIL; 825 } 826 } 827 return OK; 828 } 829 830 /* 831 * If ruby is enabled (there is installed ruby on Windows system) return TRUE, 832 * else FALSE. 833 */ 834 int 835 ruby_enabled(int verbose) 836 { 837 return ruby_runtime_link_init((char *)p_rubydll, verbose) == OK; 838 } 839 #endif // defined(DYNAMIC_RUBY) || defined(PROTO) 840 841 void 842 ruby_end(void) 843 { 844 } 845 846 void 847 ex_ruby(exarg_T *eap) 848 { 849 int state; 850 char *script = NULL; 851 852 script = (char *)script_get(eap, eap->arg); 853 if (!eap->skip && ensure_ruby_initialized()) 854 { 855 if (script == NULL) 856 rb_eval_string_protect((char *)eap->arg, &state); 857 else 858 rb_eval_string_protect(script, &state); 859 if (state) 860 error_print(state); 861 } 862 vim_free(script); 863 } 864 865 /* 866 * In Ruby 1.9 or later, ruby String object has encoding. 867 * conversion buffer string of vim to ruby String object using 868 * VIM encoding option. 869 */ 870 static VALUE 871 vim_str2rb_enc_str(const char *s) 872 { 873 #if RUBY_VERSION >= 19 874 long lval; 875 char_u *sval; 876 rb_encoding *enc; 877 878 if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string) 879 { 880 enc = rb_enc_find((char *)sval); 881 vim_free(sval); 882 if (enc) 883 return rb_enc_str_new(s, (long)strlen(s), enc); 884 } 885 #endif 886 return rb_str_new2(s); 887 } 888 889 static VALUE 890 eval_enc_string_protect(const char *str, int *state) 891 { 892 #if RUBY_VERSION >= 19 893 long lval; 894 char_u *sval; 895 rb_encoding *enc; 896 VALUE v; 897 898 if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string) 899 { 900 enc = rb_enc_find((char *)sval); 901 vim_free(sval); 902 if (enc) 903 { 904 v = rb_sprintf("#-*- coding:%s -*-\n%s", rb_enc_name(enc), str); 905 return rb_eval_string_protect(StringValuePtr(v), state); 906 } 907 } 908 #endif 909 return rb_eval_string_protect(str, state); 910 } 911 912 void 913 ex_rubydo(exarg_T *eap) 914 { 915 int state; 916 linenr_T i; 917 buf_T *was_curbuf = curbuf; 918 919 if (ensure_ruby_initialized()) 920 { 921 if (u_save(eap->line1 - 1, eap->line2 + 1) != OK) 922 return; 923 for (i = eap->line1; i <= eap->line2; i++) 924 { 925 VALUE line; 926 927 if (i > curbuf->b_ml.ml_line_count) 928 break; 929 line = vim_str2rb_enc_str((char *)ml_get(i)); 930 rb_lastline_set(line); 931 eval_enc_string_protect((char *) eap->arg, &state); 932 if (state) 933 { 934 error_print(state); 935 break; 936 } 937 if (was_curbuf != curbuf) 938 break; 939 line = rb_lastline_get(); 940 if (!NIL_P(line)) 941 { 942 if (TYPE(line) != T_STRING) 943 { 944 emsg(_("E265: $_ must be an instance of String")); 945 return; 946 } 947 ml_replace(i, (char_u *) StringValuePtr(line), 1); 948 changed(); 949 #ifdef SYNTAX_HL 950 syn_changed(i); // recompute syntax hl. for this line 951 #endif 952 } 953 } 954 check_cursor(); 955 update_curbuf(NOT_VALID); 956 } 957 } 958 959 static VALUE 960 rb_load_wrap(VALUE file_to_load) 961 { 962 rb_load(file_to_load, 0); 963 return Qnil; 964 } 965 966 void 967 ex_rubyfile(exarg_T *eap) 968 { 969 int state; 970 971 if (ensure_ruby_initialized()) 972 { 973 VALUE file_to_load = rb_str_new2((const char *)eap->arg); 974 rb_protect(rb_load_wrap, file_to_load, &state); 975 if (state) 976 error_print(state); 977 } 978 } 979 980 void 981 ruby_buffer_free(buf_T *buf) 982 { 983 if (buf->b_ruby_ref) 984 { 985 rb_hash_aset(objtbl, rb_obj_id((VALUE) buf->b_ruby_ref), Qnil); 986 RDATA(buf->b_ruby_ref)->data = NULL; 987 } 988 } 989 990 void 991 ruby_window_free(win_T *win) 992 { 993 if (win->w_ruby_ref) 994 { 995 rb_hash_aset(objtbl, rb_obj_id((VALUE) win->w_ruby_ref), Qnil); 996 RDATA(win->w_ruby_ref)->data = NULL; 997 } 998 } 999 1000 static int 1001 ensure_ruby_initialized(void) 1002 { 1003 if (!ruby_initialized) 1004 { 1005 #ifdef DYNAMIC_RUBY 1006 if (ruby_enabled(TRUE)) 1007 { 1008 #endif 1009 #ifdef MSWIN 1010 // suggested by Ariya Mizutani 1011 int argc = 1; 1012 char *argv[] = {"gvim.exe"}; 1013 char **argvp = argv; 1014 # if RUBY_VERSION >= 19 1015 ruby_sysinit(&argc, &argvp); 1016 # else 1017 NtInitialize(&argc, &argvp); 1018 # endif 1019 #endif 1020 { 1021 #if (RUBY_VERSION >= 19) || defined(RUBY_INIT_STACK) 1022 ruby_init_stack(ruby_stack_start); 1023 #endif 1024 ruby_init(); 1025 } 1026 #if RUBY_VERSION >= 19 1027 { 1028 int dummy_argc = 2; 1029 char *dummy_argv[] = {"vim-ruby", "-e_=0"}; 1030 ruby_options(dummy_argc, dummy_argv); 1031 } 1032 ruby_script("vim-ruby"); 1033 #else 1034 ruby_init_loadpath(); 1035 #endif 1036 ruby_io_init(); 1037 ruby_vim_init(); 1038 ruby_initialized = 1; 1039 #ifdef DYNAMIC_RUBY 1040 } 1041 else 1042 { 1043 emsg(_("E266: Sorry, this command is disabled, the Ruby library could not be loaded.")); 1044 return 0; 1045 } 1046 #endif 1047 } 1048 return ruby_initialized; 1049 } 1050 1051 static void 1052 error_print(int state) 1053 { 1054 #if !defined(DYNAMIC_RUBY) && (RUBY_VERSION <= 18) 1055 RUBYEXTERN VALUE ruby_errinfo; 1056 #endif 1057 VALUE error; 1058 VALUE eclass; 1059 VALUE einfo; 1060 VALUE bt; 1061 int attr; 1062 char buff[BUFSIZ]; 1063 long i; 1064 1065 #define TAG_RETURN 0x1 1066 #define TAG_BREAK 0x2 1067 #define TAG_NEXT 0x3 1068 #define TAG_RETRY 0x4 1069 #define TAG_REDO 0x5 1070 #define TAG_RAISE 0x6 1071 #define TAG_THROW 0x7 1072 #define TAG_FATAL 0x8 1073 #define TAG_MASK 0xf 1074 1075 switch (state) 1076 { 1077 case TAG_RETURN: 1078 emsg(_("E267: unexpected return")); 1079 break; 1080 case TAG_NEXT: 1081 emsg(_("E268: unexpected next")); 1082 break; 1083 case TAG_BREAK: 1084 emsg(_("E269: unexpected break")); 1085 break; 1086 case TAG_REDO: 1087 emsg(_("E270: unexpected redo")); 1088 break; 1089 case TAG_RETRY: 1090 emsg(_("E271: retry outside of rescue clause")); 1091 break; 1092 case TAG_RAISE: 1093 case TAG_FATAL: 1094 #if RUBY_VERSION >= 19 1095 error = rb_errinfo(); 1096 #else 1097 error = ruby_errinfo; 1098 #endif 1099 eclass = CLASS_OF(error); 1100 einfo = rb_obj_as_string(error); 1101 if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0) 1102 { 1103 emsg(_("E272: unhandled exception")); 1104 } 1105 else 1106 { 1107 VALUE epath; 1108 char *p; 1109 1110 epath = rb_class_path(eclass); 1111 vim_snprintf(buff, BUFSIZ, "%s: %s", 1112 RSTRING_PTR(epath), RSTRING_PTR(einfo)); 1113 p = strchr(buff, '\n'); 1114 if (p) *p = '\0'; 1115 emsg(buff); 1116 } 1117 1118 attr = syn_name2attr((char_u *)"Error"); 1119 #if RUBY_VERSION >= 21 1120 bt = rb_funcallv(error, rb_intern("backtrace"), 0, 0); 1121 for (i = 0; i < RARRAY_LEN(bt); i++) 1122 msg_attr(RSTRING_PTR(RARRAY_AREF(bt, i)), attr); 1123 #else 1124 bt = rb_funcall2(error, rb_intern("backtrace"), 0, 0); 1125 for (i = 0; i < RARRAY_LEN(bt); i++) 1126 msg_attr(RSTRING_PTR(RARRAY_PTR(bt)[i]), attr); 1127 #endif 1128 break; 1129 default: 1130 vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state); 1131 emsg(buff); 1132 break; 1133 } 1134 } 1135 1136 static VALUE 1137 vim_message(VALUE self UNUSED, VALUE str) 1138 { 1139 char *buff, *p; 1140 1141 str = rb_obj_as_string(str); 1142 if (RSTRING_LEN(str) > 0) 1143 { 1144 // Only do this when the string isn't empty, alloc(0) causes trouble. 1145 buff = ALLOCA_N(char, RSTRING_LEN(str) + 1); 1146 strcpy(buff, RSTRING_PTR(str)); 1147 p = strchr(buff, '\n'); 1148 if (p) *p = '\0'; 1149 msg(buff); 1150 } 1151 else 1152 { 1153 msg(""); 1154 } 1155 return Qnil; 1156 } 1157 1158 static VALUE 1159 vim_set_option(VALUE self UNUSED, VALUE str) 1160 { 1161 do_set((char_u *)StringValuePtr(str), 0); 1162 update_screen(NOT_VALID); 1163 return Qnil; 1164 } 1165 1166 static VALUE 1167 vim_command(VALUE self UNUSED, VALUE str) 1168 { 1169 do_cmdline_cmd((char_u *)StringValuePtr(str)); 1170 return Qnil; 1171 } 1172 1173 #ifdef FEAT_EVAL 1174 static VALUE 1175 vim_to_ruby(typval_T *tv) 1176 { 1177 VALUE result = Qnil; 1178 1179 if (tv->v_type == VAR_STRING) 1180 { 1181 result = rb_str_new2(tv->vval.v_string == NULL 1182 ? "" : (char *)(tv->vval.v_string)); 1183 } 1184 else if (tv->v_type == VAR_NUMBER) 1185 { 1186 result = INT2NUM(tv->vval.v_number); 1187 } 1188 # ifdef FEAT_FLOAT 1189 else if (tv->v_type == VAR_FLOAT) 1190 { 1191 result = rb_float_new(tv->vval.v_float); 1192 } 1193 # endif 1194 else if (tv->v_type == VAR_LIST) 1195 { 1196 list_T *list = tv->vval.v_list; 1197 listitem_T *curr; 1198 1199 result = rb_ary_new(); 1200 1201 if (list != NULL) 1202 { 1203 FOR_ALL_LIST_ITEMS(list, curr) 1204 rb_ary_push(result, vim_to_ruby(&curr->li_tv)); 1205 } 1206 } 1207 else if (tv->v_type == VAR_DICT) 1208 { 1209 result = rb_hash_new(); 1210 1211 if (tv->vval.v_dict != NULL) 1212 { 1213 hashtab_T *ht = &tv->vval.v_dict->dv_hashtab; 1214 long_u todo = ht->ht_used; 1215 hashitem_T *hi; 1216 dictitem_T *di; 1217 1218 for (hi = ht->ht_array; todo > 0; ++hi) 1219 { 1220 if (!HASHITEM_EMPTY(hi)) 1221 { 1222 --todo; 1223 1224 di = dict_lookup(hi); 1225 rb_hash_aset(result, rb_str_new2((char *)hi->hi_key), 1226 vim_to_ruby(&di->di_tv)); 1227 } 1228 } 1229 } 1230 } 1231 else if (tv->v_type == VAR_BOOL || tv->v_type == VAR_SPECIAL) 1232 { 1233 if (tv->vval.v_number == VVAL_TRUE) 1234 result = Qtrue; 1235 else if (tv->vval.v_number == VVAL_FALSE) 1236 result = Qfalse; 1237 } 1238 else if (tv->v_type == VAR_BLOB) 1239 { 1240 result = rb_str_new(tv->vval.v_blob->bv_ga.ga_data, 1241 tv->vval.v_blob->bv_ga.ga_len); 1242 } 1243 // else return Qnil; 1244 1245 return result; 1246 } 1247 #endif 1248 1249 static VALUE 1250 vim_evaluate(VALUE self UNUSED, VALUE str) 1251 { 1252 #ifdef FEAT_EVAL 1253 typval_T *tv; 1254 VALUE result; 1255 1256 tv = eval_expr((char_u *)StringValuePtr(str), NULL); 1257 if (tv == NULL) 1258 return Qnil; 1259 result = vim_to_ruby(tv); 1260 1261 free_tv(tv); 1262 1263 return result; 1264 #else 1265 return Qnil; 1266 #endif 1267 } 1268 1269 #ifdef USE_TYPEDDATA 1270 static size_t buffer_dsize(const void *buf); 1271 1272 static const rb_data_type_t buffer_type = { 1273 "vim_buffer", 1274 {0, 0, buffer_dsize, 1275 # if RUBY_VERSION >= 27 1276 0, {0} 1277 # else 1278 {0, 0} 1279 # endif 1280 }, 1281 0, 0, 1282 # ifdef RUBY_TYPED_FREE_IMMEDIATELY 1283 0, 1284 # endif 1285 }; 1286 1287 static size_t 1288 buffer_dsize(const void *buf UNUSED) 1289 { 1290 return sizeof(buf_T); 1291 } 1292 #endif 1293 1294 static VALUE 1295 buffer_new(buf_T *buf) 1296 { 1297 if (buf->b_ruby_ref) 1298 { 1299 return (VALUE) buf->b_ruby_ref; 1300 } 1301 else 1302 { 1303 #ifdef USE_TYPEDDATA 1304 VALUE obj = TypedData_Wrap_Struct(cBuffer, &buffer_type, buf); 1305 #else 1306 VALUE obj = Data_Wrap_Struct(cBuffer, 0, 0, buf); 1307 #endif 1308 buf->b_ruby_ref = (void *) obj; 1309 rb_hash_aset(objtbl, rb_obj_id(obj), obj); 1310 return obj; 1311 } 1312 } 1313 1314 static buf_T * 1315 get_buf(VALUE obj) 1316 { 1317 buf_T *buf; 1318 1319 #ifdef USE_TYPEDDATA 1320 TypedData_Get_Struct(obj, buf_T, &buffer_type, buf); 1321 #else 1322 Data_Get_Struct(obj, buf_T, buf); 1323 #endif 1324 if (buf == NULL) 1325 rb_raise(eDeletedBufferError, "attempt to refer to deleted buffer"); 1326 return buf; 1327 } 1328 1329 static VALUE 1330 vim_blob(VALUE self UNUSED, VALUE str) 1331 { 1332 VALUE result = rb_str_new("0z", 2); 1333 char buf[4]; 1334 int i; 1335 for (i = 0; i < RSTRING_LEN(str); i++) 1336 { 1337 sprintf(buf, "%02X", (unsigned char)(RSTRING_PTR(str)[i])); 1338 rb_str_concat(result, rb_str_new2(buf)); 1339 } 1340 return result; 1341 } 1342 1343 static VALUE 1344 buffer_s_current(VALUE self UNUSED) 1345 { 1346 return buffer_new(curbuf); 1347 } 1348 1349 static VALUE 1350 buffer_s_current_getter(ID id UNUSED, VALUE *x UNUSED) 1351 { 1352 return buffer_new(curbuf); 1353 } 1354 1355 static VALUE 1356 buffer_s_count(VALUE self UNUSED) 1357 { 1358 buf_T *b; 1359 int n = 0; 1360 1361 FOR_ALL_BUFFERS(b) 1362 { 1363 // Deleted buffers should not be counted 1364 // SegPhault - 01/07/05 1365 if (b->b_p_bl) 1366 n++; 1367 } 1368 1369 return INT2NUM(n); 1370 } 1371 1372 static VALUE 1373 buffer_s_aref(VALUE self UNUSED, VALUE num) 1374 { 1375 buf_T *b; 1376 int n = NUM2INT(num); 1377 1378 FOR_ALL_BUFFERS(b) 1379 { 1380 // Deleted buffers should not be counted 1381 // SegPhault - 01/07/05 1382 if (!b->b_p_bl) 1383 continue; 1384 1385 if (n == 0) 1386 return buffer_new(b); 1387 1388 n--; 1389 } 1390 return Qnil; 1391 } 1392 1393 static VALUE 1394 buffer_name(VALUE self) 1395 { 1396 buf_T *buf = get_buf(self); 1397 1398 return buf->b_ffname ? rb_str_new2((char *)buf->b_ffname) : Qnil; 1399 } 1400 1401 static VALUE 1402 buffer_number(VALUE self) 1403 { 1404 buf_T *buf = get_buf(self); 1405 1406 return INT2NUM(buf->b_fnum); 1407 } 1408 1409 static VALUE 1410 buffer_count(VALUE self) 1411 { 1412 buf_T *buf = get_buf(self); 1413 1414 return INT2NUM(buf->b_ml.ml_line_count); 1415 } 1416 1417 static VALUE 1418 get_buffer_line(buf_T *buf, linenr_T n) 1419 { 1420 if (n <= 0 || n > buf->b_ml.ml_line_count) 1421 rb_raise(rb_eIndexError, "line number %ld out of range", (long)n); 1422 return vim_str2rb_enc_str((char *)ml_get_buf(buf, n, FALSE)); 1423 } 1424 1425 static VALUE 1426 buffer_aref(VALUE self, VALUE num) 1427 { 1428 buf_T *buf = get_buf(self); 1429 1430 if (buf != NULL) 1431 return get_buffer_line(buf, (linenr_T)NUM2LONG(num)); 1432 return Qnil; // For stop warning 1433 } 1434 1435 static VALUE 1436 set_buffer_line(buf_T *buf, linenr_T n, VALUE str) 1437 { 1438 char *line = StringValuePtr(str); 1439 aco_save_T aco; 1440 1441 if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL) 1442 { 1443 // set curwin/curbuf for "buf" and save some things 1444 aucmd_prepbuf(&aco, buf); 1445 1446 if (u_savesub(n) == OK) 1447 { 1448 ml_replace(n, (char_u *)line, TRUE); 1449 changed(); 1450 #ifdef SYNTAX_HL 1451 syn_changed(n); // recompute syntax hl. for this line 1452 #endif 1453 } 1454 1455 // restore curwin/curbuf and a few other things 1456 aucmd_restbuf(&aco); 1457 // Careful: autocommands may have made "buf" invalid! 1458 1459 update_curbuf(NOT_VALID); 1460 } 1461 else 1462 { 1463 rb_raise(rb_eIndexError, "line number %ld out of range", (long)n); 1464 } 1465 return str; 1466 } 1467 1468 static VALUE 1469 buffer_aset(VALUE self, VALUE num, VALUE str) 1470 { 1471 buf_T *buf = get_buf(self); 1472 1473 if (buf != NULL) 1474 return set_buffer_line(buf, (linenr_T)NUM2LONG(num), str); 1475 return str; 1476 } 1477 1478 static VALUE 1479 buffer_delete(VALUE self, VALUE num) 1480 { 1481 buf_T *buf = get_buf(self); 1482 long n = NUM2LONG(num); 1483 aco_save_T aco; 1484 1485 if (n > 0 && n <= buf->b_ml.ml_line_count) 1486 { 1487 // set curwin/curbuf for "buf" and save some things 1488 aucmd_prepbuf(&aco, buf); 1489 1490 if (u_savedel(n, 1) == OK) 1491 { 1492 ml_delete(n); 1493 1494 // Changes to non-active buffers should properly refresh 1495 // SegPhault - 01/09/05 1496 deleted_lines_mark(n, 1L); 1497 1498 changed(); 1499 } 1500 1501 // restore curwin/curbuf and a few other things 1502 aucmd_restbuf(&aco); 1503 // Careful: autocommands may have made "buf" invalid! 1504 1505 update_curbuf(NOT_VALID); 1506 } 1507 else 1508 { 1509 rb_raise(rb_eIndexError, "line number %ld out of range", n); 1510 } 1511 return Qnil; 1512 } 1513 1514 static VALUE 1515 buffer_append(VALUE self, VALUE num, VALUE str) 1516 { 1517 buf_T *buf = get_buf(self); 1518 char *line = StringValuePtr(str); 1519 long n = NUM2LONG(num); 1520 aco_save_T aco; 1521 1522 if (line == NULL) 1523 { 1524 rb_raise(rb_eIndexError, "NULL line"); 1525 } 1526 else if (n >= 0 && n <= buf->b_ml.ml_line_count) 1527 { 1528 // set curwin/curbuf for "buf" and save some things 1529 aucmd_prepbuf(&aco, buf); 1530 1531 if (u_inssub(n + 1) == OK) 1532 { 1533 ml_append(n, (char_u *) line, (colnr_T) 0, FALSE); 1534 1535 // Changes to non-active buffers should properly refresh screen 1536 // SegPhault - 12/20/04 1537 appended_lines_mark(n, 1L); 1538 1539 changed(); 1540 } 1541 1542 // restore curwin/curbuf and a few other things 1543 aucmd_restbuf(&aco); 1544 // Careful: autocommands may have made "buf" invalid! 1545 1546 update_curbuf(NOT_VALID); 1547 } 1548 else 1549 { 1550 rb_raise(rb_eIndexError, "line number %ld out of range", n); 1551 } 1552 return str; 1553 } 1554 1555 #ifdef USE_TYPEDDATA 1556 static size_t window_dsize(const void *buf); 1557 1558 static const rb_data_type_t window_type = { 1559 "vim_window", 1560 {0, 0, window_dsize, 1561 # if RUBY_VERSION >= 27 1562 0, {0} 1563 # else 1564 {0, 0} 1565 # endif 1566 }, 1567 0, 0, 1568 # ifdef RUBY_TYPED_FREE_IMMEDIATELY 1569 0, 1570 # endif 1571 }; 1572 1573 static size_t 1574 window_dsize(const void *win UNUSED) 1575 { 1576 return sizeof(win_T); 1577 } 1578 #endif 1579 1580 static VALUE 1581 window_new(win_T *win) 1582 { 1583 if (win->w_ruby_ref) 1584 { 1585 return (VALUE) win->w_ruby_ref; 1586 } 1587 else 1588 { 1589 #ifdef USE_TYPEDDATA 1590 VALUE obj = TypedData_Wrap_Struct(cVimWindow, &window_type, win); 1591 #else 1592 VALUE obj = Data_Wrap_Struct(cVimWindow, 0, 0, win); 1593 #endif 1594 win->w_ruby_ref = (void *) obj; 1595 rb_hash_aset(objtbl, rb_obj_id(obj), obj); 1596 return obj; 1597 } 1598 } 1599 1600 static win_T * 1601 get_win(VALUE obj) 1602 { 1603 win_T *win; 1604 1605 #ifdef USE_TYPEDDATA 1606 TypedData_Get_Struct(obj, win_T, &window_type, win); 1607 #else 1608 Data_Get_Struct(obj, win_T, win); 1609 #endif 1610 if (win == NULL) 1611 rb_raise(eDeletedWindowError, "attempt to refer to deleted window"); 1612 return win; 1613 } 1614 1615 static VALUE 1616 window_s_current(VALUE self UNUSED) 1617 { 1618 return window_new(curwin); 1619 } 1620 1621 static VALUE 1622 window_s_current_getter(ID id UNUSED, VALUE *x UNUSED) 1623 { 1624 return window_new(curwin); 1625 } 1626 1627 /* 1628 * Added line manipulation functions 1629 * SegPhault - 03/07/05 1630 */ 1631 static VALUE 1632 line_s_current(VALUE self UNUSED) 1633 { 1634 return get_buffer_line(curbuf, curwin->w_cursor.lnum); 1635 } 1636 1637 static VALUE 1638 set_current_line(VALUE self UNUSED, VALUE str) 1639 { 1640 return set_buffer_line(curbuf, curwin->w_cursor.lnum, str); 1641 } 1642 1643 static VALUE 1644 current_line_number(VALUE self UNUSED) 1645 { 1646 return INT2FIX((int)curwin->w_cursor.lnum); 1647 } 1648 1649 static VALUE 1650 window_s_count(VALUE self UNUSED) 1651 { 1652 win_T *w; 1653 int n = 0; 1654 1655 FOR_ALL_WINDOWS(w) 1656 n++; 1657 return INT2NUM(n); 1658 } 1659 1660 static VALUE 1661 window_s_aref(VALUE self UNUSED, VALUE num) 1662 { 1663 win_T *w; 1664 int n = NUM2INT(num); 1665 1666 for (w = firstwin; w != NULL; w = w->w_next, --n) 1667 if (n == 0) 1668 return window_new(w); 1669 return Qnil; 1670 } 1671 1672 static VALUE 1673 window_buffer(VALUE self) 1674 { 1675 win_T *win = get_win(self); 1676 1677 return buffer_new(win->w_buffer); 1678 } 1679 1680 static VALUE 1681 window_height(VALUE self) 1682 { 1683 win_T *win = get_win(self); 1684 1685 return INT2NUM(win->w_height); 1686 } 1687 1688 static VALUE 1689 window_set_height(VALUE self, VALUE height) 1690 { 1691 win_T *win = get_win(self); 1692 win_T *savewin = curwin; 1693 1694 curwin = win; 1695 win_setheight(NUM2INT(height)); 1696 curwin = savewin; 1697 return height; 1698 } 1699 1700 static VALUE 1701 window_width(VALUE self UNUSED) 1702 { 1703 return INT2NUM(get_win(self)->w_width); 1704 } 1705 1706 static VALUE 1707 window_set_width(VALUE self UNUSED, VALUE width) 1708 { 1709 win_T *win = get_win(self); 1710 win_T *savewin = curwin; 1711 1712 curwin = win; 1713 win_setwidth(NUM2INT(width)); 1714 curwin = savewin; 1715 return width; 1716 } 1717 1718 static VALUE 1719 window_cursor(VALUE self) 1720 { 1721 win_T *win = get_win(self); 1722 1723 return rb_assoc_new(INT2NUM(win->w_cursor.lnum), INT2NUM(win->w_cursor.col)); 1724 } 1725 1726 static VALUE 1727 window_set_cursor(VALUE self, VALUE pos) 1728 { 1729 VALUE lnum, col; 1730 win_T *win = get_win(self); 1731 1732 Check_Type(pos, T_ARRAY); 1733 if (RARRAY_LEN(pos) != 2) 1734 rb_raise(rb_eArgError, "array length must be 2"); 1735 lnum = RARRAY_PTR(pos)[0]; 1736 col = RARRAY_PTR(pos)[1]; 1737 win->w_cursor.lnum = NUM2LONG(lnum); 1738 win->w_cursor.col = NUM2UINT(col); 1739 win->w_set_curswant = TRUE; 1740 check_cursor(); // put cursor on an existing line 1741 update_screen(NOT_VALID); 1742 return Qnil; 1743 } 1744 1745 static VALUE 1746 f_nop(VALUE self UNUSED) 1747 { 1748 return Qnil; 1749 } 1750 1751 static VALUE 1752 f_p(int argc, VALUE *argv, VALUE self UNUSED) 1753 { 1754 int i; 1755 VALUE str = rb_str_new("", 0); 1756 VALUE ret = Qnil; 1757 1758 for (i = 0; i < argc; i++) 1759 { 1760 if (i > 0) rb_str_cat(str, ", ", 2); 1761 rb_str_concat(str, rb_inspect(argv[i])); 1762 } 1763 msg(RSTRING_PTR(str)); 1764 1765 if (argc == 1) 1766 ret = argv[0]; 1767 else if (argc > 1) 1768 ret = rb_ary_new4(argc, argv); 1769 return ret; 1770 } 1771 1772 static void 1773 ruby_io_init(void) 1774 { 1775 #ifndef DYNAMIC_RUBY 1776 RUBYEXTERN VALUE rb_stdout; 1777 RUBYEXTERN VALUE rb_stderr; 1778 #endif 1779 1780 rb_stdout = rb_obj_alloc(rb_cObject); 1781 rb_stderr = rb_obj_alloc(rb_cObject); 1782 rb_define_singleton_method(rb_stdout, "write", vim_message, 1); 1783 rb_define_singleton_method(rb_stdout, "flush", f_nop, 0); 1784 rb_define_singleton_method(rb_stderr, "write", vim_message, 1); 1785 rb_define_singleton_method(rb_stderr, "flush", f_nop, 0); 1786 rb_define_global_function("p", f_p, -1); 1787 } 1788 1789 static void 1790 ruby_vim_init(void) 1791 { 1792 objtbl = rb_hash_new(); 1793 rb_global_variable(&objtbl); 1794 1795 // The Vim module used to be called "VIM", but "Vim" is better. Make an 1796 // alias "VIM" for backwards compatibility. 1797 mVIM = rb_define_module("Vim"); 1798 rb_define_const(rb_cObject, "VIM", mVIM); 1799 rb_define_const(mVIM, "VERSION_MAJOR", INT2NUM(VIM_VERSION_MAJOR)); 1800 rb_define_const(mVIM, "VERSION_MINOR", INT2NUM(VIM_VERSION_MINOR)); 1801 rb_define_const(mVIM, "VERSION_BUILD", INT2NUM(VIM_VERSION_BUILD)); 1802 rb_define_const(mVIM, "VERSION_PATCHLEVEL", INT2NUM(VIM_VERSION_PATCHLEVEL)); 1803 rb_define_const(mVIM, "VERSION_SHORT", rb_str_new2(VIM_VERSION_SHORT)); 1804 rb_define_const(mVIM, "VERSION_MEDIUM", rb_str_new2(VIM_VERSION_MEDIUM)); 1805 rb_define_const(mVIM, "VERSION_LONG", rb_str_new2(VIM_VERSION_LONG)); 1806 rb_define_const(mVIM, "VERSION_LONG_DATE", rb_str_new2(VIM_VERSION_LONG_DATE)); 1807 rb_define_module_function(mVIM, "message", vim_message, 1); 1808 rb_define_module_function(mVIM, "set_option", vim_set_option, 1); 1809 rb_define_module_function(mVIM, "command", vim_command, 1); 1810 rb_define_module_function(mVIM, "evaluate", vim_evaluate, 1); 1811 rb_define_module_function(mVIM, "blob", vim_blob, 1); 1812 1813 eDeletedBufferError = rb_define_class_under(mVIM, "DeletedBufferError", 1814 rb_eStandardError); 1815 eDeletedWindowError = rb_define_class_under(mVIM, "DeletedWindowError", 1816 rb_eStandardError); 1817 1818 cBuffer = rb_define_class_under(mVIM, "Buffer", rb_cObject); 1819 rb_define_singleton_method(cBuffer, "current", buffer_s_current, 0); 1820 rb_define_singleton_method(cBuffer, "count", buffer_s_count, 0); 1821 rb_define_singleton_method(cBuffer, "[]", buffer_s_aref, 1); 1822 rb_define_method(cBuffer, "name", buffer_name, 0); 1823 rb_define_method(cBuffer, "number", buffer_number, 0); 1824 rb_define_method(cBuffer, "count", buffer_count, 0); 1825 rb_define_method(cBuffer, "length", buffer_count, 0); 1826 rb_define_method(cBuffer, "[]", buffer_aref, 1); 1827 rb_define_method(cBuffer, "[]=", buffer_aset, 2); 1828 rb_define_method(cBuffer, "delete", buffer_delete, 1); 1829 rb_define_method(cBuffer, "append", buffer_append, 2); 1830 1831 // Added line manipulation functions 1832 // SegPhault - 03/07/05 1833 rb_define_method(cBuffer, "line_number", current_line_number, 0); 1834 rb_define_method(cBuffer, "line", line_s_current, 0); 1835 rb_define_method(cBuffer, "line=", set_current_line, 1); 1836 1837 1838 cVimWindow = rb_define_class_under(mVIM, "Window", rb_cObject); 1839 rb_define_singleton_method(cVimWindow, "current", window_s_current, 0); 1840 rb_define_singleton_method(cVimWindow, "count", window_s_count, 0); 1841 rb_define_singleton_method(cVimWindow, "[]", window_s_aref, 1); 1842 rb_define_method(cVimWindow, "buffer", window_buffer, 0); 1843 rb_define_method(cVimWindow, "height", window_height, 0); 1844 rb_define_method(cVimWindow, "height=", window_set_height, 1); 1845 rb_define_method(cVimWindow, "width", window_width, 0); 1846 rb_define_method(cVimWindow, "width=", window_set_width, 1); 1847 rb_define_method(cVimWindow, "cursor", window_cursor, 0); 1848 rb_define_method(cVimWindow, "cursor=", window_set_cursor, 1); 1849 1850 rb_define_virtual_variable("$curbuf", buffer_s_current_getter, 0); 1851 rb_define_virtual_variable("$curwin", window_s_current_getter, 0); 1852 } 1853 1854 void 1855 vim_ruby_init(void *stack_start) 1856 { 1857 // should get machine stack start address early in main function 1858 ruby_stack_start = stack_start; 1859 } 1860 1861 static int 1862 convert_hash2dict(VALUE key, VALUE val, VALUE arg) 1863 { 1864 dict_T *d = (dict_T *)arg; 1865 dictitem_T *di; 1866 1867 di = dictitem_alloc((char_u *)RSTRING_PTR(rb_obj_as_string(key))); 1868 if (di == NULL || ruby_convert_to_vim_value(val, &di->di_tv) != OK 1869 || dict_add(d, di) != OK) 1870 { 1871 d->dv_hashtab.ht_error = TRUE; 1872 return ST_STOP; 1873 } 1874 return ST_CONTINUE; 1875 } 1876 1877 static int 1878 ruby_convert_to_vim_value(VALUE val, typval_T *rettv) 1879 { 1880 switch (TYPE(val)) 1881 { 1882 case T_NIL: 1883 rettv->v_type = VAR_SPECIAL; 1884 rettv->vval.v_number = VVAL_NULL; 1885 break; 1886 case T_TRUE: 1887 rettv->v_type = VAR_BOOL; 1888 rettv->vval.v_number = VVAL_TRUE; 1889 break; 1890 case T_FALSE: 1891 rettv->v_type = VAR_BOOL; 1892 rettv->vval.v_number = VVAL_FALSE; 1893 break; 1894 case T_BIGNUM: 1895 case T_FIXNUM: 1896 rettv->v_type = VAR_NUMBER; 1897 rettv->vval.v_number = (varnumber_T)NUM2LONG(val); 1898 break; 1899 #ifdef FEAT_FLOAT 1900 case T_FLOAT: 1901 rettv->v_type = VAR_FLOAT; 1902 rettv->vval.v_float = (float_T)NUM2DBL(val); 1903 break; 1904 #endif 1905 default: 1906 val = rb_obj_as_string(val); 1907 // FALLTHROUGH 1908 case T_STRING: 1909 { 1910 VALUE str = (VALUE)RSTRING(val); 1911 1912 rettv->v_type = VAR_STRING; 1913 rettv->vval.v_string = vim_strnsave((char_u *)RSTRING_PTR(str), 1914 RSTRING_LEN(str)); 1915 } 1916 break; 1917 case T_ARRAY: 1918 { 1919 list_T *l; 1920 long i; 1921 typval_T v; 1922 1923 l = list_alloc(); 1924 if (l == NULL) 1925 return FAIL; 1926 1927 for (i = 0; i < RARRAY_LEN(val); ++i) 1928 { 1929 if (ruby_convert_to_vim_value((VALUE)RARRAY_PTR(val)[i], 1930 &v) != OK) 1931 { 1932 list_unref(l); 1933 return FAIL; 1934 } 1935 list_append_tv(l, &v); 1936 clear_tv(&v); 1937 } 1938 1939 rettv->v_type = VAR_LIST; 1940 rettv->vval.v_list = l; 1941 ++l->lv_refcount; 1942 } 1943 break; 1944 case T_HASH: 1945 { 1946 dict_T *d; 1947 1948 d = dict_alloc(); 1949 if (d == NULL) 1950 return FAIL; 1951 1952 rb_hash_foreach(val, convert_hash2dict, (VALUE)d); 1953 if (d->dv_hashtab.ht_error) 1954 { 1955 dict_unref(d); 1956 return FAIL; 1957 } 1958 1959 rettv->v_type = VAR_DICT; 1960 rettv->vval.v_dict = d; 1961 ++d->dv_refcount; 1962 } 1963 break; 1964 } 1965 return OK; 1966 } 1967 1968 void 1969 do_rubyeval(char_u *str, typval_T *rettv) 1970 { 1971 int retval = FAIL; 1972 1973 if (ensure_ruby_initialized()) 1974 { 1975 int state; 1976 VALUE obj; 1977 1978 obj = rb_eval_string_protect((const char *)str, &state); 1979 if (state) 1980 error_print(state); 1981 else 1982 retval = ruby_convert_to_vim_value(obj, rettv); 1983 } 1984 if (retval == FAIL) 1985 { 1986 rettv->v_type = VAR_NUMBER; 1987 rettv->vval.v_number = 0; 1988 } 1989 } 1990