1edf3f97aSBram Moolenaar /* vi:set ts=8 sts=4 sw=4 noet:
2071d4279SBram Moolenaar *
3071d4279SBram Moolenaar * VIM - Vi IMproved by Bram Moolenaar
4be4d506bSBram Moolenaar *
5be4d506bSBram Moolenaar * Ruby interface by Shugo Maeda
6be4d506bSBram Moolenaar * with improvements by SegPhault (Ryan Paul)
7f9b5ef8cSBram Moolenaar * with improvements by Jon Maken
8071d4279SBram Moolenaar *
9071d4279SBram Moolenaar * Do ":help uganda" in Vim to read copying and usage conditions.
10071d4279SBram Moolenaar * Do ":help credits" in Vim to see a list of people who contributed.
11071d4279SBram Moolenaar * See README.txt for an overview of the Vim source code.
12071d4279SBram Moolenaar */
13071d4279SBram Moolenaar
1432d19c18SBram Moolenaar #include "protodef.h"
152d73ff45SBram Moolenaar #ifdef HAVE_CONFIG_H
163ca71f1fSBram Moolenaar # include "auto/config.h"
172d73ff45SBram Moolenaar #endif
183ca71f1fSBram Moolenaar
19e2793357SBram Moolenaar #include <stdio.h>
20e2793357SBram Moolenaar #include <string.h>
21e2793357SBram Moolenaar
22071d4279SBram Moolenaar #ifdef _WIN32
2341a4141eSBram Moolenaar # if !defined(DYNAMIC_RUBY) || (RUBY_VERSION < 18)
24071d4279SBram Moolenaar # define NT
25071d4279SBram Moolenaar # endif
26071d4279SBram Moolenaar # ifndef DYNAMIC_RUBY
272ab2e860SBram Moolenaar # define IMPORT // For static dll usage __declspec(dllimport)
28071d4279SBram Moolenaar # define RUBYEXTERN __declspec(dllimport)
29071d4279SBram Moolenaar # endif
30071d4279SBram Moolenaar #endif
31071d4279SBram Moolenaar #ifndef RUBYEXTERN
32071d4279SBram Moolenaar # define RUBYEXTERN extern
33071d4279SBram Moolenaar #endif
34071d4279SBram Moolenaar
35dace9f78SBram Moolenaar // suggested by Ariya Mizutani
36dace9f78SBram Moolenaar #if (_MSC_VER == 1200)
37dace9f78SBram Moolenaar # undef _WIN32_WINNT
3806469e97SBram Moolenaar #endif
3906469e97SBram Moolenaar
40f9b5ef8cSBram Moolenaar #ifdef DYNAMIC_RUBY
41071d4279SBram Moolenaar /*
42071d4279SBram Moolenaar * This is tricky. In ruby.h there is (inline) function rb_class_of()
43071d4279SBram Moolenaar * definition. This function use these variables. But we want function to
44071d4279SBram Moolenaar * use dll_* variables.
45071d4279SBram Moolenaar */
46dace9f78SBram Moolenaar # if RUBY_VERSION >= 24
47dace9f78SBram Moolenaar # define USE_RUBY_INTEGER
48dace9f78SBram Moolenaar # endif
49dace9f78SBram Moolenaar
50071d4279SBram Moolenaar # define rb_cFalseClass (*dll_rb_cFalseClass)
51071d4279SBram Moolenaar # define rb_cFixnum (*dll_rb_cFixnum)
522016ae58SBram Moolenaar # if defined(USE_RUBY_INTEGER)
5306469e97SBram Moolenaar # define rb_cInteger (*dll_rb_cInteger)
5406469e97SBram Moolenaar # endif
5541a4141eSBram Moolenaar # if RUBY_VERSION >= 20
56db3fbe52SBram Moolenaar # define rb_cFloat (*dll_rb_cFloat)
57db3fbe52SBram Moolenaar # endif
58071d4279SBram Moolenaar # define rb_cNilClass (*dll_rb_cNilClass)
596e5ea8d2SBram Moolenaar # define rb_cString (*dll_rb_cString)
60071d4279SBram Moolenaar # define rb_cSymbol (*dll_rb_cSymbol)
61071d4279SBram Moolenaar # define rb_cTrueClass (*dll_rb_cTrueClass)
62dace9f78SBram Moolenaar
6341a4141eSBram Moolenaar # if RUBY_VERSION >= 18
64071d4279SBram Moolenaar /*
6542d57f00SBram Moolenaar * On ver 1.8, all Ruby functions are exported with "__declspec(dllimport)"
6642d57f00SBram Moolenaar * in ruby.h. But it causes trouble for these variables, because it is
67071d4279SBram Moolenaar * defined in this file. When defined this RUBY_EXPORT it modified to
68071d4279SBram Moolenaar * "extern" and be able to avoid this problem.
69071d4279SBram Moolenaar */
70071d4279SBram Moolenaar # define RUBY_EXPORT
71071d4279SBram Moolenaar # endif
72f9b5ef8cSBram Moolenaar
73dace9f78SBram Moolenaar # if RUBY_VERSION >= 19
742ab2e860SBram Moolenaar // Ruby 1.9 defines a number of static functions which use rb_num2long and
752ab2e860SBram Moolenaar // rb_int2big
7642d57f00SBram Moolenaar # define rb_num2long rb_num2long_stub
7742d57f00SBram Moolenaar # define rb_int2big rb_int2big_stub
7842d57f00SBram Moolenaar
79dace9f78SBram Moolenaar # if RUBY_VERSION >= 30 || VIM_SIZEOF_INT < VIM_SIZEOF_LONG
802ab2e860SBram Moolenaar // Ruby 1.9 defines a number of static functions which use rb_fix2int and
812ab2e860SBram Moolenaar // rb_num2int if VIM_SIZEOF_INT < VIM_SIZEOF_LONG (64bit)
820bcdd6e7SBram Moolenaar # define rb_fix2int rb_fix2int_stub
830bcdd6e7SBram Moolenaar # define rb_num2int rb_num2int_stub
840bcdd6e7SBram Moolenaar # endif
85dace9f78SBram Moolenaar # endif
860bcdd6e7SBram Moolenaar
87dace9f78SBram Moolenaar # if RUBY_VERSION == 21
882ab2e860SBram Moolenaar // Ruby 2.1 adds new GC called RGenGC and RARRAY_PTR uses
892ab2e860SBram Moolenaar // rb_gc_writebarrier_unprotect_promoted if USE_RGENGC
90a1a118b1SBram Moolenaar # define rb_gc_writebarrier_unprotect_promoted rb_gc_writebarrier_unprotect_promoted_stub
91a1a118b1SBram Moolenaar # endif
92dace9f78SBram Moolenaar
93dace9f78SBram Moolenaar # if RUBY_VERSION >= 22
940c7485fdSBram Moolenaar # define rb_gc_writebarrier_unprotect rb_gc_writebarrier_unprotect_stub
950c7485fdSBram Moolenaar # endif
96a1a118b1SBram Moolenaar
97dace9f78SBram Moolenaar # if RUBY_VERSION >= 26
98f62fc316SBram Moolenaar # define rb_ary_detransient rb_ary_detransient_stub
99b09c6841SBram Moolenaar # endif
100b09c6841SBram Moolenaar
101dace9f78SBram Moolenaar # if RUBY_VERSION >= 30
102dace9f78SBram Moolenaar # define rb_check_type rb_check_type_stub
103dace9f78SBram Moolenaar # define rb_num2uint rb_num2uint_stub
104dace9f78SBram Moolenaar # define ruby_malloc_size_overflow ruby_malloc_size_overflow_stub
105dace9f78SBram Moolenaar # endif
106dace9f78SBram Moolenaar
107dace9f78SBram Moolenaar #endif // ifdef DYNAMIC_RUBY
108dace9f78SBram Moolenaar
10981ea1dfbSBram Moolenaar // On macOS pre-installed Ruby defines "SIZEOF_TIME_T" as "SIZEOF_LONG" so it
11092c098d1SBram Moolenaar // conflicts with the definition in config.h then causes a macro-redefined
11192c098d1SBram Moolenaar // warning.
11281ea1dfbSBram Moolenaar #ifdef SIZEOF_TIME_T
11381ea1dfbSBram Moolenaar # undef SIZEOF_TIME_T
11481ea1dfbSBram Moolenaar #endif
11581ea1dfbSBram Moolenaar
116071d4279SBram Moolenaar #include <ruby.h>
11741a4141eSBram Moolenaar #if RUBY_VERSION >= 19
118165641daSBram Moolenaar # include <ruby/encoding.h>
119165641daSBram Moolenaar #endif
12041a4141eSBram Moolenaar #if RUBY_VERSION <= 18
1218dc4c729SBram Moolenaar # include <st.h> // for ST_STOP and ST_CONTINUE
1228dc4c729SBram Moolenaar #endif
123071d4279SBram Moolenaar
12492c098d1SBram Moolenaar // See above.
12592c098d1SBram Moolenaar #ifdef SIZEOF_TIME_T
12692c098d1SBram Moolenaar # undef SIZEOF_TIME_T
12792c098d1SBram Moolenaar #endif
12892c098d1SBram Moolenaar
1298dc4c729SBram Moolenaar #undef off_t // ruby defines off_t as _int64, Mingw uses long
130071d4279SBram Moolenaar #undef EXTERN
131071d4279SBram Moolenaar #undef _
132071d4279SBram Moolenaar
1332ab2e860SBram Moolenaar // T_DATA defined both by Ruby and Mac header files, hack around it...
134d057301bSBram Moolenaar #if defined(MACOS_X)
135071d4279SBram Moolenaar # define __OPENTRANSPORT__
136071d4279SBram Moolenaar # define __OPENTRANSPORTPROTOCOL__
137071d4279SBram Moolenaar # define __OPENTRANSPORTPROVIDERS__
138071d4279SBram Moolenaar #endif
139071d4279SBram Moolenaar
140165641daSBram Moolenaar /*
1410d27f64fSBram Moolenaar * The TypedData_XXX macro family can be used since Ruby 1.9.2 but
1420d27f64fSBram Moolenaar * rb_data_type_t changed in 1.9.3, therefore require at least 2.0.
1430d27f64fSBram Moolenaar * The old Data_XXX macro family was deprecated on Ruby 2.2.
144f2f6d297SBram Moolenaar * Use TypedData_XXX if available.
145f2f6d297SBram Moolenaar */
14641a4141eSBram Moolenaar #if defined(TypedData_Wrap_Struct) && (RUBY_VERSION >= 20)
147f2f6d297SBram Moolenaar # define USE_TYPEDDATA 1
148f2f6d297SBram Moolenaar #endif
149f2f6d297SBram Moolenaar
150f2f6d297SBram Moolenaar /*
15184a05accSBram Moolenaar * Backward compatibility for Ruby 1.8 and earlier.
152165641daSBram Moolenaar * Ruby 1.9 does not provide STR2CSTR, instead StringValuePtr is provided.
153165641daSBram Moolenaar * Ruby 1.9 does not provide RXXX(s)->len and RXXX(s)->ptr, instead
154165641daSBram Moolenaar * RXXX_LEN(s) and RXXX_PTR(s) are provided.
155165641daSBram Moolenaar */
156165641daSBram Moolenaar #ifndef StringValuePtr
157165641daSBram Moolenaar # define StringValuePtr(s) STR2CSTR(s)
158165641daSBram Moolenaar #endif
159165641daSBram Moolenaar #ifndef RARRAY_LEN
160165641daSBram Moolenaar # define RARRAY_LEN(s) RARRAY(s)->len
161165641daSBram Moolenaar #endif
162165641daSBram Moolenaar #ifndef RARRAY_PTR
163165641daSBram Moolenaar # define RARRAY_PTR(s) RARRAY(s)->ptr
164165641daSBram Moolenaar #endif
165165641daSBram Moolenaar #ifndef RSTRING_LEN
166165641daSBram Moolenaar # define RSTRING_LEN(s) RSTRING(s)->len
167165641daSBram Moolenaar #endif
168165641daSBram Moolenaar #ifndef RSTRING_PTR
169165641daSBram Moolenaar # define RSTRING_PTR(s) RSTRING(s)->ptr
170165641daSBram Moolenaar #endif
171165641daSBram Moolenaar
1726aa2cd4bSBram Moolenaar #ifdef HAVE_DUP
1736aa2cd4bSBram Moolenaar # undef HAVE_DUP
1746aa2cd4bSBram Moolenaar #endif
1756aa2cd4bSBram Moolenaar
176071d4279SBram Moolenaar #include "vim.h"
177071d4279SBram Moolenaar #include "version.h"
178071d4279SBram Moolenaar
1797dca2ebbSBram Moolenaar #ifdef DYNAMIC_RUBY
1807dca2ebbSBram Moolenaar # if !defined(MSWIN) // must come after including vim.h, where it is defined
1817dca2ebbSBram Moolenaar # include <dlfcn.h>
1827dca2ebbSBram Moolenaar # define HINSTANCE void*
1837dca2ebbSBram Moolenaar # define RUBY_PROC void*
1847dca2ebbSBram Moolenaar # define load_dll(n) dlopen((n), RTLD_LAZY|RTLD_GLOBAL)
1857dca2ebbSBram Moolenaar # define symbol_from_dll dlsym
1867dca2ebbSBram Moolenaar # define close_dll dlclose
187*1a3e5747SMartin Tournoij # define load_dll_error dlerror
1887dca2ebbSBram Moolenaar # else
1897dca2ebbSBram Moolenaar # define RUBY_PROC FARPROC
1907dca2ebbSBram Moolenaar # define load_dll vimLoadLib
1917dca2ebbSBram Moolenaar # define symbol_from_dll GetProcAddress
1927dca2ebbSBram Moolenaar # define close_dll FreeLibrary
193*1a3e5747SMartin Tournoij # define load_dll_error GetWin32Error
1947dca2ebbSBram Moolenaar # endif
1957dca2ebbSBram Moolenaar #endif
1967dca2ebbSBram Moolenaar
197071d4279SBram Moolenaar #if defined(PROTO) && !defined(FEAT_RUBY)
1982ab2e860SBram Moolenaar // Define these to be able to generate the function prototypes.
199071d4279SBram Moolenaar # define VALUE int
200071d4279SBram Moolenaar # define RUBY_DATA_FUNC int
201071d4279SBram Moolenaar #endif
202071d4279SBram Moolenaar
203071d4279SBram Moolenaar static int ruby_initialized = 0;
20499685e6aSBram Moolenaar static void *ruby_stack_start;
205071d4279SBram Moolenaar static VALUE objtbl;
206071d4279SBram Moolenaar
207071d4279SBram Moolenaar static VALUE mVIM;
208071d4279SBram Moolenaar static VALUE cBuffer;
209071d4279SBram Moolenaar static VALUE cVimWindow;
210071d4279SBram Moolenaar static VALUE eDeletedBufferError;
211071d4279SBram Moolenaar static VALUE eDeletedWindowError;
212071d4279SBram Moolenaar
213071d4279SBram Moolenaar static int ensure_ruby_initialized(void);
214071d4279SBram Moolenaar static void error_print(int);
215071d4279SBram Moolenaar static void ruby_io_init(void);
216071d4279SBram Moolenaar static void ruby_vim_init(void);
217e99be0e6SBram Moolenaar static int ruby_convert_to_vim_value(VALUE val, typval_T *rettv);
218071d4279SBram Moolenaar
21941a4141eSBram Moolenaar #if (RUBY_VERSION >= 19) || defined(RUBY_INIT_STACK)
2203b9abb6cSBram Moolenaar # if defined(__ia64) && !defined(ruby_init_stack)
2213b9abb6cSBram Moolenaar # define ruby_init_stack(addr) ruby_init_stack((addr), rb_ia64_bsp())
2223b9abb6cSBram Moolenaar # endif
22310f3a79eSBram Moolenaar #endif
2243b9abb6cSBram Moolenaar
225071d4279SBram Moolenaar #if defined(DYNAMIC_RUBY) || defined(PROTO)
226ef26954aSBram Moolenaar # if defined(PROTO) && !defined(HINSTANCE)
2272ab2e860SBram Moolenaar # define HINSTANCE int // for generating prototypes
228071d4279SBram Moolenaar # endif
229071d4279SBram Moolenaar
230071d4279SBram Moolenaar /*
231071d4279SBram Moolenaar * Wrapper defines
232071d4279SBram Moolenaar */
2338b430b4cSBram Moolenaar // Ruby 2.7 actually expands the following symbols as macro.
2348b430b4cSBram Moolenaar # if RUBY_VERSION >= 27
2358b430b4cSBram Moolenaar # undef rb_define_global_function
2368b430b4cSBram Moolenaar # undef rb_define_method
2378b430b4cSBram Moolenaar # undef rb_define_module_function
2388b430b4cSBram Moolenaar # undef rb_define_singleton_method
2398b430b4cSBram Moolenaar # endif
2408b430b4cSBram Moolenaar
241071d4279SBram Moolenaar # define rb_assoc_new dll_rb_assoc_new
242071d4279SBram Moolenaar # define rb_cObject (*dll_rb_cObject)
2436e5ea8d2SBram Moolenaar # define rb_class_new_instance dll_rb_class_new_instance
244dace9f78SBram Moolenaar # if RUBY_VERSION < 30
245071d4279SBram Moolenaar # define rb_check_type dll_rb_check_type
246dace9f78SBram Moolenaar # endif
247f2f6d297SBram Moolenaar # ifdef USE_TYPEDDATA
248f2f6d297SBram Moolenaar # define rb_check_typeddata dll_rb_check_typeddata
2490c7485fdSBram Moolenaar # endif
250071d4279SBram Moolenaar # define rb_class_path dll_rb_class_path
251f2f6d297SBram Moolenaar # ifdef USE_TYPEDDATA
25241a4141eSBram Moolenaar # if RUBY_VERSION >= 23
253f2f6d297SBram Moolenaar # define rb_data_typed_object_wrap dll_rb_data_typed_object_wrap
254f2f6d297SBram Moolenaar # else
255f2f6d297SBram Moolenaar # define rb_data_typed_object_alloc dll_rb_data_typed_object_alloc
256f2f6d297SBram Moolenaar # endif
257f2f6d297SBram Moolenaar # else
258071d4279SBram Moolenaar # define rb_data_object_alloc dll_rb_data_object_alloc
259f2f6d297SBram Moolenaar # endif
260071d4279SBram Moolenaar # define rb_define_class_under dll_rb_define_class_under
261071d4279SBram Moolenaar # define rb_define_const dll_rb_define_const
262071d4279SBram Moolenaar # define rb_define_global_function dll_rb_define_global_function
263071d4279SBram Moolenaar # define rb_define_method dll_rb_define_method
264071d4279SBram Moolenaar # define rb_define_module dll_rb_define_module
265071d4279SBram Moolenaar # define rb_define_module_function dll_rb_define_module_function
266071d4279SBram Moolenaar # define rb_define_singleton_method dll_rb_define_singleton_method
267071d4279SBram Moolenaar # define rb_define_virtual_variable dll_rb_define_virtual_variable
268071d4279SBram Moolenaar # define rb_stdout (*dll_rb_stdout)
269b6c8cd8dSBram Moolenaar # define rb_stderr (*dll_rb_stderr)
270071d4279SBram Moolenaar # define rb_eArgError (*dll_rb_eArgError)
271071d4279SBram Moolenaar # define rb_eIndexError (*dll_rb_eIndexError)
272071d4279SBram Moolenaar # define rb_eRuntimeError (*dll_rb_eRuntimeError)
273071d4279SBram Moolenaar # define rb_eStandardError (*dll_rb_eStandardError)
274071d4279SBram Moolenaar # define rb_eval_string_protect dll_rb_eval_string_protect
27541a4141eSBram Moolenaar # if RUBY_VERSION >= 21
276f711cb2fSBram Moolenaar # define rb_funcallv dll_rb_funcallv
277f711cb2fSBram Moolenaar # else
278f711cb2fSBram Moolenaar # define rb_funcall2 dll_rb_funcall2
279f711cb2fSBram Moolenaar # endif
280071d4279SBram Moolenaar # define rb_global_variable dll_rb_global_variable
281071d4279SBram Moolenaar # define rb_hash_aset dll_rb_hash_aset
282e99be0e6SBram Moolenaar # define rb_hash_foreach dll_rb_hash_foreach
283071d4279SBram Moolenaar # define rb_hash_new dll_rb_hash_new
284071d4279SBram Moolenaar # define rb_inspect dll_rb_inspect
285071d4279SBram Moolenaar # define rb_int2inum dll_rb_int2inum
286218beb3eSBram Moolenaar
287218beb3eSBram Moolenaar // ruby.h may redefine rb_intern to use RUBY_CONST_ID_CACHE(), but that won't
288218beb3eSBram Moolenaar // work. Not using the cache appears to be the best solution.
289218beb3eSBram Moolenaar # undef rb_intern
290f711cb2fSBram Moolenaar # define rb_intern dll_rb_intern
291218beb3eSBram Moolenaar
2922ab2e860SBram Moolenaar # if VIM_SIZEOF_INT < VIM_SIZEOF_LONG // 64 bits only
29341a4141eSBram Moolenaar # if RUBY_VERSION <= 18
294498af70eSBram Moolenaar # define rb_fix2int dll_rb_fix2int
295498af70eSBram Moolenaar # define rb_num2int dll_rb_num2int
296498af70eSBram Moolenaar # endif
297dace9f78SBram Moolenaar # if RUBY_VERSION < 30
2982623b4f4SBram Moolenaar # define rb_num2uint dll_rb_num2uint
299b213da0bSBram Moolenaar # endif
300dace9f78SBram Moolenaar # endif
301e99be0e6SBram Moolenaar # define rb_num2dbl dll_rb_num2dbl
302071d4279SBram Moolenaar # define rb_lastline_get dll_rb_lastline_get
303071d4279SBram Moolenaar # define rb_lastline_set dll_rb_lastline_set
304d057301bSBram Moolenaar # define rb_protect dll_rb_protect
305d057301bSBram Moolenaar # define rb_load dll_rb_load
30641a4141eSBram Moolenaar # if RUBY_VERSION <= 18
307071d4279SBram Moolenaar # define rb_num2long dll_rb_num2long
3083ca71f1fSBram Moolenaar # endif
30941a4141eSBram Moolenaar # if RUBY_VERSION <= 19
310071d4279SBram Moolenaar # define rb_num2ulong dll_rb_num2ulong
311886ed691SBram Moolenaar # endif
312071d4279SBram Moolenaar # define rb_obj_alloc dll_rb_obj_alloc
313071d4279SBram Moolenaar # define rb_obj_as_string dll_rb_obj_as_string
314071d4279SBram Moolenaar # define rb_obj_id dll_rb_obj_id
315071d4279SBram Moolenaar # define rb_raise dll_rb_raise
316071d4279SBram Moolenaar # define rb_str_cat dll_rb_str_cat
317071d4279SBram Moolenaar # define rb_str_concat dll_rb_str_concat
3186aa2cd4bSBram Moolenaar # undef rb_str_new
319071d4279SBram Moolenaar # define rb_str_new dll_rb_str_new
3201d2beae1SBram Moolenaar # ifdef rb_str_new2
3212ab2e860SBram Moolenaar // Ruby may #define rb_str_new2 to use rb_str_new_cstr.
3221d2beae1SBram Moolenaar # define need_rb_str_new_cstr 1
3232ab2e860SBram Moolenaar // Ruby's headers #define rb_str_new_cstr to make use of GCC's
3242ab2e860SBram Moolenaar // __builtin_constant_p extension.
3253ca71f1fSBram Moolenaar # undef rb_str_new_cstr
3261d2beae1SBram Moolenaar # define rb_str_new_cstr dll_rb_str_new_cstr
3271d2beae1SBram Moolenaar # else
328071d4279SBram Moolenaar # define rb_str_new2 dll_rb_str_new2
329218116c1SBram Moolenaar # endif
33041a4141eSBram Moolenaar # if RUBY_VERSION >= 18
331f9b5ef8cSBram Moolenaar # define rb_string_value dll_rb_string_value
33242d57f00SBram Moolenaar # define rb_string_value_ptr dll_rb_string_value_ptr
33342d57f00SBram Moolenaar # define rb_float_new dll_rb_float_new
33442d57f00SBram Moolenaar # define rb_ary_new dll_rb_ary_new
33551e9fbf1SBram Moolenaar # ifdef rb_ary_new4
33651e9fbf1SBram Moolenaar # define RB_ARY_NEW4_MACRO 1
33751e9fbf1SBram Moolenaar # undef rb_ary_new4
33851e9fbf1SBram Moolenaar # endif
33951e9fbf1SBram Moolenaar # define rb_ary_new4 dll_rb_ary_new4
34042d57f00SBram Moolenaar # define rb_ary_push dll_rb_ary_push
34141a4141eSBram Moolenaar # if (RUBY_VERSION >= 19) || defined(RUBY_INIT_STACK)
34276a86063SBram Moolenaar # ifdef __ia64
34376a86063SBram Moolenaar # define rb_ia64_bsp dll_rb_ia64_bsp
34476a86063SBram Moolenaar # undef ruby_init_stack
34576a86063SBram Moolenaar # define ruby_init_stack(addr) dll_ruby_init_stack((addr), rb_ia64_bsp())
34676a86063SBram Moolenaar # else
34799685e6aSBram Moolenaar # define ruby_init_stack dll_ruby_init_stack
34876a86063SBram Moolenaar # endif
34910f3a79eSBram Moolenaar # endif
350f9b5ef8cSBram Moolenaar # else
351f9b5ef8cSBram Moolenaar # define rb_str2cstr dll_rb_str2cstr
35242d57f00SBram Moolenaar # endif
35341a4141eSBram Moolenaar # if RUBY_VERSION >= 19
354165641daSBram Moolenaar # define rb_errinfo dll_rb_errinfo
355165641daSBram Moolenaar # else
356071d4279SBram Moolenaar # define ruby_errinfo (*dll_ruby_errinfo)
357165641daSBram Moolenaar # endif
358071d4279SBram Moolenaar # define ruby_init dll_ruby_init
359071d4279SBram Moolenaar # define ruby_init_loadpath dll_ruby_init_loadpath
3604f97475dSBram Moolenaar # ifdef MSWIN
36141a4141eSBram Moolenaar # if RUBY_VERSION >= 19
3624f391796SBram Moolenaar # define ruby_sysinit dll_ruby_sysinit
3639d5c84a0SBram Moolenaar # else
3649d5c84a0SBram Moolenaar # define NtInitialize dll_NtInitialize
3659d5c84a0SBram Moolenaar # endif
36641a4141eSBram Moolenaar # if RUBY_VERSION >= 18
367071d4279SBram Moolenaar # define rb_w32_snprintf dll_rb_w32_snprintf
368071d4279SBram Moolenaar # endif
3693ca71f1fSBram Moolenaar # endif
370071d4279SBram Moolenaar
37141a4141eSBram Moolenaar # if RUBY_VERSION >= 19
372165641daSBram Moolenaar # define ruby_script dll_ruby_script
373165641daSBram Moolenaar # define rb_enc_find_index dll_rb_enc_find_index
374165641daSBram Moolenaar # define rb_enc_find dll_rb_enc_find
3756aa2cd4bSBram Moolenaar # undef rb_enc_str_new
376165641daSBram Moolenaar # define rb_enc_str_new dll_rb_enc_str_new
377165641daSBram Moolenaar # define rb_sprintf dll_rb_sprintf
3787a8ef14cSBram Moolenaar # define rb_require dll_rb_require
3799b1067e0SBram Moolenaar # define ruby_options dll_ruby_options
380165641daSBram Moolenaar # endif
381165641daSBram Moolenaar
382071d4279SBram Moolenaar /*
383071d4279SBram Moolenaar * Pointers for dynamic link
384071d4279SBram Moolenaar */
385071d4279SBram Moolenaar static VALUE (*dll_rb_assoc_new) (VALUE, VALUE);
386ba52cde5SBram Moolenaar VALUE *dll_rb_cFalseClass;
387ba52cde5SBram Moolenaar VALUE *dll_rb_cFixnum;
3882016ae58SBram Moolenaar # if defined(USE_RUBY_INTEGER)
38906469e97SBram Moolenaar VALUE *dll_rb_cInteger;
39006469e97SBram Moolenaar # endif
39141a4141eSBram Moolenaar # if RUBY_VERSION >= 20
392db3fbe52SBram Moolenaar VALUE *dll_rb_cFloat;
393db3fbe52SBram Moolenaar # endif
394ba52cde5SBram Moolenaar VALUE *dll_rb_cNilClass;
395071d4279SBram Moolenaar static VALUE *dll_rb_cObject;
3966e5ea8d2SBram Moolenaar VALUE *dll_rb_cString;
397ba52cde5SBram Moolenaar VALUE *dll_rb_cSymbol;
398ba52cde5SBram Moolenaar VALUE *dll_rb_cTrueClass;
3996e5ea8d2SBram Moolenaar static VALUE (*dll_rb_class_new_instance) (int,VALUE*,VALUE);
400071d4279SBram Moolenaar static void (*dll_rb_check_type) (VALUE,int);
401f2f6d297SBram Moolenaar # ifdef USE_TYPEDDATA
402f2f6d297SBram Moolenaar static void *(*dll_rb_check_typeddata) (VALUE,const rb_data_type_t *);
403f2f6d297SBram Moolenaar # endif
404071d4279SBram Moolenaar static VALUE (*dll_rb_class_path) (VALUE);
405f2f6d297SBram Moolenaar # ifdef USE_TYPEDDATA
40641a4141eSBram Moolenaar # if RUBY_VERSION >= 23
407f2f6d297SBram Moolenaar static VALUE (*dll_rb_data_typed_object_wrap) (VALUE, void*, const rb_data_type_t *);
408f2f6d297SBram Moolenaar # else
409f2f6d297SBram Moolenaar static VALUE (*dll_rb_data_typed_object_alloc) (VALUE, void*, const rb_data_type_t *);
410f2f6d297SBram Moolenaar # endif
411f2f6d297SBram Moolenaar # else
412071d4279SBram Moolenaar static VALUE (*dll_rb_data_object_alloc) (VALUE, void*, RUBY_DATA_FUNC, RUBY_DATA_FUNC);
413f2f6d297SBram Moolenaar # endif
414071d4279SBram Moolenaar static VALUE (*dll_rb_define_class_under) (VALUE, const char*, VALUE);
415071d4279SBram Moolenaar static void (*dll_rb_define_const) (VALUE,const char*,VALUE);
416071d4279SBram Moolenaar static void (*dll_rb_define_global_function) (const char*,VALUE(*)(),int);
417071d4279SBram Moolenaar static void (*dll_rb_define_method) (VALUE,const char*,VALUE(*)(),int);
418071d4279SBram Moolenaar static VALUE (*dll_rb_define_module) (const char*);
419071d4279SBram Moolenaar static void (*dll_rb_define_module_function) (VALUE,const char*,VALUE(*)(),int);
420071d4279SBram Moolenaar static void (*dll_rb_define_singleton_method) (VALUE,const char*,VALUE(*)(),int);
421071d4279SBram Moolenaar static void (*dll_rb_define_virtual_variable) (const char*,VALUE(*)(),void(*)());
422071d4279SBram Moolenaar static VALUE *dll_rb_stdout;
423b6c8cd8dSBram Moolenaar static VALUE *dll_rb_stderr;
424071d4279SBram Moolenaar static VALUE *dll_rb_eArgError;
425071d4279SBram Moolenaar static VALUE *dll_rb_eIndexError;
426071d4279SBram Moolenaar static VALUE *dll_rb_eRuntimeError;
427071d4279SBram Moolenaar static VALUE *dll_rb_eStandardError;
428071d4279SBram Moolenaar static VALUE (*dll_rb_eval_string_protect) (const char*, int*);
42941a4141eSBram Moolenaar # if RUBY_VERSION >= 21
430f711cb2fSBram Moolenaar static VALUE (*dll_rb_funcallv) (VALUE, ID, int, const VALUE*);
431f711cb2fSBram Moolenaar # else
432f711cb2fSBram Moolenaar static VALUE (*dll_rb_funcall2) (VALUE, ID, int, const VALUE*);
433f711cb2fSBram Moolenaar # endif
434071d4279SBram Moolenaar static void (*dll_rb_global_variable) (VALUE*);
435071d4279SBram Moolenaar static VALUE (*dll_rb_hash_aset) (VALUE, VALUE, VALUE);
436e99be0e6SBram Moolenaar static VALUE (*dll_rb_hash_foreach) (VALUE, int (*)(VALUE, VALUE, VALUE), VALUE);
437071d4279SBram Moolenaar static VALUE (*dll_rb_hash_new) (void);
438071d4279SBram Moolenaar static VALUE (*dll_rb_inspect) (VALUE);
439071d4279SBram Moolenaar static VALUE (*dll_rb_int2inum) (long);
440f711cb2fSBram Moolenaar static ID (*dll_rb_intern) (const char*);
4419d20daffSBram Moolenaar # if RUBY_VERSION >= 30 || VIM_SIZEOF_INT < VIM_SIZEOF_LONG
4422623b4f4SBram Moolenaar static long (*dll_rb_fix2int) (VALUE);
4432623b4f4SBram Moolenaar static long (*dll_rb_num2int) (VALUE);
4442623b4f4SBram Moolenaar static unsigned long (*dll_rb_num2uint) (VALUE);
445b213da0bSBram Moolenaar # endif
446e99be0e6SBram Moolenaar static double (*dll_rb_num2dbl) (VALUE);
447071d4279SBram Moolenaar static VALUE (*dll_rb_lastline_get) (void);
448071d4279SBram Moolenaar static void (*dll_rb_lastline_set) (VALUE);
44937badc89SBram Moolenaar static VALUE (*dll_rb_protect) (VALUE (*)(VALUE), VALUE, int*);
450d057301bSBram Moolenaar static void (*dll_rb_load) (VALUE, int);
451071d4279SBram Moolenaar static long (*dll_rb_num2long) (VALUE);
452071d4279SBram Moolenaar static unsigned long (*dll_rb_num2ulong) (VALUE);
453071d4279SBram Moolenaar static VALUE (*dll_rb_obj_alloc) (VALUE);
454071d4279SBram Moolenaar static VALUE (*dll_rb_obj_as_string) (VALUE);
455071d4279SBram Moolenaar static VALUE (*dll_rb_obj_id) (VALUE);
456071d4279SBram Moolenaar static void (*dll_rb_raise) (VALUE, const char*, ...);
45741a4141eSBram Moolenaar # if RUBY_VERSION >= 18
458f9b5ef8cSBram Moolenaar static VALUE (*dll_rb_string_value) (volatile VALUE*);
459f9b5ef8cSBram Moolenaar # else
460071d4279SBram Moolenaar static char *(*dll_rb_str2cstr) (VALUE,int*);
461f9b5ef8cSBram Moolenaar # endif
462071d4279SBram Moolenaar static VALUE (*dll_rb_str_cat) (VALUE, const char*, long);
463071d4279SBram Moolenaar static VALUE (*dll_rb_str_concat) (VALUE, VALUE);
464071d4279SBram Moolenaar static VALUE (*dll_rb_str_new) (const char*, long);
4651d2beae1SBram Moolenaar # ifdef need_rb_str_new_cstr
4662ab2e860SBram Moolenaar // Ruby may #define rb_str_new2 to use rb_str_new_cstr.
4671d2beae1SBram Moolenaar static VALUE (*dll_rb_str_new_cstr) (const char*);
4681d2beae1SBram Moolenaar # else
469071d4279SBram Moolenaar static VALUE (*dll_rb_str_new2) (const char*);
4701d2beae1SBram Moolenaar # endif
47141a4141eSBram Moolenaar # if RUBY_VERSION >= 19
472165641daSBram Moolenaar static VALUE (*dll_rb_errinfo) (void);
473165641daSBram Moolenaar # else
474071d4279SBram Moolenaar static VALUE *dll_ruby_errinfo;
475165641daSBram Moolenaar # endif
476071d4279SBram Moolenaar static void (*dll_ruby_init) (void);
477071d4279SBram Moolenaar static void (*dll_ruby_init_loadpath) (void);
4784f97475dSBram Moolenaar # ifdef MSWIN
47941a4141eSBram Moolenaar # if RUBY_VERSION >= 19
4804f391796SBram Moolenaar static void (*dll_ruby_sysinit) (int*, char***);
4819d5c84a0SBram Moolenaar # else
4829d5c84a0SBram Moolenaar static void (*dll_NtInitialize) (int*, char***);
4839d5c84a0SBram Moolenaar # endif
48441a4141eSBram Moolenaar # if RUBY_VERSION >= 18
4853ca71f1fSBram Moolenaar static int (*dll_rb_w32_snprintf)(char*, size_t, const char*, ...);
4863ca71f1fSBram Moolenaar # endif
4873ca71f1fSBram Moolenaar # endif
48841a4141eSBram Moolenaar # if RUBY_VERSION >= 18
48942d57f00SBram Moolenaar static char * (*dll_rb_string_value_ptr) (volatile VALUE*);
49042d57f00SBram Moolenaar static VALUE (*dll_rb_float_new) (double);
49142d57f00SBram Moolenaar static VALUE (*dll_rb_ary_new) (void);
49251e9fbf1SBram Moolenaar static VALUE (*dll_rb_ary_new4) (long n, const VALUE *elts);
49342d57f00SBram Moolenaar static VALUE (*dll_rb_ary_push) (VALUE, VALUE);
49441a4141eSBram Moolenaar # if RUBY_VERSION >= 26
495b09c6841SBram Moolenaar static void (*dll_rb_ary_detransient) (VALUE);
496b09c6841SBram Moolenaar # endif
49741a4141eSBram Moolenaar # if (RUBY_VERSION >= 19) || defined(RUBY_INIT_STACK)
49876a86063SBram Moolenaar # ifdef __ia64
49976a86063SBram Moolenaar static void * (*dll_rb_ia64_bsp) (void);
50076a86063SBram Moolenaar static void (*dll_ruby_init_stack)(VALUE*, void*);
50176a86063SBram Moolenaar # else
50276a86063SBram Moolenaar static void (*dll_ruby_init_stack)(VALUE*);
50376a86063SBram Moolenaar # endif
50442d57f00SBram Moolenaar # endif
50510f3a79eSBram Moolenaar # endif
50641a4141eSBram Moolenaar # if RUBY_VERSION >= 19
50742d57f00SBram Moolenaar static VALUE (*dll_rb_int2big)(SIGNED_VALUE);
50842d57f00SBram Moolenaar # endif
509071d4279SBram Moolenaar
51041a4141eSBram Moolenaar # if RUBY_VERSION >= 19
511165641daSBram Moolenaar static void (*dll_ruby_script) (const char*);
512165641daSBram Moolenaar static int (*dll_rb_enc_find_index) (const char*);
513165641daSBram Moolenaar static rb_encoding* (*dll_rb_enc_find) (const char*);
514165641daSBram Moolenaar static VALUE (*dll_rb_enc_str_new) (const char*, long, rb_encoding*);
515165641daSBram Moolenaar static VALUE (*dll_rb_sprintf) (const char*, ...);
5167a8ef14cSBram Moolenaar static VALUE (*dll_rb_require) (const char*);
517dace9f78SBram Moolenaar static void* (*dll_ruby_options)(int, char**);
518165641daSBram Moolenaar # endif
519165641daSBram Moolenaar
520a1a118b1SBram Moolenaar # if defined(USE_RGENGC) && USE_RGENGC
52141a4141eSBram Moolenaar # if RUBY_VERSION == 21
522a1a118b1SBram Moolenaar static void (*dll_rb_gc_writebarrier_unprotect_promoted)(VALUE);
5230c7485fdSBram Moolenaar # else
5240c7485fdSBram Moolenaar static void (*dll_rb_gc_writebarrier_unprotect)(VALUE obj);
5250c7485fdSBram Moolenaar # endif
526a1a118b1SBram Moolenaar # endif
527a1a118b1SBram Moolenaar
528dace9f78SBram Moolenaar # if RUBY_VERSION >= 30
5299d20daffSBram Moolenaar # ifdef _MSC_VER
5309d20daffSBram Moolenaar static void (*dll_ruby_malloc_size_overflow)(size_t, size_t);
5319d20daffSBram Moolenaar # else
532dace9f78SBram Moolenaar NORETURN(static void (*dll_ruby_malloc_size_overflow)(size_t, size_t));
533dace9f78SBram Moolenaar # endif
5349d20daffSBram Moolenaar # endif
535dace9f78SBram Moolenaar
5360e121405SBram Moolenaar # if RUBY_VERSION >= 26
5370e121405SBram Moolenaar void rb_ary_detransient_stub(VALUE x);
5380e121405SBram Moolenaar # endif
5390e121405SBram Moolenaar
540dace9f78SBram Moolenaar // Do not generate a prototype here, VALUE isn't always defined.
541dace9f78SBram Moolenaar # ifndef PROTO
542dace9f78SBram Moolenaar # if RUBY_VERSION >= 19
54341a4141eSBram Moolenaar # if RUBY_VERSION >= 22
544e99be0e6SBram Moolenaar long
rb_num2long_stub(VALUE x)545e99be0e6SBram Moolenaar rb_num2long_stub(VALUE x)
546bbc1a592SBram Moolenaar # else
547e99be0e6SBram Moolenaar SIGNED_VALUE
548e99be0e6SBram Moolenaar rb_num2long_stub(VALUE x)
549bbc1a592SBram Moolenaar # endif
55042d57f00SBram Moolenaar {
55142d57f00SBram Moolenaar return dll_rb_num2long(x);
55242d57f00SBram Moolenaar }
55341a4141eSBram Moolenaar # if RUBY_VERSION >= 26
554e99be0e6SBram Moolenaar VALUE
rb_int2big_stub(intptr_t x)555e99be0e6SBram Moolenaar rb_int2big_stub(intptr_t x)
55663d1fea8SBram Moolenaar # else
557e99be0e6SBram Moolenaar VALUE
558e99be0e6SBram Moolenaar rb_int2big_stub(SIGNED_VALUE x)
55963d1fea8SBram Moolenaar # endif
56042d57f00SBram Moolenaar {
56142d57f00SBram Moolenaar return dll_rb_int2big(x);
56242d57f00SBram Moolenaar }
5639d20daffSBram Moolenaar # if RUBY_VERSION >= 30 || VIM_SIZEOF_INT < VIM_SIZEOF_LONG
564e99be0e6SBram Moolenaar long
rb_fix2int_stub(VALUE x)565e99be0e6SBram Moolenaar rb_fix2int_stub(VALUE x)
5660bcdd6e7SBram Moolenaar {
5670bcdd6e7SBram Moolenaar return dll_rb_fix2int(x);
5680bcdd6e7SBram Moolenaar }
569e99be0e6SBram Moolenaar long
rb_num2int_stub(VALUE x)570e99be0e6SBram Moolenaar rb_num2int_stub(VALUE x)
5710bcdd6e7SBram Moolenaar {
5720bcdd6e7SBram Moolenaar return dll_rb_num2int(x);
5730bcdd6e7SBram Moolenaar }
5740bcdd6e7SBram Moolenaar # endif
57541a4141eSBram Moolenaar # if RUBY_VERSION >= 20
576886ed691SBram Moolenaar VALUE
rb_float_new_in_heap(double d)577886ed691SBram Moolenaar rb_float_new_in_heap(double d)
578886ed691SBram Moolenaar {
579886ed691SBram Moolenaar return dll_rb_float_new(d);
580886ed691SBram Moolenaar }
58141a4141eSBram Moolenaar # if RUBY_VERSION >= 22
582e99be0e6SBram Moolenaar unsigned long
rb_num2ulong(VALUE x)583e99be0e6SBram Moolenaar rb_num2ulong(VALUE x)
584bbc1a592SBram Moolenaar # else
585e99be0e6SBram Moolenaar VALUE
586e99be0e6SBram Moolenaar rb_num2ulong(VALUE x)
587bbc1a592SBram Moolenaar # endif
588886ed691SBram Moolenaar {
589886ed691SBram Moolenaar return (long)RSHIFT((SIGNED_VALUE)(x),1);
590886ed691SBram Moolenaar }
591886ed691SBram Moolenaar # endif
59242d57f00SBram Moolenaar # endif
593dace9f78SBram Moolenaar # if defined(USE_RGENGC) && USE_RGENGC
59441a4141eSBram Moolenaar # if RUBY_VERSION == 21
595e99be0e6SBram Moolenaar void
rb_gc_writebarrier_unprotect_promoted_stub(VALUE obj)596e99be0e6SBram Moolenaar rb_gc_writebarrier_unprotect_promoted_stub(VALUE obj)
597a1a118b1SBram Moolenaar {
59890140749SBram Moolenaar dll_rb_gc_writebarrier_unprotect_promoted(obj);
599a1a118b1SBram Moolenaar }
6000c7485fdSBram Moolenaar # else
601e99be0e6SBram Moolenaar void
rb_gc_writebarrier_unprotect_stub(VALUE obj)602e99be0e6SBram Moolenaar rb_gc_writebarrier_unprotect_stub(VALUE obj)
6030c7485fdSBram Moolenaar {
6040c7485fdSBram Moolenaar dll_rb_gc_writebarrier_unprotect(obj);
6050c7485fdSBram Moolenaar }
6060c7485fdSBram Moolenaar # endif
6070c7485fdSBram Moolenaar # endif
60841a4141eSBram Moolenaar # if RUBY_VERSION >= 26
609e99be0e6SBram Moolenaar void
rb_ary_detransient_stub(VALUE x)610e99be0e6SBram Moolenaar rb_ary_detransient_stub(VALUE x)
611f62fc316SBram Moolenaar {
612f62fc316SBram Moolenaar dll_rb_ary_detransient(x);
613f62fc316SBram Moolenaar }
614f62fc316SBram Moolenaar # endif
615dace9f78SBram Moolenaar # if RUBY_VERSION >= 30
616dace9f78SBram Moolenaar void
rb_check_type_stub(VALUE obj,int t)617dace9f78SBram Moolenaar rb_check_type_stub(VALUE obj, int t)
618dace9f78SBram Moolenaar {
619dace9f78SBram Moolenaar dll_rb_check_type(obj, t);
620dace9f78SBram Moolenaar }
621dace9f78SBram Moolenaar unsigned long
rb_num2uint_stub(VALUE x)622dace9f78SBram Moolenaar rb_num2uint_stub(VALUE x)
623dace9f78SBram Moolenaar {
624dace9f78SBram Moolenaar return dll_rb_num2uint(x);
625dace9f78SBram Moolenaar }
626dace9f78SBram Moolenaar void
ruby_malloc_size_overflow_stub(size_t x,size_t y)627dace9f78SBram Moolenaar ruby_malloc_size_overflow_stub(size_t x, size_t y)
628dace9f78SBram Moolenaar {
629dace9f78SBram Moolenaar dll_ruby_malloc_size_overflow(x, y);
630dace9f78SBram Moolenaar }
631dace9f78SBram Moolenaar # endif
632dace9f78SBram Moolenaar # endif // ifndef PROTO
633f62fc316SBram Moolenaar
6342ab2e860SBram Moolenaar static HINSTANCE hinstRuby = NULL; // Instance of ruby.dll
635071d4279SBram Moolenaar
636071d4279SBram Moolenaar /*
637da2303d9SBram Moolenaar * Table of name to function pointer of ruby.
638071d4279SBram Moolenaar */
639071d4279SBram Moolenaar static struct
640071d4279SBram Moolenaar {
641071d4279SBram Moolenaar char *name;
642071d4279SBram Moolenaar RUBY_PROC *ptr;
643071d4279SBram Moolenaar } ruby_funcname_table[] =
644071d4279SBram Moolenaar {
645071d4279SBram Moolenaar {"rb_assoc_new", (RUBY_PROC*)&dll_rb_assoc_new},
646071d4279SBram Moolenaar {"rb_cFalseClass", (RUBY_PROC*)&dll_rb_cFalseClass},
6472016ae58SBram Moolenaar # if defined(USE_RUBY_INTEGER)
64806469e97SBram Moolenaar {"rb_cInteger", (RUBY_PROC*)&dll_rb_cInteger},
6496abda995SBram Moolenaar # else
6506abda995SBram Moolenaar {"rb_cFixnum", (RUBY_PROC*)&dll_rb_cFixnum},
65106469e97SBram Moolenaar # endif
65241a4141eSBram Moolenaar # if RUBY_VERSION >= 20
653db3fbe52SBram Moolenaar {"rb_cFloat", (RUBY_PROC*)&dll_rb_cFloat},
654db3fbe52SBram Moolenaar # endif
655071d4279SBram Moolenaar {"rb_cNilClass", (RUBY_PROC*)&dll_rb_cNilClass},
656071d4279SBram Moolenaar {"rb_cObject", (RUBY_PROC*)&dll_rb_cObject},
6576e5ea8d2SBram Moolenaar {"rb_cString", (RUBY_PROC*)&dll_rb_cString},
658071d4279SBram Moolenaar {"rb_cSymbol", (RUBY_PROC*)&dll_rb_cSymbol},
659071d4279SBram Moolenaar {"rb_cTrueClass", (RUBY_PROC*)&dll_rb_cTrueClass},
6606e5ea8d2SBram Moolenaar {"rb_class_new_instance", (RUBY_PROC*)&dll_rb_class_new_instance},
661071d4279SBram Moolenaar {"rb_check_type", (RUBY_PROC*)&dll_rb_check_type},
662f2f6d297SBram Moolenaar # ifdef USE_TYPEDDATA
663f2f6d297SBram Moolenaar {"rb_check_typeddata", (RUBY_PROC*)&dll_rb_check_typeddata},
664f2f6d297SBram Moolenaar # endif
665071d4279SBram Moolenaar {"rb_class_path", (RUBY_PROC*)&dll_rb_class_path},
666f2f6d297SBram Moolenaar # ifdef USE_TYPEDDATA
66741a4141eSBram Moolenaar # if RUBY_VERSION >= 23
668f2f6d297SBram Moolenaar {"rb_data_typed_object_wrap", (RUBY_PROC*)&dll_rb_data_typed_object_wrap},
669f2f6d297SBram Moolenaar # else
670f2f6d297SBram Moolenaar {"rb_data_typed_object_alloc", (RUBY_PROC*)&dll_rb_data_typed_object_alloc},
671f2f6d297SBram Moolenaar # endif
672f2f6d297SBram Moolenaar # else
673071d4279SBram Moolenaar {"rb_data_object_alloc", (RUBY_PROC*)&dll_rb_data_object_alloc},
674f2f6d297SBram Moolenaar # endif
675071d4279SBram Moolenaar {"rb_define_class_under", (RUBY_PROC*)&dll_rb_define_class_under},
676071d4279SBram Moolenaar {"rb_define_const", (RUBY_PROC*)&dll_rb_define_const},
677071d4279SBram Moolenaar {"rb_define_global_function", (RUBY_PROC*)&dll_rb_define_global_function},
678071d4279SBram Moolenaar {"rb_define_method", (RUBY_PROC*)&dll_rb_define_method},
679071d4279SBram Moolenaar {"rb_define_module", (RUBY_PROC*)&dll_rb_define_module},
680071d4279SBram Moolenaar {"rb_define_module_function", (RUBY_PROC*)&dll_rb_define_module_function},
681071d4279SBram Moolenaar {"rb_define_singleton_method", (RUBY_PROC*)&dll_rb_define_singleton_method},
682071d4279SBram Moolenaar {"rb_define_virtual_variable", (RUBY_PROC*)&dll_rb_define_virtual_variable},
683071d4279SBram Moolenaar {"rb_stdout", (RUBY_PROC*)&dll_rb_stdout},
684b6c8cd8dSBram Moolenaar {"rb_stderr", (RUBY_PROC*)&dll_rb_stderr},
685071d4279SBram Moolenaar {"rb_eArgError", (RUBY_PROC*)&dll_rb_eArgError},
686071d4279SBram Moolenaar {"rb_eIndexError", (RUBY_PROC*)&dll_rb_eIndexError},
687071d4279SBram Moolenaar {"rb_eRuntimeError", (RUBY_PROC*)&dll_rb_eRuntimeError},
688071d4279SBram Moolenaar {"rb_eStandardError", (RUBY_PROC*)&dll_rb_eStandardError},
689071d4279SBram Moolenaar {"rb_eval_string_protect", (RUBY_PROC*)&dll_rb_eval_string_protect},
69041a4141eSBram Moolenaar # if RUBY_VERSION >= 21
691f711cb2fSBram Moolenaar {"rb_funcallv", (RUBY_PROC*)&dll_rb_funcallv},
692f711cb2fSBram Moolenaar # else
693f711cb2fSBram Moolenaar {"rb_funcall2", (RUBY_PROC*)&dll_rb_funcall2},
694f711cb2fSBram Moolenaar # endif
695071d4279SBram Moolenaar {"rb_global_variable", (RUBY_PROC*)&dll_rb_global_variable},
696071d4279SBram Moolenaar {"rb_hash_aset", (RUBY_PROC*)&dll_rb_hash_aset},
697e99be0e6SBram Moolenaar {"rb_hash_foreach", (RUBY_PROC*)&dll_rb_hash_foreach},
698071d4279SBram Moolenaar {"rb_hash_new", (RUBY_PROC*)&dll_rb_hash_new},
699071d4279SBram Moolenaar {"rb_inspect", (RUBY_PROC*)&dll_rb_inspect},
700071d4279SBram Moolenaar {"rb_int2inum", (RUBY_PROC*)&dll_rb_int2inum},
701f711cb2fSBram Moolenaar {"rb_intern", (RUBY_PROC*)&dll_rb_intern},
7029d20daffSBram Moolenaar # if RUBY_VERSION >= 30 || VIM_SIZEOF_INT < VIM_SIZEOF_LONG
7032623b4f4SBram Moolenaar {"rb_fix2int", (RUBY_PROC*)&dll_rb_fix2int},
7042623b4f4SBram Moolenaar {"rb_num2int", (RUBY_PROC*)&dll_rb_num2int},
7052623b4f4SBram Moolenaar {"rb_num2uint", (RUBY_PROC*)&dll_rb_num2uint},
706b213da0bSBram Moolenaar # endif
707e99be0e6SBram Moolenaar {"rb_num2dbl", (RUBY_PROC*)&dll_rb_num2dbl},
708071d4279SBram Moolenaar {"rb_lastline_get", (RUBY_PROC*)&dll_rb_lastline_get},
709071d4279SBram Moolenaar {"rb_lastline_set", (RUBY_PROC*)&dll_rb_lastline_set},
710d057301bSBram Moolenaar {"rb_protect", (RUBY_PROC*)&dll_rb_protect},
711d057301bSBram Moolenaar {"rb_load", (RUBY_PROC*)&dll_rb_load},
712071d4279SBram Moolenaar {"rb_num2long", (RUBY_PROC*)&dll_rb_num2long},
713071d4279SBram Moolenaar {"rb_num2ulong", (RUBY_PROC*)&dll_rb_num2ulong},
714071d4279SBram Moolenaar {"rb_obj_alloc", (RUBY_PROC*)&dll_rb_obj_alloc},
715071d4279SBram Moolenaar {"rb_obj_as_string", (RUBY_PROC*)&dll_rb_obj_as_string},
716071d4279SBram Moolenaar {"rb_obj_id", (RUBY_PROC*)&dll_rb_obj_id},
717071d4279SBram Moolenaar {"rb_raise", (RUBY_PROC*)&dll_rb_raise},
71841a4141eSBram Moolenaar # if RUBY_VERSION >= 18
719f9b5ef8cSBram Moolenaar {"rb_string_value", (RUBY_PROC*)&dll_rb_string_value},
720f9b5ef8cSBram Moolenaar # else
721071d4279SBram Moolenaar {"rb_str2cstr", (RUBY_PROC*)&dll_rb_str2cstr},
722f9b5ef8cSBram Moolenaar # endif
723071d4279SBram Moolenaar {"rb_str_cat", (RUBY_PROC*)&dll_rb_str_cat},
724071d4279SBram Moolenaar {"rb_str_concat", (RUBY_PROC*)&dll_rb_str_concat},
725071d4279SBram Moolenaar {"rb_str_new", (RUBY_PROC*)&dll_rb_str_new},
7261d2beae1SBram Moolenaar # ifdef need_rb_str_new_cstr
7271d2beae1SBram Moolenaar {"rb_str_new_cstr", (RUBY_PROC*)&dll_rb_str_new_cstr},
7281d2beae1SBram Moolenaar # else
729071d4279SBram Moolenaar {"rb_str_new2", (RUBY_PROC*)&dll_rb_str_new2},
7301d2beae1SBram Moolenaar # endif
73141a4141eSBram Moolenaar # if RUBY_VERSION >= 19
732165641daSBram Moolenaar {"rb_errinfo", (RUBY_PROC*)&dll_rb_errinfo},
733165641daSBram Moolenaar # else
734071d4279SBram Moolenaar {"ruby_errinfo", (RUBY_PROC*)&dll_ruby_errinfo},
735165641daSBram Moolenaar # endif
736071d4279SBram Moolenaar {"ruby_init", (RUBY_PROC*)&dll_ruby_init},
737071d4279SBram Moolenaar {"ruby_init_loadpath", (RUBY_PROC*)&dll_ruby_init_loadpath},
7384f97475dSBram Moolenaar # ifdef MSWIN
73941a4141eSBram Moolenaar # if RUBY_VERSION >= 19
7404f391796SBram Moolenaar {"ruby_sysinit", (RUBY_PROC*)&dll_ruby_sysinit},
7419d5c84a0SBram Moolenaar # else
7429d5c84a0SBram Moolenaar {"NtInitialize", (RUBY_PROC*)&dll_NtInitialize},
74342d57f00SBram Moolenaar # endif
74441a4141eSBram Moolenaar # if RUBY_VERSION >= 18
745071d4279SBram Moolenaar {"rb_w32_snprintf", (RUBY_PROC*)&dll_rb_w32_snprintf},
746071d4279SBram Moolenaar # endif
7473ca71f1fSBram Moolenaar # endif
74841a4141eSBram Moolenaar # if RUBY_VERSION >= 18
74942d57f00SBram Moolenaar {"rb_string_value_ptr", (RUBY_PROC*)&dll_rb_string_value_ptr},
75041a4141eSBram Moolenaar # if RUBY_VERSION <= 19
75142d57f00SBram Moolenaar {"rb_float_new", (RUBY_PROC*)&dll_rb_float_new},
752886ed691SBram Moolenaar # else
753886ed691SBram Moolenaar {"rb_float_new_in_heap", (RUBY_PROC*)&dll_rb_float_new},
754886ed691SBram Moolenaar # endif
75542d57f00SBram Moolenaar {"rb_ary_new", (RUBY_PROC*)&dll_rb_ary_new},
75651e9fbf1SBram Moolenaar # ifdef RB_ARY_NEW4_MACRO
75751e9fbf1SBram Moolenaar {"rb_ary_new_from_values", (RUBY_PROC*)&dll_rb_ary_new4},
75851e9fbf1SBram Moolenaar # else
75951e9fbf1SBram Moolenaar {"rb_ary_new4", (RUBY_PROC*)&dll_rb_ary_new4},
76051e9fbf1SBram Moolenaar # endif
76142d57f00SBram Moolenaar {"rb_ary_push", (RUBY_PROC*)&dll_rb_ary_push},
76241a4141eSBram Moolenaar # if RUBY_VERSION >= 26
763b09c6841SBram Moolenaar {"rb_ary_detransient", (RUBY_PROC*)&dll_rb_ary_detransient},
764b09c6841SBram Moolenaar # endif
76542d57f00SBram Moolenaar # endif
76641a4141eSBram Moolenaar # if RUBY_VERSION >= 19
76742d57f00SBram Moolenaar {"rb_int2big", (RUBY_PROC*)&dll_rb_int2big},
768165641daSBram Moolenaar {"ruby_script", (RUBY_PROC*)&dll_ruby_script},
769165641daSBram Moolenaar {"rb_enc_find_index", (RUBY_PROC*)&dll_rb_enc_find_index},
770165641daSBram Moolenaar {"rb_enc_find", (RUBY_PROC*)&dll_rb_enc_find},
771165641daSBram Moolenaar {"rb_enc_str_new", (RUBY_PROC*)&dll_rb_enc_str_new},
772165641daSBram Moolenaar {"rb_sprintf", (RUBY_PROC*)&dll_rb_sprintf},
7737a8ef14cSBram Moolenaar {"rb_require", (RUBY_PROC*)&dll_rb_require},
7749b1067e0SBram Moolenaar {"ruby_options", (RUBY_PROC*)&dll_ruby_options},
775165641daSBram Moolenaar # endif
77641a4141eSBram Moolenaar # if (RUBY_VERSION >= 19) || defined(RUBY_INIT_STACK)
77710f3a79eSBram Moolenaar # ifdef __ia64
77810f3a79eSBram Moolenaar {"rb_ia64_bsp", (RUBY_PROC*)&dll_rb_ia64_bsp},
77910f3a79eSBram Moolenaar # endif
78010f3a79eSBram Moolenaar {"ruby_init_stack", (RUBY_PROC*)&dll_ruby_init_stack},
78110f3a79eSBram Moolenaar # endif
782a1a118b1SBram Moolenaar # if defined(USE_RGENGC) && USE_RGENGC
78341a4141eSBram Moolenaar # if RUBY_VERSION == 21
784a1a118b1SBram Moolenaar {"rb_gc_writebarrier_unprotect_promoted", (RUBY_PROC*)&dll_rb_gc_writebarrier_unprotect_promoted},
7850c7485fdSBram Moolenaar # else
7860c7485fdSBram Moolenaar {"rb_gc_writebarrier_unprotect", (RUBY_PROC*)&dll_rb_gc_writebarrier_unprotect},
7870c7485fdSBram Moolenaar # endif
788a1a118b1SBram Moolenaar # endif
789dace9f78SBram Moolenaar # if RUBY_VERSION >= 30
790dace9f78SBram Moolenaar {"ruby_malloc_size_overflow", (RUBY_PROC*)&dll_ruby_malloc_size_overflow},
791dace9f78SBram Moolenaar # endif
792071d4279SBram Moolenaar {"", NULL},
793071d4279SBram Moolenaar };
794071d4279SBram Moolenaar
795071d4279SBram Moolenaar /*
796071d4279SBram Moolenaar * Load library and get all pointers.
797071d4279SBram Moolenaar * Parameter 'libname' provides name of DLL.
798071d4279SBram Moolenaar * Return OK or FAIL.
799071d4279SBram Moolenaar */
800071d4279SBram Moolenaar static int
ruby_runtime_link_init(char * libname,int verbose)801071d4279SBram Moolenaar ruby_runtime_link_init(char *libname, int verbose)
802071d4279SBram Moolenaar {
803071d4279SBram Moolenaar int i;
804071d4279SBram Moolenaar
805071d4279SBram Moolenaar if (hinstRuby)
806071d4279SBram Moolenaar return OK;
807f9b5ef8cSBram Moolenaar hinstRuby = load_dll(libname);
808071d4279SBram Moolenaar if (!hinstRuby)
809071d4279SBram Moolenaar {
810071d4279SBram Moolenaar if (verbose)
811*1a3e5747SMartin Tournoij semsg(_(e_loadlib), libname, load_dll_error());
812071d4279SBram Moolenaar return FAIL;
813071d4279SBram Moolenaar }
814071d4279SBram Moolenaar
815071d4279SBram Moolenaar for (i = 0; ruby_funcname_table[i].ptr; ++i)
816071d4279SBram Moolenaar {
817f9b5ef8cSBram Moolenaar if (!(*ruby_funcname_table[i].ptr = symbol_from_dll(hinstRuby,
818071d4279SBram Moolenaar ruby_funcname_table[i].name)))
819071d4279SBram Moolenaar {
820f9b5ef8cSBram Moolenaar close_dll(hinstRuby);
8213ca71f1fSBram Moolenaar hinstRuby = NULL;
822071d4279SBram Moolenaar if (verbose)
823f9e3e09fSBram Moolenaar semsg(_(e_loadfunc), ruby_funcname_table[i].name);
824071d4279SBram Moolenaar return FAIL;
825071d4279SBram Moolenaar }
826071d4279SBram Moolenaar }
827071d4279SBram Moolenaar return OK;
828071d4279SBram Moolenaar }
829071d4279SBram Moolenaar
830071d4279SBram Moolenaar /*
831071d4279SBram Moolenaar * If ruby is enabled (there is installed ruby on Windows system) return TRUE,
832071d4279SBram Moolenaar * else FALSE.
833071d4279SBram Moolenaar */
834071d4279SBram Moolenaar int
ruby_enabled(int verbose)83568c2f638SBram Moolenaar ruby_enabled(int verbose)
836071d4279SBram Moolenaar {
83725e4fcdeSBram Moolenaar return ruby_runtime_link_init((char *)p_rubydll, verbose) == OK;
838071d4279SBram Moolenaar }
8392ab2e860SBram Moolenaar #endif // defined(DYNAMIC_RUBY) || defined(PROTO)
840071d4279SBram Moolenaar
841071d4279SBram Moolenaar void
ruby_end(void)84268c2f638SBram Moolenaar ruby_end(void)
843071d4279SBram Moolenaar {
844071d4279SBram Moolenaar }
845071d4279SBram Moolenaar
846e99be0e6SBram Moolenaar void
ex_ruby(exarg_T * eap)847e99be0e6SBram Moolenaar ex_ruby(exarg_T *eap)
848071d4279SBram Moolenaar {
849071d4279SBram Moolenaar int state;
850071d4279SBram Moolenaar char *script = NULL;
851071d4279SBram Moolenaar
85235a2e197SBram Moolenaar script = (char *)script_get(eap, eap->arg);
853071d4279SBram Moolenaar if (!eap->skip && ensure_ruby_initialized())
854071d4279SBram Moolenaar {
855071d4279SBram Moolenaar if (script == NULL)
856071d4279SBram Moolenaar rb_eval_string_protect((char *)eap->arg, &state);
857071d4279SBram Moolenaar else
858071d4279SBram Moolenaar rb_eval_string_protect(script, &state);
859071d4279SBram Moolenaar if (state)
860071d4279SBram Moolenaar error_print(state);
861071d4279SBram Moolenaar }
862071d4279SBram Moolenaar vim_free(script);
863071d4279SBram Moolenaar }
864071d4279SBram Moolenaar
865165641daSBram Moolenaar /*
866165641daSBram Moolenaar * In Ruby 1.9 or later, ruby String object has encoding.
867165641daSBram Moolenaar * conversion buffer string of vim to ruby String object using
868165641daSBram Moolenaar * VIM encoding option.
869165641daSBram Moolenaar */
870165641daSBram Moolenaar static VALUE
vim_str2rb_enc_str(const char * s)871165641daSBram Moolenaar vim_str2rb_enc_str(const char *s)
872165641daSBram Moolenaar {
87341a4141eSBram Moolenaar #if RUBY_VERSION >= 19
874165641daSBram Moolenaar long lval;
875165641daSBram Moolenaar char_u *sval;
876165641daSBram Moolenaar rb_encoding *enc;
877165641daSBram Moolenaar
878dd1f426bSBram Moolenaar if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string)
879165641daSBram Moolenaar {
880165641daSBram Moolenaar enc = rb_enc_find((char *)sval);
881165641daSBram Moolenaar vim_free(sval);
882758535a1SBram Moolenaar if (enc)
8839b0ac229SBram Moolenaar return rb_enc_str_new(s, (long)strlen(s), enc);
884165641daSBram Moolenaar }
885165641daSBram Moolenaar #endif
886165641daSBram Moolenaar return rb_str_new2(s);
887165641daSBram Moolenaar }
888165641daSBram Moolenaar
889165641daSBram Moolenaar static VALUE
eval_enc_string_protect(const char * str,int * state)890165641daSBram Moolenaar eval_enc_string_protect(const char *str, int *state)
891165641daSBram Moolenaar {
89241a4141eSBram Moolenaar #if RUBY_VERSION >= 19
893165641daSBram Moolenaar long lval;
894165641daSBram Moolenaar char_u *sval;
895165641daSBram Moolenaar rb_encoding *enc;
896165641daSBram Moolenaar VALUE v;
897165641daSBram Moolenaar
898dd1f426bSBram Moolenaar if (get_option_value((char_u *)"enc", &lval, &sval, 0) == gov_string)
899165641daSBram Moolenaar {
900165641daSBram Moolenaar enc = rb_enc_find((char *)sval);
901165641daSBram Moolenaar vim_free(sval);
902165641daSBram Moolenaar if (enc)
903165641daSBram Moolenaar {
904165641daSBram Moolenaar v = rb_sprintf("#-*- coding:%s -*-\n%s", rb_enc_name(enc), str);
905165641daSBram Moolenaar return rb_eval_string_protect(StringValuePtr(v), state);
906165641daSBram Moolenaar }
907165641daSBram Moolenaar }
908165641daSBram Moolenaar #endif
909165641daSBram Moolenaar return rb_eval_string_protect(str, state);
910165641daSBram Moolenaar }
911165641daSBram Moolenaar
912e99be0e6SBram Moolenaar void
ex_rubydo(exarg_T * eap)913e99be0e6SBram Moolenaar ex_rubydo(exarg_T *eap)
914071d4279SBram Moolenaar {
915071d4279SBram Moolenaar int state;
916071d4279SBram Moolenaar linenr_T i;
917c593fee0SBram Moolenaar buf_T *was_curbuf = curbuf;
918071d4279SBram Moolenaar
919071d4279SBram Moolenaar if (ensure_ruby_initialized())
920071d4279SBram Moolenaar {
921071d4279SBram Moolenaar if (u_save(eap->line1 - 1, eap->line2 + 1) != OK)
922071d4279SBram Moolenaar return;
923758535a1SBram Moolenaar for (i = eap->line1; i <= eap->line2; i++)
924758535a1SBram Moolenaar {
925e980d8a9SBram Moolenaar VALUE line;
926071d4279SBram Moolenaar
927c593fee0SBram Moolenaar if (i > curbuf->b_ml.ml_line_count)
928c593fee0SBram Moolenaar break;
929e980d8a9SBram Moolenaar line = vim_str2rb_enc_str((char *)ml_get(i));
930071d4279SBram Moolenaar rb_lastline_set(line);
931165641daSBram Moolenaar eval_enc_string_protect((char *) eap->arg, &state);
932758535a1SBram Moolenaar if (state)
933758535a1SBram Moolenaar {
934071d4279SBram Moolenaar error_print(state);
935071d4279SBram Moolenaar break;
936071d4279SBram Moolenaar }
937c593fee0SBram Moolenaar if (was_curbuf != curbuf)
938c593fee0SBram Moolenaar break;
939071d4279SBram Moolenaar line = rb_lastline_get();
940758535a1SBram Moolenaar if (!NIL_P(line))
941758535a1SBram Moolenaar {
942758535a1SBram Moolenaar if (TYPE(line) != T_STRING)
943758535a1SBram Moolenaar {
944f9e3e09fSBram Moolenaar emsg(_("E265: $_ must be an instance of String"));
945071d4279SBram Moolenaar return;
946071d4279SBram Moolenaar }
947165641daSBram Moolenaar ml_replace(i, (char_u *) StringValuePtr(line), 1);
948071d4279SBram Moolenaar changed();
949071d4279SBram Moolenaar #ifdef SYNTAX_HL
9502ab2e860SBram Moolenaar syn_changed(i); // recompute syntax hl. for this line
951071d4279SBram Moolenaar #endif
952071d4279SBram Moolenaar }
953071d4279SBram Moolenaar }
954071d4279SBram Moolenaar check_cursor();
955071d4279SBram Moolenaar update_curbuf(NOT_VALID);
956071d4279SBram Moolenaar }
957071d4279SBram Moolenaar }
958071d4279SBram Moolenaar
959e99be0e6SBram Moolenaar static VALUE
rb_load_wrap(VALUE file_to_load)960e99be0e6SBram Moolenaar rb_load_wrap(VALUE file_to_load)
96137badc89SBram Moolenaar {
96237badc89SBram Moolenaar rb_load(file_to_load, 0);
96337badc89SBram Moolenaar return Qnil;
96437badc89SBram Moolenaar }
96537badc89SBram Moolenaar
966e99be0e6SBram Moolenaar void
ex_rubyfile(exarg_T * eap)967e99be0e6SBram Moolenaar ex_rubyfile(exarg_T *eap)
968071d4279SBram Moolenaar {
969071d4279SBram Moolenaar int state;
970071d4279SBram Moolenaar
971071d4279SBram Moolenaar if (ensure_ruby_initialized())
972071d4279SBram Moolenaar {
97337badc89SBram Moolenaar VALUE file_to_load = rb_str_new2((const char *)eap->arg);
97437badc89SBram Moolenaar rb_protect(rb_load_wrap, file_to_load, &state);
97537badc89SBram Moolenaar if (state)
97637badc89SBram Moolenaar error_print(state);
977071d4279SBram Moolenaar }
978071d4279SBram Moolenaar }
979071d4279SBram Moolenaar
980e99be0e6SBram Moolenaar void
ruby_buffer_free(buf_T * buf)981e99be0e6SBram Moolenaar ruby_buffer_free(buf_T *buf)
982071d4279SBram Moolenaar {
983e344beadSBram Moolenaar if (buf->b_ruby_ref)
984e344beadSBram Moolenaar {
985e344beadSBram Moolenaar rb_hash_aset(objtbl, rb_obj_id((VALUE) buf->b_ruby_ref), Qnil);
986e344beadSBram Moolenaar RDATA(buf->b_ruby_ref)->data = NULL;
987071d4279SBram Moolenaar }
988071d4279SBram Moolenaar }
989071d4279SBram Moolenaar
990e99be0e6SBram Moolenaar void
ruby_window_free(win_T * win)991e99be0e6SBram Moolenaar ruby_window_free(win_T *win)
992071d4279SBram Moolenaar {
993e344beadSBram Moolenaar if (win->w_ruby_ref)
994e344beadSBram Moolenaar {
995e344beadSBram Moolenaar rb_hash_aset(objtbl, rb_obj_id((VALUE) win->w_ruby_ref), Qnil);
996e344beadSBram Moolenaar RDATA(win->w_ruby_ref)->data = NULL;
997071d4279SBram Moolenaar }
998071d4279SBram Moolenaar }
999071d4279SBram Moolenaar
1000e99be0e6SBram Moolenaar static int
ensure_ruby_initialized(void)1001e99be0e6SBram Moolenaar ensure_ruby_initialized(void)
1002071d4279SBram Moolenaar {
1003071d4279SBram Moolenaar if (!ruby_initialized)
1004071d4279SBram Moolenaar {
1005071d4279SBram Moolenaar #ifdef DYNAMIC_RUBY
1006071d4279SBram Moolenaar if (ruby_enabled(TRUE))
1007071d4279SBram Moolenaar {
1008071d4279SBram Moolenaar #endif
10094f97475dSBram Moolenaar #ifdef MSWIN
10102ab2e860SBram Moolenaar // suggested by Ariya Mizutani
10110b69c734SBram Moolenaar int argc = 1;
10120b69c734SBram Moolenaar char *argv[] = {"gvim.exe"};
101390140749SBram Moolenaar char **argvp = argv;
101441a4141eSBram Moolenaar # if RUBY_VERSION >= 19
1015fe6ce331SBram Moolenaar ruby_sysinit(&argc, &argvp);
1016fe6ce331SBram Moolenaar # else
101790140749SBram Moolenaar NtInitialize(&argc, &argvp);
10180b69c734SBram Moolenaar # endif
1019fe6ce331SBram Moolenaar #endif
1020b2c0350cSBram Moolenaar {
102141a4141eSBram Moolenaar #if (RUBY_VERSION >= 19) || defined(RUBY_INIT_STACK)
102299685e6aSBram Moolenaar ruby_init_stack(ruby_stack_start);
1023165641daSBram Moolenaar #endif
1024071d4279SBram Moolenaar ruby_init();
1025b2c0350cSBram Moolenaar }
102641a4141eSBram Moolenaar #if RUBY_VERSION >= 19
10277a8ef14cSBram Moolenaar {
10287a8ef14cSBram Moolenaar int dummy_argc = 2;
1029d1bc96ceSBram Moolenaar char *dummy_argv[] = {"vim-ruby", "-e_=0"};
10309b1067e0SBram Moolenaar ruby_options(dummy_argc, dummy_argv);
10317a8ef14cSBram Moolenaar }
1032165641daSBram Moolenaar ruby_script("vim-ruby");
10337a8ef14cSBram Moolenaar #else
1034071d4279SBram Moolenaar ruby_init_loadpath();
1035165641daSBram Moolenaar #endif
10367a8ef14cSBram Moolenaar ruby_io_init();
1037071d4279SBram Moolenaar ruby_vim_init();
1038071d4279SBram Moolenaar ruby_initialized = 1;
1039071d4279SBram Moolenaar #ifdef DYNAMIC_RUBY
1040071d4279SBram Moolenaar }
1041071d4279SBram Moolenaar else
1042071d4279SBram Moolenaar {
1043f9e3e09fSBram Moolenaar emsg(_("E266: Sorry, this command is disabled, the Ruby library could not be loaded."));
1044071d4279SBram Moolenaar return 0;
1045071d4279SBram Moolenaar }
1046071d4279SBram Moolenaar #endif
1047071d4279SBram Moolenaar }
1048071d4279SBram Moolenaar return ruby_initialized;
1049071d4279SBram Moolenaar }
1050071d4279SBram Moolenaar
1051e99be0e6SBram Moolenaar static void
error_print(int state)1052e99be0e6SBram Moolenaar error_print(int state)
1053071d4279SBram Moolenaar {
105441a4141eSBram Moolenaar #if !defined(DYNAMIC_RUBY) && (RUBY_VERSION <= 18)
1055071d4279SBram Moolenaar RUBYEXTERN VALUE ruby_errinfo;
1056071d4279SBram Moolenaar #endif
1057f711cb2fSBram Moolenaar VALUE error;
1058071d4279SBram Moolenaar VALUE eclass;
1059071d4279SBram Moolenaar VALUE einfo;
1060f711cb2fSBram Moolenaar VALUE bt;
1061f711cb2fSBram Moolenaar int attr;
1062071d4279SBram Moolenaar char buff[BUFSIZ];
1063f711cb2fSBram Moolenaar long i;
1064071d4279SBram Moolenaar
1065071d4279SBram Moolenaar #define TAG_RETURN 0x1
1066071d4279SBram Moolenaar #define TAG_BREAK 0x2
1067071d4279SBram Moolenaar #define TAG_NEXT 0x3
1068071d4279SBram Moolenaar #define TAG_RETRY 0x4
1069071d4279SBram Moolenaar #define TAG_REDO 0x5
1070071d4279SBram Moolenaar #define TAG_RAISE 0x6
1071071d4279SBram Moolenaar #define TAG_THROW 0x7
1072071d4279SBram Moolenaar #define TAG_FATAL 0x8
1073071d4279SBram Moolenaar #define TAG_MASK 0xf
1074071d4279SBram Moolenaar
1075758535a1SBram Moolenaar switch (state)
1076758535a1SBram Moolenaar {
1077071d4279SBram Moolenaar case TAG_RETURN:
1078f9e3e09fSBram Moolenaar emsg(_("E267: unexpected return"));
1079071d4279SBram Moolenaar break;
1080071d4279SBram Moolenaar case TAG_NEXT:
1081f9e3e09fSBram Moolenaar emsg(_("E268: unexpected next"));
1082071d4279SBram Moolenaar break;
1083071d4279SBram Moolenaar case TAG_BREAK:
1084f9e3e09fSBram Moolenaar emsg(_("E269: unexpected break"));
1085071d4279SBram Moolenaar break;
1086071d4279SBram Moolenaar case TAG_REDO:
1087f9e3e09fSBram Moolenaar emsg(_("E270: unexpected redo"));
1088071d4279SBram Moolenaar break;
1089071d4279SBram Moolenaar case TAG_RETRY:
1090f9e3e09fSBram Moolenaar emsg(_("E271: retry outside of rescue clause"));
1091071d4279SBram Moolenaar break;
1092071d4279SBram Moolenaar case TAG_RAISE:
1093071d4279SBram Moolenaar case TAG_FATAL:
109441a4141eSBram Moolenaar #if RUBY_VERSION >= 19
1095f711cb2fSBram Moolenaar error = rb_errinfo();
1096165641daSBram Moolenaar #else
1097f711cb2fSBram Moolenaar error = ruby_errinfo;
1098165641daSBram Moolenaar #endif
1099f711cb2fSBram Moolenaar eclass = CLASS_OF(error);
1100f711cb2fSBram Moolenaar einfo = rb_obj_as_string(error);
1101758535a1SBram Moolenaar if (eclass == rb_eRuntimeError && RSTRING_LEN(einfo) == 0)
1102758535a1SBram Moolenaar {
1103f9e3e09fSBram Moolenaar emsg(_("E272: unhandled exception"));
1104071d4279SBram Moolenaar }
1105758535a1SBram Moolenaar else
1106758535a1SBram Moolenaar {
1107071d4279SBram Moolenaar VALUE epath;
1108071d4279SBram Moolenaar char *p;
1109071d4279SBram Moolenaar
1110071d4279SBram Moolenaar epath = rb_class_path(eclass);
11119c13b359SBram Moolenaar vim_snprintf(buff, BUFSIZ, "%s: %s",
1112165641daSBram Moolenaar RSTRING_PTR(epath), RSTRING_PTR(einfo));
1113071d4279SBram Moolenaar p = strchr(buff, '\n');
1114071d4279SBram Moolenaar if (p) *p = '\0';
1115f9e3e09fSBram Moolenaar emsg(buff);
1116071d4279SBram Moolenaar }
1117f711cb2fSBram Moolenaar
1118f711cb2fSBram Moolenaar attr = syn_name2attr((char_u *)"Error");
111941a4141eSBram Moolenaar #if RUBY_VERSION >= 21
1120f711cb2fSBram Moolenaar bt = rb_funcallv(error, rb_intern("backtrace"), 0, 0);
1121f711cb2fSBram Moolenaar for (i = 0; i < RARRAY_LEN(bt); i++)
112232526b3cSBram Moolenaar msg_attr(RSTRING_PTR(RARRAY_AREF(bt, i)), attr);
1123f711cb2fSBram Moolenaar #else
1124f711cb2fSBram Moolenaar bt = rb_funcall2(error, rb_intern("backtrace"), 0, 0);
1125f711cb2fSBram Moolenaar for (i = 0; i < RARRAY_LEN(bt); i++)
112632526b3cSBram Moolenaar msg_attr(RSTRING_PTR(RARRAY_PTR(bt)[i]), attr);
1127f711cb2fSBram Moolenaar #endif
1128071d4279SBram Moolenaar break;
1129071d4279SBram Moolenaar default:
11309c13b359SBram Moolenaar vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state);
1131f9e3e09fSBram Moolenaar emsg(buff);
1132071d4279SBram Moolenaar break;
1133071d4279SBram Moolenaar }
1134071d4279SBram Moolenaar }
1135071d4279SBram Moolenaar
1136e99be0e6SBram Moolenaar static VALUE
vim_message(VALUE self UNUSED,VALUE str)1137e99be0e6SBram Moolenaar vim_message(VALUE self UNUSED, VALUE str)
1138071d4279SBram Moolenaar {
1139071d4279SBram Moolenaar char *buff, *p;
1140071d4279SBram Moolenaar
1141071d4279SBram Moolenaar str = rb_obj_as_string(str);
11423f5f795fSBram Moolenaar if (RSTRING_LEN(str) > 0)
11433f5f795fSBram Moolenaar {
11442ab2e860SBram Moolenaar // Only do this when the string isn't empty, alloc(0) causes trouble.
114500ccf546SBram Moolenaar buff = ALLOCA_N(char, RSTRING_LEN(str) + 1);
1146165641daSBram Moolenaar strcpy(buff, RSTRING_PTR(str));
1147071d4279SBram Moolenaar p = strchr(buff, '\n');
1148071d4279SBram Moolenaar if (p) *p = '\0';
114932526b3cSBram Moolenaar msg(buff);
11503f5f795fSBram Moolenaar }
11513f5f795fSBram Moolenaar else
11523f5f795fSBram Moolenaar {
115332526b3cSBram Moolenaar msg("");
11543f5f795fSBram Moolenaar }
1155071d4279SBram Moolenaar return Qnil;
1156071d4279SBram Moolenaar }
1157071d4279SBram Moolenaar
1158e99be0e6SBram Moolenaar static VALUE
vim_set_option(VALUE self UNUSED,VALUE str)1159e99be0e6SBram Moolenaar vim_set_option(VALUE self UNUSED, VALUE str)
1160071d4279SBram Moolenaar {
1161165641daSBram Moolenaar do_set((char_u *)StringValuePtr(str), 0);
1162071d4279SBram Moolenaar update_screen(NOT_VALID);
1163071d4279SBram Moolenaar return Qnil;
1164071d4279SBram Moolenaar }
1165071d4279SBram Moolenaar
1166e99be0e6SBram Moolenaar static VALUE
vim_command(VALUE self UNUSED,VALUE str)1167e99be0e6SBram Moolenaar vim_command(VALUE self UNUSED, VALUE str)
1168071d4279SBram Moolenaar {
1169165641daSBram Moolenaar do_cmdline_cmd((char_u *)StringValuePtr(str));
1170071d4279SBram Moolenaar return Qnil;
1171071d4279SBram Moolenaar }
1172071d4279SBram Moolenaar
11733fac56e8SBram Moolenaar #ifdef FEAT_EVAL
1174e99be0e6SBram Moolenaar static VALUE
vim_to_ruby(typval_T * tv)1175e99be0e6SBram Moolenaar vim_to_ruby(typval_T *tv)
11763fac56e8SBram Moolenaar {
11773fac56e8SBram Moolenaar VALUE result = Qnil;
11783fac56e8SBram Moolenaar
11793fac56e8SBram Moolenaar if (tv->v_type == VAR_STRING)
11803fac56e8SBram Moolenaar {
118194127e4aSBram Moolenaar result = rb_str_new2(tv->vval.v_string == NULL
118294127e4aSBram Moolenaar ? "" : (char *)(tv->vval.v_string));
11833fac56e8SBram Moolenaar }
11843fac56e8SBram Moolenaar else if (tv->v_type == VAR_NUMBER)
11853fac56e8SBram Moolenaar {
11863fac56e8SBram Moolenaar result = INT2NUM(tv->vval.v_number);
11873fac56e8SBram Moolenaar }
11883fac56e8SBram Moolenaar # ifdef FEAT_FLOAT
11893fac56e8SBram Moolenaar else if (tv->v_type == VAR_FLOAT)
11903fac56e8SBram Moolenaar {
11913fac56e8SBram Moolenaar result = rb_float_new(tv->vval.v_float);
11923fac56e8SBram Moolenaar }
11933fac56e8SBram Moolenaar # endif
11943fac56e8SBram Moolenaar else if (tv->v_type == VAR_LIST)
11953fac56e8SBram Moolenaar {
11963fac56e8SBram Moolenaar list_T *list = tv->vval.v_list;
11973fac56e8SBram Moolenaar listitem_T *curr;
11983fac56e8SBram Moolenaar
11993fac56e8SBram Moolenaar result = rb_ary_new();
12003fac56e8SBram Moolenaar
12013fac56e8SBram Moolenaar if (list != NULL)
12023fac56e8SBram Moolenaar {
1203aeea7215SBram Moolenaar FOR_ALL_LIST_ITEMS(list, curr)
12043fac56e8SBram Moolenaar rb_ary_push(result, vim_to_ruby(&curr->li_tv));
12053fac56e8SBram Moolenaar }
12063fac56e8SBram Moolenaar }
12073fac56e8SBram Moolenaar else if (tv->v_type == VAR_DICT)
12083fac56e8SBram Moolenaar {
12093fac56e8SBram Moolenaar result = rb_hash_new();
12103fac56e8SBram Moolenaar
12113fac56e8SBram Moolenaar if (tv->vval.v_dict != NULL)
12123fac56e8SBram Moolenaar {
12133fac56e8SBram Moolenaar hashtab_T *ht = &tv->vval.v_dict->dv_hashtab;
12143fac56e8SBram Moolenaar long_u todo = ht->ht_used;
12153fac56e8SBram Moolenaar hashitem_T *hi;
12163fac56e8SBram Moolenaar dictitem_T *di;
12173fac56e8SBram Moolenaar
12183fac56e8SBram Moolenaar for (hi = ht->ht_array; todo > 0; ++hi)
12193fac56e8SBram Moolenaar {
12203fac56e8SBram Moolenaar if (!HASHITEM_EMPTY(hi))
12213fac56e8SBram Moolenaar {
12223fac56e8SBram Moolenaar --todo;
12233fac56e8SBram Moolenaar
12243fac56e8SBram Moolenaar di = dict_lookup(hi);
12253fac56e8SBram Moolenaar rb_hash_aset(result, rb_str_new2((char *)hi->hi_key),
12263fac56e8SBram Moolenaar vim_to_ruby(&di->di_tv));
12273fac56e8SBram Moolenaar }
12283fac56e8SBram Moolenaar }
12293fac56e8SBram Moolenaar }
1230520e1e41SBram Moolenaar }
12319b4a15d5SBram Moolenaar else if (tv->v_type == VAR_BOOL || tv->v_type == VAR_SPECIAL)
1232520e1e41SBram Moolenaar {
1233d84b26a0SBram Moolenaar if (tv->vval.v_number == VVAL_TRUE)
1234d84b26a0SBram Moolenaar result = Qtrue;
1235d84b26a0SBram Moolenaar else if (tv->vval.v_number == VVAL_FALSE)
1236d84b26a0SBram Moolenaar result = Qfalse;
12376e5ea8d2SBram Moolenaar }
12386e5ea8d2SBram Moolenaar else if (tv->v_type == VAR_BLOB)
12396e5ea8d2SBram Moolenaar {
12406e5ea8d2SBram Moolenaar result = rb_str_new(tv->vval.v_blob->bv_ga.ga_data,
12416e5ea8d2SBram Moolenaar tv->vval.v_blob->bv_ga.ga_len);
12426e5ea8d2SBram Moolenaar }
12432ab2e860SBram Moolenaar // else return Qnil;
12443fac56e8SBram Moolenaar
12453fac56e8SBram Moolenaar return result;
12463fac56e8SBram Moolenaar }
12473fac56e8SBram Moolenaar #endif
12483fac56e8SBram Moolenaar
1249e99be0e6SBram Moolenaar static VALUE
vim_evaluate(VALUE self UNUSED,VALUE str)1250e99be0e6SBram Moolenaar vim_evaluate(VALUE self UNUSED, VALUE str)
1251071d4279SBram Moolenaar {
1252071d4279SBram Moolenaar #ifdef FEAT_EVAL
12533fac56e8SBram Moolenaar typval_T *tv;
12543fac56e8SBram Moolenaar VALUE result;
1255071d4279SBram Moolenaar
12563fac56e8SBram Moolenaar tv = eval_expr((char_u *)StringValuePtr(str), NULL);
12573fac56e8SBram Moolenaar if (tv == NULL)
1258071d4279SBram Moolenaar return Qnil;
12593fac56e8SBram Moolenaar result = vim_to_ruby(tv);
12603fac56e8SBram Moolenaar
12613fac56e8SBram Moolenaar free_tv(tv);
12623fac56e8SBram Moolenaar
12633fac56e8SBram Moolenaar return result;
12643fac56e8SBram Moolenaar #else
12653fac56e8SBram Moolenaar return Qnil;
12663fac56e8SBram Moolenaar #endif
12673fac56e8SBram Moolenaar }
1268071d4279SBram Moolenaar
1269f2f6d297SBram Moolenaar #ifdef USE_TYPEDDATA
1270f2f6d297SBram Moolenaar static size_t buffer_dsize(const void *buf);
1271f2f6d297SBram Moolenaar
1272f2f6d297SBram Moolenaar static const rb_data_type_t buffer_type = {
1273f2f6d297SBram Moolenaar "vim_buffer",
127441a4141eSBram Moolenaar {0, 0, buffer_dsize,
127541a4141eSBram Moolenaar # if RUBY_VERSION >= 27
12768b430b4cSBram Moolenaar 0, {0}
127741a4141eSBram Moolenaar # else
127841a4141eSBram Moolenaar {0, 0}
127941a4141eSBram Moolenaar # endif
128041a4141eSBram Moolenaar },
1281f2f6d297SBram Moolenaar 0, 0,
1282f2f6d297SBram Moolenaar # ifdef RUBY_TYPED_FREE_IMMEDIATELY
1283f2f6d297SBram Moolenaar 0,
1284f2f6d297SBram Moolenaar # endif
1285f2f6d297SBram Moolenaar };
1286f2f6d297SBram Moolenaar
1287e99be0e6SBram Moolenaar static size_t
buffer_dsize(const void * buf UNUSED)1288e99be0e6SBram Moolenaar buffer_dsize(const void *buf UNUSED)
1289f2f6d297SBram Moolenaar {
1290f2f6d297SBram Moolenaar return sizeof(buf_T);
1291f2f6d297SBram Moolenaar }
1292f2f6d297SBram Moolenaar #endif
1293f2f6d297SBram Moolenaar
1294e99be0e6SBram Moolenaar static VALUE
buffer_new(buf_T * buf)1295e99be0e6SBram Moolenaar buffer_new(buf_T *buf)
1296071d4279SBram Moolenaar {
1297e344beadSBram Moolenaar if (buf->b_ruby_ref)
1298e344beadSBram Moolenaar {
1299e344beadSBram Moolenaar return (VALUE) buf->b_ruby_ref;
1300071d4279SBram Moolenaar }
1301e344beadSBram Moolenaar else
1302e344beadSBram Moolenaar {
1303f2f6d297SBram Moolenaar #ifdef USE_TYPEDDATA
1304f2f6d297SBram Moolenaar VALUE obj = TypedData_Wrap_Struct(cBuffer, &buffer_type, buf);
1305f2f6d297SBram Moolenaar #else
1306071d4279SBram Moolenaar VALUE obj = Data_Wrap_Struct(cBuffer, 0, 0, buf);
1307f2f6d297SBram Moolenaar #endif
1308e344beadSBram Moolenaar buf->b_ruby_ref = (void *) obj;
1309071d4279SBram Moolenaar rb_hash_aset(objtbl, rb_obj_id(obj), obj);
1310071d4279SBram Moolenaar return obj;
1311071d4279SBram Moolenaar }
1312071d4279SBram Moolenaar }
1313071d4279SBram Moolenaar
1314e99be0e6SBram Moolenaar static buf_T *
get_buf(VALUE obj)1315e99be0e6SBram Moolenaar get_buf(VALUE obj)
1316071d4279SBram Moolenaar {
1317071d4279SBram Moolenaar buf_T *buf;
1318071d4279SBram Moolenaar
1319f2f6d297SBram Moolenaar #ifdef USE_TYPEDDATA
1320f2f6d297SBram Moolenaar TypedData_Get_Struct(obj, buf_T, &buffer_type, buf);
1321f2f6d297SBram Moolenaar #else
1322071d4279SBram Moolenaar Data_Get_Struct(obj, buf_T, buf);
1323f2f6d297SBram Moolenaar #endif
1324071d4279SBram Moolenaar if (buf == NULL)
1325071d4279SBram Moolenaar rb_raise(eDeletedBufferError, "attempt to refer to deleted buffer");
1326071d4279SBram Moolenaar return buf;
1327071d4279SBram Moolenaar }
1328071d4279SBram Moolenaar
1329e99be0e6SBram Moolenaar static VALUE
vim_blob(VALUE self UNUSED,VALUE str)1330e99be0e6SBram Moolenaar vim_blob(VALUE self UNUSED, VALUE str)
13316e5ea8d2SBram Moolenaar {
13326e5ea8d2SBram Moolenaar VALUE result = rb_str_new("0z", 2);
13336e5ea8d2SBram Moolenaar char buf[4];
13346e5ea8d2SBram Moolenaar int i;
13356e5ea8d2SBram Moolenaar for (i = 0; i < RSTRING_LEN(str); i++)
13366e5ea8d2SBram Moolenaar {
13370d13cce3SBram Moolenaar sprintf(buf, "%02X", (unsigned char)(RSTRING_PTR(str)[i]));
1338b191be2fSBram Moolenaar rb_str_concat(result, rb_str_new2(buf));
13396e5ea8d2SBram Moolenaar }
13406e5ea8d2SBram Moolenaar return result;
13416e5ea8d2SBram Moolenaar }
13426e5ea8d2SBram Moolenaar
1343e99be0e6SBram Moolenaar static VALUE
buffer_s_current(VALUE self UNUSED)1344d5a986f4SBram Moolenaar buffer_s_current(VALUE self UNUSED)
1345071d4279SBram Moolenaar {
1346071d4279SBram Moolenaar return buffer_new(curbuf);
1347071d4279SBram Moolenaar }
1348071d4279SBram Moolenaar
1349e99be0e6SBram Moolenaar static VALUE
buffer_s_current_getter(ID id UNUSED,VALUE * x UNUSED)1350d5a986f4SBram Moolenaar buffer_s_current_getter(ID id UNUSED, VALUE *x UNUSED)
1351d5a986f4SBram Moolenaar {
1352d5a986f4SBram Moolenaar return buffer_new(curbuf);
1353d5a986f4SBram Moolenaar }
1354d5a986f4SBram Moolenaar
1355d5a986f4SBram Moolenaar static VALUE
buffer_s_count(VALUE self UNUSED)1356d5a986f4SBram Moolenaar buffer_s_count(VALUE self UNUSED)
1357071d4279SBram Moolenaar {
1358071d4279SBram Moolenaar buf_T *b;
1359071d4279SBram Moolenaar int n = 0;
1360071d4279SBram Moolenaar
136129323590SBram Moolenaar FOR_ALL_BUFFERS(b)
1362be4d506bSBram Moolenaar {
13632ab2e860SBram Moolenaar // Deleted buffers should not be counted
13642ab2e860SBram Moolenaar // SegPhault - 01/07/05
1365be4d506bSBram Moolenaar if (b->b_p_bl)
1366be4d506bSBram Moolenaar n++;
1367be4d506bSBram Moolenaar }
1368be4d506bSBram Moolenaar
1369071d4279SBram Moolenaar return INT2NUM(n);
1370071d4279SBram Moolenaar }
1371071d4279SBram Moolenaar
1372e99be0e6SBram Moolenaar static VALUE
buffer_s_aref(VALUE self UNUSED,VALUE num)1373e99be0e6SBram Moolenaar buffer_s_aref(VALUE self UNUSED, VALUE num)
1374071d4279SBram Moolenaar {
1375071d4279SBram Moolenaar buf_T *b;
1376071d4279SBram Moolenaar int n = NUM2INT(num);
1377071d4279SBram Moolenaar
137829323590SBram Moolenaar FOR_ALL_BUFFERS(b)
1379be4d506bSBram Moolenaar {
13802ab2e860SBram Moolenaar // Deleted buffers should not be counted
13812ab2e860SBram Moolenaar // SegPhault - 01/07/05
1382be4d506bSBram Moolenaar if (!b->b_p_bl)
1383be4d506bSBram Moolenaar continue;
1384be4d506bSBram Moolenaar
1385071d4279SBram Moolenaar if (n == 0)
1386071d4279SBram Moolenaar return buffer_new(b);
1387be4d506bSBram Moolenaar
1388be4d506bSBram Moolenaar n--;
1389071d4279SBram Moolenaar }
1390071d4279SBram Moolenaar return Qnil;
1391071d4279SBram Moolenaar }
1392071d4279SBram Moolenaar
1393e99be0e6SBram Moolenaar static VALUE
buffer_name(VALUE self)1394e99be0e6SBram Moolenaar buffer_name(VALUE self)
1395071d4279SBram Moolenaar {
1396071d4279SBram Moolenaar buf_T *buf = get_buf(self);
1397071d4279SBram Moolenaar
139835a2e197SBram Moolenaar return buf->b_ffname ? rb_str_new2((char *)buf->b_ffname) : Qnil;
1399071d4279SBram Moolenaar }
1400071d4279SBram Moolenaar
1401e99be0e6SBram Moolenaar static VALUE
buffer_number(VALUE self)1402e99be0e6SBram Moolenaar buffer_number(VALUE self)
1403071d4279SBram Moolenaar {
1404071d4279SBram Moolenaar buf_T *buf = get_buf(self);
1405071d4279SBram Moolenaar
1406071d4279SBram Moolenaar return INT2NUM(buf->b_fnum);
1407071d4279SBram Moolenaar }
1408071d4279SBram Moolenaar
1409e99be0e6SBram Moolenaar static VALUE
buffer_count(VALUE self)1410e99be0e6SBram Moolenaar buffer_count(VALUE self)
1411071d4279SBram Moolenaar {
1412071d4279SBram Moolenaar buf_T *buf = get_buf(self);
1413071d4279SBram Moolenaar
1414071d4279SBram Moolenaar return INT2NUM(buf->b_ml.ml_line_count);
1415071d4279SBram Moolenaar }
1416071d4279SBram Moolenaar
1417e99be0e6SBram Moolenaar static VALUE
get_buffer_line(buf_T * buf,linenr_T n)1418e99be0e6SBram Moolenaar get_buffer_line(buf_T *buf, linenr_T n)
1419071d4279SBram Moolenaar {
14203c531603SBram Moolenaar if (n <= 0 || n > buf->b_ml.ml_line_count)
1421165641daSBram Moolenaar rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
14223c531603SBram Moolenaar return vim_str2rb_enc_str((char *)ml_get_buf(buf, n, FALSE));
1423071d4279SBram Moolenaar }
1424071d4279SBram Moolenaar
1425e99be0e6SBram Moolenaar static VALUE
buffer_aref(VALUE self,VALUE num)1426e99be0e6SBram Moolenaar buffer_aref(VALUE self, VALUE num)
1427071d4279SBram Moolenaar {
1428071d4279SBram Moolenaar buf_T *buf = get_buf(self);
1429be4d506bSBram Moolenaar
1430be4d506bSBram Moolenaar if (buf != NULL)
1431be4d506bSBram Moolenaar return get_buffer_line(buf, (linenr_T)NUM2LONG(num));
14322ab2e860SBram Moolenaar return Qnil; // For stop warning
1433be4d506bSBram Moolenaar }
1434be4d506bSBram Moolenaar
1435e99be0e6SBram Moolenaar static VALUE
set_buffer_line(buf_T * buf,linenr_T n,VALUE str)1436e99be0e6SBram Moolenaar set_buffer_line(buf_T *buf, linenr_T n, VALUE str)
1437be4d506bSBram Moolenaar {
1438165641daSBram Moolenaar char *line = StringValuePtr(str);
143920ff7923SBram Moolenaar aco_save_T aco;
1440071d4279SBram Moolenaar
144120ff7923SBram Moolenaar if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL)
144220ff7923SBram Moolenaar {
14432ab2e860SBram Moolenaar // set curwin/curbuf for "buf" and save some things
144420ff7923SBram Moolenaar aucmd_prepbuf(&aco, buf);
144520ff7923SBram Moolenaar
1446758535a1SBram Moolenaar if (u_savesub(n) == OK)
1447758535a1SBram Moolenaar {
1448071d4279SBram Moolenaar ml_replace(n, (char_u *)line, TRUE);
1449071d4279SBram Moolenaar changed();
1450071d4279SBram Moolenaar #ifdef SYNTAX_HL
14512ab2e860SBram Moolenaar syn_changed(n); // recompute syntax hl. for this line
1452071d4279SBram Moolenaar #endif
1453071d4279SBram Moolenaar }
145420ff7923SBram Moolenaar
14552ab2e860SBram Moolenaar // restore curwin/curbuf and a few other things
145620ff7923SBram Moolenaar aucmd_restbuf(&aco);
14572ab2e860SBram Moolenaar // Careful: autocommands may have made "buf" invalid!
1458f30e74c1SBram Moolenaar
1459071d4279SBram Moolenaar update_curbuf(NOT_VALID);
1460071d4279SBram Moolenaar }
146120ff7923SBram Moolenaar else
146220ff7923SBram Moolenaar {
1463165641daSBram Moolenaar rb_raise(rb_eIndexError, "line number %ld out of range", (long)n);
1464071d4279SBram Moolenaar }
1465071d4279SBram Moolenaar return str;
1466071d4279SBram Moolenaar }
1467071d4279SBram Moolenaar
1468e99be0e6SBram Moolenaar static VALUE
buffer_aset(VALUE self,VALUE num,VALUE str)1469e99be0e6SBram Moolenaar buffer_aset(VALUE self, VALUE num, VALUE str)
1470be4d506bSBram Moolenaar {
1471be4d506bSBram Moolenaar buf_T *buf = get_buf(self);
1472be4d506bSBram Moolenaar
1473be4d506bSBram Moolenaar if (buf != NULL)
1474be4d506bSBram Moolenaar return set_buffer_line(buf, (linenr_T)NUM2LONG(num), str);
1475be4d506bSBram Moolenaar return str;
1476be4d506bSBram Moolenaar }
1477be4d506bSBram Moolenaar
1478e99be0e6SBram Moolenaar static VALUE
buffer_delete(VALUE self,VALUE num)1479e99be0e6SBram Moolenaar buffer_delete(VALUE self, VALUE num)
1480071d4279SBram Moolenaar {
1481071d4279SBram Moolenaar buf_T *buf = get_buf(self);
1482071d4279SBram Moolenaar long n = NUM2LONG(num);
148320ff7923SBram Moolenaar aco_save_T aco;
1484071d4279SBram Moolenaar
148520ff7923SBram Moolenaar if (n > 0 && n <= buf->b_ml.ml_line_count)
148620ff7923SBram Moolenaar {
14872ab2e860SBram Moolenaar // set curwin/curbuf for "buf" and save some things
148820ff7923SBram Moolenaar aucmd_prepbuf(&aco, buf);
148920ff7923SBram Moolenaar
1490758535a1SBram Moolenaar if (u_savedel(n, 1) == OK)
1491758535a1SBram Moolenaar {
1492ca70c07bSBram Moolenaar ml_delete(n);
1493be4d506bSBram Moolenaar
14942ab2e860SBram Moolenaar // Changes to non-active buffers should properly refresh
14952ab2e860SBram Moolenaar // SegPhault - 01/09/05
1496be4d506bSBram Moolenaar deleted_lines_mark(n, 1L);
1497be4d506bSBram Moolenaar
1498071d4279SBram Moolenaar changed();
1499071d4279SBram Moolenaar }
150020ff7923SBram Moolenaar
15012ab2e860SBram Moolenaar // restore curwin/curbuf and a few other things
150220ff7923SBram Moolenaar aucmd_restbuf(&aco);
15032ab2e860SBram Moolenaar // Careful: autocommands may have made "buf" invalid!
1504f30e74c1SBram Moolenaar
1505071d4279SBram Moolenaar update_curbuf(NOT_VALID);
1506071d4279SBram Moolenaar }
150720ff7923SBram Moolenaar else
150820ff7923SBram Moolenaar {
1509165641daSBram Moolenaar rb_raise(rb_eIndexError, "line number %ld out of range", n);
1510071d4279SBram Moolenaar }
1511071d4279SBram Moolenaar return Qnil;
1512071d4279SBram Moolenaar }
1513071d4279SBram Moolenaar
1514e99be0e6SBram Moolenaar static VALUE
buffer_append(VALUE self,VALUE num,VALUE str)1515e99be0e6SBram Moolenaar buffer_append(VALUE self, VALUE num, VALUE str)
1516071d4279SBram Moolenaar {
1517071d4279SBram Moolenaar buf_T *buf = get_buf(self);
1518165641daSBram Moolenaar char *line = StringValuePtr(str);
1519071d4279SBram Moolenaar long n = NUM2LONG(num);
152020ff7923SBram Moolenaar aco_save_T aco;
1521071d4279SBram Moolenaar
15223c531603SBram Moolenaar if (line == NULL)
15233c531603SBram Moolenaar {
1524165641daSBram Moolenaar rb_raise(rb_eIndexError, "NULL line");
1525165641daSBram Moolenaar }
1526165641daSBram Moolenaar else if (n >= 0 && n <= buf->b_ml.ml_line_count)
152720ff7923SBram Moolenaar {
15282ab2e860SBram Moolenaar // set curwin/curbuf for "buf" and save some things
152920ff7923SBram Moolenaar aucmd_prepbuf(&aco, buf);
153020ff7923SBram Moolenaar
1531758535a1SBram Moolenaar if (u_inssub(n + 1) == OK)
1532758535a1SBram Moolenaar {
1533071d4279SBram Moolenaar ml_append(n, (char_u *) line, (colnr_T) 0, FALSE);
1534be4d506bSBram Moolenaar
15352ab2e860SBram Moolenaar // Changes to non-active buffers should properly refresh screen
15362ab2e860SBram Moolenaar // SegPhault - 12/20/04
1537be4d506bSBram Moolenaar appended_lines_mark(n, 1L);
1538be4d506bSBram Moolenaar
1539071d4279SBram Moolenaar changed();
1540071d4279SBram Moolenaar }
154120ff7923SBram Moolenaar
15422ab2e860SBram Moolenaar // restore curwin/curbuf and a few other things
154320ff7923SBram Moolenaar aucmd_restbuf(&aco);
15442ab2e860SBram Moolenaar // Careful: autocommands may have made "buf" invalid!
1545f30e74c1SBram Moolenaar
1546071d4279SBram Moolenaar update_curbuf(NOT_VALID);
1547071d4279SBram Moolenaar }
15483c531603SBram Moolenaar else
15493c531603SBram Moolenaar {
1550165641daSBram Moolenaar rb_raise(rb_eIndexError, "line number %ld out of range", n);
1551071d4279SBram Moolenaar }
1552071d4279SBram Moolenaar return str;
1553071d4279SBram Moolenaar }
1554071d4279SBram Moolenaar
1555f2f6d297SBram Moolenaar #ifdef USE_TYPEDDATA
1556f2f6d297SBram Moolenaar static size_t window_dsize(const void *buf);
1557f2f6d297SBram Moolenaar
1558f2f6d297SBram Moolenaar static const rb_data_type_t window_type = {
1559f2f6d297SBram Moolenaar "vim_window",
156041a4141eSBram Moolenaar {0, 0, window_dsize,
156141a4141eSBram Moolenaar # if RUBY_VERSION >= 27
15628b430b4cSBram Moolenaar 0, {0}
156341a4141eSBram Moolenaar # else
156441a4141eSBram Moolenaar {0, 0}
156541a4141eSBram Moolenaar # endif
156641a4141eSBram Moolenaar },
1567f2f6d297SBram Moolenaar 0, 0,
1568f2f6d297SBram Moolenaar # ifdef RUBY_TYPED_FREE_IMMEDIATELY
1569f2f6d297SBram Moolenaar 0,
1570f2f6d297SBram Moolenaar # endif
1571f2f6d297SBram Moolenaar };
1572f2f6d297SBram Moolenaar
1573e99be0e6SBram Moolenaar static size_t
window_dsize(const void * win UNUSED)1574e99be0e6SBram Moolenaar window_dsize(const void *win UNUSED)
1575f2f6d297SBram Moolenaar {
1576f2f6d297SBram Moolenaar return sizeof(win_T);
1577f2f6d297SBram Moolenaar }
1578f2f6d297SBram Moolenaar #endif
1579f2f6d297SBram Moolenaar
1580e99be0e6SBram Moolenaar static VALUE
window_new(win_T * win)1581e99be0e6SBram Moolenaar window_new(win_T *win)
1582071d4279SBram Moolenaar {
1583e344beadSBram Moolenaar if (win->w_ruby_ref)
1584e344beadSBram Moolenaar {
1585e344beadSBram Moolenaar return (VALUE) win->w_ruby_ref;
1586071d4279SBram Moolenaar }
1587e344beadSBram Moolenaar else
1588e344beadSBram Moolenaar {
1589f2f6d297SBram Moolenaar #ifdef USE_TYPEDDATA
1590f2f6d297SBram Moolenaar VALUE obj = TypedData_Wrap_Struct(cVimWindow, &window_type, win);
1591f2f6d297SBram Moolenaar #else
1592071d4279SBram Moolenaar VALUE obj = Data_Wrap_Struct(cVimWindow, 0, 0, win);
1593f2f6d297SBram Moolenaar #endif
1594e344beadSBram Moolenaar win->w_ruby_ref = (void *) obj;
1595071d4279SBram Moolenaar rb_hash_aset(objtbl, rb_obj_id(obj), obj);
1596071d4279SBram Moolenaar return obj;
1597071d4279SBram Moolenaar }
1598071d4279SBram Moolenaar }
1599071d4279SBram Moolenaar
1600e99be0e6SBram Moolenaar static win_T *
get_win(VALUE obj)1601e99be0e6SBram Moolenaar get_win(VALUE obj)
1602071d4279SBram Moolenaar {
1603071d4279SBram Moolenaar win_T *win;
1604071d4279SBram Moolenaar
1605f2f6d297SBram Moolenaar #ifdef USE_TYPEDDATA
1606f2f6d297SBram Moolenaar TypedData_Get_Struct(obj, win_T, &window_type, win);
1607f2f6d297SBram Moolenaar #else
1608071d4279SBram Moolenaar Data_Get_Struct(obj, win_T, win);
1609f2f6d297SBram Moolenaar #endif
1610071d4279SBram Moolenaar if (win == NULL)
1611071d4279SBram Moolenaar rb_raise(eDeletedWindowError, "attempt to refer to deleted window");
1612071d4279SBram Moolenaar return win;
1613071d4279SBram Moolenaar }
1614071d4279SBram Moolenaar
1615e99be0e6SBram Moolenaar static VALUE
window_s_current(VALUE self UNUSED)1616d5a986f4SBram Moolenaar window_s_current(VALUE self UNUSED)
1617d5a986f4SBram Moolenaar {
1618d5a986f4SBram Moolenaar return window_new(curwin);
1619d5a986f4SBram Moolenaar }
1620d5a986f4SBram Moolenaar
1621d5a986f4SBram Moolenaar static VALUE
window_s_current_getter(ID id UNUSED,VALUE * x UNUSED)1622d5a986f4SBram Moolenaar window_s_current_getter(ID id UNUSED, VALUE *x UNUSED)
1623071d4279SBram Moolenaar {
1624071d4279SBram Moolenaar return window_new(curwin);
1625071d4279SBram Moolenaar }
1626071d4279SBram Moolenaar
1627be4d506bSBram Moolenaar /*
1628be4d506bSBram Moolenaar * Added line manipulation functions
1629be4d506bSBram Moolenaar * SegPhault - 03/07/05
1630be4d506bSBram Moolenaar */
1631e99be0e6SBram Moolenaar static VALUE
line_s_current(VALUE self UNUSED)1632d5a986f4SBram Moolenaar line_s_current(VALUE self UNUSED)
1633be4d506bSBram Moolenaar {
1634be4d506bSBram Moolenaar return get_buffer_line(curbuf, curwin->w_cursor.lnum);
1635be4d506bSBram Moolenaar }
1636be4d506bSBram Moolenaar
1637e99be0e6SBram Moolenaar static VALUE
set_current_line(VALUE self UNUSED,VALUE str)1638e99be0e6SBram Moolenaar set_current_line(VALUE self UNUSED, VALUE str)
1639be4d506bSBram Moolenaar {
1640be4d506bSBram Moolenaar return set_buffer_line(curbuf, curwin->w_cursor.lnum, str);
1641be4d506bSBram Moolenaar }
1642be4d506bSBram Moolenaar
1643e99be0e6SBram Moolenaar static VALUE
current_line_number(VALUE self UNUSED)1644d5a986f4SBram Moolenaar current_line_number(VALUE self UNUSED)
1645be4d506bSBram Moolenaar {
1646be4d506bSBram Moolenaar return INT2FIX((int)curwin->w_cursor.lnum);
1647be4d506bSBram Moolenaar }
1648be4d506bSBram Moolenaar
1649e99be0e6SBram Moolenaar static VALUE
window_s_count(VALUE self UNUSED)1650d5a986f4SBram Moolenaar window_s_count(VALUE self UNUSED)
1651071d4279SBram Moolenaar {
1652071d4279SBram Moolenaar win_T *w;
1653071d4279SBram Moolenaar int n = 0;
1654071d4279SBram Moolenaar
165529323590SBram Moolenaar FOR_ALL_WINDOWS(w)
1656071d4279SBram Moolenaar n++;
1657071d4279SBram Moolenaar return INT2NUM(n);
1658071d4279SBram Moolenaar }
1659071d4279SBram Moolenaar
1660e99be0e6SBram Moolenaar static VALUE
window_s_aref(VALUE self UNUSED,VALUE num)1661e99be0e6SBram Moolenaar window_s_aref(VALUE self UNUSED, VALUE num)
1662071d4279SBram Moolenaar {
1663071d4279SBram Moolenaar win_T *w;
1664071d4279SBram Moolenaar int n = NUM2INT(num);
1665071d4279SBram Moolenaar
1666071d4279SBram Moolenaar for (w = firstwin; w != NULL; w = w->w_next, --n)
1667071d4279SBram Moolenaar if (n == 0)
1668071d4279SBram Moolenaar return window_new(w);
1669071d4279SBram Moolenaar return Qnil;
1670071d4279SBram Moolenaar }
1671071d4279SBram Moolenaar
1672e99be0e6SBram Moolenaar static VALUE
window_buffer(VALUE self)1673e99be0e6SBram Moolenaar window_buffer(VALUE self)
1674071d4279SBram Moolenaar {
1675071d4279SBram Moolenaar win_T *win = get_win(self);
1676071d4279SBram Moolenaar
1677071d4279SBram Moolenaar return buffer_new(win->w_buffer);
1678071d4279SBram Moolenaar }
1679071d4279SBram Moolenaar
1680e99be0e6SBram Moolenaar static VALUE
window_height(VALUE self)1681e99be0e6SBram Moolenaar window_height(VALUE self)
1682071d4279SBram Moolenaar {
1683071d4279SBram Moolenaar win_T *win = get_win(self);
1684071d4279SBram Moolenaar
1685071d4279SBram Moolenaar return INT2NUM(win->w_height);
1686071d4279SBram Moolenaar }
1687071d4279SBram Moolenaar
1688e99be0e6SBram Moolenaar static VALUE
window_set_height(VALUE self,VALUE height)1689e99be0e6SBram Moolenaar window_set_height(VALUE self, VALUE height)
1690071d4279SBram Moolenaar {
1691071d4279SBram Moolenaar win_T *win = get_win(self);
1692071d4279SBram Moolenaar win_T *savewin = curwin;
1693071d4279SBram Moolenaar
1694071d4279SBram Moolenaar curwin = win;
1695071d4279SBram Moolenaar win_setheight(NUM2INT(height));
1696071d4279SBram Moolenaar curwin = savewin;
1697071d4279SBram Moolenaar return height;
1698071d4279SBram Moolenaar }
1699071d4279SBram Moolenaar
1700e99be0e6SBram Moolenaar static VALUE
window_width(VALUE self UNUSED)1701e99be0e6SBram Moolenaar window_width(VALUE self UNUSED)
1702da2303d9SBram Moolenaar {
1703e745d75cSBram Moolenaar return INT2NUM(get_win(self)->w_width);
1704da2303d9SBram Moolenaar }
1705da2303d9SBram Moolenaar
1706e99be0e6SBram Moolenaar static VALUE
window_set_width(VALUE self UNUSED,VALUE width)1707e99be0e6SBram Moolenaar window_set_width(VALUE self UNUSED, VALUE width)
1708da2303d9SBram Moolenaar {
1709da2303d9SBram Moolenaar win_T *win = get_win(self);
1710da2303d9SBram Moolenaar win_T *savewin = curwin;
1711da2303d9SBram Moolenaar
1712da2303d9SBram Moolenaar curwin = win;
1713da2303d9SBram Moolenaar win_setwidth(NUM2INT(width));
1714da2303d9SBram Moolenaar curwin = savewin;
1715da2303d9SBram Moolenaar return width;
1716da2303d9SBram Moolenaar }
1717da2303d9SBram Moolenaar
1718e99be0e6SBram Moolenaar static VALUE
window_cursor(VALUE self)1719e99be0e6SBram Moolenaar window_cursor(VALUE self)
1720071d4279SBram Moolenaar {
1721071d4279SBram Moolenaar win_T *win = get_win(self);
1722071d4279SBram Moolenaar
1723071d4279SBram Moolenaar return rb_assoc_new(INT2NUM(win->w_cursor.lnum), INT2NUM(win->w_cursor.col));
1724071d4279SBram Moolenaar }
1725071d4279SBram Moolenaar
1726e99be0e6SBram Moolenaar static VALUE
window_set_cursor(VALUE self,VALUE pos)1727e99be0e6SBram Moolenaar window_set_cursor(VALUE self, VALUE pos)
1728071d4279SBram Moolenaar {
1729071d4279SBram Moolenaar VALUE lnum, col;
1730071d4279SBram Moolenaar win_T *win = get_win(self);
1731071d4279SBram Moolenaar
1732071d4279SBram Moolenaar Check_Type(pos, T_ARRAY);
1733165641daSBram Moolenaar if (RARRAY_LEN(pos) != 2)
1734071d4279SBram Moolenaar rb_raise(rb_eArgError, "array length must be 2");
1735165641daSBram Moolenaar lnum = RARRAY_PTR(pos)[0];
1736165641daSBram Moolenaar col = RARRAY_PTR(pos)[1];
1737071d4279SBram Moolenaar win->w_cursor.lnum = NUM2LONG(lnum);
1738071d4279SBram Moolenaar win->w_cursor.col = NUM2UINT(col);
173953901442SBram Moolenaar win->w_set_curswant = TRUE;
17402ab2e860SBram Moolenaar check_cursor(); // put cursor on an existing line
1741071d4279SBram Moolenaar update_screen(NOT_VALID);
1742071d4279SBram Moolenaar return Qnil;
1743071d4279SBram Moolenaar }
1744071d4279SBram Moolenaar
1745e99be0e6SBram Moolenaar static VALUE
f_nop(VALUE self UNUSED)1746e99be0e6SBram Moolenaar f_nop(VALUE self UNUSED)
174735df7d2dSBram Moolenaar {
174835df7d2dSBram Moolenaar return Qnil;
174935df7d2dSBram Moolenaar }
175035df7d2dSBram Moolenaar
1751e99be0e6SBram Moolenaar static VALUE
f_p(int argc,VALUE * argv,VALUE self UNUSED)1752e99be0e6SBram Moolenaar f_p(int argc, VALUE *argv, VALUE self UNUSED)
1753071d4279SBram Moolenaar {
1754071d4279SBram Moolenaar int i;
1755071d4279SBram Moolenaar VALUE str = rb_str_new("", 0);
175651e9fbf1SBram Moolenaar VALUE ret = Qnil;
1757071d4279SBram Moolenaar
1758758535a1SBram Moolenaar for (i = 0; i < argc; i++)
1759758535a1SBram Moolenaar {
1760071d4279SBram Moolenaar if (i > 0) rb_str_cat(str, ", ", 2);
1761071d4279SBram Moolenaar rb_str_concat(str, rb_inspect(argv[i]));
1762071d4279SBram Moolenaar }
176332526b3cSBram Moolenaar msg(RSTRING_PTR(str));
176451e9fbf1SBram Moolenaar
176551e9fbf1SBram Moolenaar if (argc == 1)
176651e9fbf1SBram Moolenaar ret = argv[0];
176751e9fbf1SBram Moolenaar else if (argc > 1)
176851e9fbf1SBram Moolenaar ret = rb_ary_new4(argc, argv);
176951e9fbf1SBram Moolenaar return ret;
1770071d4279SBram Moolenaar }
1771071d4279SBram Moolenaar
1772e99be0e6SBram Moolenaar static void
ruby_io_init(void)1773e99be0e6SBram Moolenaar ruby_io_init(void)
1774071d4279SBram Moolenaar {
1775071d4279SBram Moolenaar #ifndef DYNAMIC_RUBY
1776071d4279SBram Moolenaar RUBYEXTERN VALUE rb_stdout;
1777b6c8cd8dSBram Moolenaar RUBYEXTERN VALUE rb_stderr;
1778071d4279SBram Moolenaar #endif
1779071d4279SBram Moolenaar
1780071d4279SBram Moolenaar rb_stdout = rb_obj_alloc(rb_cObject);
1781b6c8cd8dSBram Moolenaar rb_stderr = rb_obj_alloc(rb_cObject);
1782071d4279SBram Moolenaar rb_define_singleton_method(rb_stdout, "write", vim_message, 1);
178335df7d2dSBram Moolenaar rb_define_singleton_method(rb_stdout, "flush", f_nop, 0);
1784b6c8cd8dSBram Moolenaar rb_define_singleton_method(rb_stderr, "write", vim_message, 1);
1785b6c8cd8dSBram Moolenaar rb_define_singleton_method(rb_stderr, "flush", f_nop, 0);
1786071d4279SBram Moolenaar rb_define_global_function("p", f_p, -1);
1787071d4279SBram Moolenaar }
1788071d4279SBram Moolenaar
1789e99be0e6SBram Moolenaar static void
ruby_vim_init(void)1790e99be0e6SBram Moolenaar ruby_vim_init(void)
1791071d4279SBram Moolenaar {
1792071d4279SBram Moolenaar objtbl = rb_hash_new();
1793071d4279SBram Moolenaar rb_global_variable(&objtbl);
1794071d4279SBram Moolenaar
17952ab2e860SBram Moolenaar // The Vim module used to be called "VIM", but "Vim" is better. Make an
17962ab2e860SBram Moolenaar // alias "VIM" for backwards compatibility.
1797f711faf0SBram Moolenaar mVIM = rb_define_module("Vim");
1798f711faf0SBram Moolenaar rb_define_const(rb_cObject, "VIM", mVIM);
1799071d4279SBram Moolenaar rb_define_const(mVIM, "VERSION_MAJOR", INT2NUM(VIM_VERSION_MAJOR));
1800071d4279SBram Moolenaar rb_define_const(mVIM, "VERSION_MINOR", INT2NUM(VIM_VERSION_MINOR));
1801071d4279SBram Moolenaar rb_define_const(mVIM, "VERSION_BUILD", INT2NUM(VIM_VERSION_BUILD));
1802071d4279SBram Moolenaar rb_define_const(mVIM, "VERSION_PATCHLEVEL", INT2NUM(VIM_VERSION_PATCHLEVEL));
1803071d4279SBram Moolenaar rb_define_const(mVIM, "VERSION_SHORT", rb_str_new2(VIM_VERSION_SHORT));
1804071d4279SBram Moolenaar rb_define_const(mVIM, "VERSION_MEDIUM", rb_str_new2(VIM_VERSION_MEDIUM));
1805071d4279SBram Moolenaar rb_define_const(mVIM, "VERSION_LONG", rb_str_new2(VIM_VERSION_LONG));
1806071d4279SBram Moolenaar rb_define_const(mVIM, "VERSION_LONG_DATE", rb_str_new2(VIM_VERSION_LONG_DATE));
1807071d4279SBram Moolenaar rb_define_module_function(mVIM, "message", vim_message, 1);
1808071d4279SBram Moolenaar rb_define_module_function(mVIM, "set_option", vim_set_option, 1);
1809071d4279SBram Moolenaar rb_define_module_function(mVIM, "command", vim_command, 1);
1810071d4279SBram Moolenaar rb_define_module_function(mVIM, "evaluate", vim_evaluate, 1);
18116e5ea8d2SBram Moolenaar rb_define_module_function(mVIM, "blob", vim_blob, 1);
1812071d4279SBram Moolenaar
1813071d4279SBram Moolenaar eDeletedBufferError = rb_define_class_under(mVIM, "DeletedBufferError",
1814071d4279SBram Moolenaar rb_eStandardError);
1815071d4279SBram Moolenaar eDeletedWindowError = rb_define_class_under(mVIM, "DeletedWindowError",
1816071d4279SBram Moolenaar rb_eStandardError);
1817071d4279SBram Moolenaar
1818071d4279SBram Moolenaar cBuffer = rb_define_class_under(mVIM, "Buffer", rb_cObject);
1819071d4279SBram Moolenaar rb_define_singleton_method(cBuffer, "current", buffer_s_current, 0);
1820071d4279SBram Moolenaar rb_define_singleton_method(cBuffer, "count", buffer_s_count, 0);
1821071d4279SBram Moolenaar rb_define_singleton_method(cBuffer, "[]", buffer_s_aref, 1);
1822071d4279SBram Moolenaar rb_define_method(cBuffer, "name", buffer_name, 0);
1823071d4279SBram Moolenaar rb_define_method(cBuffer, "number", buffer_number, 0);
1824071d4279SBram Moolenaar rb_define_method(cBuffer, "count", buffer_count, 0);
1825071d4279SBram Moolenaar rb_define_method(cBuffer, "length", buffer_count, 0);
1826071d4279SBram Moolenaar rb_define_method(cBuffer, "[]", buffer_aref, 1);
1827071d4279SBram Moolenaar rb_define_method(cBuffer, "[]=", buffer_aset, 2);
1828071d4279SBram Moolenaar rb_define_method(cBuffer, "delete", buffer_delete, 1);
1829071d4279SBram Moolenaar rb_define_method(cBuffer, "append", buffer_append, 2);
1830071d4279SBram Moolenaar
18312ab2e860SBram Moolenaar // Added line manipulation functions
18322ab2e860SBram Moolenaar // SegPhault - 03/07/05
1833be4d506bSBram Moolenaar rb_define_method(cBuffer, "line_number", current_line_number, 0);
1834be4d506bSBram Moolenaar rb_define_method(cBuffer, "line", line_s_current, 0);
1835be4d506bSBram Moolenaar rb_define_method(cBuffer, "line=", set_current_line, 1);
1836be4d506bSBram Moolenaar
1837be4d506bSBram Moolenaar
1838071d4279SBram Moolenaar cVimWindow = rb_define_class_under(mVIM, "Window", rb_cObject);
1839071d4279SBram Moolenaar rb_define_singleton_method(cVimWindow, "current", window_s_current, 0);
1840071d4279SBram Moolenaar rb_define_singleton_method(cVimWindow, "count", window_s_count, 0);
1841071d4279SBram Moolenaar rb_define_singleton_method(cVimWindow, "[]", window_s_aref, 1);
1842071d4279SBram Moolenaar rb_define_method(cVimWindow, "buffer", window_buffer, 0);
1843071d4279SBram Moolenaar rb_define_method(cVimWindow, "height", window_height, 0);
1844071d4279SBram Moolenaar rb_define_method(cVimWindow, "height=", window_set_height, 1);
1845da2303d9SBram Moolenaar rb_define_method(cVimWindow, "width", window_width, 0);
1846da2303d9SBram Moolenaar rb_define_method(cVimWindow, "width=", window_set_width, 1);
1847071d4279SBram Moolenaar rb_define_method(cVimWindow, "cursor", window_cursor, 0);
1848071d4279SBram Moolenaar rb_define_method(cVimWindow, "cursor=", window_set_cursor, 1);
1849071d4279SBram Moolenaar
1850d5a986f4SBram Moolenaar rb_define_virtual_variable("$curbuf", buffer_s_current_getter, 0);
1851d5a986f4SBram Moolenaar rb_define_virtual_variable("$curwin", window_s_current_getter, 0);
1852071d4279SBram Moolenaar }
185399685e6aSBram Moolenaar
1854e99be0e6SBram Moolenaar void
vim_ruby_init(void * stack_start)1855e99be0e6SBram Moolenaar vim_ruby_init(void *stack_start)
185699685e6aSBram Moolenaar {
18572ab2e860SBram Moolenaar // should get machine stack start address early in main function
185899685e6aSBram Moolenaar ruby_stack_start = stack_start;
185999685e6aSBram Moolenaar }
1860e99be0e6SBram Moolenaar
1861e99be0e6SBram Moolenaar static int
convert_hash2dict(VALUE key,VALUE val,VALUE arg)1862e99be0e6SBram Moolenaar convert_hash2dict(VALUE key, VALUE val, VALUE arg)
1863e99be0e6SBram Moolenaar {
1864e99be0e6SBram Moolenaar dict_T *d = (dict_T *)arg;
1865e99be0e6SBram Moolenaar dictitem_T *di;
1866e99be0e6SBram Moolenaar
1867dace9f78SBram Moolenaar di = dictitem_alloc((char_u *)RSTRING_PTR(rb_obj_as_string(key)));
1868e99be0e6SBram Moolenaar if (di == NULL || ruby_convert_to_vim_value(val, &di->di_tv) != OK
1869e99be0e6SBram Moolenaar || dict_add(d, di) != OK)
1870e99be0e6SBram Moolenaar {
1871e99be0e6SBram Moolenaar d->dv_hashtab.ht_error = TRUE;
1872e99be0e6SBram Moolenaar return ST_STOP;
1873e99be0e6SBram Moolenaar }
1874e99be0e6SBram Moolenaar return ST_CONTINUE;
1875e99be0e6SBram Moolenaar }
1876e99be0e6SBram Moolenaar
1877e99be0e6SBram Moolenaar static int
ruby_convert_to_vim_value(VALUE val,typval_T * rettv)1878e99be0e6SBram Moolenaar ruby_convert_to_vim_value(VALUE val, typval_T *rettv)
1879e99be0e6SBram Moolenaar {
1880e99be0e6SBram Moolenaar switch (TYPE(val))
1881e99be0e6SBram Moolenaar {
1882e99be0e6SBram Moolenaar case T_NIL:
1883e99be0e6SBram Moolenaar rettv->v_type = VAR_SPECIAL;
1884e99be0e6SBram Moolenaar rettv->vval.v_number = VVAL_NULL;
1885e99be0e6SBram Moolenaar break;
1886e99be0e6SBram Moolenaar case T_TRUE:
18879b4a15d5SBram Moolenaar rettv->v_type = VAR_BOOL;
1888e99be0e6SBram Moolenaar rettv->vval.v_number = VVAL_TRUE;
1889e99be0e6SBram Moolenaar break;
1890e99be0e6SBram Moolenaar case T_FALSE:
18919b4a15d5SBram Moolenaar rettv->v_type = VAR_BOOL;
1892e99be0e6SBram Moolenaar rettv->vval.v_number = VVAL_FALSE;
1893e99be0e6SBram Moolenaar break;
1894e99be0e6SBram Moolenaar case T_BIGNUM:
1895e99be0e6SBram Moolenaar case T_FIXNUM:
1896e99be0e6SBram Moolenaar rettv->v_type = VAR_NUMBER;
1897e99be0e6SBram Moolenaar rettv->vval.v_number = (varnumber_T)NUM2LONG(val);
1898e99be0e6SBram Moolenaar break;
1899e99be0e6SBram Moolenaar #ifdef FEAT_FLOAT
1900e99be0e6SBram Moolenaar case T_FLOAT:
1901e99be0e6SBram Moolenaar rettv->v_type = VAR_FLOAT;
1902e99be0e6SBram Moolenaar rettv->vval.v_float = (float_T)NUM2DBL(val);
1903e99be0e6SBram Moolenaar break;
1904e99be0e6SBram Moolenaar #endif
1905e99be0e6SBram Moolenaar default:
1906e99be0e6SBram Moolenaar val = rb_obj_as_string(val);
1907e99be0e6SBram Moolenaar // FALLTHROUGH
1908e99be0e6SBram Moolenaar case T_STRING:
1909e99be0e6SBram Moolenaar {
1910e99be0e6SBram Moolenaar VALUE str = (VALUE)RSTRING(val);
1911e99be0e6SBram Moolenaar
1912e99be0e6SBram Moolenaar rettv->v_type = VAR_STRING;
1913e99be0e6SBram Moolenaar rettv->vval.v_string = vim_strnsave((char_u *)RSTRING_PTR(str),
191471ccd03eSBram Moolenaar RSTRING_LEN(str));
1915e99be0e6SBram Moolenaar }
1916e99be0e6SBram Moolenaar break;
1917e99be0e6SBram Moolenaar case T_ARRAY:
1918e99be0e6SBram Moolenaar {
1919e99be0e6SBram Moolenaar list_T *l;
1920e99be0e6SBram Moolenaar long i;
1921e99be0e6SBram Moolenaar typval_T v;
1922e99be0e6SBram Moolenaar
1923e99be0e6SBram Moolenaar l = list_alloc();
1924e99be0e6SBram Moolenaar if (l == NULL)
1925e99be0e6SBram Moolenaar return FAIL;
1926e99be0e6SBram Moolenaar
1927e99be0e6SBram Moolenaar for (i = 0; i < RARRAY_LEN(val); ++i)
1928e99be0e6SBram Moolenaar {
1929e99be0e6SBram Moolenaar if (ruby_convert_to_vim_value((VALUE)RARRAY_PTR(val)[i],
1930e99be0e6SBram Moolenaar &v) != OK)
1931e99be0e6SBram Moolenaar {
1932e99be0e6SBram Moolenaar list_unref(l);
1933e99be0e6SBram Moolenaar return FAIL;
1934e99be0e6SBram Moolenaar }
1935e99be0e6SBram Moolenaar list_append_tv(l, &v);
1936e99be0e6SBram Moolenaar clear_tv(&v);
1937e99be0e6SBram Moolenaar }
1938e99be0e6SBram Moolenaar
1939e99be0e6SBram Moolenaar rettv->v_type = VAR_LIST;
1940e99be0e6SBram Moolenaar rettv->vval.v_list = l;
1941e99be0e6SBram Moolenaar ++l->lv_refcount;
1942e99be0e6SBram Moolenaar }
1943e99be0e6SBram Moolenaar break;
1944e99be0e6SBram Moolenaar case T_HASH:
1945e99be0e6SBram Moolenaar {
1946e99be0e6SBram Moolenaar dict_T *d;
1947e99be0e6SBram Moolenaar
1948e99be0e6SBram Moolenaar d = dict_alloc();
1949e99be0e6SBram Moolenaar if (d == NULL)
1950e99be0e6SBram Moolenaar return FAIL;
1951e99be0e6SBram Moolenaar
1952e99be0e6SBram Moolenaar rb_hash_foreach(val, convert_hash2dict, (VALUE)d);
1953e99be0e6SBram Moolenaar if (d->dv_hashtab.ht_error)
1954e99be0e6SBram Moolenaar {
1955e99be0e6SBram Moolenaar dict_unref(d);
1956e99be0e6SBram Moolenaar return FAIL;
1957e99be0e6SBram Moolenaar }
1958e99be0e6SBram Moolenaar
1959e99be0e6SBram Moolenaar rettv->v_type = VAR_DICT;
1960e99be0e6SBram Moolenaar rettv->vval.v_dict = d;
1961e99be0e6SBram Moolenaar ++d->dv_refcount;
1962e99be0e6SBram Moolenaar }
1963e99be0e6SBram Moolenaar break;
1964e99be0e6SBram Moolenaar }
1965e99be0e6SBram Moolenaar return OK;
1966e99be0e6SBram Moolenaar }
1967e99be0e6SBram Moolenaar
1968e99be0e6SBram Moolenaar void
do_rubyeval(char_u * str,typval_T * rettv)1969e99be0e6SBram Moolenaar do_rubyeval(char_u *str, typval_T *rettv)
1970e99be0e6SBram Moolenaar {
1971e99be0e6SBram Moolenaar int retval = FAIL;
1972e99be0e6SBram Moolenaar
1973e99be0e6SBram Moolenaar if (ensure_ruby_initialized())
1974e99be0e6SBram Moolenaar {
1975e99be0e6SBram Moolenaar int state;
1976e99be0e6SBram Moolenaar VALUE obj;
1977e99be0e6SBram Moolenaar
1978e99be0e6SBram Moolenaar obj = rb_eval_string_protect((const char *)str, &state);
1979e99be0e6SBram Moolenaar if (state)
1980e99be0e6SBram Moolenaar error_print(state);
1981e99be0e6SBram Moolenaar else
1982e99be0e6SBram Moolenaar retval = ruby_convert_to_vim_value(obj, rettv);
1983e99be0e6SBram Moolenaar }
1984e99be0e6SBram Moolenaar if (retval == FAIL)
1985e99be0e6SBram Moolenaar {
1986e99be0e6SBram Moolenaar rettv->v_type = VAR_NUMBER;
1987e99be0e6SBram Moolenaar rettv->vval.v_number = 0;
1988e99be0e6SBram Moolenaar }
1989e99be0e6SBram Moolenaar }
1990