Mercurial > vim
annotate src/if_ruby.c @ 2076:1c7a66d820e4 v7.2.360
updated for version 7.2.360
Problem: Ruby on MS-Windows: can't use sockets.
Solution: Call NtInitialize() during initialization. (Ariya Mizutani)
author | Bram Moolenaar <bram@zimbu.org> |
---|---|
date | Wed, 17 Feb 2010 15:11:50 +0100 |
parents | ae2251be41f9 |
children | d8983769c9dd |
rev | line source |
---|---|
7 | 1 /* vi:set ts=8 sts=4 sw=4: |
2 * | |
3 * VIM - Vi IMproved by Bram Moolenaar | |
779 | 4 * |
5 * Ruby interface by Shugo Maeda | |
6 * with improvements by SegPhault (Ryan Paul) | |
7 | 7 * |
8 * Do ":help uganda" in Vim to read copying and usage conditions. | |
9 * Do ":help credits" in Vim to see a list of people who contributed. | |
10 * See README.txt for an overview of the Vim source code. | |
11 */ | |
12 | |
13 #include <stdio.h> | |
14 #include <string.h> | |
15 | |
16 #ifdef _WIN32 | |
17 # if !defined(DYNAMIC_RUBY_VER) || (DYNAMIC_RUBY_VER < 18) | |
18 # define NT | |
19 # endif | |
20 # ifndef DYNAMIC_RUBY | |
21 # define IMPORT /* For static dll usage __declspec(dllimport) */ | |
22 # define RUBYEXTERN __declspec(dllimport) | |
23 # endif | |
24 #endif | |
25 #ifndef RUBYEXTERN | |
26 # define RUBYEXTERN extern | |
27 #endif | |
28 | |
29 /* | |
30 * This is tricky. In ruby.h there is (inline) function rb_class_of() | |
31 * definition. This function use these variables. But we want function to | |
32 * use dll_* variables. | |
33 */ | |
34 #ifdef DYNAMIC_RUBY | |
35 # define rb_cFalseClass (*dll_rb_cFalseClass) | |
36 # define rb_cFixnum (*dll_rb_cFixnum) | |
37 # define rb_cNilClass (*dll_rb_cNilClass) | |
38 # define rb_cSymbol (*dll_rb_cSymbol) | |
39 # define rb_cTrueClass (*dll_rb_cTrueClass) | |
40 # if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18 | |
41 /* | |
42 * On ver 1.8, all Ruby functions are exported with "__declspce(dllimport)" | |
43 * in ruby.h. But it cause trouble for these variables, because it is | |
44 * defined in this file. When defined this RUBY_EXPORT it modified to | |
45 * "extern" and be able to avoid this problem. | |
46 */ | |
47 # define RUBY_EXPORT | |
48 # endif | |
49 #endif | |
50 | |
2076
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
51 /* suggested by Ariya Mizutani */ |
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
52 #if (_MSC_VER == 1200) |
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
53 # undef _WIN32_WINNT |
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
54 #endif |
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
55 |
7 | 56 #include <ruby.h> |
57 | |
58 #undef EXTERN | |
59 #undef _ | |
60 | |
61 /* T_DATA defined both by Ruby and Mac header files, hack around it... */ | |
1233 | 62 #if defined(MACOS_X_UNIX) || defined(macintosh) |
7 | 63 # define __OPENTRANSPORT__ |
64 # define __OPENTRANSPORTPROTOCOL__ | |
65 # define __OPENTRANSPORTPROVIDERS__ | |
66 #endif | |
67 | |
68 #include "vim.h" | |
69 #include "version.h" | |
70 | |
71 #if defined(PROTO) && !defined(FEAT_RUBY) | |
72 /* Define these to be able to generate the function prototypes. */ | |
73 # define VALUE int | |
74 # define RUBY_DATA_FUNC int | |
75 #endif | |
76 | |
77 static int ruby_initialized = 0; | |
78 static VALUE objtbl; | |
79 | |
80 static VALUE mVIM; | |
81 static VALUE cBuffer; | |
82 static VALUE cVimWindow; | |
83 static VALUE eDeletedBufferError; | |
84 static VALUE eDeletedWindowError; | |
85 | |
86 static int ensure_ruby_initialized(void); | |
87 static void error_print(int); | |
88 static void ruby_io_init(void); | |
89 static void ruby_vim_init(void); | |
90 | |
91 #if defined(DYNAMIC_RUBY) || defined(PROTO) | |
92 #ifdef PROTO | |
93 # define HINSTANCE int /* for generating prototypes */ | |
94 #endif | |
95 | |
96 /* | |
97 * Wrapper defines | |
98 */ | |
99 #define rb_assoc_new dll_rb_assoc_new | |
100 #define rb_cObject (*dll_rb_cObject) | |
101 #define rb_check_type dll_rb_check_type | |
102 #define rb_class_path dll_rb_class_path | |
103 #define rb_data_object_alloc dll_rb_data_object_alloc | |
104 #define rb_define_class_under dll_rb_define_class_under | |
105 #define rb_define_const dll_rb_define_const | |
106 #define rb_define_global_function dll_rb_define_global_function | |
107 #define rb_define_method dll_rb_define_method | |
108 #define rb_define_module dll_rb_define_module | |
109 #define rb_define_module_function dll_rb_define_module_function | |
110 #define rb_define_singleton_method dll_rb_define_singleton_method | |
111 #define rb_define_virtual_variable dll_rb_define_virtual_variable | |
112 #define rb_stdout (*dll_rb_stdout) | |
113 #define rb_eArgError (*dll_rb_eArgError) | |
114 #define rb_eIndexError (*dll_rb_eIndexError) | |
115 #define rb_eRuntimeError (*dll_rb_eRuntimeError) | |
116 #define rb_eStandardError (*dll_rb_eStandardError) | |
117 #define rb_eval_string_protect dll_rb_eval_string_protect | |
118 #define rb_global_variable dll_rb_global_variable | |
119 #define rb_hash_aset dll_rb_hash_aset | |
120 #define rb_hash_new dll_rb_hash_new | |
121 #define rb_inspect dll_rb_inspect | |
122 #define rb_int2inum dll_rb_int2inum | |
123 #define rb_lastline_get dll_rb_lastline_get | |
124 #define rb_lastline_set dll_rb_lastline_set | |
125 #define rb_load_protect dll_rb_load_protect | |
126 #define rb_num2long dll_rb_num2long | |
127 #define rb_num2ulong dll_rb_num2ulong | |
128 #define rb_obj_alloc dll_rb_obj_alloc | |
129 #define rb_obj_as_string dll_rb_obj_as_string | |
130 #define rb_obj_id dll_rb_obj_id | |
131 #define rb_raise dll_rb_raise | |
132 #define rb_str2cstr dll_rb_str2cstr | |
133 #define rb_str_cat dll_rb_str_cat | |
134 #define rb_str_concat dll_rb_str_concat | |
135 #define rb_str_new dll_rb_str_new | |
136 #define rb_str_new2 dll_rb_str_new2 | |
137 #define ruby_errinfo (*dll_ruby_errinfo) | |
138 #define ruby_init dll_ruby_init | |
139 #define ruby_init_loadpath dll_ruby_init_loadpath | |
2076
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
140 #define NtInitialize dll_NtInitialize |
7 | 141 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18 |
142 # define rb_w32_snprintf dll_rb_w32_snprintf | |
143 #endif | |
144 | |
145 /* | |
146 * Pointers for dynamic link | |
147 */ | |
148 static VALUE (*dll_rb_assoc_new) (VALUE, VALUE); | |
149 static VALUE *dll_rb_cFalseClass; | |
150 static VALUE *dll_rb_cFixnum; | |
151 static VALUE *dll_rb_cNilClass; | |
152 static VALUE *dll_rb_cObject; | |
153 static VALUE *dll_rb_cSymbol; | |
154 static VALUE *dll_rb_cTrueClass; | |
155 static void (*dll_rb_check_type) (VALUE,int); | |
156 static VALUE (*dll_rb_class_path) (VALUE); | |
157 static VALUE (*dll_rb_data_object_alloc) (VALUE, void*, RUBY_DATA_FUNC, RUBY_DATA_FUNC); | |
158 static VALUE (*dll_rb_define_class_under) (VALUE, const char*, VALUE); | |
159 static void (*dll_rb_define_const) (VALUE,const char*,VALUE); | |
160 static void (*dll_rb_define_global_function) (const char*,VALUE(*)(),int); | |
161 static void (*dll_rb_define_method) (VALUE,const char*,VALUE(*)(),int); | |
162 static VALUE (*dll_rb_define_module) (const char*); | |
163 static void (*dll_rb_define_module_function) (VALUE,const char*,VALUE(*)(),int); | |
164 static void (*dll_rb_define_singleton_method) (VALUE,const char*,VALUE(*)(),int); | |
165 static void (*dll_rb_define_virtual_variable) (const char*,VALUE(*)(),void(*)()); | |
166 static VALUE *dll_rb_stdout; | |
167 static VALUE *dll_rb_eArgError; | |
168 static VALUE *dll_rb_eIndexError; | |
169 static VALUE *dll_rb_eRuntimeError; | |
170 static VALUE *dll_rb_eStandardError; | |
171 static VALUE (*dll_rb_eval_string_protect) (const char*, int*); | |
172 static void (*dll_rb_global_variable) (VALUE*); | |
173 static VALUE (*dll_rb_hash_aset) (VALUE, VALUE, VALUE); | |
174 static VALUE (*dll_rb_hash_new) (void); | |
175 static VALUE (*dll_rb_inspect) (VALUE); | |
176 static VALUE (*dll_rb_int2inum) (long); | |
177 static VALUE (*dll_rb_int2inum) (long); | |
178 static VALUE (*dll_rb_lastline_get) (void); | |
179 static void (*dll_rb_lastline_set) (VALUE); | |
180 static void (*dll_rb_load_protect) (VALUE, int, int*); | |
181 static long (*dll_rb_num2long) (VALUE); | |
182 static unsigned long (*dll_rb_num2ulong) (VALUE); | |
183 static VALUE (*dll_rb_obj_alloc) (VALUE); | |
184 static VALUE (*dll_rb_obj_as_string) (VALUE); | |
185 static VALUE (*dll_rb_obj_id) (VALUE); | |
186 static void (*dll_rb_raise) (VALUE, const char*, ...); | |
187 static char *(*dll_rb_str2cstr) (VALUE,int*); | |
188 static VALUE (*dll_rb_str_cat) (VALUE, const char*, long); | |
189 static VALUE (*dll_rb_str_concat) (VALUE, VALUE); | |
190 static VALUE (*dll_rb_str_new) (const char*, long); | |
191 static VALUE (*dll_rb_str_new2) (const char*); | |
192 static VALUE *dll_ruby_errinfo; | |
193 static void (*dll_ruby_init) (void); | |
194 static void (*dll_ruby_init_loadpath) (void); | |
2076
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
195 static void (*dll_NtInitialize) (int*, char***); |
7 | 196 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18 |
197 static int (*dll_rb_w32_snprintf)(char*, size_t, const char*, ...); | |
198 #endif | |
199 | |
200 static HINSTANCE hinstRuby = 0; /* Instance of ruby.dll */ | |
201 | |
202 /* | |
501 | 203 * Table of name to function pointer of ruby. |
7 | 204 */ |
205 #define RUBY_PROC FARPROC | |
206 static struct | |
207 { | |
208 char *name; | |
209 RUBY_PROC *ptr; | |
210 } ruby_funcname_table[] = | |
211 { | |
212 {"rb_assoc_new", (RUBY_PROC*)&dll_rb_assoc_new}, | |
213 {"rb_cFalseClass", (RUBY_PROC*)&dll_rb_cFalseClass}, | |
214 {"rb_cFixnum", (RUBY_PROC*)&dll_rb_cFixnum}, | |
215 {"rb_cNilClass", (RUBY_PROC*)&dll_rb_cNilClass}, | |
216 {"rb_cObject", (RUBY_PROC*)&dll_rb_cObject}, | |
217 {"rb_cSymbol", (RUBY_PROC*)&dll_rb_cSymbol}, | |
218 {"rb_cTrueClass", (RUBY_PROC*)&dll_rb_cTrueClass}, | |
219 {"rb_check_type", (RUBY_PROC*)&dll_rb_check_type}, | |
220 {"rb_class_path", (RUBY_PROC*)&dll_rb_class_path}, | |
221 {"rb_data_object_alloc", (RUBY_PROC*)&dll_rb_data_object_alloc}, | |
222 {"rb_define_class_under", (RUBY_PROC*)&dll_rb_define_class_under}, | |
223 {"rb_define_const", (RUBY_PROC*)&dll_rb_define_const}, | |
224 {"rb_define_global_function", (RUBY_PROC*)&dll_rb_define_global_function}, | |
225 {"rb_define_method", (RUBY_PROC*)&dll_rb_define_method}, | |
226 {"rb_define_module", (RUBY_PROC*)&dll_rb_define_module}, | |
227 {"rb_define_module_function", (RUBY_PROC*)&dll_rb_define_module_function}, | |
228 {"rb_define_singleton_method", (RUBY_PROC*)&dll_rb_define_singleton_method}, | |
229 {"rb_define_virtual_variable", (RUBY_PROC*)&dll_rb_define_virtual_variable}, | |
230 {"rb_stdout", (RUBY_PROC*)&dll_rb_stdout}, | |
231 {"rb_eArgError", (RUBY_PROC*)&dll_rb_eArgError}, | |
232 {"rb_eIndexError", (RUBY_PROC*)&dll_rb_eIndexError}, | |
233 {"rb_eRuntimeError", (RUBY_PROC*)&dll_rb_eRuntimeError}, | |
234 {"rb_eStandardError", (RUBY_PROC*)&dll_rb_eStandardError}, | |
235 {"rb_eval_string_protect", (RUBY_PROC*)&dll_rb_eval_string_protect}, | |
236 {"rb_global_variable", (RUBY_PROC*)&dll_rb_global_variable}, | |
237 {"rb_hash_aset", (RUBY_PROC*)&dll_rb_hash_aset}, | |
238 {"rb_hash_new", (RUBY_PROC*)&dll_rb_hash_new}, | |
239 {"rb_inspect", (RUBY_PROC*)&dll_rb_inspect}, | |
240 {"rb_int2inum", (RUBY_PROC*)&dll_rb_int2inum}, | |
241 {"rb_lastline_get", (RUBY_PROC*)&dll_rb_lastline_get}, | |
242 {"rb_lastline_set", (RUBY_PROC*)&dll_rb_lastline_set}, | |
243 {"rb_load_protect", (RUBY_PROC*)&dll_rb_load_protect}, | |
244 {"rb_num2long", (RUBY_PROC*)&dll_rb_num2long}, | |
245 {"rb_num2ulong", (RUBY_PROC*)&dll_rb_num2ulong}, | |
246 {"rb_obj_alloc", (RUBY_PROC*)&dll_rb_obj_alloc}, | |
247 {"rb_obj_as_string", (RUBY_PROC*)&dll_rb_obj_as_string}, | |
248 {"rb_obj_id", (RUBY_PROC*)&dll_rb_obj_id}, | |
249 {"rb_raise", (RUBY_PROC*)&dll_rb_raise}, | |
250 {"rb_str2cstr", (RUBY_PROC*)&dll_rb_str2cstr}, | |
251 {"rb_str_cat", (RUBY_PROC*)&dll_rb_str_cat}, | |
252 {"rb_str_concat", (RUBY_PROC*)&dll_rb_str_concat}, | |
253 {"rb_str_new", (RUBY_PROC*)&dll_rb_str_new}, | |
254 {"rb_str_new2", (RUBY_PROC*)&dll_rb_str_new2}, | |
255 {"ruby_errinfo", (RUBY_PROC*)&dll_ruby_errinfo}, | |
256 {"ruby_init", (RUBY_PROC*)&dll_ruby_init}, | |
257 {"ruby_init_loadpath", (RUBY_PROC*)&dll_ruby_init_loadpath}, | |
2076
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
258 {"NtInitialize", (RUBY_PROC*)&dll_NtInitialize}, |
7 | 259 #if defined(DYNAMIC_RUBY_VER) && DYNAMIC_RUBY_VER >= 18 |
260 {"rb_w32_snprintf", (RUBY_PROC*)&dll_rb_w32_snprintf}, | |
261 #endif | |
262 {"", NULL}, | |
263 }; | |
264 | |
265 /* | |
266 * Free ruby.dll | |
267 */ | |
268 static void | |
269 end_dynamic_ruby() | |
270 { | |
271 if (hinstRuby) | |
272 { | |
273 FreeLibrary(hinstRuby); | |
274 hinstRuby = 0; | |
275 } | |
276 } | |
277 | |
278 /* | |
279 * Load library and get all pointers. | |
280 * Parameter 'libname' provides name of DLL. | |
281 * Return OK or FAIL. | |
282 */ | |
283 static int | |
284 ruby_runtime_link_init(char *libname, int verbose) | |
285 { | |
286 int i; | |
287 | |
288 if (hinstRuby) | |
289 return OK; | |
290 hinstRuby = LoadLibrary(libname); | |
291 if (!hinstRuby) | |
292 { | |
293 if (verbose) | |
294 EMSG2(_(e_loadlib), libname); | |
295 return FAIL; | |
296 } | |
297 | |
298 for (i = 0; ruby_funcname_table[i].ptr; ++i) | |
299 { | |
300 if (!(*ruby_funcname_table[i].ptr = GetProcAddress(hinstRuby, | |
301 ruby_funcname_table[i].name))) | |
302 { | |
303 FreeLibrary(hinstRuby); | |
304 hinstRuby = 0; | |
305 if (verbose) | |
306 EMSG2(_(e_loadfunc), ruby_funcname_table[i].name); | |
307 return FAIL; | |
308 } | |
309 } | |
310 return OK; | |
311 } | |
312 | |
313 /* | |
314 * If ruby is enabled (there is installed ruby on Windows system) return TRUE, | |
315 * else FALSE. | |
316 */ | |
317 int | |
318 ruby_enabled(verbose) | |
319 int verbose; | |
320 { | |
321 return ruby_runtime_link_init(DYNAMIC_RUBY_DLL, verbose) == OK; | |
322 } | |
323 #endif /* defined(DYNAMIC_RUBY) || defined(PROTO) */ | |
324 | |
325 void | |
326 ruby_end() | |
327 { | |
328 #ifdef DYNAMIC_RUBY | |
329 end_dynamic_ruby(); | |
330 #endif | |
331 } | |
332 | |
333 void ex_ruby(exarg_T *eap) | |
334 { | |
335 int state; | |
336 char *script = NULL; | |
337 | |
750 | 338 script = (char *)script_get(eap, eap->arg); |
7 | 339 if (!eap->skip && ensure_ruby_initialized()) |
340 { | |
341 if (script == NULL) | |
342 rb_eval_string_protect((char *)eap->arg, &state); | |
343 else | |
344 rb_eval_string_protect(script, &state); | |
345 if (state) | |
346 error_print(state); | |
347 } | |
348 vim_free(script); | |
349 } | |
350 | |
351 void ex_rubydo(exarg_T *eap) | |
352 { | |
353 int state; | |
354 linenr_T i; | |
355 | |
356 if (ensure_ruby_initialized()) | |
357 { | |
358 if (u_save(eap->line1 - 1, eap->line2 + 1) != OK) | |
359 return; | |
360 for (i = eap->line1; i <= eap->line2; i++) { | |
361 VALUE line, oldline; | |
362 | |
750 | 363 line = oldline = rb_str_new2((char *)ml_get(i)); |
7 | 364 rb_lastline_set(line); |
365 rb_eval_string_protect((char *) eap->arg, &state); | |
366 if (state) { | |
367 error_print(state); | |
368 break; | |
369 } | |
370 line = rb_lastline_get(); | |
371 if (!NIL_P(line)) { | |
372 if (TYPE(line) != T_STRING) { | |
835 | 373 EMSG(_("E265: $_ must be an instance of String")); |
7 | 374 return; |
375 } | |
376 ml_replace(i, (char_u *) STR2CSTR(line), 1); | |
377 changed(); | |
378 #ifdef SYNTAX_HL | |
379 syn_changed(i); /* recompute syntax hl. for this line */ | |
380 #endif | |
381 } | |
382 } | |
383 check_cursor(); | |
384 update_curbuf(NOT_VALID); | |
385 } | |
386 } | |
387 | |
388 void ex_rubyfile(exarg_T *eap) | |
389 { | |
390 int state; | |
391 | |
392 if (ensure_ruby_initialized()) | |
393 { | |
394 rb_load_protect(rb_str_new2((char *) eap->arg), 0, &state); | |
395 if (state) error_print(state); | |
396 } | |
397 } | |
398 | |
399 void ruby_buffer_free(buf_T *buf) | |
400 { | |
502 | 401 if (buf->b_ruby_ref) |
402 { | |
403 rb_hash_aset(objtbl, rb_obj_id((VALUE) buf->b_ruby_ref), Qnil); | |
404 RDATA(buf->b_ruby_ref)->data = NULL; | |
7 | 405 } |
406 } | |
407 | |
408 void ruby_window_free(win_T *win) | |
409 { | |
502 | 410 if (win->w_ruby_ref) |
411 { | |
412 rb_hash_aset(objtbl, rb_obj_id((VALUE) win->w_ruby_ref), Qnil); | |
413 RDATA(win->w_ruby_ref)->data = NULL; | |
7 | 414 } |
415 } | |
416 | |
417 static int ensure_ruby_initialized(void) | |
418 { | |
419 if (!ruby_initialized) | |
420 { | |
421 #ifdef DYNAMIC_RUBY | |
422 if (ruby_enabled(TRUE)) | |
423 { | |
424 #endif | |
2076
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
425 #ifdef _WIN32 |
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
426 /* suggested by Ariya Mizutani */ |
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
427 int argc = 1; |
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
428 char *argv[] = {"gvim.exe"}; |
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
429 NtInitialize(&argc, &argv); |
1c7a66d820e4
updated for version 7.2.360
Bram Moolenaar <bram@zimbu.org>
parents:
1888
diff
changeset
|
430 #endif |
7 | 431 ruby_init(); |
432 ruby_init_loadpath(); | |
433 ruby_io_init(); | |
434 ruby_vim_init(); | |
435 ruby_initialized = 1; | |
436 #ifdef DYNAMIC_RUBY | |
437 } | |
438 else | |
439 { | |
440 EMSG(_("E266: Sorry, this command is disabled, the Ruby library could not be loaded.")); | |
441 return 0; | |
442 } | |
443 #endif | |
444 } | |
445 return ruby_initialized; | |
446 } | |
447 | |
448 static void error_print(int state) | |
449 { | |
450 #ifndef DYNAMIC_RUBY | |
451 RUBYEXTERN VALUE ruby_errinfo; | |
452 #endif | |
453 VALUE eclass; | |
454 VALUE einfo; | |
455 char buff[BUFSIZ]; | |
456 | |
457 #define TAG_RETURN 0x1 | |
458 #define TAG_BREAK 0x2 | |
459 #define TAG_NEXT 0x3 | |
460 #define TAG_RETRY 0x4 | |
461 #define TAG_REDO 0x5 | |
462 #define TAG_RAISE 0x6 | |
463 #define TAG_THROW 0x7 | |
464 #define TAG_FATAL 0x8 | |
465 #define TAG_MASK 0xf | |
466 | |
467 switch (state) { | |
468 case TAG_RETURN: | |
835 | 469 EMSG(_("E267: unexpected return")); |
7 | 470 break; |
471 case TAG_NEXT: | |
835 | 472 EMSG(_("E268: unexpected next")); |
7 | 473 break; |
474 case TAG_BREAK: | |
835 | 475 EMSG(_("E269: unexpected break")); |
7 | 476 break; |
477 case TAG_REDO: | |
835 | 478 EMSG(_("E270: unexpected redo")); |
7 | 479 break; |
480 case TAG_RETRY: | |
835 | 481 EMSG(_("E271: retry outside of rescue clause")); |
7 | 482 break; |
483 case TAG_RAISE: | |
484 case TAG_FATAL: | |
485 eclass = CLASS_OF(ruby_errinfo); | |
486 einfo = rb_obj_as_string(ruby_errinfo); | |
487 if (eclass == rb_eRuntimeError && RSTRING(einfo)->len == 0) { | |
835 | 488 EMSG(_("E272: unhandled exception")); |
7 | 489 } |
490 else { | |
491 VALUE epath; | |
492 char *p; | |
493 | |
494 epath = rb_class_path(eclass); | |
272 | 495 vim_snprintf(buff, BUFSIZ, "%s: %s", |
7 | 496 RSTRING(epath)->ptr, RSTRING(einfo)->ptr); |
497 p = strchr(buff, '\n'); | |
498 if (p) *p = '\0'; | |
499 EMSG(buff); | |
500 } | |
501 break; | |
502 default: | |
272 | 503 vim_snprintf(buff, BUFSIZ, _("E273: unknown longjmp status %d"), state); |
7 | 504 EMSG(buff); |
505 break; | |
506 } | |
507 } | |
508 | |
1888 | 509 static VALUE vim_message(VALUE self UNUSED, VALUE str) |
7 | 510 { |
511 char *buff, *p; | |
512 | |
513 str = rb_obj_as_string(str); | |
514 buff = ALLOCA_N(char, RSTRING(str)->len); | |
515 strcpy(buff, RSTRING(str)->ptr); | |
516 p = strchr(buff, '\n'); | |
517 if (p) *p = '\0'; | |
518 MSG(buff); | |
519 return Qnil; | |
520 } | |
521 | |
1888 | 522 static VALUE vim_set_option(VALUE self UNUSED, VALUE str) |
7 | 523 { |
524 do_set((char_u *)STR2CSTR(str), 0); | |
525 update_screen(NOT_VALID); | |
526 return Qnil; | |
527 } | |
528 | |
1888 | 529 static VALUE vim_command(VALUE self UNUSED, VALUE str) |
7 | 530 { |
531 do_cmdline_cmd((char_u *)STR2CSTR(str)); | |
532 return Qnil; | |
533 } | |
534 | |
1888 | 535 static VALUE vim_evaluate(VALUE self UNUSED, VALUE str) |
7 | 536 { |
537 #ifdef FEAT_EVAL | |
714 | 538 char_u *value = eval_to_string((char_u *)STR2CSTR(str), NULL, TRUE); |
7 | 539 |
750 | 540 if (value != NULL) |
7 | 541 { |
750 | 542 VALUE val = rb_str_new2((char *)value); |
7 | 543 vim_free(value); |
544 return val; | |
545 } | |
546 else | |
547 #endif | |
548 return Qnil; | |
549 } | |
550 | |
551 static VALUE buffer_new(buf_T *buf) | |
552 { | |
502 | 553 if (buf->b_ruby_ref) |
554 { | |
555 return (VALUE) buf->b_ruby_ref; | |
7 | 556 } |
502 | 557 else |
558 { | |
7 | 559 VALUE obj = Data_Wrap_Struct(cBuffer, 0, 0, buf); |
502 | 560 buf->b_ruby_ref = (void *) obj; |
7 | 561 rb_hash_aset(objtbl, rb_obj_id(obj), obj); |
562 return obj; | |
563 } | |
564 } | |
565 | |
566 static buf_T *get_buf(VALUE obj) | |
567 { | |
568 buf_T *buf; | |
569 | |
570 Data_Get_Struct(obj, buf_T, buf); | |
571 if (buf == NULL) | |
572 rb_raise(eDeletedBufferError, "attempt to refer to deleted buffer"); | |
573 return buf; | |
574 } | |
575 | |
576 static VALUE buffer_s_current() | |
577 { | |
578 return buffer_new(curbuf); | |
579 } | |
580 | |
581 static VALUE buffer_s_count() | |
582 { | |
583 buf_T *b; | |
584 int n = 0; | |
585 | |
779 | 586 for (b = firstbuf; b != NULL; b = b->b_next) |
587 { | |
856 | 588 /* Deleted buffers should not be counted |
589 * SegPhault - 01/07/05 */ | |
590 if (b->b_p_bl) | |
779 | 591 n++; |
592 } | |
593 | |
7 | 594 return INT2NUM(n); |
595 } | |
596 | |
1888 | 597 static VALUE buffer_s_aref(VALUE self UNUSED, VALUE num) |
7 | 598 { |
599 buf_T *b; | |
600 int n = NUM2INT(num); | |
601 | |
779 | 602 for (b = firstbuf; b != NULL; b = b->b_next) |
603 { | |
856 | 604 /* Deleted buffers should not be counted |
605 * SegPhault - 01/07/05 */ | |
606 if (!b->b_p_bl) | |
779 | 607 continue; |
608 | |
856 | 609 if (n == 0) |
7 | 610 return buffer_new(b); |
779 | 611 |
856 | 612 n--; |
7 | 613 } |
614 return Qnil; | |
615 } | |
616 | |
617 static VALUE buffer_name(VALUE self) | |
618 { | |
619 buf_T *buf = get_buf(self); | |
620 | |
750 | 621 return buf->b_ffname ? rb_str_new2((char *)buf->b_ffname) : Qnil; |
7 | 622 } |
623 | |
624 static VALUE buffer_number(VALUE self) | |
625 { | |
626 buf_T *buf = get_buf(self); | |
627 | |
628 return INT2NUM(buf->b_fnum); | |
629 } | |
630 | |
631 static VALUE buffer_count(VALUE self) | |
632 { | |
633 buf_T *buf = get_buf(self); | |
634 | |
635 return INT2NUM(buf->b_ml.ml_line_count); | |
636 } | |
637 | |
779 | 638 static VALUE get_buffer_line(buf_T *buf, linenr_T n) |
7 | 639 { |
779 | 640 if (n > 0 && n <= buf->b_ml.ml_line_count) |
641 { | |
750 | 642 char *line = (char *)ml_get_buf(buf, n, FALSE); |
7 | 643 return line ? rb_str_new2(line) : Qnil; |
644 } | |
779 | 645 rb_raise(rb_eIndexError, "index %d out of buffer", n); |
1888 | 646 #ifndef __GNUC__ |
779 | 647 return Qnil; /* For stop warning */ |
1888 | 648 #endif |
7 | 649 } |
650 | |
779 | 651 static VALUE buffer_aref(VALUE self, VALUE num) |
7 | 652 { |
653 buf_T *buf = get_buf(self); | |
779 | 654 |
655 if (buf != NULL) | |
656 return get_buffer_line(buf, (linenr_T)NUM2LONG(num)); | |
657 return Qnil; /* For stop warning */ | |
658 } | |
659 | |
660 static VALUE set_buffer_line(buf_T *buf, linenr_T n, VALUE str) | |
661 { | |
896 | 662 char *line = STR2CSTR(str); |
663 aco_save_T aco; | |
7 | 664 |
896 | 665 if (n > 0 && n <= buf->b_ml.ml_line_count && line != NULL) |
666 { | |
667 /* set curwin/curbuf for "buf" and save some things */ | |
668 aucmd_prepbuf(&aco, buf); | |
669 | |
7 | 670 if (u_savesub(n) == OK) { |
779 | 671 ml_replace(n, (char_u *)line, TRUE); |
7 | 672 changed(); |
673 #ifdef SYNTAX_HL | |
674 syn_changed(n); /* recompute syntax hl. for this line */ | |
675 #endif | |
676 } | |
896 | 677 |
678 /* restore curwin/curbuf and a few other things */ | |
679 aucmd_restbuf(&aco); | |
680 /* Careful: autocommands may have made "buf" invalid! */ | |
934 | 681 |
7 | 682 update_curbuf(NOT_VALID); |
683 } | |
896 | 684 else |
685 { | |
7 | 686 rb_raise(rb_eIndexError, "index %d out of buffer", n); |
1888 | 687 #ifndef __GNUC__ |
7 | 688 return Qnil; /* For stop warning */ |
1888 | 689 #endif |
7 | 690 } |
691 return str; | |
692 } | |
693 | |
779 | 694 static VALUE buffer_aset(VALUE self, VALUE num, VALUE str) |
695 { | |
696 buf_T *buf = get_buf(self); | |
697 | |
698 if (buf != NULL) | |
699 return set_buffer_line(buf, (linenr_T)NUM2LONG(num), str); | |
700 return str; | |
701 } | |
702 | |
7 | 703 static VALUE buffer_delete(VALUE self, VALUE num) |
704 { | |
896 | 705 buf_T *buf = get_buf(self); |
706 long n = NUM2LONG(num); | |
707 aco_save_T aco; | |
7 | 708 |
896 | 709 if (n > 0 && n <= buf->b_ml.ml_line_count) |
710 { | |
711 /* set curwin/curbuf for "buf" and save some things */ | |
712 aucmd_prepbuf(&aco, buf); | |
713 | |
7 | 714 if (u_savedel(n, 1) == OK) { |
715 ml_delete(n, 0); | |
779 | 716 |
856 | 717 /* Changes to non-active buffers should properly refresh |
718 * SegPhault - 01/09/05 */ | |
719 deleted_lines_mark(n, 1L); | |
779 | 720 |
7 | 721 changed(); |
722 } | |
896 | 723 |
724 /* restore curwin/curbuf and a few other things */ | |
725 aucmd_restbuf(&aco); | |
726 /* Careful: autocommands may have made "buf" invalid! */ | |
934 | 727 |
7 | 728 update_curbuf(NOT_VALID); |
729 } | |
896 | 730 else |
731 { | |
7 | 732 rb_raise(rb_eIndexError, "index %d out of buffer", n); |
733 } | |
734 return Qnil; | |
735 } | |
736 | |
737 static VALUE buffer_append(VALUE self, VALUE num, VALUE str) | |
738 { | |
896 | 739 buf_T *buf = get_buf(self); |
740 char *line = STR2CSTR(str); | |
741 long n = NUM2LONG(num); | |
742 aco_save_T aco; | |
7 | 743 |
896 | 744 if (n >= 0 && n <= buf->b_ml.ml_line_count && line != NULL) |
745 { | |
746 /* set curwin/curbuf for "buf" and save some things */ | |
747 aucmd_prepbuf(&aco, buf); | |
748 | |
7 | 749 if (u_inssub(n + 1) == OK) { |
750 ml_append(n, (char_u *) line, (colnr_T) 0, FALSE); | |
779 | 751 |
856 | 752 /* Changes to non-active buffers should properly refresh screen |
753 * SegPhault - 12/20/04 */ | |
754 appended_lines_mark(n, 1L); | |
779 | 755 |
856 | 756 changed(); |
7 | 757 } |
896 | 758 |
759 /* restore curwin/curbuf and a few other things */ | |
760 aucmd_restbuf(&aco); | |
761 /* Careful: autocommands may have made "buf" invalid! */ | |
934 | 762 |
7 | 763 update_curbuf(NOT_VALID); |
764 } | |
765 else { | |
766 rb_raise(rb_eIndexError, "index %d out of buffer", n); | |
767 } | |
768 return str; | |
769 } | |
770 | |
771 static VALUE window_new(win_T *win) | |
772 { | |
502 | 773 if (win->w_ruby_ref) |
774 { | |
775 return (VALUE) win->w_ruby_ref; | |
7 | 776 } |
502 | 777 else |
778 { | |
7 | 779 VALUE obj = Data_Wrap_Struct(cVimWindow, 0, 0, win); |
502 | 780 win->w_ruby_ref = (void *) obj; |
7 | 781 rb_hash_aset(objtbl, rb_obj_id(obj), obj); |
782 return obj; | |
783 } | |
784 } | |
785 | |
786 static win_T *get_win(VALUE obj) | |
787 { | |
788 win_T *win; | |
789 | |
790 Data_Get_Struct(obj, win_T, win); | |
791 if (win == NULL) | |
792 rb_raise(eDeletedWindowError, "attempt to refer to deleted window"); | |
793 return win; | |
794 } | |
795 | |
796 static VALUE window_s_current() | |
797 { | |
798 return window_new(curwin); | |
799 } | |
800 | |
779 | 801 /* |
802 * Added line manipulation functions | |
803 * SegPhault - 03/07/05 | |
804 */ | |
805 static VALUE line_s_current() | |
806 { | |
807 return get_buffer_line(curbuf, curwin->w_cursor.lnum); | |
808 } | |
809 | |
1888 | 810 static VALUE set_current_line(VALUE self UNUSED, VALUE str) |
779 | 811 { |
812 return set_buffer_line(curbuf, curwin->w_cursor.lnum, str); | |
813 } | |
814 | |
815 static VALUE current_line_number() | |
816 { | |
817 return INT2FIX((int)curwin->w_cursor.lnum); | |
818 } | |
819 | |
820 | |
821 | |
7 | 822 static VALUE window_s_count() |
823 { | |
824 #ifdef FEAT_WINDOWS | |
825 win_T *w; | |
826 int n = 0; | |
827 | |
671 | 828 for (w = firstwin; w != NULL; w = w->w_next) |
7 | 829 n++; |
830 return INT2NUM(n); | |
831 #else | |
832 return INT2NUM(1); | |
833 #endif | |
834 } | |
835 | |
1888 | 836 static VALUE window_s_aref(VALUE self UNUSED, VALUE num) |
7 | 837 { |
838 win_T *w; | |
839 int n = NUM2INT(num); | |
840 | |
841 #ifndef FEAT_WINDOWS | |
842 w = curwin; | |
843 #else | |
844 for (w = firstwin; w != NULL; w = w->w_next, --n) | |
845 #endif | |
846 if (n == 0) | |
847 return window_new(w); | |
848 return Qnil; | |
849 } | |
850 | |
851 static VALUE window_buffer(VALUE self) | |
852 { | |
853 win_T *win = get_win(self); | |
854 | |
855 return buffer_new(win->w_buffer); | |
856 } | |
857 | |
858 static VALUE window_height(VALUE self) | |
859 { | |
860 win_T *win = get_win(self); | |
861 | |
862 return INT2NUM(win->w_height); | |
863 } | |
864 | |
865 static VALUE window_set_height(VALUE self, VALUE height) | |
866 { | |
867 win_T *win = get_win(self); | |
868 win_T *savewin = curwin; | |
869 | |
870 curwin = win; | |
871 win_setheight(NUM2INT(height)); | |
872 curwin = savewin; | |
873 return height; | |
874 } | |
875 | |
501 | 876 static VALUE window_width(VALUE self) |
877 { | |
878 win_T *win = get_win(self); | |
879 | |
880 return INT2NUM(win->w_width); | |
881 } | |
882 | |
883 static VALUE window_set_width(VALUE self, VALUE width) | |
884 { | |
885 win_T *win = get_win(self); | |
886 win_T *savewin = curwin; | |
887 | |
888 curwin = win; | |
889 win_setwidth(NUM2INT(width)); | |
890 curwin = savewin; | |
891 return width; | |
892 } | |
893 | |
7 | 894 static VALUE window_cursor(VALUE self) |
895 { | |
896 win_T *win = get_win(self); | |
897 | |
898 return rb_assoc_new(INT2NUM(win->w_cursor.lnum), INT2NUM(win->w_cursor.col)); | |
899 } | |
900 | |
901 static VALUE window_set_cursor(VALUE self, VALUE pos) | |
902 { | |
903 VALUE lnum, col; | |
904 win_T *win = get_win(self); | |
905 | |
906 Check_Type(pos, T_ARRAY); | |
907 if (RARRAY(pos)->len != 2) | |
908 rb_raise(rb_eArgError, "array length must be 2"); | |
909 lnum = RARRAY(pos)->ptr[0]; | |
910 col = RARRAY(pos)->ptr[1]; | |
911 win->w_cursor.lnum = NUM2LONG(lnum); | |
912 win->w_cursor.col = NUM2UINT(col); | |
913 check_cursor(); /* put cursor on an existing line */ | |
914 update_screen(NOT_VALID); | |
915 return Qnil; | |
916 } | |
917 | |
1888 | 918 static VALUE f_p(int argc, VALUE *argv, VALUE self UNUSED) |
7 | 919 { |
920 int i; | |
921 VALUE str = rb_str_new("", 0); | |
922 | |
923 for (i = 0; i < argc; i++) { | |
924 if (i > 0) rb_str_cat(str, ", ", 2); | |
925 rb_str_concat(str, rb_inspect(argv[i])); | |
926 } | |
927 MSG(RSTRING(str)->ptr); | |
928 return Qnil; | |
929 } | |
930 | |
931 static void ruby_io_init(void) | |
932 { | |
933 #ifndef DYNAMIC_RUBY | |
934 RUBYEXTERN VALUE rb_stdout; | |
935 #endif | |
936 | |
937 rb_stdout = rb_obj_alloc(rb_cObject); | |
938 rb_define_singleton_method(rb_stdout, "write", vim_message, 1); | |
939 rb_define_global_function("p", f_p, -1); | |
940 } | |
941 | |
942 static void ruby_vim_init(void) | |
943 { | |
944 objtbl = rb_hash_new(); | |
945 rb_global_variable(&objtbl); | |
946 | |
1188 | 947 /* The Vim module used to be called "VIM", but "Vim" is better. Make an |
948 * alias "VIM" for backwards compatiblity. */ | |
949 mVIM = rb_define_module("Vim"); | |
950 rb_define_const(rb_cObject, "VIM", mVIM); | |
7 | 951 rb_define_const(mVIM, "VERSION_MAJOR", INT2NUM(VIM_VERSION_MAJOR)); |
952 rb_define_const(mVIM, "VERSION_MINOR", INT2NUM(VIM_VERSION_MINOR)); | |
953 rb_define_const(mVIM, "VERSION_BUILD", INT2NUM(VIM_VERSION_BUILD)); | |
954 rb_define_const(mVIM, "VERSION_PATCHLEVEL", INT2NUM(VIM_VERSION_PATCHLEVEL)); | |
955 rb_define_const(mVIM, "VERSION_SHORT", rb_str_new2(VIM_VERSION_SHORT)); | |
956 rb_define_const(mVIM, "VERSION_MEDIUM", rb_str_new2(VIM_VERSION_MEDIUM)); | |
957 rb_define_const(mVIM, "VERSION_LONG", rb_str_new2(VIM_VERSION_LONG)); | |
958 rb_define_const(mVIM, "VERSION_LONG_DATE", rb_str_new2(VIM_VERSION_LONG_DATE)); | |
959 rb_define_module_function(mVIM, "message", vim_message, 1); | |
960 rb_define_module_function(mVIM, "set_option", vim_set_option, 1); | |
961 rb_define_module_function(mVIM, "command", vim_command, 1); | |
962 rb_define_module_function(mVIM, "evaluate", vim_evaluate, 1); | |
963 | |
964 eDeletedBufferError = rb_define_class_under(mVIM, "DeletedBufferError", | |
965 rb_eStandardError); | |
966 eDeletedWindowError = rb_define_class_under(mVIM, "DeletedWindowError", | |
967 rb_eStandardError); | |
968 | |
969 cBuffer = rb_define_class_under(mVIM, "Buffer", rb_cObject); | |
970 rb_define_singleton_method(cBuffer, "current", buffer_s_current, 0); | |
971 rb_define_singleton_method(cBuffer, "count", buffer_s_count, 0); | |
972 rb_define_singleton_method(cBuffer, "[]", buffer_s_aref, 1); | |
973 rb_define_method(cBuffer, "name", buffer_name, 0); | |
974 rb_define_method(cBuffer, "number", buffer_number, 0); | |
975 rb_define_method(cBuffer, "count", buffer_count, 0); | |
976 rb_define_method(cBuffer, "length", buffer_count, 0); | |
977 rb_define_method(cBuffer, "[]", buffer_aref, 1); | |
978 rb_define_method(cBuffer, "[]=", buffer_aset, 2); | |
979 rb_define_method(cBuffer, "delete", buffer_delete, 1); | |
980 rb_define_method(cBuffer, "append", buffer_append, 2); | |
981 | |
779 | 982 /* Added line manipulation functions |
983 * SegPhault - 03/07/05 */ | |
984 rb_define_method(cBuffer, "line_number", current_line_number, 0); | |
985 rb_define_method(cBuffer, "line", line_s_current, 0); | |
986 rb_define_method(cBuffer, "line=", set_current_line, 1); | |
987 | |
988 | |
7 | 989 cVimWindow = rb_define_class_under(mVIM, "Window", rb_cObject); |
990 rb_define_singleton_method(cVimWindow, "current", window_s_current, 0); | |
991 rb_define_singleton_method(cVimWindow, "count", window_s_count, 0); | |
992 rb_define_singleton_method(cVimWindow, "[]", window_s_aref, 1); | |
993 rb_define_method(cVimWindow, "buffer", window_buffer, 0); | |
994 rb_define_method(cVimWindow, "height", window_height, 0); | |
995 rb_define_method(cVimWindow, "height=", window_set_height, 1); | |
501 | 996 rb_define_method(cVimWindow, "width", window_width, 0); |
997 rb_define_method(cVimWindow, "width=", window_set_width, 1); | |
7 | 998 rb_define_method(cVimWindow, "cursor", window_cursor, 0); |
999 rb_define_method(cVimWindow, "cursor=", window_set_cursor, 1); | |
1000 | |
1001 rb_define_virtual_variable("$curbuf", buffer_s_current, 0); | |
1002 rb_define_virtual_variable("$curwin", window_s_current, 0); | |
1003 } |