ruby-changes:7715
From: nobu <ko1@a...>
Date: Mon, 8 Sep 2008 08:13:57 +0900 (JST)
Subject: [ruby-changes:7715] Ruby:r19236 (mvm): * merged from trunk r19180:19235.
nobu 2008-09-08 08:13:24 +0900 (Mon, 08 Sep 2008) New Revision: 19236 http://svn.ruby-lang.org/cgi-bin/viewvc.cgi?view=rev&revision=19236 Log: * merged from trunk r19180:19235. Modified files: branches/mvm/.merged-trunk-revision branches/mvm/ChangeLog branches/mvm/array.c branches/mvm/complex.c branches/mvm/configure.in branches/mvm/enc/emacs_mule.c branches/mvm/ext/socket/mkconstants.rb branches/mvm/file.c branches/mvm/include/ruby/encoding.h branches/mvm/io.c branches/mvm/misc/inf-ruby.el branches/mvm/misc/ruby-electric.el branches/mvm/misc/ruby-mode.el branches/mvm/misc/ruby-style.el branches/mvm/misc/rubydb3x.el branches/mvm/parse.y branches/mvm/proc.c branches/mvm/rational.c branches/mvm/sample/test.rb branches/mvm/string.c branches/mvm/test/ruby/test_complex.rb branches/mvm/test/ruby/test_econv.rb branches/mvm/test/ruby/test_io_m17n.rb branches/mvm/test/ruby/test_parse.rb branches/mvm/test/ruby/test_rational.rb branches/mvm/tool/transcode-tblgen.rb branches/mvm/transcode.c branches/mvm/transcode_data.h Index: mvm/complex.c =================================================================== --- mvm/complex.c (revision 19235) +++ mvm/complex.c (revision 19236) @@ -19,12 +19,11 @@ #define ONE INT2FIX(1) #define TWO INT2FIX(2) -static ID id_Unify, id_abs, id_abs2, id_arg, id_atan2_bang, id_cmp, - id_conjugate, id_convert, id_cos, id_denominator, id_divmod, - id_equal_p, id_exact_p, id_exp_bang, id_expt, id_floor, id_format, - id_hypot, id_idiv, id_inspect, id_log_bang, id_negate, id_new, id_new_bang, - id_numerator, id_polar, id_quo, id_scalar_p, id_sin, id_sqrt, id_to_f, - id_to_i, id_to_r, id_to_s, id_truncate; +static ID id_Unify, id_abs, id_abs2, id_arg, id_cmp, id_conjugate, + id_convert, id_denominator, id_divmod, id_equal_p, id_exact_p, id_expt, + id_floor, id_format, id_idiv, id_inspect, id_negate, id_new, id_new_bang, + id_numerator, id_polar, id_quo, id_scalar_p, id_to_f, id_to_i, id_to_r, + id_to_s, id_truncate; #define f_boolcast(x) ((x) ? Qtrue : Qfalse) @@ -1342,23 +1341,18 @@ id_abs = rb_intern("abs"); id_abs2 = rb_intern("abs2"); id_arg = rb_intern("arg"); - id_atan2_bang = rb_intern("atan2!"); id_cmp = rb_intern("<=>"); id_conjugate = rb_intern("conjugate"); id_convert = rb_intern("convert"); - id_cos = rb_intern("cos"); id_denominator = rb_intern("denominator"); id_divmod = rb_intern("divmod"); id_equal_p = rb_intern("=="); id_exact_p = rb_intern("exact?"); - id_exp_bang = rb_intern("exp!"); id_expt = rb_intern("**"); id_floor = rb_intern("floor"); id_format = rb_intern("format"); - id_hypot = rb_intern("hypot"); id_idiv = rb_intern("div"); id_inspect = rb_intern("inspect"); - id_log_bang = rb_intern("log!"); id_negate = rb_intern("-@"); id_new = rb_intern("new"); id_new_bang = rb_intern("new!"); @@ -1366,8 +1360,6 @@ id_polar = rb_intern("polar"); id_quo = rb_intern("quo"); id_scalar_p = rb_intern("scalar?"); - id_sin = rb_intern("sin"); - id_sqrt = rb_intern("sqrt"); id_to_f = rb_intern("to_f"); id_to_i = rb_intern("to_i"); id_to_r = rb_intern("to_r"); Index: mvm/array.c =================================================================== --- mvm/array.c (revision 19235) +++ mvm/array.c (revision 19236) @@ -3010,7 +3010,7 @@ * array.sample -> obj * array.sample(n) -> an_array * - * Choose a random element, or the random +n+ elements, fron the array. + * Choose a random element, or the random +n+ elements, from the array. * If the array is empty, the first form returns <code>nil</code>, and the * second form returns an empty array. * Index: mvm/include/ruby/encoding.h =================================================================== --- mvm/include/ruby/encoding.h (revision 19235) +++ mvm/include/ruby/encoding.h (revision 19236) @@ -221,7 +221,7 @@ void rb_econv_close(rb_econv_t *ec); /* result: 0:success -1:failure */ -int rb_econv_set_replacemenet(rb_econv_t *ec, const unsigned char *str, size_t len, const char *encname); +int rb_econv_set_replacement(rb_econv_t *ec, const unsigned char *str, size_t len, const char *encname); VALUE rb_econv_open_exc(const char *senc, const char *denc, int ecflags); @@ -249,27 +249,35 @@ void rb_econv_binmode(rb_econv_t *ec); /* flags for rb_econv_open */ -#define ECONV_INVALID_MASK 0x000f -#define ECONV_INVALID_REPLACE 0x0002 -#define ECONV_UNDEF_MASK 0x00f0 -#define ECONV_UNDEF_REPLACE 0x0020 -#define ECONV_UNDEF_HEX_CHARREF 0x0030 +#define ECONV_ERROR_HANDLER_MASK 0x000000ff +#define ECONV_INVALID_MASK 0x0000000f +#define ECONV_INVALID_REPLACE 0x00000002 + +#define ECONV_UNDEF_MASK 0x000000f0 +#define ECONV_UNDEF_REPLACE 0x00000020 +#define ECONV_UNDEF_HEX_CHARREF 0x00000030 + /* usable only if destination encoding is ascii compatible */ -#define ECONV_UNIVERSAL_NEWLINE_DECODER 0x0100 +#define ECONV_DECODER_MASK 0x00000f00 +#define ECONV_UNIVERSAL_NEWLINE_DECODER 0x00000100 /* usable only if source encoding is ascii compatible */ -#define ECONV_CRLF_NEWLINE_ENCODER 0x0200 -#define ECONV_CR_NEWLINE_ENCODER 0x0400 -#define ECONV_HTML_TEXT_ENCODER 0x0800 -#define ECONV_HTML_ATTR_ENCODER 0x1000 +#define ECONV_ENCODER_MASK 0x0000f000 +#define ECONV_CRLF_NEWLINE_ENCODER 0x00001000 +#define ECONV_CR_NEWLINE_ENCODER 0x00002000 +#define ECONV_XML_TEXT_ENCODER 0x00004000 +#define ECONV_XML_ATTR_CONTENT_ENCODER 0x00008000 +#define ECONV_STATEFUL_ENCODER_MASK 0x00f00000 +#define ECONV_XML_ATTR_QUOTE_ENCODER 0x00100000 + /* end of flags for rb_econv_open */ /* flags for rb_econv_convert */ -#define ECONV_PARTIAL_INPUT 0x10000 -#define ECONV_OUTPUT_FOLLOWED_BY_INPUT 0x20000 +#define ECONV_PARTIAL_INPUT 0x00010000 +#define ECONV_OUTPUT_FOLLOWED_BY_INPUT 0x00020000 /* end of flags for rb_econv_convert */ #endif /* RUBY_ENCODING_H */ Index: mvm/configure.in =================================================================== --- mvm/configure.in (revision 19235) +++ mvm/configure.in (revision 19236) @@ -526,6 +526,26 @@ AC_DEFINE(BROKEN_SETREUID, 1) AC_DEFINE(BROKEN_SETREGID, 1) ]) + ac_cv_lib_crypt_crypt=no + AC_CACHE_CHECK(for broken crypt with 8bit chars, rb_cv_broken_crypt, + [AC_TRY_RUN([ +#include <stdio.h> +#include <unistd.h> +#include <string.h> +int +main() +{ + char buf[256]; + strcpy(buf, crypt("", "\xE0\xA0")); + return strcmp(buf, crypt("", "\xE0\xA0")); +} +], + rb_cv_broken_crypt=no, + rb_cv_broken_crypt=yes, + rb_cv_broken_crypt=yes)]) + if test "$rb_cv_broken_crypt" = yes; then + AC_DEFINE(BROKEN_CRYPT, 1) + fi ;; hpux*) LIBS="-lm $LIBS" ac_cv_c_inline=no;; Index: mvm/ChangeLog =================================================================== --- mvm/ChangeLog (revision 19235) +++ mvm/ChangeLog (revision 19236) @@ -1,3 +1,9 @@ +Mon Sep 8 07:09:42 2008 Tadayoshi Funaba <tadf@d...> + + * complex.c: some adjustments. + + * rational.c: ditto. + Mon Sep 8 06:38:22 2008 Nobuyoshi Nakada <nobu@r...> * configure.in (XLDFLAGS): added --enable-auto-import for cygwin and @@ -14,6 +20,194 @@ * vm_core.h (rb_thread_set_current_raw): fixed typo. +Mon Sep 8 02:04:25 2008 Tanaka Akira <akr@f...> + + * include/ruby/encoding.h (rb_econv_set_replacement): renamed from + rb_econv_set_replacemenet. + + * transcode.c: follow the renaming. + +Mon Sep 8 01:10:41 2008 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb (transcode_tblgen): log message refined. + +Mon Sep 8 00:58:04 2008 Tadayoshi Funaba <tadf@d...> + + * rational.c: removed unused code. + +Mon Sep 8 00:04:09 2008 Tanaka Akira <akr@f...> + + * enc/trans/iso2022.trans: upcase to iso-2022-jp. + + * enc/emacs_mule.c: ditto. + +Sun Sep 7 23:46:36 2008 Tanaka Akira <akr@f...> + + * enc/trans/iso2022.trans: stateless-iso-2022-jp is defined to avoid + undefined conversion error between iso-2022-jp and the corresponding + stateless encoding. + + * enc/emacs_mule.c: replicate emacs-mule as stateless-iso-2022-jp. + +Sun Sep 7 20:03:01 2008 Tanaka Akira <akr@f...> + + * enc/trans/escape.trans (hexstr): renamed from str1. + +Sun Sep 7 19:45:31 2008 Tanaka Akira <akr@f...> + + * enc/trans/escape.trans: use transcode_tblgen. + + * tool/transcode-tblgen.rb: generate an empty line after str1. + +Sun Sep 7 19:16:38 2008 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb (ActionMap#str_name): new method to + generate a name base on string content. + (ActionMap#gen_str): extracted from generate_info and use str_name. + +Sun Sep 7 18:28:05 2008 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb (ActionMap#generate_info): use a memo to + avoid duplication for STR1. + +Sun Sep 7 18:10:28 2008 Tanaka Akira <akr@f...> + + * transcode_data.h (STR1): defined for a string up to 255 bytes. + (STR1_BYTEINDEX): defined. + (makeSTR1): defined. + + * tool/transcode-tblgen.rb: generate STR1. + + * transcode.c (transcode_restartable0): interpret STR1. + + * enc/trans/escape.trans (fun_so_escape_xml_chref): removed. STR1 is + used instead. + +Sun Sep 7 17:54:45 2008 Kazuhiro NISHIYAMA <zn@m...> + + * configure.in: Mac OS X's crypt(2) is broken with invalid salt. + [ruby-dev:35899] + * string.c (rb_str_crypt): ditto. + +Sun Sep 7 17:29:49 2008 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb: o4 is usable only if the first byte is + f0-f7. + +Sun Sep 7 12:44:26 2008 Tanaka Akira <akr@f...> + + * io.c (make_writeconv): choose ASCII compatible encoding as + intermediate encoding if stateful encoder exists. + +Sun Sep 7 12:09:29 2008 Tanaka Akira <akr@f...> + + * include/ruby/encoding.h (ECONV_XML_ATTR_CONTENT_ENCODER): defined. + (ECONV_STATEFUL_ENCODER_MASK): defined. + (ECONV_XML_ATTR_QUOTE_ENCODER): defined. + (ECONV_XML_ATTR_ENCODER): removed. + + * enc/trans/escape.trans (rb_escape_xml_attr_content): defined. + (rb_escape_xml_attr_quote): defined. + (rb_escape_xml_attr): removed. + + * io.c (NEED_WRITECONV): writeconv is required if supplemental + converter is used. + (make_writeconv): apply stateful encoder in writeconv. + + * transcode.c: follow the constant change. + +Sun Sep 7 07:24:09 2008 Yukihiro Matsumoto <matz@r...> + + * misc/*.el: merged the following patches from Nathan Weizenbaum + <nex342 at gmail.com>. [ruby-core:18424] + + * misc/ruby-mode.el: improve here-doc performance. + + * misc/ruby-mode.el: don't crash the whole mode if the Subversion + $ keyword isn't interpolated. + + * misc/ruby-mode.el: don't highlight keywords when they're the + beginning of non-keyword symbols. + + * misc/ruby-mode.el, misc/ruby-electric.el: use regexp-opt where + possible for more efficient regexps. + + * misc/*.el: untabify, for internal consistency and consistency + with standard Emacs elisp files. + + * misc/ruby-mode.el: fix a variable-name error. + + * misc/emacs-mode.el: don't set case-fold-search globally to nil; + instead just set it when we need it. + +Sun Sep 7 06:31:51 2008 Yukihiro Matsumoto <matz@r...> + + * file.c (file_expand_path): applied a patch from Nobuhiro Tachino + in [ruby-dev:35948]. fix #491 + +Sun Sep 7 03:37:05 2008 Yukihiro Matsumoto <matz@r...> + + * parse.y (f_block_optarg): allow default for block parameters as + long as the value is primary. a patch from Eric Mahurin + <eric.mahurin at gmail.com> in [ruby-core:16880]. + +Sun Sep 7 01:07:10 2008 Yukihiro Matsumoto <matz@r...> + + * parse.y (yylex): "1.upto 2 {|i| p i }" should be syntax error. + [ruby-dev:36008] + + * test/ruby/test_parse.rb (TestParse): update a test not to use + recently fixed inconsistent syntax. + +Sun Sep 7 00:37:25 2008 Tanaka Akira <akr@f...> + + * include/ruby/encoding.h (ECONV_ERROR_HANDLER_MASK): defined. + (ECONV_DECODER_MASK): defined. + (ECONV_ENCODER_MASK): defined. + + * io.c (make_writeconv): restrict ecflags for writeconv with + ECONV_ERROR_HANDLER_MASK. + +Sat Sep 6 23:03:41 2008 Tanaka Akira <akr@f...> + + * include/ruby/encoding.h (ECONV_XML_TEXT_ENCODER): renamed from + ECONV_HTML_TEXT_ENCODER. + (ECONV_XML_ATTR_ENCODER): renamed from ECONV_HTML_ATTR_ENCODER. + + * enc/trans/escape.trans: follow the renaming. + + * transcode.c: ditto. + +Sat Sep 6 21:35:52 2008 Yukihiro Matsumoto <matz@r...> + + * ext/socket/mkconstants.rb: add some IPV6 constants. [ruby-dev:36175] + +Sat Sep 6 20:10:48 2008 Tanaka Akira <akr@f...> + + * transcode.c (econv_description): show ECONV_HTML_TEXT_ENCODER and + ECONV_HTML_ATTR_ENCODER. + +Sat Sep 6 20:06:09 2008 Tanaka Akira <akr@f...> + + * transcode.c (rb_econv_binmode): check actual transcoders. + +Sat Sep 6 19:54:25 2008 Tanaka Akira <akr@f...> + + * transcode.c (rb_econv_open): fix last_tc. + +Sat Sep 6 19:36:34 2008 Tanaka Akira <akr@f...> + + * io.c (rb_io_binmode): clear newline flags in writeconv_pre_ecflags. + +Sat Sep 6 18:47:40 2008 Tanaka Akira <akr@f...> + + * transcode.c (str_transcode0): check ECONV_HTML_TEXT_ENCODER and + ECONV_HTML_ATTR_ENCODER. + +Sat Sep 6 18:38:47 2008 Tanaka Akira <akr@f...> + + * transcode.c (allocate_converted_string): fix overflow condition. + Sat Sep 6 15:06:21 2008 Tanaka Akira <akr@f...> * transcode.c (sym_html): new variable. @@ -104,7 +298,7 @@ (rb_econv_convert): call output_hex_charref if ECONV_UNDEF_HEX_CHARREF. (Init_transcode): Encoding::Converter::UNDEF_HEX_CHARREF added. - + Sat Sep 6 03:52:47 2008 Tanaka Akira <akr@f...> * transcode.c (rb_econv_convert): use ECONV_INVALID_MASK and @@ -116,6 +310,11 @@ a patch from Tadashi Saito <shiba at mail2.accsnet.ne.jp> in [ruby-dev:36102]. +Sat Sep 6 04:44:06 2008 Yukihiro Matsumoto <matz@r...> + + * proc.c (Init_Proc): add '===' operator to use procs in when + clause of the case statement. inspired by <http://www.aimred.com/news/developers/2008/08/14/unlocking_the_power_of_case_equality_proc/>. + Sat Sep 6 03:18:17 2008 Tanaka Akira <akr@f...> * transcode.c (allocate_converted_string): add arguments for a buffer @@ -184,7 +383,7 @@ Fri Sep 5 02:56:37 2008 Koichi Sasada <ko1@a...> - * vm.c (thread_recycle_stack_slot, thread_recycle_stack_count): + * vm.c (thread_recycle_stack_slot, thread_recycle_stack_count): make it static. Fri Sep 5 02:40:38 2008 Koichi Sasada <ko1@a...> @@ -233,7 +432,7 @@ Thu Sep 4 23:05:54 2008 Yuki Sonoda (Yugui) <yugui@y...> - * lib/prime.rb (Prime::OldCompatibility#each): added compatibility to + * lib/prime.rb (Prime::OldCompatibility#each): added compatibility to Ruby 1.8.7. (Prime#each): added more rdocs. (Prime#each): remembers the last value of the given block. @@ -268,7 +467,7 @@ Thu Sep 4 20:30:24 2008 Tanaka Akira <akr@f...> - * transcode_data.h (PType): defined unconditionaly. + * transcode_data.h (PType): defined unconditionally. * transcode.c (PType): don't define here. @@ -307,7 +506,7 @@ * vm_core.h (struct rb_vm_struct): replaced signal staff with trap staff. - * signal.c (signal_buff): per process resouce now. + * signal.c (signal_buff): per process resource now. * signal.c (trap_list): moved to VM. @@ -514,7 +713,7 @@ (Integer.each_prime): added. (Integer#prime?): added. (Prime): moved from mathn.rb. - Its implmentation was rewritten. see [ruby-dev:35863]. + Its implementation was rewritten. see [ruby-dev:35863]. And patched by Keiju ISHITSUKA <keiju@i...>, see [ruby-dev:36128]. (Prime.new): obsolete. @@ -548,8 +747,107 @@ * test/test_prime.rb: added. +Wed Sep 3 21:49:00 2008 David A. Black <dblack@r...> + + * lib/scanf.rb: fixed bug involving matching literal '[' + + * test/scanf/test_scanf.rb: added test for scanf.rb fix + +Wed Sep 3 21:31:59 2008 Tanaka Akira <akr@f...> + + * transcode_data.h (WORDINDEX_SHIFT_BITS): defined. + (WORDINDEX2INFO): defined. + (INFO2WORDINDEX): defined. + + * tool/transcode-tblgen.rb: use WORDINDEX2INFO. + + * transcode.c: use INFO2WORDINDEX. + +Wed Sep 3 21:19:51 2008 Kazuhiro NISHIYAMA <zn@m...> + + * golf_prelude.rb: suppress warnings when goruby -v. + +Wed Sep 3 21:07:30 2008 Tanaka Akira <akr@f...> + + * transcode.c (BL_MIN_BYTE): defined. + (BL_MAX_BYTE): defined. + (BL_OFFSET): defined. + (BL_ACTION): defined. + (transcode_restartable0): use BL_MIN_BYTE, BL_MAX_BYTE and + BL_ACTION. + +Wed Sep 3 20:58:30 2008 Tanaka Akira <akr@f...> + + * transcode.c (BYTE_ADDR): defined. + (WORD_ADDR): ditto. + (BL_BASE): use BYTE_ADDR and WORD_ADDR. + (BL_INFO): use WORD_ADDR. + +Wed Sep 3 20:47:31 2008 Tanaka Akira <akr@f...> + + * transcode_data.h (rb_transcoder): new field: byte_array_length and + word_array_length. + + * tool/transcode-tblgen.rb (transcode_generated_code): generate + byte_array_length and word_array_length. + +Wed Sep 3 20:34:10 2008 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb (ArrayCode): new class. + (ActionMap#gen_array_code): moved to ArrayCode. + (ActionMap#numelt_array_code): ditto. + (ActionMap#array_code_insert_at_last): ditto. + (TRANSCODE_GENERATED_BYTES_CODE): use ArrayCode. + (TRANSCODE_GENERATED_WORDS_CODE): ditto. + +Wed Sep 3 20:08:35 2008 Tanaka Akira <akr@f...> + + * enc/trans/japanese.trans: new file. + +Wed Sep 3 20:04:33 2008 Tanaka Akira <akr@f...> + + * tool/transcode-tblgen.rb (ActionMap#gen_array_code): extracted from + generate_lookup_node. + (ActionMap#numelt_array_code): ditto. + (ActionMap#array_code_insert_at_last): ditto. + +Wed Sep 3 20:01:01 2008 Tanaka Akira <akr@f...> + + * parse.y (parser_encoding_name): defined. + (parser_tokadd_mbchar): show encoding in the message of + "invalid multibyte char" error. + +Wed Sep 3 19:28:04 2008 NAKAMURA Usaku <usa@r...> + + * vm_insnhelper.c (vm_method_missing): C99. + +Wed Sep 3 19:18:12 2008 Koichi Sasada <ko1@a...> + + * test/ruby/test_thread.rb: fix test. + [ruby-dev:35960] + +Wed Sep 3 17:48:32 2008 NARUSE, Yui <naruse@r...> + + * enc/trans/make_transdb.rb: check $(srcdir)/enc/trans before + enc/trans. + + * enc/trans/make_transdb.rb: keep names_t. + +Wed Sep 3 16:54:46 2008 Koichi Sasada <ko1@a...> + + * include/ruby/signal.h: removed. + + * common.mk, class.c, eval.c, eval_intern.h, file.c, gc.c, hash.c, + io.c, process.c, signal.c: vm_core.h: ditto. + Some unused external global variables are also removed. + (rb_prohibit_interrupt, rb_trap_immediate, rb_trap_pending, + rb_thread_critical) + + * ext/openssl/ossl_ssl.c, ext/openssl/ossl_x509store.c, + ext/readline/readline.c, ext/socket/depend, + ext/socket/socket.c: ditto. + Wed Sep 3 10:17:55 2008 Koichi Sasada <ko1@a...> - * include/ruby/mvm.h, include/ruby/ruby.h, main.c: main.c doesn't need "ruby.h" any more. @@ -908,7 +1206,7 @@ * enc/trans/eucjp-tbl.rb: replace by previous Citrus maps. - * enc/trans/sjis-tble.rb: ditto. + * enc/trans/sjis-tbl.rb: ditto. Mon Sep 1 01:18:26 2008 NARUSE, Yui <naruse@r...> @@ -1216,7 +1514,7 @@ * ext/iconv/iconv.c: remove include pragma for "ruby/intern.h". -Sat Aug 30 10:43:03 2008 2008 Koichi Sasada <ko1@a...> +Sat Aug 30 10:43:03 2008 Koichi Sasada <ko1@a...> * parse.y: remove include pragma for "ruby/intern.h". @@ -3054,7 +3352,7 @@ * test/ruby/test_file_exhaustive.rb (TestFileExhaustive#setup): set group of tmpdir. [ruby-dev:35633] -Thu Aug 14 15:50:30 2008 Giuseppe Bilotta <giuseppe.bilotta@g...> +Thu Aug 14 15:50:30 2008 Giuseppe Bilotta <giuseppe.bilotta@g...> * hash.c (set_default): fix rdoc. #441 Index: mvm/misc/rubydb3x.el =================================================================== --- mvm/misc/rubydb3x.el (revision 19235) +++ mvm/misc/rubydb3x.el (revision 19236) @@ -28,20 +28,20 @@ ;; Process all the complete markers in this chunk. (while (string-match "\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n" - gud-rubydb-marker-acc) + gud-rubydb-marker-acc) (setq ;; Extract the frame position from the marker. gud-last-frame (cons (substring gud-rubydb-marker-acc (match-beginning 1) (match-end 1)) - (string-to-int (substring gud-rubydb-marker-acc - (match-beginning 2) - (match-end 2)))) + (string-to-int (substring gud-rubydb-marker-acc + (match-beginning 2) + (match-end 2)))) ;; Append any text before the marker to the output we're going ;; to return - we don't include the marker in this text. output (concat output - (substring gud-rubydb-marker-acc 0 (match-beginning 0))) + (substring gud-rubydb-marker-acc 0 (match-beginning 0))) ;; Set the accumulator to the remaining text. gud-rubydb-marker-acc (substring gud-rubydb-marker-acc (match-end 0)))) @@ -52,17 +52,17 @@ ;; know the full marker regexp above failed, it's pretty simple to ;; test for marker starts. (if (string-match "\032.*\\'" gud-rubydb-marker-acc) - (progn - ;; Everything before the potential marker start can be output. - (setq output (concat output (substring gud-rubydb-marker-acc - 0 (match-beginning 0)))) + (progn + ;; Everything before the potential marker start can be output. + (setq output (concat output (substring gud-rubydb-marker-acc + 0 (match-beginning 0)))) - ;; Everything after, we save, to combine with later input. - (setq gud-rubydb-marker-acc - (substring gud-rubydb-marker-acc (match-beginning 0)))) + ;; Everything after, we save, to combine with later input. + (setq gud-rubydb-marker-acc + (substring gud-rubydb-marker-acc (match-beginning 0)))) (setq output (concat output gud-rubydb-marker-acc) - gud-rubydb-marker-acc "")) + gud-rubydb-marker-acc "")) output)) @@ -83,18 +83,18 @@ and source-file directory for your debugger." (interactive (list (read-from-minibuffer "Run rubydb (like this): " - (if (consp gud-rubydb-history) - (car gud-rubydb-history) - (concat rubydb-command-name " ")) - nil nil - '(gud-rubydb-history . 1)))) + (if (consp gud-rubydb-history) + (car gud-rubydb-history) + (concat rubydb-command-name " ")) + nil nil + '(gud-rubydb-history . 1)))) (if (not (fboundp 'gud-overload-functions)) (gud-common-init command-line 'gud-rubydb-massage-args - 'gud-rubydb-marker-filter 'gud-rubydb-find-file) + 'gud-rubydb-marker-filter 'gud-rubydb-find-file) (gud-overload-functions '((gud-massage-args . gud-rubydb-massage-args) - (gud-marker-filter . gud-rubydb-marker-filter) - (gud-find-file . gud-rubydb-find-file))) + (gud-marker-filter . gud-rubydb-marker-filter) + (gud-find-file . gud-rubydb-find-file))) (gud-common-init command-line rubydb-command-name)) (gud-def gud-break "b %l" "\C-b" "Set breakpoint at current line.") Index: mvm/misc/ruby-mode.el =================================================================== --- mvm/misc/ruby-mode.el (revision 19235) +++ mvm/misc/ruby-mode.el (revision 19236) @@ -9,42 +9,54 @@ "Ruby mode revision string.") (defconst ruby-mode-version - (progn - (string-match "[0-9.]+" ruby-mode-revision) - (substring ruby-mode-revision (match-beginning 0) (match-end 0))) + (and (string-match "[0-9.]+" ruby-mode-revision) + (substring ruby-mode-revision (match-beginning 0) (match-end 0))) "Ruby mode version number.") +(defconst ruby-block-beg-keywords + '("class" "module" "def" "if" "unless" "case" "while" "until" "for" "begin" "do") + "Keywords at the beginning of blocks.") + (defconst ruby-block-beg-re - "class\\|module\\|def\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin\\|do" - "Regexp to match the beginning of blocks in ruby-mode.") + (regexp-opt ruby-block-beg-keywords) + "Regexp to match the beginning of blocks.") (defconst ruby-non-block-do-re - "\\(while\\|until\\|for\\|rescue\\)\\>[^_]" + (concat (regexp-opt '("while" "until" "for" "rescue") t) "\\_>") "Regexp to match") (defconst ruby-indent-beg-re - "\\(\\s *\\(class\\|module\\|def\\)\\)\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin" + (concat "\\(\\s *" (regexp-opt '("class" "module" "def") t) "\\)" + (regexp-opt '("if" "unless" "case" "while" "until" "for" "begin"))) "Regexp to match where the indentation gets deeper.") +(defconst ruby-modifier-beg-keywords + '("if" "unless" "while" "until") + "Modifiers that are the same as the beginning of blocks.") + (defconst ruby-modifier-beg-re - "if\\|unless\\|while\\|until" + (regexp-opt ruby-modifier-beg-keywords) "Regexp to match modifiers same as the beginning of blocks.") (defconst ruby-modifier-re - (concat ruby-modifier-beg-re "\\|rescue") + (regexp-opt (cons "rescue" ruby-modifier-beg-keywords)) "Regexp to match modifiers.") +(defconst ruby-block-mid-keywords + '("then" "else" "elsif" "when" "rescue" "ensure") + "Keywords where the indentation gets shallower in middle of block statements.") + (defconst ruby-block-mid-re - "then\\|else\\|elsif\\|when\\|rescue\\|ensure" + (regexp-opt ruby-block-mid-keywords) "Regexp to match where the indentation gets shallower in middle of block statements.") -(defconst ruby-block-op-re - "and\\|or\\|not" - "Regexp to match ") +(defconst ruby-block-op-keywords + '("and" "or" "not") + "Block operators.") (defconst ruby-block-hanging-re - (concat ruby-modifier-beg-re "\\|" ruby-block-op-re) - ) + (regexp-opt (append ruby-modifier-beg-keywords ruby-block-op-keywords)) + "Regexp to match hanging block modifiers.") (defconst ruby-block-end-re "\\<end\\>") @@ -56,11 +68,11 @@ (defun ruby-here-doc-end-match () (concat "^" - (if (match-string 2) "[ \t]*" nil) - (regexp-quote - (or (match-string 4) - (match-string 5) - (match-string 6))))) + (if (match-string 2) "[ \t]*" nil) + (regexp-quote + (or (match-string 4) + (match-string 5) + (match-string 6))))) (defun ruby-here-doc-beg-match () (let ((contents (regexp-quote (concat (match-string 2) (match-string 3))))) @@ -68,19 +80,19 @@ (let ((match (match-string 1))) (if (and match (> (length match) 0)) (concat "\\(?:-\\([\"']?\\)\\|\\([\"']\\)" (match-string 1) "\\)" - contents "\\(\\1\\|\\2\\)") - (concat "-?\\([\"']\\|\\)" contents "\\1")))))) + contents "\\b\\(\\1\\|\\2\\)") + (concat "-?\\([\"']\\|\\)" contents "\\b\\1")))))) (defconst ruby-delimiter (concat "[?$/%(){}#\"'`.:]\\|<<\\|\\[\\|\\]\\|\\<\\(" - ruby-block-beg-re - "\\)\\>\\|" ruby-block-end-re - "\\|^=begin\\|" ruby-here-doc-beg-re) + ruby-block-beg-re + "\\)\\>\\|" ruby-block-end-re + "\\|^=begin\\|" ruby-here-doc-beg-re) ) (defconst ruby-negative (concat "^[ \t]*\\(\\(" ruby-block-mid-re "\\)\\>\\|" - ruby-block-end-re "\\|}\\|\\]\\)") + ruby-block-end-re "\\|}\\|\\]\\)") "Regexp to match where the indentation gets shallower.") (defconst ruby-operator-chars "-,.+*/%&|^~=<>:") @@ -184,7 +196,7 @@ (eval-when-compile (require 'cl)) (defun ruby-imenu-create-index-in-block (prefix beg end) - (let ((index-alist '()) + (let ((index-alist '()) (case-fold-search nil) name next pos decl sing) (goto-char beg) (while (re-search-forward "^\\s *\\(\\(class\\s +\\|\\(class\\s *<<\\s *\\)\\|module\\s +\\)\\([^\(<\n ]+\\)\\|\\(def\\|alias\\)\\s +\\([^\(\n ]+\\)\\)" end t) @@ -195,29 +207,29 @@ (setq pos (match-beginning 0)) (cond ((string= "alias" decl) - (if prefix (setq name (concat prefix name))) - (push (cons name pos) index-alist)) + (if prefix (setq name (concat prefix name))) + (push (cons name pos) index-alist)) ((string= "def" decl) - (if prefix - (setq name - (cond - ((string-match "^self\." name) - (concat (substring prefix 0 -1) (substring name 4))) - (t (concat prefix name))))) - (push (cons name pos) index-alist) - (ruby-accurate-end-of-block end)) + (if prefix + (setq name + (cond + ((string-match "^self\." name) + (concat (substring prefix 0 -1) (substring name 4))) + (t (concat prefix name))))) + (push (cons name pos) index-alist) + (ruby-accurate-end-of-block end)) (t - (if (string= "self" name) - (if prefix (setq name (substring prefix 0 -1))) - (if prefix (setq name (concat (substring prefix 0 -1) "::" name))) - (push (cons name pos) index-alist)) - (ruby-accurate-end-of-block end) - (setq beg (point)) - (setq index-alist - (nconc (ruby-imenu-create-index-in-block - (concat name (if sing "." "#")) - next beg) index-alist)) - (goto-char beg)))) + (if (string= "self" name) + (if prefix (setq name (substring prefix 0 -1))) + (if prefix (setq name (concat (substring prefix 0 -1) "::" name))) + (push (cons name pos) index-alist)) + (ruby-accurate-end-of-block end) + (setq beg (point)) + (setq index-alist + (nconc (ruby-imenu-create-index-in-block + (concat name (if sing "." "#")) + next beg) index-alist)) + (goto-char beg)))) index-alist)) (defun ruby-imenu-create-index () @@ -227,12 +239,11 @@ (let (state) (or end (setq end (point-max))) (while (and (setq state (apply 'ruby-parse-partial end state)) - (>= (nth 2 state) 0) (< (point) end))))) + (>= (nth 2 state) 0) (< (point) end))))) (defun ruby-mode-variables () (set-syntax-table ruby-mode-syntax-table) (setq local-abbrev-table ruby-mode-abbrev-table) - (setq case-fold-search nil) (make-local-variable 'indent-line-function) (setq indent-line-function 'ruby-indent-line) (make-local-variable 'require-final-newline) @@ -264,33 +275,33 @@ (when (re-search-forward "[^\0-\177]" nil t) (goto-char (point-min)) (let ((coding-system - (or coding-system-for-write - buffer-file-coding-system))) - (if coding-system - (setq coding-system - (or (coding-system-get coding-system 'mime-charset) - (coding-system-change-eol-conversion coding-system nil)))) - (setq coding-system - (if coding-system - (symbol-name - (or (and ruby-use-encoding-map - (cdr (assq coding-system ruby-encoding-map))) - coding-system)) - "ascii-8bit")) - (if (looking-at "^#![^\n]*ruby") (beginning-of-line 2)) - (cond ((looking-at "\\s *#.*-\*-\\s *\\(en\\)?coding\\s *:\\s *\\([-a-z0-9_]*\\)\\s *\\(;\\|-\*-\\)") - (unless (string= (match-string 2) coding-system) - (goto-char (match-beginning 2)) - (delete-region (point) (match-end 2)) - (and (looking-at "-\*-") - (let ((n (skip-chars-backward " "))) - (cond ((= n 0) (insert " ") (backward-char)) - ((= n -1) (insert " ")) - ((forward-char))))) - (insert coding-system))) - ((looking-at "\\s *#.*coding\\s *[:=]")) - (t (insert "# -*- coding: " coding-system " -*-\n")) - ))))) + (or coding-system-for-write + buffer-file-coding-system))) + (if coding-system + (setq coding-system + (or (coding-system-get coding-system 'mime-charset) + (coding-system-change-eol-conversion coding-system nil)))) + (setq coding-system + (if coding-system + (symbol-name + (or (and ruby-use-encoding-map + (cdr (assq coding-system ruby-encoding-map))) + coding-system)) + "ascii-8bit")) + (if (looking-at "^#![^\n]*ruby") (beginning-of-line 2)) + (cond ((looking-at "\\s *#.*-\*-\\s *\\(en\\)?coding\\s *:\\s *\\([-a-z0-9_]*\\)\\s *\\(;\\|-\*-\\)") + (unless (string= (match-string 2) coding-system) + (goto-char (match-beginning 2)) + (delete-region (point) (match-end 2)) + (and (looking-at "-\*-") + (let ((n (skip-chars-backward " "))) + (cond ((= n 0) (insert " ") (backward-char)) + ((= n -1) (insert " ")) + ((forward-char))))) + (insert coding-system))) + ((looking-at "\\s *#.*coding\\s *[:=]")) + (t (insert "# -*- coding: " coding-system " -*-\n")) + ))))) ;;;###autoload (defun ruby-mode () @@ -316,10 +327,10 @@ (add-hook (cond ((boundp 'before-save-hook) - (make-local-variable 'before-save-hook) - 'before-save-hook) - ((boundp 'write-contents-functions) 'write-contents-functions) - ((boundp 'write-contents-hooks) 'write-contents-hooks)) + (make-local-variable 'before-save-hook) + 'before-save-hook) + ((boundp 'write-contents-functions) 'write-contents-functions) + ((boundp 'write-contents-hooks) 'write-contents-hooks)) 'ruby-mode-set-encoding) (set (make-local-variable 'font-lock-defaults) '((ruby-font-lock-keywords) nil nil)) @@ -348,89 +359,91 @@ (defun ruby-indent-to (x) (if x (let (shift top beg) - (and (< x 0) (error "invalid nest")) - (setq shift (current-column)) - (beginning-of-line) - (setq beg (point)) - (back-to-indentation) - (setq top (current-column)) - (skip-chars-backward " \t") - (if (>= shift top) (setq shift (- shift top)) - (setq shift 0)) - (if (and (bolp) - (= x top)) - (move-to-column (+ x shift)) - (move-to-column top) - (delete-region beg (point)) - (beginning-of-line) - (indent-to x) - (move-to-column (+ x shift)))))) + (and (< x 0) (error "invalid nest")) + (setq shift (current-column)) + (beginning-of-line) + (setq beg (point)) + (back-to-indentation) + (setq top (current-column)) + (skip-chars-backward " \t") + (if (>= shift top) (setq shift (- shift top)) + (setq shift 0)) + (if (and (bolp) + (= x top)) + (move-to-column (+ x shift)) + (move-to-column top) + (delete-region beg (point)) + (beginning-of-line) + (indent-to x) + (move-to-column (+ x shift)))))) (defun ruby-special-char-p (&optional pnt) (setq pnt (or pnt (point))) (let ((c (char-before pnt)) (b (and (< (point-min) pnt) (char-before (1- pnt))))) (cond ((or (eq c ??) (eq c ?$))) - ((and (eq c ?:) (or (not b) (eq (char-syntax b) ? )))) - ((eq c ?\\) (eq b ??))))) + ((and (eq c ?:) (or (not b) (eq (char-syntax b) ? )))) + ((eq c ?\\) (eq b ??))))) (defun ruby-expr-beg (&optional option) (save-excursion (store-match-data nil) (let ((space (skip-chars-backward " \t")) - (start (point))) + (start (point))) (cond ((bolp) t) ((progn - (forward-char -1) - (and (looking-at "\\?") - (or (eq (char-syntax (char-before (point))) ?w) - (ruby-special-char-p)))) - nil) + (forward-char -1) + (and (looking-at "\\?") + (or (eq (char-syntax (char-before (point))) ?w) + (ruby-special-char-p)))) + nil) ((and (eq option 'heredoc) (< space 0)) t) ((or (looking-at ruby-operator-re) - (looking-at "[\\[({,;]") - (and (looking-at "[!?]") - (or (not (eq option 'modifier)) - (bolp) - (save-excursion (forward-char -1) (looking-at "\\Sw$")))) - (and (looking-at ruby-symbol-re) - (skip-chars-backward ruby-symbol-chars) - (cond - ((or (looking-at (concat "\\<\\(" ruby-block-beg-re - "|" ruby-block-op-re - "|" ruby-block-mid-re "\\)\\>"))) - (goto-char (match-end 0)) - (not (looking-at "\\s_"))) - ((eq option 'expr-qstr) - (looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]")) - ((eq option 'expr-re) - (looking-at "[a-zA-Z][a-zA-z0-9_]* +/[^ \t]")) - (t nil))))))))) + (looking-at "[\\[({,;]") + (and (looking-at "[!?]") + (or (not (eq option 'modifier)) + (bolp) + (save-excursion (forward-char -1) (looking-at "\\Sw$")))) + (and (looking-at ruby-symbol-re) + (skip-chars-backward ruby-symbol-chars) + (cond + ((looking-at (regexp-opt + (append ruby-block-beg-keywords + ruby-block-op-keywords + ruby-block-mid-keywords) + 'words)) + (goto-char (match-end 0)) + (not (looking-at "\\s_"))) + ((eq option 'expr-qstr) + (looking-at "[a-zA-Z][a-zA-z0-9_]* +%[^ \t]")) + ((eq option 'expr-re) + (looking-at "[a-zA-Z][a-zA-z0-9_]* +/[^ \t]")) + (t nil))))))))) (defun ruby-forward-string (term &optional end no-error expand) (let ((n 1) (c (string-to-char term)) - (re (if expand - (concat "[^\\]\\(\\\\\\\\\\)*\\([" term "]\\|\\(#{\\)\\)") - (concat "[^\\]\\(\\\\\\\\\\)*[" term "]")))) + (re (if expand + (concat "[^\\]\\(\\\\\\\\\\)*\\([" term "]\\|\\(#{\\)\\)") + (concat "[^\\]\\(\\\\\\\\\\)*[" term "]")))) (while (and (re-search-forward re end no-error) - (if (match-beginning 3) - (ruby-forward-string "}{" end no-error nil) - (> (setq n (if (eq (char-before (point)) c) - (1- n) (1+ n))) 0))) + (if (match-beginning 3) + (ruby-forward-string "}{" end no-error nil) + (> (setq n (if (eq (char-before (point)) c) + (1- n) (1+ n))) 0))) (forward-char -1)) (cond ((zerop n)) - (no-error nil) - ((error "unterminated string"))))) + (no-error nil) + ((error "unterminated string"))))) (defun ruby-deep-indent-paren-p (c) (cond ((listp ruby-deep-indent-paren) - (let ((deep (assoc c ruby-deep-indent-paren))) - (cond (deep - (or (cdr deep) ruby-deep-indent-paren-style)) - ((memq c ruby-deep-indent-paren) - ruby-deep-indent-paren-style)))) - ((eq c ruby-deep-indent-paren) ruby-deep-indent-paren-style) - ((eq c ?\( ) ruby-deep-arglist))) + (let ((deep (assoc c ruby-deep-indent-paren))) + (cond (deep + (or (cdr deep) ruby-deep-indent-paren-style)) + ((memq c ruby-deep-indent-paren) + ruby-deep-indent-paren-style)))) + ((eq c ruby-deep-indent-paren) ruby-deep-indent-paren-style) + ((eq c ?\( ) ruby-deep-arglist))) (defun ruby-parse-partial (&optional end in-string nest depth pcol indent) (or depth (setq depth 0)) @@ -440,218 +453,218 @@ (goto-char (match-beginning 0)) (cond ((and (memq (char-before) '(?@ ?$)) (looking-at "\\sw")) - (goto-char pnt)) - ((looking-at "[\"`]") ;skip string - (cond - ((and (not (eobp)) - (ruby-forward-string (buffer-substring (point) (1+ (point))) end t t)) - nil) - (t - (setq in-string (point)) - (goto-char end)))) + (goto-char pnt)) + ((looking-at "[\"`]") ;skip string + (cond + ((and (not (eobp)) + (ruby-forward-string (buffer-substring (point) (1+ (point))) end t t)) + nil) + (t + (setq in-string (point)) + (goto-char end)))) ((looking-at "'") - (cond - ((and (not (eobp)) - (re-search-forward "[^\\]\\(\\\\\\\\\\)*'" end t)) - nil) - (t - (setq in-string (point)) - (goto-char end)))) + (cond + ((and (not (eobp)) + (re-search-forward "[^\\]\\(\\\\\\\\\\)*'" end t)) + nil) + (t + (setq in-string (point)) + (goto-char end)))) ((looking-at "/=") - (goto-char pnt)) + (goto-char pnt)) ((looking-at "/") - (cond - ((and (not (eobp)) (ruby-expr-beg 'expr-re)) - (if (ruby-forward-string "/" end t t) - nil - (setq in-string (point)) - (goto-char end))) - (t - (goto-char pnt)))) + (cond + ((and (not (eobp)) (ruby-expr-beg 'expr-re)) + (if (ruby-forward-string "/" end t t) + nil + (setq in-string (point)) + (goto-char end))) + (t + (goto-char pnt)))) ((looking-at "%") - (cond - ((and (not (eobp)) - (ruby-expr-beg 'expr-qstr) - (not (looking-at "%=")) - (looking-at "%[QqrxWw]?\\([^a-zA-Z0-9 \t\n]\\)")) - (goto-char (match-beginning 1)) - (setq expand (not (memq (char-before) '(?q ?w)))) - (setq w (match-string 1)) - (cond - ((string= w "[") (setq re "][")) - ((string= w "{") (setq re "}{")) - ((string= w "(") (setq re ")(")) - ((string= w "<") (setq re "><")) - ((and expand (string= w "\\")) - (setq w (concat "\\" w)))) - (unless (cond (re (ruby-forward-string re end t expand)) - (expand (ruby-forward-string w end t t)) - (t (re-search-forward - (if (string= w "\\") - "\\\\[^\\]*\\\\" - (concat "[^\\]\\(\\\\\\\\\\)*" w)) - end t))) - (setq in-string (point)) - (goto-char end))) - (t - (goto-char pnt)))) - ((looking-at "\\?") ;skip ?char - (cond - ((and (ruby-expr-beg) - (looking-at "?\\(\\\\C-\\|\\\\M-\\)*\\\\?.")) - (goto-char (match-end 0))) - (t - (goto-char pnt)))) - ((looking-at "\\$") ;skip $char - (goto-char pnt) - (forward-char 1)) - ((looking-at "#") ;skip comment - (forward-line 1) - (goto-char (point)) - ) + (cond + ((and (not (eobp)) + (ruby-expr-beg 'expr-qstr) + (not (looking-at "%=")) + (looking-at "%[QqrxWw]?\\([^a-zA-Z0-9 \t\n]\\)")) + (goto-char (match-beginning 1)) + (setq expand (not (memq (char-before) '(?q ?w)))) + (setq w (match-string 1)) + (cond + ((string= w "[") (setq re "][")) + ((string= w "{") (setq re "}{")) + ((string= w "(") (setq re ")(")) + ((string= w "<") (setq re "><")) + ((and expand (string= w "\\")) + (setq w (concat "\\" w)))) + (unless (cond (re (ruby-forward-string re end t expand)) + (expand (ruby-forward-string w end t t)) + (t (re-search-forward + (if (string= w "\\") + "\\\\[^\\]*\\\\" + (concat "[^\\]\\(\\\\\\\\\\)*" w)) + end t))) + (setq in-string (point)) + (goto-char end))) + (t + (goto-char pnt)))) + ((looking-at "\\?") ;skip ?char + (cond + ((and (ruby-expr-beg) + (looking-at "?\\(\\\\C-\\|\\\\M-\\)*\\\\?.")) + (goto-char (match-end 0))) + (t + (goto-char pnt)))) + ((looking-at "\\$") ;skip $char + (goto-char pnt) + (forward-char 1)) + ((looking-at "#") ;skip comment + (forward-line 1) + (goto-char (point)) + ) ((looking-at "[\\[{(]") - (let ((deep (ruby-deep-indent-paren-p (char-after)))) - (if (and deep (or (not (eq (char-after) ?\{)) (ruby-expr-beg))) - (progn - (and (eq deep 'space) (looking-at ".\\s +[^# \t\n]") - (setq pnt (1- (match-end 0)))) - (setq nest (cons (cons (char-after (point)) pnt) nest)) - (setq pcol (cons (cons pnt depth) pcol)) - (setq depth 0)) - (setq nest (cons (cons (char-after (point)) pnt) nest)) - (setq depth (1+ depth)))) - (goto-char pnt) - ) + (let ((deep (ruby-deep-indent-paren-p (char-after)))) + (if (and deep (or (not (eq (char-after) ?\{)) (ruby-expr-beg))) + (progn + (and (eq deep 'space) (looking-at ".\\s +[^# \t\n]") + (setq pnt (1- (match-end 0)))) + (setq nest (cons (cons (char-after (point)) pnt) nest)) + (setq pcol (cons (cons pnt depth) pcol)) + (setq depth 0)) + (setq nest (cons (cons (char-after (point)) pnt) nest)) + (setq depth (1+ depth)))) + (goto-char pnt) + ) ((looking-at "[])}]") - (if (ruby-deep-indent-paren-p (matching-paren (char-after))) - (setq depth (cdr (car pcol)) pcol (cdr pcol)) - (setq depth (1- depth))) - (setq nest (cdr nest)) - (goto-char pnt)) + (if (ruby-deep-indent-paren-p (matching-paren (char-after))) + (setq depth (cdr (car pcol)) pcol (cdr pcol)) + (setq depth (1- depth))) + (setq nest (cdr nest)) + (goto-char pnt)) ((looking-at ruby-block-end-re) - (if (or (and (not (bolp)) - (progn - (forward-char -1) - (setq w (char-after (point))) - (or (eq ?_ w) - (eq ?. w)))) - (progn - (goto-char pnt) - (setq w (char-after (point))) - (or (eq ?_ w) - (eq ?! w) - (eq ?? w)))) - nil - (setq nest (cdr nest)) - (setq depth (1- depth))) - (goto-char pnt)) + (if (or (and (not (bolp)) + (progn + (forward-char -1) + (setq w (char-after (point))) + (or (eq ?_ w) + (eq ?. w)))) + (progn + (goto-char pnt) + (setq w (char-after (point))) + (or (eq ?_ w) + (eq ?! w) + (eq ?? w)))) + nil + (setq nest (cdr nest)) + (setq depth (1- depth))) + (goto-char pnt)) ((looking-at "def\\s +[^(\n;]*") - (if (or (bolp) - (progn - (forward-char -1) - (not (eq ?_ (char-after (point)))))) - (progn - (setq nest (cons (cons nil pnt) nest)) - (setq depth (1+ depth)))) - (goto-char (match-end 0))) + (if (or (bolp) + (progn + (forward-char -1) + (not (eq ?_ (char-after (point)))))) + (progn + (setq nest (cons (cons nil pnt) nest)) + (setq depth (1+ depth)))) + (goto-char (match-end 0))) ((looking-at (concat "\\<\\(" ruby-block-beg-re "\\)\\>")) - (and - (save-match-data - (or (not (looking-at "do\\>[^_]")) - (save-excursion - (back-to-indentation) - (not (looking-at ruby-non-block-do-re))))) - (or (bolp) - (progn - (forward-char -1) - (setq w (char-after (point))) - (not (or (eq ?_ w) - (eq ?. w))))) - (goto-char pnt) - (setq w (char-after (point))) - (not (eq ?_ w)) - (not (eq ?! w)) - (not (eq ?? w)) - (skip-chars-forward " \t") - (goto-char (match-beginning 0)) - (or (not (looking-at ruby-modifier-re)) - (ruby-expr-beg 'modifier)) - (goto-char pnt) - (setq nest (cons (cons nil pnt) nest)) - (setq depth (1+ depth))) - (goto-char pnt)) + (and + (save-match-data + (or (not (looking-at "do\\_>")) + (save-excursion + (back-to-indentation) + (not (looking-at ruby-non-block-do-re))))) + (or (bolp) + (progn + (forward-char -1) + (setq w (char-after (point))) + (not (or (eq ?_ w) + (eq ?. w))))) + (goto-char pnt) + (setq w (char-after (point))) + (not (eq ?_ w)) + (not (eq ?! w)) + (not (eq ?? w)) + (skip-chars-forward " \t") + (goto-char (match-beginning 0)) + (or (not (looking-at ruby-modifier-re)) + (ruby-expr-beg 'modifier)) + (goto-char pnt) + (setq nest (cons (cons nil pnt) nest)) + (setq depth (1+ depth))) + (goto-char pnt)) ((looking-at ":\\(['\"]\\)") - (goto-char (match-beginning 1)) - (ruby-forward-string (buffer-substring (match-beginning 1) (match-end 1)) end)) + (goto-char (match-beginning 1)) + (ruby-forward-string (buffer-substring (match-beginning 1) (match-end 1)) end)) ((looking-at ":\\([-,.+*/%&|^~<>]=?\\|===?\\|<=>\\)") - (goto-char (match-end 0))) + (goto-char (match-end 0))) ((looking-at ":\\([a-zA-Z_][a-zA-Z_0-9]*[!?=]?\\)?") - (goto-char (match-end 0))) + (goto-char (match-end 0))) ((or (looking-at "\\.\\.\\.?") - (looking-at "\\.[0-9]+") - (looking-at "\\.[a-zA-Z_0-9]+") - (looking-at "\\.")) - (goto-char (match-end 0))) + (looking-at "\\.[0-9]+") + (looking-at "\\.[a-zA-Z_0-9]+") + (looking-at "\\.")) + (goto-char (match-end 0))) ((looking-at "^=begin") - (if (re-search-forward "^=end" end t) - (forward-line 1) - (setq in-string (match-end 0)) - (goto-char end))) + (if (re-search-forward "^=end" end t) + (forward-line 1) + (setq in-string (match-end 0)) + (goto-char end))) ((looking-at "<<") - (cond - ((and (ruby-expr-beg 'heredoc) - (looking-at "<<\\(-\\)?\\(\\([\"'`]\\)\\([^\n]+?\\)\\3\\|\\(?:\\sw\\|\\s_\\)+\\)")) - (setq re (regexp-quote (or (match-string 4) (match-string 2)))) - (if (match-beginning 1) (setq re (concat "\\s *" re))) - (let* ((id-end (goto-char (match-end 0))) - (line-end-position (save-excursion (end-of-line) (point))) - (state (list in-string nest depth pcol indent))) - ;; parse the rest of the line - (while (and (> line-end-position (point)) - (setq state (apply 'ruby-parse-partial - line-end-position state)))) - (setq in-string (car state) - nest (nth 1 state) - depth (nth 2 state) - pcol (nth 3 state) - indent (nth 4 state)) - ;; skip heredoc section - (if (re-search-forward (concat "^" re "$") end 'move) - (forward-line 1) - (setq in-string id-end) - (goto-char end)))) - (t - (goto-char pnt)))) + (cond + ((and (ruby-expr-beg 'heredoc) + (looking-at "<<\\(-\\)?\\(\\([\"'`]\\)\\([^\n]+?\\)\\3\\|\\(?:\\sw\\|\\s_\\)+\\)")) + (setq re (regexp-quote (or (match-string 4) (match-string 2)))) + (if (match-beginning 1) (setq re (concat "\\s *" re))) + (let* ((id-end (goto-char (match-end 0))) + (line-end-position (save-excursion (end-of-line) (point))) + (state (list in-string nest depth pcol indent))) + ;; parse the rest of the line + (while (and (> line-end-position (point)) + (setq state (apply 'ruby-parse-partial + line-end-position state)))) + (setq in-string (car state) + nest (nth 1 state) + depth (nth 2 state) + pcol (nth 3 state) + indent (nth 4 state)) + ;; skip heredoc section + (if (re-search-forward (concat "^" re "$") end 'move) + (forward-line 1) + (setq in-string id-end) + (goto-char end)))) + (t + (goto-char pnt)))) ((looking-at "^__END__$") - (goto-char pnt)) + (goto-char pnt)) ((looking-at ruby-here-doc-beg-re) - (if (re-search-forward (ruby-here-doc-end-match) - indent-point t) - (forward-line 1) - (setq in-string (match-end 0)) - (goto-char indent-point))) + (if (re-search-forward (ruby-here-doc-end-match) + indent-point t) + (forward-line 1) + (setq in-string (match-end 0)) + (goto-char indent-point))) (t - (error (format "bad string %s" - (buffer-substring (point) pnt) - )))))) + (error (format "bad string %s" + (buffer-substring (point) pnt) + )))))) (list in-string nest depth pcol)) (defun ruby-parse-region (start end) (let (state) (save-excursion (if start - (goto-char start) - (ruby-beginning-of-indent)) + (goto-char start) + (ruby-beginning-of-indent)) (save-restriction - (narrow-to-region (point) end) - (while (and (> end (point)) - (setq state (apply 'ruby-parse-partial end state)))))) - (list (nth 0 state) ; in-string - (car (nth 1 state)) ; nest - (nth 2 state) ; depth - (car (car (nth 3 state))) ; pcol - ;(car (nth 5 state)) ; indent - ))) + (narrow-to-region (point) end) + (while (and (> end (point)) + (setq state (apply 'ruby-parse-partial end state)))))) + (list (nth 0 state) ; in-string + (car (nth 1 state)) ; nest + (nth 2 state) ; depth + (car (car (nth 3 state))) ; pcol + ;(car (nth 5 state)) ; indent + ))) (defun ruby-indent-size (pos nest) (+ pos (* (or nest 1) ruby-indent-level))) @@ -660,160 +673,161 @@ (save-excursion (beginning-of-line) (let ((indent-point (point)) - state bol eol begin op-end - (paren (progn (skip-syntax-forward " ") - (and (char-after) (matching-paren (char-after))))) - (indent 0)) + (case-fold-search nil) + state bol eol begin op-end + (paren (progn (skip-syntax-forward " ") + (and (char-after) (matching-paren (char-after))))) + (indent 0)) (if parse-start - (goto-char parse-start) - (ruby-beginning-of-indent) - (setq parse-start (point))) + (goto-char parse-start) + (ruby-beginning-of-indent) + (setq parse-start (point))) (back-to-indentation) (setq indent (current-column)) (setq state (ruby-parse-region parse-start indent-point)) (cond - ((nth 0 state) ; within string - (setq indent nil)) ; do nothing - ((car (nth 1 state)) ; in paren - (goto-char (setq begin (cdr (nth 1 state)))) - (let ((deep (ruby-deep-indent-paren-p (car (nth 1 state))))) - (if deep - (cond ((and (eq deep t) (eq (car (nth 1 state)) paren)) - (skip-syntax-backward " ") - (setq indent (1- (current-column)))) - ((let ((s (ruby-parse-region (point) indent-point))) - (and (nth 2 s) (> (nth 2 s) 0) - (or (goto-char (cdr (nth 1 s))) t))) - (forward-word -1) - (setq indent (ruby-indent-size (current-column) (nth 2 state)))) - (t - (setq indent (current-column)) - (cond ((eq deep 'space)) - (paren (setq indent (1- indent))) - (t (setq indent (ruby-indent-size (1- indent) 1)))))) - (if (nth 3 state) (goto-char (nth 3 state)) - (goto-char parse-start) (back-to-indentation)) - (setq indent (ruby-indent-size (current-column) (nth 2 state)))) - (and (eq (car (nth 1 state)) paren) - (ruby-deep-indent-paren-p (matching-paren paren)) - (search-backward (char-to-string paren)) - (setq indent (current-column))))) + ((nth 0 state) ; within string + (setq indent nil)) ; do nothing + ((car (nth 1 state)) ; in paren + (goto-char (setq begin (cdr (nth 1 state)))) + (let ((deep (ruby-deep-indent-paren-p (car (nth 1 state))))) + (if deep + (cond ((and (eq deep t) (eq (car (nth 1 state)) paren)) + (skip-syntax-backward " ") + (setq indent (1- (current-column)))) + ((let ((s (ruby-parse-region (point) indent-point))) + (and (nth 2 s) (> (nth 2 s) 0) + (or (goto-char (cdr (nth 1 s))) t))) + (forward-word -1) + (setq indent (ruby-indent-size (current-column) (nth 2 state)))) + (t + (setq indent (current-column)) + (cond ((eq deep 'space)) + (paren (setq indent (1- indent))) + (t (setq indent (ruby-indent-size (1- indent) 1)))))) + (if (nth 3 state) (goto-char (nth 3 state)) + (goto-char parse-start) (back-to-indentation)) + (setq indent (ruby-indent-size (current-column) (nth 2 state)))) + (and (eq (car (nth 1 state)) paren) + (ruby-deep-indent-paren-p (matching-paren paren)) + (search-backward (char-to-string paren)) + (setq indent (current-column))))) ((and (nth 2 state) (> (nth 2 state) 0)) ; in nest - (if (null (cdr (nth 1 state))) - (error "invalid nest")) - (goto-char (cdr (nth 1 state))) - (forward-word -1) ; skip back a keyword - (setq begin (point)) - (cond - ((looking-at "do\\>[^_]") ; iter block is a special case - (if (nth 3 state) (goto-char (nth 3 state)) - (goto-char parse-start) (back-to-indentation)) - (setq indent (ruby-indent-size (current-column) (nth 2 state)))) - (t - (setq indent (+ (current-column) ruby-indent-level))))) + (if (null (cdr (nth 1 state))) + (error "invalid nest")) + (goto-char (cdr (nth 1 state))) + (forward-word -1) ; skip back a keyword + (setq begin (point)) + (cond + ((looking-at "do\\>[^_]") ; iter block is a special case + (if (nth 3 state) (goto-char (nth 3 state)) + (goto-char parse-start) (back-to-indentation)) + (setq indent (ruby-indent-size (current-column) (nth 2 state)))) + (t + (setq indent (+ (current-column) ruby-indent-level))))) ((and (nth 2 state) (< (nth 2 state) 0)) ; in negative nest - (setq indent (ruby-indent-size (current-column) (nth 2 state))))) + (setq indent (ruby-indent-size (current-column) (nth 2 state))))) (when indent - (goto-char indent-point) - (end-of-line) - (setq eol (point)) - (beginning-of-line) - (cond - ((and (not (ruby-deep-indent-paren-p paren)) - (re-search-forward ruby-negative eol t)) - (and (not (eq ?_ (char-after (match-end 0)))) - (setq indent (- indent ruby-indent-level)))) - ((and - (save-excursion - (beginning-of-line) - (not (bobp))) - (or (ruby-deep-indent-paren-p t) - (null (car (nth 1 state))))) - ;; goto beginning of non-empty no-comment line - (let (end done) - (while (not done) - (skip-chars-backward " \t\n") - (setq end (point)) - (beginning-of-line) - (if (re-search-forward "^\\s *#" end t) - (beginning-of-line) - (setq done t)))) - (setq bol (point)) - (end-of-line) - ;; skip the comment at the end - (skip-chars-backward " \t") - (let (end (pos (point))) - (beginning-of-line) - (while (and (re-search-forward "#" pos t) - (setq end (1- (point))) - (or (ruby-special-char-p end) - (and (setq state (ruby-parse-region parse-start end)) - (nth 0 state)))) - (setq end nil)) - (goto-char (or end pos)) - (skip-chars-backward " \t") - (setq begin (if (and end (nth 0 state)) pos (cdr (nth 1 state)))) - (setq state (ruby-parse-region parse-start (point)))) - (or (bobp) (forward-char -1)) - (and - (or (and (looking-at ruby-symbol-re) - (skip-chars-backward ruby-symbol-chars) - (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>")) - (not (eq (point) (nth 3 state))) - (save-excursion - (goto-char (match-end 0)) - (not (looking-at "[a-z_]")))) - (and (looking-at ruby-operator-re) - (not (ruby-special-char-p)) - ;; operator at the end of line - (let ((c (char-after (point)))) - (and -;; (or (null begin) -;; (save-excursion -;; (goto-char begin) -;; (skip-chars-forward " \t") -;; (not (or (eolp) (looking-at "#") -;; (and (eq (car (nth 1 state)) ?{) -;; (looking-at "|")))))) - (or (not (eq ?/ c)) - (null (nth 0 (ruby-parse-region (or begin parse-start) (point))))) - (or (not (eq ?| (char-after (point)))) - (save-excursion - (or (eolp) (forward-char -1)) - (cond - ((search-backward "|" nil t) - (skip-chars-backward " \t\n") - (and (not (eolp)) - (progn - (forward-char -1) - (not (looking-at "{"))) - (progn - (forward-word -1) - (not (looking-at "do\\>[^_]"))))) - (t t)))) - (not (eq ?, c)) - (setq op-end t))))) - (setq indent - (cond - ((and - (null op-end) - (not (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>"))) - (eq (ruby-deep-indent-paren-p t) 'space) - (not (bobp))) - (widen) - (goto-char (or begin parse-start)) - (skip-syntax-forward " ") - (current-column)) - ((car (nth 1 state)) indent) - (t - (+ indent ruby-indent-level)))))))) + (goto-char indent-point) + (end-of-line) + (setq eol (point)) + (beginning-of-line) + (cond + ((and (not (ruby-deep-indent-paren-p paren)) + (re-search-forward ruby-negative eol t)) + (and (not (eq ?_ (char-after (match-end 0)))) + (setq indent (- indent ruby-indent-level)))) + ((and + (save-excursion + (beginning-of-line) + (not (bobp))) + (or (ruby-deep-indent-paren-p t) + (null (car (nth 1 state))))) + ;; goto beginning of non-empty no-comment line + (let (end done) + (while (not done) + (skip-chars-backward " \t\n") + (setq end (point)) + (beginning-of-line) + (if (re-search-forward "^\\s *#" end t) + (beginning-of-line) + (setq done t)))) + (setq bol (point)) + (end-of-line) + ;; skip the comment at the end + (skip-chars-backward " \t") + (let (end (pos (point))) + (beginning-of-line) + (while (and (re-search-forward "#" pos t) + (setq end (1- (point))) + (or (ruby-special-char-p end) + (and (setq state (ruby-parse-region parse-start end)) + (nth 0 state)))) + (setq end nil)) + (goto-char (or end pos)) + (skip-chars-backward " \t") + (setq begin (if (and end (nth 0 state)) pos (cdr (nth 1 state)))) + (setq state (ruby-parse-region parse-start (point)))) + (or (bobp) (forward-char -1)) + (and + (or (and (looking-at ruby-symbol-re) + (skip-chars-backward ruby-symbol-chars) + (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>")) + (not (eq (point) (nth 3 state))) + (save-excursion + (goto-char (match-end 0)) + (not (looking-at "[a-z_]")))) + (and (looking-at ruby-operator-re) + (not (ruby-special-char-p)) + ;; operator at the end of line + (let ((c (char-after (point)))) + (and +;; (or (null begin) +;; (save-excursion +;; (goto-char begin) +;; (skip-chars-forward " \t") +;; (not (or (eolp) (looking-at "#") +;; (and (eq (car (nth 1 state)) ?{) +;; (looking-at "|")))))) + (or (not (eq ?/ c)) + (null (nth 0 (ruby-parse-region (or begin parse-start) (point))))) + (or (not (eq ?| (char-after (point)))) + (save-excursion + (or (eolp) (forward-char -1)) + (cond + ((search-backward "|" nil t) + (skip-chars-backward " \t\n") + (and (not (eolp)) + (progn + (forward-char -1) + (not (looking-at "{"))) + (progn + (forward-word -1) + (not (looking-at "do\\>[^_]"))))) + (t t)))) + (not (eq ?, c)) + (setq op-end t))))) + (setq indent + (cond + ((and + (null op-end) + (not (looking-at (concat "\\<\\(" ruby-block-hanging-re "\\)\\>"))) + (eq (ruby-deep-indent-paren-p t) 'space) + (not (bobp))) + (widen) + (goto-char (or begin parse-start)) + (skip-syntax-forward " ") + (current-column)) + ((car (nth 1 state)) indent) + (t + (+ indent ruby-indent-level)))))))) (goto-char indent-point) (beginning-of-line) (skip-syntax-forward " ") (if (looking-at "\\.[^.]") - (+ indent ruby-indent-level) - indent)))) + (+ indent ruby-indent-level) + indent)))) (defun ruby-electric-brace (arg) (interactive "P") @@ -826,10 +840,10 @@ (defmacro defun-region-command (func args &rest body) (let ((intr (car body))) (when (featurep 'xemacs) - (if (stringp intr) (setq intr (cadr body))) - (and (eq (car intr) 'interactive) - (setq intr (cdr intr)) - (setcar intr (concat "_" (car intr))))) + (if (stringp intr) (setq intr (cadr body))) + (and (eq (car intr) 'interactive) + (setq intr (cdr intr)) + (setcar intr (concat "_" (car intr))))) (cons 'defun (cons func (cons args body)))))) (defun-region-command ruby-beginning-of-defun (&optional arg) @@ -838,22 +852,22 @@ Returns t unless search stops due to end of buffer." (interactive "p") (and (re-search-backward (concat "^\\(" ruby-block-beg-re "\\)\\b") - nil 'move (or arg 1)) + nil 'move (or arg 1)) (progn (beginning-of-line) t))) (defun ruby-beginning-of-indent () (and (re-search-backward (concat "^\\(" ruby-indent-beg-re "\\)\\b") - nil 'move) + nil 'move) (progn - (beginning-of-line) - t))) + (beginning-of-line) + t))) (defun-region-command ruby-end-of-defun (&optional arg) "Move forward to next end of defun. An end of a defun is found by moving forward from the beginning of one." (interactive "p") (and (re-search-forward (concat "^\\(" ruby-block-end-re "\\)\\($\\|\\b[^_]\\)") - nil 'move (or arg 1)) + nil 'move (or arg 1)) (progn (beginning-of-line) t)) (forward-line 1)) @@ -861,30 +875,30 @@ (let (start pos done down) (setq start (ruby-calculate-indent)) (setq down (looking-at (if (< n 0) ruby-block-end-re - (concat "\\<\\(" ruby-block-beg-re "\\)\\>")))) + (concat "\\<\\(" ruby-block-beg-re "\\)\\>")))) (while (and (not done) (not (if (< n 0) (bobp) (eobp)))) (forward-line n) (cond ((looking-at "^\\s *$")) ((looking-at "^\\s *#")) ((and (> n 0) (looking-at "^=begin\\>")) - (re-search-forward "^=end\\>")) + (re-search-forward "^=end\\>")) ((and (< n 0) (looking-at "^=end\\>")) - (re-search-backward "^=begin\\>")) + (re-search-backward "^=begin\\>")) (t - (setq pos (current-indentation)) - (cond - ((< start pos) - (setq down t)) - ((and down (= pos start)) - (setq done t)) - ((> start pos) - (setq done t))))) + (setq pos (current-indentation)) + (cond + ((< start pos) + (setq down t)) + ((and down (= pos start)) + (setq done t)) + ((> start pos) + (setq done t))))) (if done - (save-excursion - (back-to-indentation) - (if (looking-at (concat "\\<\\(" ruby-block-mid-re "\\)\\>")) - (setq done nil)))))) + (save-excursion + (back-to-indentation) + (if (looking-at (concat "\\<\\(" ruby-block-mid-re "\\)\\>")) + (setq done nil)))))) (back-to-indentation)) (defun-region-command ruby-beginning-of-block (&optional arg) @@ -903,37 +917,37 @@ (ruby-backward-sexp (- cnt)) (let ((i (or cnt 1))) (condition-case nil - (while (> i 0) - (skip-syntax-forward " ") - (cond ((looking-at "\\?\\(\\\\[CM]-\\)*\\\\?\\S ") - (goto-char (match-end 0))) - ((progn - (skip-chars-forward ",.:;|&^~=!?\\+\\-\\*") - (looking-at "\\s(")) - (goto-char (scan-sexps (point) 1))) - ((and (looking-at (concat "\\<\\(" ruby-block-beg-re "\\)\\>")) - (not (eq (char-before (point)) ?.)) - (not (eq (char-before (point)) ?:))) - (ruby-end-of-block) - (forward-word 1)) - ((looking-at "\\(\\$\\|@@?\\)?\\sw") - (while (progn - (while (progn (forward-word 1) (looking-at "_"))) - (cond ((looking-at "::") (forward-char 2) t) - ((> (skip-chars-forward ".") 0)) - ((looking-at "\\?\\|!\\(=[~=>]\\|[^~=]\\)") - (forward-char 1) nil))))) - ((let (state expr) - (while - (progn - (setq expr (or expr (ruby-expr-beg) - (looking-at "%\\sw?\\Sw\\|[\"'`/]"))) - (nth 1 (setq state (apply 'ruby-parse-partial nil state)))) - (setq expr t) - (skip-chars-forward "<")) - (not expr)))) - (setq i (1- i))) - ((error) (forward-word 1))) + (while (> i 0) + (skip-syntax-forward " ") + (cond ((looking-at "\\?\\(\\\\[CM]-\\)*\\\\?\\S ") + (goto-char (match-end 0))) + ((progn + (skip-chars-forward ",.:;|&^~=!?\\+\\-\\*") + (looking-at "\\s(")) + (goto-char (scan-sexps (point) 1))) + ((and (looking-at (concat "\\<\\(" ruby-block-beg-re "\\)\\>")) + (not (eq (char-before (point)) ?.)) + (not (eq (char-before (point)) ?:))) + (ruby-end-of-block) + (forward-word 1)) + ((looking-at "\\(\\$\\|@@?\\)?\\sw") + (while (progn + (while (progn (forward-word 1) (looking-at "_"))) + (cond ((looking-at "::") (forward-char 2) t) + ((> (skip-chars-forward ".") 0)) + ((looking-at "\\?\\|!\\(=[~=>]\\|[^~=]\\)") + (forward-char 1) nil))))) + ((let (state expr) + (while + (progn + (setq expr (or expr (ruby-expr-beg) + (looking-at "%\\sw?\\Sw\\|[\"'`/]"))) + (nth 1 (setq state (apply 'ruby-parse-partial nil state)))) + (setq expr t) + (skip-chars-forward "<")) + (not expr)))) + (setq i (1- i))) + ((error) (forward-word 1))) i))) (defun-region-command ruby-backward-sexp (&optional cnt) @@ -942,41 +956,41 @@ (ruby-forward-sexp (- cnt)) (let ((i (or cnt 1))) (condition-case nil - (while (> i 0) - (skip-chars-backward " \t\n,.:;|&^~=!?\\+\\-\\*") - (forward-char -1) - (cond ((looking-at "\\s)") - (goto-char (scan-sexps (1+ (point)) -1)) - (case (char-before) - (?% (forward-char -1)) - ('(?q ?Q ?w ?W ?r ?x) - (if (eq (char-before (1- (point))) ?%) (forward-char -2)))) - nil) - ((looking-at "\\s\"\\|\\\\\\S_") - (let ((c (char-to-string (char-before (match-end 0))))) - (while (and (search-backward c) - (oddp (skip-chars-backward "\\"))))) - nil) - ((looking-at "\\s.\\|\\s\\") - (if (ruby-special-char-p) (forward-char -1))) - ((looking-at "\\s(") nil) - (t - (forward-char 1) - (while (progn (forward-word -1) - (case (char-before) - (?_ t) - (?. (forward-char -1) t) - ((?$ ?@) - (forward-char -1) - (and (eq (char-before) (char-after)) (forward-char -1))) - (?: - (forward-char -1) - (eq (char-before) :))))) - (if (looking-at ruby-block-end-re) - (ruby-beginning-of-block)) - nil)) - (setq i (1- i))) - ((error))) + (while (> i 0) + (skip-chars-backward " \t\n,.:;|&^~=!?\\+\\-\\*") + (forward-char -1) + (cond ((looking-at "\\s)") + (goto-char (scan-sexps (1+ (point)) -1)) + (case (char-before) + (?% (forward-char -1)) + ('(?q ?Q ?w ?W ?r ?x) + (if (eq (char-before (1- (point))) ?%) (forward-char -2)))) + nil) + ((looking-at "\\s\"\\|\\\\\\S_") + (let ((c (char-to-string (char-before (match-end 0))))) + (while (and (search-backward c) + (oddp (skip-chars-backward "\\"))))) + nil) + ((looking-at "\\s.\\|\\s\\") + (if (ruby-special-char-p) (forward-char -1))) + ((looking-at "\\s(") nil) + (t + (forward-char 1) + (while (progn (forward-word -1) + (case (char-before) + (?_ t) + (?. (forward-char -1) t) + ((?$ ?@) + (forward-char -1) + (and (eq (char-before) (char-after)) (forward-char -1))) + (?: + (forward-char -1) + (eq (char-before) :))))) + (if (looking-at ruby-block-end-re) + (ruby-beginning-of-block)) + nil)) + (setq i (1- i))) + ((error))) i))) (defun ruby-reindent-then-newline-and-indent () @@ -997,7 +1011,7 @@ (while (re-search-forward "^\\([ \t]*\\)#" end t) (replace-match "\\1" nil nil) (save-excursion - (ruby-indent-line))))) + (ruby-indent-line))))) (defun ruby-insert-end () (interactive) @@ -1022,18 +1036,18 @@ (let ((here (point-marker)) start top column (nest t)) (set-marker-insertion-type here t) (unwind-protect - (progn - (beginning-of-line) - (setq start (point) top (current-indentation)) - (while (and (not (eobp)) - (progn - (setq column (ruby-calculate-indent start)) - (cond ((> column top) - (setq nest t)) - ((and (= column top) nest) - (setq nest nil) t)))) - (ruby-indent-to column) - (beginning-of-line 2))) + (progn + (beginning-of-line) + (setq start (point) top (current-indentation)) + (while (and (not (eobp)) + (progn + (setq column (ruby-calculate-indent start)) + (cond ((> column top) + (setq nest t)) + ((and (= column top) nest) + (setq nest nil) t)))) + (ruby-indent-to column) + (beginning-of-line 2))) (goto-char here) (set-marker here nil)))) @@ -1041,62 +1055,62 @@ "Return current method string." (condition-case nil (save-excursion - (let (mname mlist (indent 0)) - ;; get current method (or class/module) - (if (re-search-backward - (concat "^[ \t]*\\(def\\|class\\|module\\)[ \t]+" - "\\(" - ;; \\. and :: for class method - "\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)" - "+\\)") - nil t) - (progn - (setq mname (match-string 2)) - (unless (string-equal "def" (match-string 1)) - (setq mlist (list mname) mname nil)) - (goto-char (match-beginning 1)) - (setq indent (current-column)) - (beginning-of-line))) - ;; nest class/module - (while (and (> indent 0) - (re-search-backward - (concat - "^[ \t]*\\(class\\|module\\)[ \t]+" - "\\([A-Z]" ruby-symbol-re "*\\)") - nil t)) - (goto-char (match-beginning 1)) - (if (< (current-column) indent) - (progn - (setq mlist (cons (match-string 2) mlist)) - (setq indent (current-column)) - (beginning-of-line)))) - (when mname - (let ((mn (split-string mname "\\.\\|::"))) - (if (cdr mn) - (progn - (cond - ((string-equal "" (car mn)) - (setq mn (cdr mn) mlist nil)) - ((string-equal "self" (car mn)) - (setq mn (cdr mn))) - ((let ((ml (nreverse mlist))) - (while ml - (if (string-equal (car ml) (car mn)) - (setq mlist (nreverse (cdr ml)) ml nil)) - (or (setq ml (cdr ml)) (nreverse mlist)))))) - (if mlist - (setcdr (last mlist) mn) - (setq mlist mn)) - (setq mn (last mn 2)) - (setq mname (concat "." (cadr mn))) - (setcdr mn nil)) - (setq mname (concat "#" mname))))) - ;; generate string - (if (consp mlist) - (setq mlist (mapconcat (function identity) mlist "::"))) - (if mname - (if mlist (concat mlist mname) mname) - mlist))))) + (let (mname mlist (indent 0)) + ;; get current method (or class/module) + (if (re-search-backward + (concat "^[ \t]*\\(def\\|class\\|module\\)[ \t]+" + "\\(" + ;; \\. and :: for class method + "\\([A-Za-z_]" ruby-symbol-re "*\\|\\.\\|::" "\\)" + "+\\)") + nil t) + (progn + (setq mname (match-string 2)) + (unless (string-equal "def" (match-string 1)) + (setq mlist (list mname) mname nil)) + (goto-char (match-beginning 1)) + (setq indent (current-column)) + (beginning-of-line))) + ;; nest class/module + (while (and (> indent 0) + (re-search-backward + (concat + "^[ \t]*\\(class\\|module\\)[ \t]+" + "\\([A-Z]" ruby-symbol-re "*\\)") + nil t)) + (goto-char (match-beginning 1)) + (if (< (current-column) indent) + (progn + (setq mlist (cons (match-string 2) mlist)) + (setq indent (current-column)) + (beginning-of-line)))) + (when mname + (let ((mn (split-string mname "\\.\\|::"))) + (if (cdr mn) + (progn + (cond + ((string-equal "" (car mn)) + (setq mn (cdr mn) mlist nil)) + ((string-equal "self" (car mn)) + (setq mn (cdr mn))) + ((let ((ml (nreverse mlist))) + (while ml + (if (string-equal (car ml) (car mn)) + (setq mlist (nreverse (cdr ml)) ml nil)) + (or (setq ml (cdr ml)) (nreverse mlist)))))) + (if mlist + (setcdr (last mlist) mn) + (setq mlist mn)) + (setq mn (last mn 2)) + (setq mname (concat "." (cadr mn))) + (setcdr mn nil)) + (setq mname (concat "#" mname))))) + ;; generate string + (if (consp mlist) + (setq mlist (mapconcat (function identity) mlist "::"))) + (if mname + (if mlist (concat mlist mname) mname) + mlist))))) (cond ((featurep 'font-lock) @@ -1104,27 +1118,27 @@ (setq font-lock-variable-name-face font-lock-type-face)) (setq ruby-font-lock-syntactic-keywords - `( - ;; #{ }, #$hoge, #@foo are not comments - ("\\(#\\)[{$@]" 1 (1 . nil)) - ;; the last $', $", $` in the respective string is not variable - ;; the last ?', ?", ?` in the respective string is not ascii code - ("\\(^\\|[\[ \t\n<+\(,=]\\)\\(['\"`]\\)\\(\\\\.\\|\\2\\|[^'\"`\n\\\\]\\)*?\\\\?[?$]\\(\\2\\)" - (2 (7 . nil)) - (4 (7 . nil))) - ;; $' $" $` .... are variables - ;; ?' ?" ?` are ascii codes - ("\\(^\\|[^\\\\]\\)\\(\\\\\\\\\\)*[?$]\\([#\"'`]\\)" 3 (1 . nil)) - ;; regexps - ("\\(^\\|[=(,~?:;<>]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)" - (4 (7 . ?/)) - (6 (7 . ?/))) - ("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil)) - ("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil)) - (,(concat ruby-here-doc-beg-re ".*\\(\n\\)") - ,(+ 1 (regexp-opt-depth ruby-here-doc-beg-re)) + `( + ;; #{ }, #$hoge, #@foo are not comments + ("\\(#\\)[{$@]" 1 (1 . nil)) + ;; the last $', $", $` in the respective string is not variable + ;; the last ?', ?", ?` in the respective string is not ascii code + ("\\(^\\|[\[ \t\n<+\(,=]\\)\\(['\"`]\\)\\(\\\\.\\|\\2\\|[^'\"`\n\\\\]\\)*?\\\\?[?$]\\(\\2\\)" + (2 (7 . nil)) + (4 (7 . nil))) + ;; $' $" $` .... are variables + ;; ?' ?" ?` are ascii codes + ("\\(^\\|[^\\\\]\\)\\(\\\\\\\\\\)*[?$]\\([#\"'`]\\)" 3 (1 . nil)) + ;; regexps + ("\\(^\\|[=(,~?:;<>]\\|\\(^\\|\\s \\)\\(if\\|elsif\\|unless\\|while\\|until\\|when\\|and\\|or\\|&&\\|||\\)\\|g?sub!?\\|scan\\|split!?\\)\\s *\\(/\\)[^/\n\\\\]*\\(\\\\.[^/\n\\\\]*\\)*\\(/\\)" + (4 (7 . ?/)) + (6 (7 . ?/))) + ("^\\(=\\)begin\\(\\s \\|$\\)" 1 (7 . nil)) + ("^\\(=\\)end\\(\\s \\|$\\)" 1 (7 . nil)) + (,(concat ruby-here-doc-beg-re ".*\\(\n\\)") + ,(+ 1 (regexp-opt-depth ruby-here-doc-beg-re)) (ruby-here-doc-beg-syntax)) - (,ruby-here-doc-end-re 3 (ruby-here-doc-end-syntax)))) + (,ruby-here-doc-end-re 3 (ruby-here-doc-end-syntax)))) (defun ruby-in-non-here-doc-string-p () (let ((syntax (syntax-ppss))) @@ -1136,7 +1150,7 @@ (defun ruby-in-here-doc-p () (save-excursion - (let ((old-point (point))) + (let ((old-point (point)) (case-fold-search nil)) (beginning-of-line) (catch 'found-beg (while (re-search-backward ruby-here-doc-beg-re nil t) @@ -1153,6 +1167,7 @@ (beginning-of-line) (catch 'done (let ((eol (save-excursion (end-of-line) (point))) + (case-fold-search nil) ;; Fake match data such that (match-end 0) is at eol (end-match-data (progn (looking-at ".*$") (match-data))) beg-match-data end-re) @@ -1179,51 +1194,51 @@ (string-to-syntax "|")))) (defun ruby-here-doc-end-syntax () - (save-excursion - (goto-char (match-end 0)) - (let ((old-point (point)) - (beg-exists (re-search-backward (ruby-here-doc-beg-match) nil t)) - (eol (save-excursion (end-of-line) (point)))) - (if (and beg-exists ; If there is a heredoc that matches this line... - (null (syntax-ppss-context (syntax-ppss))) ; And that's not inside a heredoc/string/comment... - (progn (goto-char (match-end 0)) ; And it's the last heredoc on its line... - (not (re-search-forward ruby-here-doc-beg-re eol t))) - (eq old-point (ruby-here-doc-find-end old-point))) ; And it ends at this point... - (string-to-syntax "|"))))) + (let ((pss (syntax-ppss)) (case-fold-search nil)) + (when (eq (syntax-ppss-context pss) 'string) + (save-excursion + (goto-char (nth 8 pss)) + (let ((eol (point))) + (beginning-of-line) + (if (and (re-search-forward (ruby-here-doc-beg-match) eol t) ; If there is a heredoc that matches this line... + (null (syntax-ppss-context (syntax-ppss))) ; And that's not inside a heredoc/string/comment... + (progn (goto-char (match-end 0)) ; And it's the last heredoc on its line... + (not (re-search-forward ruby-here-doc-beg-re eol t)))) + (string-to-syntax "|"))))))) (if (featurep 'xemacs) (put 'ruby-mode 'font-lock-defaults - '((ruby-font-lock-keywords) - nil nil nil - beginning-of-line - (font-lock-syntactic-keywords - . ruby-font-lock-syntactic-keywords)))) + '((ruby-font-lock-keywords) + nil nil nil + beginning-of-line + (font-lock-syntactic-keywords + . ruby-font-lock-syntactic-keywords)))) (defun ruby-font-lock-docs (limit) (if (re-search-forward "^=begin\\(\\s \\|$\\)" limit t) - (let (beg) - (beginning-of-line) - (setq beg (point)) - (forward-line 1) - (if (re-search-forward "^=end\\(\\s \\|$\\)" limit t) - (progn - (set-match-data (list beg (point))) - t))))) + (let (beg) + (beginning-of-line) + (setq beg (point)) + (forward-line 1) + (if (re-search-forward "^=end\\(\\s \\|$\\)" limit t) + (progn + (set-match-data (list beg (point))) + t))))) (defun ruby-font-lock-maybe-docs (limit) (let (beg) (save-excursion - (if (and (re-search-backward "^=\\(begin\\|end\\)\\(\\s \\|$\\)" nil t) - (string= (match-string 1) "begin")) - (progn - (beginning-of-line) - (setq beg (point))))) + (if (and (re-search-backward "^=\\(begin\\|end\\)\\(\\s \\|$\\)" nil t) + (string= (match-string 1) "begin")) + (progn + (beginning-of-line) + (setq beg (point))))) (if (and beg (and (re-search-forward "^=\\(begin\\|end\\)\\(\\s \\|$\\)" nil t) - (string= (match-string 1) "end"))) - (progn - (set-match-data (list beg (point))) - t) - nil))) + (string= (match-string 1) "end"))) + (progn + (set-match-data (list beg (point))) + t) + nil))) (defvar ruby-font-lock-syntax-table (let* ((tbl (copy-syntax-table ruby-mode-syntax-table))) @@ -1237,48 +1252,47 @@ 1 font-lock-function-name-face) ;; keywords (cons (concat - "\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(defined\\?\\|\\(" - (mapconcat - 'identity - '("alias" - "and" - "begin" - "break" - "case" - "catch" - "class" - "def" - "do" - "elsif" - "else" - "fail" - "ensure" - "for" - "end" - "if" - "in" - "module" - "next" - "not" - "or" - "raise" - "redo" - "rescue" - "retry" - "return" - "then" - "throw" - "super" - "unless" - "undef" - "until" - "when" - "while" - "yield" - ) - "\\|") - "\\)\\>\\)") - 2) + "\\(^\\|[^_:.@$]\\|\\.\\.\\)\\b\\(defined\\?\\|" + (regexp-opt + '("alias" + "and" + "begin" + "break" + "case" + "catch" + "class" + "def" + "do" + "elsif" + "else" + "fail" + "ensure" + "for" + "end" + "if" + "in" + "module" + "next" + "not" + "or" + "raise" + "redo" + "rescue" + "retry" + "return" + "then" + "throw" + "super" + "unless" + "undef" + "until" + "when" + "while" + "yield" + ) + t) + "\\_>\\)") + 2) ;; here-doc beginnings (list ruby-here-doc-beg-re 0 'font-lock-string-face) ;; variables Index: mvm/misc/ruby-electric.el =================================================================== --- mvm/misc/ruby-electric.el (revision 19235) +++ mvm/misc/ruby-electric.el (revision 19236) @@ -67,8 +67,8 @@ (?\` . ?\`) (?\" . ?\"))) -(defcustom ruby-electric-simple-keywords-re - "\\(def\\|if\\|class\\|module\\|unless\\|case\\|while\\|do\\|until\\|for\\|begin\\)" +(defcustom ruby-electric-simple-keywords-re + (regexp-opt '("def" "if" "class" "module" "unless" "case" "while" "do" "until" "for" "begin") t) "*Regular expresion matching keywords for which closing 'end' is to be inserted." :type 'regexp :group 'ruby-electric) @@ -77,14 +77,14 @@ "*List of contexts where matching delimiter should be inserted. The word 'all' will do all insertions." :type '(set :extra-offset 8 - (const :tag "Everything" all ) - (const :tag "Curly brace" ?\{ ) - (const :tag "Square brace" ?\[ ) - (const :tag "Round brace" ?\( ) - (const :tag "Quote" ?\' ) - (const :tag "Double quote" ?\" ) - (const :tag "Back quote" ?\` ) - (const :tag "Vertical bar" ?\| )) + (const :tag "Everything" all ) + (const :tag "Curly brace" ?\{ ) + (const :tag "Square brace" ?\[ ) + (const :tag "Round brace" ?\( ) + (const :tag "Quote" ?\' ) + (const :tag "Double quote" ?\" ) + (const :tag "Back quote" ?\` ) + (const :tag "Vertical bar" ?\| )) :group 'ruby-electric) (defcustom ruby-electric-newline-before-closing-bracket nil @@ -126,15 +126,15 @@ (self-insert-command (prefix-numeric-value arg)) (if (ruby-electric-space-can-be-expanded-p) (save-excursion - (ruby-indent-line t) - (newline) - (ruby-insert-end)))) + (ruby-indent-line t) + (newline) + (ruby-insert-end)))) (defun ruby-electric-code-at-point-p() (and ruby-electric-mode (let* ((properties (text-properties-at (point)))) - (and (null (memq 'font-lock-string-face properties)) - (null (memq 'font-lock-comment-face properties)))))) + (and (null (memq 'font-lock-string-face properties)) + (null (memq 'font-lock-comment-face properties)))))) (defun ruby-electric-string-at-point-p() (and ruby-electric-mode @@ -147,17 +147,17 @@ (defun ruby-electric-space-can-be-expanded-p() (if (ruby-electric-code-at-point-p) (let* ((ruby-electric-keywords-re - (concat ruby-electric-simple-keywords-re "\\s-$")) - (ruby-electric-single-keyword-in-line-re - (concat "\\s-*" ruby-electric-keywords-re))) - (save-excursion - (backward-word 1) - (or (looking-at ruby-electric-expandable-do-re) - (and (looking-at ruby-electric-keywords-re) - (not (string= "do" (match-string 1))) - (progn - (beginning-of-line) - (looking-at ruby-electric-single-keyword-in-line-re)))))))) + (concat ruby-electric-simple-keywords-re "\\s-$")) + (ruby-electric-single-keyword-in-line-re + (concat "\\s-*" ruby-electric-keywords-re))) + (save-excursion + (backward-word 1) + (or (looking-at ruby-electric-expandable-do-re) + (and (looking-at ruby-electric-keywords-re) + (not (string= "do" (match-string 1))) + (progn + (beginning-of-line) + (looking-at ruby-electric-single-keyword-in-line-re)))))))) (defun ruby-electric-curlies(arg) @@ -165,17 +165,17 @@ (self-insert-command (prefix-numeric-value arg)) (if (ruby-electric-is-last-command-char-expandable-punct-p) (cond ((ruby-electric-code-at-point-p) - (insert " ") - (save-excursion - (if ruby-electric-newline-before-closing-bracket - (newline)) - (insert "}"))) - ((ruby-electric-string-at-point-p) - (save-excursion - (backward-char 1) - (when (char-equal ?\# (preceding-char)) - (forward-char 1) - (insert "}"))))))) + (insert " ") + (save-excursion + (if ruby-electric-newline-before-closing-bracket + (newline)) + (insert "}"))) + ((ruby-electric-string-at-point-p) + (save-excursion + (backward-char 1) + (when (char-equal ?\# (preceding-char)) + (forward-char 1) + (insert "}"))))))) (defun ruby-electric-matching-char(arg) (interactive "P") @@ -183,8 +183,8 @@ (and (ruby-electric-is-last-command-char-expandable-punct-p) (ruby-electric-code-at-point-p) (save-excursion - (insert (cdr (assoc last-command-char - ruby-electric-matching-delimeter-alist)))))) + (insert (cdr (assoc last-command-char + ruby-electric-matching-delimeter-alist)))))) (defun ruby-electric-bar(arg) (interactive "P") @@ -192,9 +192,9 @@ (and (ruby-electric-is-last-command-char-expandable-punct-p) (ruby-electric-code-at-point-p) (and (save-excursion (re-search-backward ruby-electric-expandable-bar nil t)) - (= (point) (match-end 0))) ;looking-back is missing on XEmacs + (= (point) (match-end 0))) ;looking-back is missing on XEmacs (save-excursion - (insert "|")))) + (insert "|")))) (provide 'ruby-electric) Index: mvm/misc/inf-ruby.el =================================================================== --- mvm/misc/inf-ruby.el (revision 19235) +++ mvm/misc/inf-ruby.el (revision 19236) @@ -18,7 +18,7 @@ ;;; (setq auto-mode-alist ;;; (append '(("\\.rb$" . ruby-mode)) auto-mode-alist)) ;;; (setq interpreter-mode-alist (append '(("ruby" . ruby-mode)) -;;; interpreter-mode-alist)) +;;; interpreter-mode-alist)) ;;; ;;; (2) set to load inf-ruby and set inf-ruby key definition in ruby-mode. ;;; @@ -33,79 +33,79 @@ ;;; ;;; HISTORY ;;; senda - 8 Apr 1998: Created. -;;; $Log$ -;;; Revision 1.7 2004/07/27 08:11:36 matz -;;; * eval.c (rb_eval): copy on write for argument local variable -;;; assignment. +;;; $Log$ +;;; Revision 1.7 2004/07/27 08:11:36 matz +;;; * eval.c (rb_eval): copy on write for argument local variable +;;; assignment. ;;; -;;; * eval.c (assign): ditto. +;;; * eval.c (assign): ditto. ;;; -;;; * eval.c (rb_call0): update ruby_frame->argv with the default -;;; value used for the optional arguments. +;;; * eval.c (rb_call0): update ruby_frame->argv with the default +;;; value used for the optional arguments. ;;; -;;; * object.c (Init_Object): "===" calls rb_obj_equal() directly. -;;; [ruby-list:39937] +;;; * object.c (Init_Object): "===" calls rb_obj_equal() directly. +;;; [ruby-list:39937] ;;; -;;; Revision 1.6 2002/09/07 14:35:46 nobu -;;; * misc/inf-ruby.el (inferior-ruby-error-regexp-alist): regexp -;;; alist for error message from ruby. -;;; -;;; * misc/inf-ruby.el (inferior-ruby-mode): fixed for Emacs. -;;; -;;; * misc/inf-ruby.el (ruby-send-region): compilation-parse-errors -;;; doesn't parse first line, so insert separators before each -;;; evaluations. -;;; -;;; Revision 1.5 2002/08/19 10:05:47 nobu -;;; * misc/inf-ruby.el (inf-ruby-keys): ruby-send-definition -;;; conflicted with ruby-insert-end. -;;; -;;; * misc/inf-ruby.el (inferior-ruby-mode): compilation-minor-mode. -;;; -;;; * misc/inf-ruby.el (ruby-send-region): send as here document to -;;; adjust source file/line. [ruby-talk:47113], [ruby-dev:17965] -;;; -;;; * misc/inf-ruby.el (ruby-send-terminator): added to make unique -;;; terminator. -;;; -;;; Revision 1.4 2002/01/29 07:16:09 matz -;;; * file.c (rb_stat_rdev_major): added. [new] -;;; -;;; * file.c (rb_stat_rdev_minor): added. [new] -;;; -;;; * file.c (rb_stat_inspect): print mode in octal. -;;; -;;; Revision 1.3 1999/12/01 09:24:18 matz -;;; 19991201 -;;; -;;; Revision 1.2 1999/08/13 05:45:18 matz -;;; 1.4.0 -;;; -;;; Revision 1.1.1.1.2.1 1999/07/15 07:59:59 matz -;;; 990715 -;;; -;;; Revision 1.1.1.1 1999/01/20 04:59:36 matz -;;; ruby 1.3 cycle -;;; -;;; Revision 1.1.2.1 1998/12/16 07:30:36 matz -;;; first public release of 1.1d (pre1.2) series -;;; -;;; Revision 1.4 1998/05/20 02:45:58 senda -;;; default program to irb +;;; Revision 1.6 2002/09/07 14:35:46 nobu +;;; * misc/inf-ruby.el (inferior-ruby-error-regexp-alist): regexp +;;; alist for error message from ruby. +;;; +;;; * misc/inf-ruby.el (inferior-ruby-mode): fixed for Emacs. +;;; +;;; * misc/inf-ruby.el (ruby-send-region): compilation-parse-errors +;;; doesn't parse first line, so insert separators before each +;;; evaluations. +;;; +;;; Revision 1.5 2002/08/19 10:05:47 nobu +;;; * misc/inf-ruby.el (inf-ruby-keys): ruby-send-definition +;;; conflicted with ruby-insert-end. +;;; +;;; * misc/inf-ruby.el (inferior-ruby-mode): compilation-minor-mode. +;;; +;;; * misc/inf-ruby.el (ruby-send-region): send as here document to +;;; adjust source file/line. [ruby-talk:47113], [ruby-dev:17965] +;;; +;;; * misc/inf-ruby.el (ruby-send-terminator): added to make unique +;;; terminator. +;;; +;;; Revision 1.4 2002/01/29 07:16:09 matz +;;; * file.c (rb_stat_rdev_major): added. [new] +;;; +;;; * file.c (rb_stat_rdev_minor): added. [new] +;;; +;;; * file.c (rb_stat_inspect): print mode in octal. +;;; +;;; Revision 1.3 1999/12/01 09:24:18 matz +;;; 19991201 +;;; +;;; Revision 1.2 1999/08/13 05:45:18 matz +;;; 1.4.0 +;;; +;;; Revision 1.1.1.1.2.1 1999/07/15 07:59:59 matz +;;; 990715 +;;; +;;; Revision 1.1.1.1 1999/01/20 04:59:36 matz +;;; ruby 1.3 cycle +;;; +;;; Revision 1.1.2.1 1998/12/16 07:30:36 matz +;;; first public release of 1.1d (pre1.2) series +;;; +;;; Revision 1.4 1998/05/20 02:45:58 senda +;;; default program to irb ;;; -;;; Revision 1.3 1998/04/10 04:11:30 senda -;;; modification by Matsumoto san (1.1b9_09) -;;; remove-in-string defined -;;; global variable : -;;; inferior-ruby-first-prompt-pattern -;;; inferior-ruby-prompt-pattern -;;; defined +;;; Revision 1.3 1998/04/10 04:11:30 senda +;;; modification by Matsumoto san (1.1b9_09) +;;; remove-in-string defined +;;; global variable : +;;; inferior-ruby-first-prompt-pattern +;;; inferior-ruby-prompt-pattern +;;; defined ;;; -;;; Revision 1.2 1998/04/09 07:53:42 senda -;;; remove M-C-x in inferior-ruby-mode +;;; Revision 1.2 1998/04/09 07:53:42 senda +;;; remove M-C-x in inferior-ruby-mode ;;; -;;; Revision 1.1 1998/04/09 07:28:36 senda -;;; Initial revision +;;; Revision 1.1 1998/04/09 07:28:36 senda +;;; Initial revision ;;; ;;; @@ -145,13 +145,13 @@ (defconst inferior-ruby-error-regexp-alist '(("SyntaxError: compile error\n^\\([^\(].*\\):\\([1-9][0-9]*\\):" 1 2) - ("^\tfrom \\([^\(].*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?$" 1 2))) + ("^\tfrom \\([^\(].*\\):\\([1-9][0-9]*\\)\\(:in `.*'\\)?$" 1 2))) (cond ((not inferior-ruby-mode-map) (setq inferior-ruby-mode-map - (copy-keymap comint-mode-map)) + (copy-keymap comint-mode-map)) ; (define-key inferior-ruby-mode-map "\M-\C-x" ;gnu convention -; 'ruby-send-definition) +; 'ruby-send-definition) ; (define-key inferior-ruby-mode-map "\C-x\C-e" 'ruby-send-last-sexp) (define-key inferior-ruby-mode-map "\C-c\C-l" 'ruby-load-file) )) @@ -239,8 +239,8 @@ (let ((rtn-str "") (start 0) match prev-start) (while (setq match (string-match regexp str start)) (setq prev-start start - start (match-end 0) - rtn-str (concat rtn-str (substring str prev-start match)))) + start (match-end 0) + rtn-str (concat rtn-str (substring str prev-start match)))) (concat rtn-str (substring str start)))) (defun ruby-get-old-input () @@ -249,21 +249,21 @@ (let ((end (point))) (re-search-backward inferior-ruby-first-prompt-pattern) (remove-in-string (buffer-substring (point) end) - inferior-ruby-prompt-pattern) + inferior-ruby-prompt-pattern) ))) (defun ruby-args-to-list (string) (let ((where (string-match "[ \t]" string))) (cond ((null where) (list string)) - ((not (= where 0)) - (cons (substring string 0 where) - (ruby-args-to-list (substring string (+ 1 where) - (length string))))) - (t (let ((pos (string-match "[^ \t]" string))) - (if (null pos) - nil - (ruby-args-to-list (substring string pos - (length string))))))))) + ((not (= where 0)) + (cons (substring string 0 where) + (ruby-args-to-list (substring string (+ 1 where) + (length string))))) + (t (let ((pos (string-match "[^ \t]" string))) + (if (null pos) + nil + (ruby-args-to-list (substring string pos + (length string))))))))) (defun run-ruby (cmd) "Run an inferior Ruby process, input and output via buffer *ruby*. @@ -274,13 +274,13 @@ \(Type \\[describe-mode] in the process buffer for a list of commands.)" (interactive (list (if current-prefix-arg - (read-string "Run Ruby: " ruby-program-name) - ruby-program-name))) + (read-string "Run Ruby: " ruby-program-name) + ruby-program-name))) (if (not (comint-check-proc "*ruby*")) (let ((cmdlist (ruby-args-to-list cmd))) - (set-buffer (apply 'make-comint "ruby" (car cmdlist) - nil (cdr cmdlist))) - (inferior-ruby-mode))) + (set-buffer (apply 'make-comint "ruby" (car cmdlist) + nil (cdr cmdlist))) + (inferior-ruby-mode))) (setq ruby-program-name cmd) (setq ruby-buffer "*ruby*") (pop-to-buffer "*ruby*")) @@ -297,20 +297,20 @@ (let (term (file (buffer-file-name)) line) (save-excursion (save-restriction - (widen) - (goto-char start) - (setq line (+ start (forward-line (- start)) 1)) - (goto-char start) - (while (progn - (setq term (apply 'format ruby-send-terminator (random) (current-time))) - (re-search-forward (concat "^" (regexp-quote term) "$") end t))))) + (widen) + (goto-char start) + (setq line (+ start (forward-line (- start)) 1)) + (goto-char start) + (while (progn + (setq term (apply 'format ruby-send-terminator (random) (current-time))) + (re-search-forward (concat "^" (regexp-quote term) "$") end t))))) ;; compilation-parse-errors parses from second line. (save-excursion (let ((m (process-mark (ruby-proc)))) - (set-buffer (marker-buffer m)) - (goto-char m) - (insert ruby-eval-separator "\n") - (set-marker m (point)))) + (set-buffer (marker-buffer m)) + (goto-char m) + (insert ruby-eval-separator "\n") + (set-marker m (point)))) (comint-send-string (ruby-proc) (format "eval <<'%s', nil, %S, %d\n" term file line)) (comint-send-region (ruby-proc) start end) (comint-send-string (ruby-proc) (concat "\n" term "\n")))) @@ -347,8 +347,8 @@ (pop-to-buffer ruby-buffer) (error "No current process buffer. See variable ruby-buffer.")) (cond (eob-p - (push-mark) - (goto-char (point-max))))) + (push-mark) + (goto-char (point-max))))) (defun ruby-send-region-and-go (start end) "Send the current region to the inferior Ruby process. @@ -386,29 +386,29 @@ (defun ruby-load-file (file-name) "Load a Ruby file into the inferior Ruby process." (interactive (comint-get-source "Load Ruby file: " ruby-prev-l/c-dir/file - ruby-source-modes t)) ; T because LOAD + ruby-source-modes t)) ; T because LOAD ; needs an exact name (comint-check-source file-name) ; Check to see if buffer needs saved. (setq ruby-prev-l/c-dir/file (cons (file-name-directory file-name) - (file-name-nondirectory file-name))) + (file-name-nondirectory file-name))) (comint-send-string (ruby-proc) (concat "(load \"" - file-name - "\"\)\n"))) + file-name + "\"\)\n"))) (defun ruby-proc () "Returns the current ruby process. See variable ruby-buffer." (let ((proc (get-buffer-process (if (eq major-mode 'inferior-ruby-mode) - (current-buffer) - ruby-buffer)))) + (current-buffer) + ruby-buffer)))) (or proc - (error "No current process. See variable ruby-buffer")))) + (error "No current process. See variable ruby-buffer")))) ;;; Do the user's customisation... (defvar inf-ruby-load-hook nil "This hook is run when inf-ruby is loaded in. This is a good place to put keybindings.") - + (run-hooks 'inf-ruby-load-hook) (provide 'inf-ruby) Index: mvm/misc/ruby-style.el =================================================================== --- mvm/misc/ruby-style.el (revision 19235) +++ mvm/misc/ruby-style.el (revision 19236) @@ -21,7 +21,7 @@ (save-excursion (back-to-indentation) (unless (progn (backward-up-list) (back-to-indentation) - (> (point) (cdr x))) + (> (point) (cdr x))) (goto-char (cdr x)) (if (looking-at "\\<case\\|default\\>") '*)))) @@ -29,14 +29,14 @@ (save-excursion (back-to-indentation) (unless (progn (backward-up-list) (back-to-indentation) - (>= (point) (cdr x))) + (>= (point) (cdr x))) (goto-char (cdr x)) (condition-case () - (progn - (backward-up-list) - (backward-sexp 2) - (if (looking-at "\\<switch\\>") '/)) - (error))))) + (progn + (backward-up-list) + (backward-sexp 2) + (if (looking-at "\\<switch\\>") '/)) + (error))))) (require 'cc-styles) (c-add-style Index: mvm/enc/emacs_mule.c =================================================================== --- mvm/enc/emacs_mule.c (revision 19235) +++ mvm/enc/emacs_mule.c (revision 19236) @@ -338,3 +338,4 @@ 0 }; +ENC_REPLICATE("stateless-ISO-2022-JP", "Emacs-Mule") Index: mvm/sample/test.rb =================================================================== --- mvm/sample/test.rb (revision 19235) +++ mvm/sample/test.rb (revision 19236) @@ -296,6 +296,64 @@ test_ok(f.call([42,55]) == [[42,55]]) test_ok(f.call(42,55) == [42,55]) +f = lambda { |a, b=42, *c| [a,b,c] } +test_ok(f.call(1 ) == [1,42,[ ]] ) +test_ok(f.call(1,43 ) == [1,43,[ ]] ) +test_ok(f.call(1,43,44) == [1,43,[44]] ) + +f = lambda { |a, b=(a|16), *c, &block| [a,b,c,block&&block[]] } +test_ok(f.call(8 ) == [8,24,[ ],nil] ) +test_ok(f.call(8,43 ) == [8,43,[ ],nil] ) +test_ok(f.call(8,43,44) == [8,43,[44],nil] ) +test_ok(f.call(8 ){45} == [8,24,[ ],45 ] ) +test_ok(f.call(8,43 ){45} == [8,43,[ ],45 ] ) +test_ok(f.call(8,43,44){45} == [8,43,[44],45 ] ) + +f = lambda { |a, b=42, *c, d| [a,b,c,d] } +test_ok(f.call(1 ,99) == [1,42,[ ],99] ) +test_ok(f.call(1,43 ,99) == [1,43,[ ],99] ) +test_ok(f.call(1,43,44,99) == [1,43,[44],99] ) + +f = lambda { |a, b=(a|16), &block| [a,b,block&&block[]] } +test_ok(f.call(8 ) == [8,24,nil] ) +test_ok(f.call(8,43) == [8,43,nil] ) +test_ok(f.call(8,43) == [8,43,nil] ) +test_ok(f.call(8 ){45} == [8,24,45 ] ) +test_ok(f.call(8,43){45} == [8,43,45 ] ) +test_ok(f.call(8,43){45} == [8,43,45 ] ) + +f = lambda { |a, b=42, d| [a,b,d] } +test_ok(f.call(1 ,99) == [1,42,99] ) +test_ok(f.call(1,43,99) == [1,43,99] ) +test_ok(f.call(1,43,99) == [1,43,99] ) + +f = lambda { |b=42, *c, &block| [b,c,block&&block[]] } +test_ok(f.call( ) == [42,[ ],nil] ) +test_ok(f.call(43 ) == [43,[ ],nil] ) +test_ok(f.call(43,44) == [43,[44],nil] ) +test_ok(f.call( ){45} == [42,[ ],45 ] ) +test_ok(f.call(43 ){45} == [43,[ ],45 ] ) +test_ok(f.call(43,44){45} == [43,[44],45 ] ) + +f = lambda { |b=42, *c, d| [b,c,d] } +test_ok(f.call( 99) == [42,[ ],99] ) +test_ok(f.call(43 ,99) == [43,[ ],99] ) +test_ok(f.call(43,44,99) == [43,[44],99] ) + +f = lambda { |b=42, &block| [b,block&&block[]] } +test_ok(f.call( ) == [42,nil] ) +test_ok(f.call(43) == [43,nil] ) +test_ok(f.call(43) == [43,nil] ) +test_ok(f.call( ){45} == [42,45 ] ) +test_ok(f.call(43){45} == [43,45 ] ) +test_ok(f.call(43){45} == [43,45 ] ) + +f = lambda { |b=42, d| [b,d] } +test_ok(f.call( 99) == [42,99] ) +test_ok(f.call(43,99) == [43,99] ) +test_ok(f.call(43,99) == [43,99] ) + + a,=*[1] test_ok(a == 1) a,=*[[1]] Index: mvm/string.c =================================================================== --- mvm/string.c (revision 19235) +++ mvm/string.c (revision 19236) @@ -5886,6 +5886,10 @@ extern char *crypt(const char *, const char *); VALUE result; const char *s; +#ifdef BROKEN_CRYPT + VALUE salt_8bit_clean; + rb_encoding *enc; +#endif StringValue(salt); if (RSTRING_LEN(salt) < 2) @@ -5893,7 +5897,18 @@ if (RSTRING_PTR(str)) s = RSTRING_PTR(str); else s = ""; +#ifdef BROKEN_CRYPT + salt_8bit_clean = rb_str_dup(salt); + enc = rb_ascii8bit_encoding(); + str_modifiable(salt_8bit_clean); + rb_enc_associate(salt_8bit_clean, enc); + salt_8bit_clean = rb_str_tr(salt_8bit_clean, + rb_enc_str_new("\x80-\xFF", 3, enc), + rb_usascii_str_new("\x00-\x7F", 3)); + result = rb_str_new2(crypt(s, RSTRING_PTR(salt_8bit_clean))); +#else result = rb_str_new2(crypt(s, RSTRING_PTR(salt))); +#endif OBJ_INFECT(result, str); OBJ_INFECT(result, salt); return result; Index: mvm/io.c =================================================================== --- mvm/io.c (revision 19235) +++ mvm/io.c (revision 19236) @@ -683,7 +683,7 @@ # define NEED_NEWLINE_ENCODER(fptr) 0 #endif #define NEED_READCONV(fptr) (fptr->encs.enc2 != NULL || NEED_NEWLINE_DECODER(fptr)) -#define NEED_WRITECONV(fptr) (fptr->encs.enc != NULL || NEED_NEWLINE_ENCODER(fptr)) +#define NEED_WRITECONV(fptr) (fptr->encs.enc != NULL || NEED_NEWLINE_ENCODER(fptr) || (fptr->encs.ecflags & (ECONV_DECODER_MASK|ECONV_ENCODER_MASK|ECONV_STATEFUL_ENCODER_MASK))) static void make_writeconv(rb_io_t *fptr) @@ -696,41 +696,58 @@ fptr->writeconv_initialized = 1; - /* ECONV_INVALID_XXX and ECONV_UNDEF_XXX should be set both. - * But ECONV_CRLF_NEWLINE_ENCODER should be set only for the first. */ - fptr->writeconv_pre_ecflags = fptr->encs.ecflags; - fptr->writeconv_pre_ecopts = fptr->encs.ecopts; ecflags = fptr->encs.ecflags; ecopts = fptr->encs.ecopts; +#ifdef TEXTMODE_NEWLINE_ENCODER + if (NEED_NEWLINE_ENCODER(fptr)) + ecflags |= TEXTMODE_NEWLINE_ENCODER; +#endif -#ifdef TEXTMODE_NEWLINE_ENCODER if (!fptr->encs.enc) { - if (NEED_NEWLINE_ENCODER(fptr)) - ecflags |= TEXTMODE_NEWLINE_ENCODER; + /* no encoding conversion */ + fptr->writeconv_pre_ecflags = 0; + fptr->writeconv_pre_ecopts = Qnil; fptr->writeconv = rb_econv_open_opts("", "", ecflags, ecopts); if (!fptr->writeconv) rb_exc_raise(rb_econv_open_exc("", "", ecflags)); fptr->writeconv_stateless = Qnil; - return; } - - if (NEED_NEWLINE_ENCODER(fptr)) - fptr->writeconv_pre_ecflags |= TEXTMODE_NEWLINE_ENCODER; -#endif - - enc = fptr->encs.enc2 ? fptr->encs.enc2 : fptr->encs.enc; - senc = rb_econv_stateless_encoding(enc->name); - if (senc) { - denc = enc->name; - fptr->writeconv_stateless = rb_str_new2(senc); - fptr->writeconv = rb_econv_open_opts(senc, denc, ecflags, ecopts); - if (!fptr->writeconv) - rb_exc_raise(rb_econv_open_exc(senc, denc, ecflags)); - } else { - denc = NULL; - fptr->writeconv_stateless = Qnil; - fptr->writeconv = NULL; + enc = fptr->encs.enc2 ? fptr->encs.enc2 : fptr->encs.enc; + senc = rb_econv_stateless_encoding(enc->name); + if (!senc && !(fptr->encs.ecflags & ECONV_STATEFUL_ENCODER_MASK)) { + /* single conversion */ + fptr->writeconv_pre_ecflags = ecflags; + fptr->writeconv_pre_ecopts = ecopts; + fptr->writeconv = NULL; + fptr->writeconv_stateless = Qnil; + } + else { + /* double conversion */ + fptr->writeconv_pre_ecflags = ecflags & ~ECONV_STATEFUL_ENCODER_MASK; + fptr->writeconv_pre_ecopts = ecopts; + if (senc) { + denc = enc->name; + fptr->writeconv_stateless = rb_str_new2(senc); + } + else if ((fptr->encs.ecflags & ECONV_STATEFUL_ENCODER_MASK) && !rb_enc_asciicompat(enc)) { + /* xxx: stateful encoder works for ASCII compatible encoding. + * So we need to choose an encoding which is ASCII compatible and superset of enc. + * For encodings which is superset of UTF-8, UTF-8 is not appropriate choice. */ + senc = "UTF-8"; + denc = enc->name; + fptr->writeconv_stateless = rb_str_new2("UTF-8"); + } + else { + senc = denc = ""; + fptr->writeconv_stateless = rb_str_new2(enc->name); + } + ecflags = fptr->encs.ecflags & (ECONV_ERROR_HANDLER_MASK|ECONV_STATEFUL_ENCODER_MASK); + ecopts = fptr->encs.ecopts; + fptr->writeconv = rb_econv_open_opts(senc, denc, ecflags, ecopts); + if (!fptr->writeconv) + rb_exc_raise(rb_econv_open_exc(senc, denc, ecflags)); + } } } } @@ -3514,6 +3531,7 @@ rb_econv_binmode(fptr->writeconv); fptr->mode |= FMODE_BINMODE; fptr->mode &= ~FMODE_TEXTMODE; + fptr->writeconv_pre_ecflags &= ~(ECONV_UNIVERSAL_NEWLINE_DECODER|ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER); return io; } Index: mvm/proc.c =================================================================== --- mvm/proc.c (revision 19235) +++ mvm/proc.c (revision 19236) @@ -461,12 +461,14 @@ * call-seq: * prc.call(params,...) => obj * prc[params,...] => obj + * prc.(params,...) => obj * * Invokes the block, setting the block's parameters to the values in * <i>params</i> using something close to method calling semantics. * Generates a warning if multiple values are passed to a proc that * expects just one (previously this silently converted the parameters - * to an array). + * to an array). Note that prc.() invokes prc.call() with the parameters + * given. It's a syntax sugar to hide "call". * * For procs created using <code>Kernel.proc</code>, generates an * error if the wrong number of parameters @@ -489,6 +491,14 @@ * from prog.rb:5 */ +/* + * call-seq: + * prc === obj => obj + * + * Invokes the block, with <i>obj</i> as the block's parameter. It is + * to allow a proc object to be a target of when clause in the case statement. + */ + static VALUE proc_call(int argc, VALUE *argv, VALUE procval) { @@ -1740,6 +1750,7 @@ rb_define_singleton_method(rb_cProc, "new", rb_proc_s_new, -1); rb_define_method(rb_cProc, "call", proc_call, -1); rb_define_method(rb_cProc, "[]", proc_call, -1); + rb_define_method(rb_cProc, "===", proc_call, -1); rb_define_method(rb_cProc, "yield", proc_call, -1); rb_define_method(rb_cProc, "to_proc", proc_to_proc, 0); rb_define_method(rb_cProc, "arity", proc_arity, 0); Index: mvm/parse.y =================================================================== --- mvm/parse.y (revision 19235) +++ mvm/parse.y (revision 19236) @@ -673,6 +673,7 @@ %type <node> paren_args opt_paren_args %type <node> command_args aref_args opt_block_arg block_arg var_ref var_lhs %type <node> mrhs superclass block_call block_command +%type <node> f_block_optarg f_block_opt %type <node> f_arglist f_args f_arg f_arg_item f_optarg f_marg f_marg_list f_margs %type <node> assoc_list assocs assoc undef_list backref string_dvar for_var %type <node> block_param opt_block_param block_param_def f_opt @@ -3206,9 +3207,41 @@ } ; -block_param : f_arg ',' f_rest_arg opt_f_block_arg +block_param : f_arg ',' f_block_optarg ',' f_rest_arg opt_f_block_arg { /*%%%*/ + $$ = new_args($1, $3, $5, 0, $6); + /*% + $$ = params_new($1, $3, $5, Qnil, escape_Qundef($6)); + %*/ + } + | f_arg ',' f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg + { + /*%%%*/ + $$ = new_args($1, $3, $5, $7, $8); + /*% + $$ = params_new($1, $3, $5, $7, escape_Qundef($8)); + %*/ + } + | f_arg ',' f_block_optarg opt_f_block_arg + { + /*%%%*/ + $$ = new_args($1, $3, 0, 0, $4); + /*% + $$ = params_new($1, $3, Qnil, Qnil, escape_Qundef($4)); + %*/ + } + | f_arg ',' f_block_optarg ',' f_arg opt_f_block_arg + { + /*%%%*/ + $$ = new_args($1, $3, 0, $5, $6); + /*% + $$ = params_new($1, $3, Qnil, $5, escape_Qundef($6)); + %*/ + } + | f_arg ',' f_rest_arg opt_f_block_arg + { + /*%%%*/ $$ = new_args($1, 0, $3, 0, $4); /*% $$ = params_new($1, Qnil, $3, Qnil, escape_Qundef($4)); @@ -3239,6 +3272,38 @@ $$ = params_new($1, Qnil,Qnil, Qnil, escape_Qundef($2)); %*/ } + | f_block_optarg ',' f_rest_arg opt_f_block_arg + { + /*%%%*/ + $$ = new_args(0, $1, $3, 0, $4); + /*% + $$ = params_new(Qnil, $1, $3, Qnil, escape_Qundef($4)); + %*/ + } + | f_block_optarg ',' f_rest_arg ',' f_arg opt_f_block_arg + { + /*%%%*/ + $$ = new_args(0, $1, $3, $5, $6); + /*% + $$ = params_new(Qnil, $1, $3, $5, escape_Qundef($6)); + %*/ + } + | f_block_optarg opt_f_block_arg + { + /*%%%*/ + $$ = new_args(0, $1, 0, 0, $2); + /*% + $$ = params_new(Qnil, $1, Qnil, Qnil,escape_Qundef($2)); + %*/ + } + | f_block_optarg ',' f_arg opt_f_block_arg + { + /*%%%*/ + $$ = new_args(0, $1, 0, $3, $4); + /*% + $$ = params_new(Qnil, $1, Qnil, $3, escape_Qundef($4)); + %*/ + } | f_rest_arg opt_f_block_arg { /*%%%*/ @@ -3955,10 +4020,10 @@ symbol : tSYMBEG sym { /*%%%*/ - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; $$ = $2; /*% - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; $$ = dispatch1(symbol, $2); %*/ } @@ -3973,7 +4038,7 @@ dsym : tSYMBEG xstring_contents tSTRING_END { /*%%%*/ - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; if (!($$ = $2)) { $$ = NEW_LIT(ID2SYM(rb_intern(""))); } @@ -3995,7 +4060,7 @@ } } /*% - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; $$ = dispatch1(dyna_symbol, $2); %*/ } @@ -4339,6 +4404,44 @@ } ; +f_block_opt : tIDENTIFIER '=' primary_value + { + /*%%%*/ + if (!is_local_id($1)) + yyerror("formal argument must be local variable"); + shadowing_lvar($1); + arg_var($1); + $$ = NEW_OPT_ARG(0, assignable($1, $3)); + /*% + $$ = rb_assoc_new($1, $3); + %*/ + } + ; + +f_block_optarg : f_block_opt + { + /*%%%*/ + $$ = $1; + /*% + $$ = rb_ary_new3(1, $1); + %*/ + } + | f_block_optarg ',' f_block_opt + { + /*%%%*/ + NODE *opts = $1; + + while (opts->nd_next) { + opts = opts->nd_next; + } + opts->nd_next = $3; + $$ = $1; + /*% + $$ = rb_ary_push($1, $3); + %*/ + } + ; + f_optarg : f_opt { /*%%%*/ @@ -6191,7 +6294,7 @@ token = here_document(lex_strterm); if (token == tSTRING_END) { lex_strterm = 0; - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; } } else { @@ -6199,7 +6302,7 @@ if (token == tSTRING_END || token == tREGEXP_END) { rb_gc_force_recycle((VALUE)lex_strterm); lex_strterm = 0; - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; } } return token; @@ -6493,8 +6596,7 @@ return tSTRING_BEG; case '?': - if (lex_state == EXPR_END || - lex_state == EXPR_ENDARG) { + if (lex_state == EXPR_END || lex_state == EXPR_ENDARG) { lex_state = EXPR_VALUE; return '?'; } @@ -6565,7 +6667,7 @@ } tokfix(); set_yylval_str(STR_NEW3(tok(), toklen(), enc, 0)); - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; return tCHAR; case '&': @@ -6714,7 +6816,7 @@ int is_float, seen_point, seen_e, nondigit; is_float = seen_point = seen_e = nondigit = 0; - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; newtok(); if (c == '-' || c == '+') { tokadd(c); @@ -6950,8 +7052,7 @@ lex_state = EXPR_DOT; return tCOLON2; } - if (lex_state == EXPR_END || - lex_state == EXPR_ENDARG || ISSPACE(c)) { + if (lex_state == EXPR_END || lex_state == EXPR_ENDARG || ISSPACE(c)) { pushback(c); lex_state = EXPR_BEG; return ':'; @@ -7190,7 +7291,7 @@ case '$': last_state = lex_state; - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; newtok(); c = nextc(); switch (c) { @@ -7351,11 +7452,11 @@ last_state = lex_state; switch (tok()[0]) { case '$': - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; result = tGVAR; break; case '@': - lex_state = EXPR_ENDARG; + lex_state = EXPR_END; if (tok()[1] == '@') result = tCVAR; else Index: mvm/ext/socket/mkconstants.rb =================================================================== --- mvm/ext/socket/mkconstants.rb (revision 19235) +++ mvm/ext/socket/mkconstants.rb (revision 19236) @@ -260,3 +260,31 @@ SHUT_RD 0 SHUT_WR 1 SHUT_RDWR 2 + +IPV6_JOIN_GROUP +IPV6_LEAVE_GROUP +IPV6_MULTICAST_HOPS +IPV6_MULTICAST_IF +IPV6_MULTICAST_LOOP +IPV6_UNICAST_HOPS +IPV6_V6ONLY +IPV6_CHECKSUM +IPV6_DONTFRAG +IPV6_DSTOPTS +IPV6_HOPLIMIT +IPV6_HOPOPTS +IPV6_NEXTHOP +IPV6_PATHMTU +IPV6_PKTINFO +IPV6_RECVDSTOPTS +IPV6_RECVHOPLIMIT +IPV6_RECVHOPOPTS +IPV6_RECVPKTINFO +IPV6_RECVRTHDR +IPV6_RECVTCLASS +IPV6_RTHDR +IPV6_RTHDRDSTOPTS +IPV6_RTHDR_TYPE_0 +IPV6_RECVPATHMTU +IPV6_TCLASS +IPV6_USE_MIN_MTU Index: mvm/.merged-trunk-revision =================================================================== --- mvm/.merged-trunk-revision (revision 19235) +++ mvm/.merged-trunk-revision (revision 19236) @@ -1 +1 @@ -19180 +19235 Index: mvm/transcode_data.h =================================================================== --- mvm/transcode_data.h (revision 19235) +++ mvm/transcode_data.h (revision 19236) @@ -34,7 +34,11 @@ #define FUNsi (PType 0x0D) /* function from start to info */ #define FUNio (PType 0x0E) /* function from info to output */ #define FUNso (PType 0x0F) /* function from start to output */ +#define STR1 (PType 0x11) /* string up to 255 bytes: 1byte length + content */ +#define STR1_BYTEINDEX(w) ((w) >> 6) +#define makeSTR1(bi) (((bi) << 6) | STR1) + #define o1(b1) (PType((((unsigned char)(b1))<<8)|ONEbt)) #define o2(b1,b2) (PType((((unsigned char)(b1))<<8)|(((unsigned char)(b2))<<16)|TWObt)) #define o3(b1,b2,b3) (PType(((((unsigned char)(b1))<<8)|(((unsigned char)(b2))<<16)|(((unsigned char)(b3))<<24)|THREEbt)&0xffffffffU)) Index: mvm/tool/transcode-tblgen.rb =================================================================== --- mvm/tool/transcode-tblgen.rb (revision 19235) +++ mvm/tool/transcode-tblgen.rb (revision 19236) @@ -277,6 +277,38 @@ code end + UsedName = {} + + StrMemo = {} + + def str_name(bytes) + size = @bytes_code.length + rawbytes = [bytes].pack("H*") + + n = nil + if !n && !(suf = rawbytes.gsub(/[^A-Za-z0-9_]/, '')).empty? && !UsedName[nn = "str1_" + suf] then n = nn end + if !n && !UsedName[nn = "str1_" + bytes] then n = nn end + n ||= "str1s_#{size}" + + StrMemo[bytes] = n + UsedName[n] = true + n + end + + def gen_str(bytes) + if n = StrMemo[bytes] + n + else + len = bytes.length/2 + size = @bytes_code.length + n = str_name(bytes) + @bytes_code.insert_at_last(1 + len, + "\#define #{n} makeSTR1(#{size})\n" + + " #{len}," + bytes.gsub(/../, ' 0x\&,') + "\n\n") + n + end + end + def generate_info(info) case info when :nomap @@ -299,8 +331,10 @@ "o2(0x#$1,0x#$2)" when /\A([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])\z/i "o3(0x#$1,0x#$2,0x#$3)" - when /\A([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])\z/i + when /\A(f[0-7])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])\z/i "o4(0x#$1,0x#$2,0x#$3,0x#$4)" + when /\A([0-9a-f][0-9a-f]){0,255}\z/i + gen_str(info.upcase) when /\A\/\*BYTE_LOOKUP\*\// # pointer to BYTE_LOOKUP structure $'.to_s else @@ -414,7 +448,11 @@ end def gennode(bytes_code, words_code, name_hint=nil, valid_encoding=nil) + @bytes_code = bytes_code + @words_code = words_code name = generate_node(bytes_code, words_code, name_hint, valid_encoding) + @bytes_code = nil + @words_code = nil return name end end @@ -565,7 +603,13 @@ TRANSCODE_GENERATED_TRANSCODER_CODE = '' def transcode_tblgen(from, to, map) - STDERR.puts "converter from #{from} to #{to}" if VERBOSE_MODE + if VERBOSE_MODE + if from.empty? || to.empty? + STDERR.puts "converter for #{from.empty? ? to : from}" + else + STDERR.puts "converter from #{from} to #{to}" + end + end id_from = from.tr('^0-9A-Za-z', '_') id_to = to.tr('^0-9A-Za-z', '_') if from == "UTF-8" Index: mvm/test/ruby/test_io_m17n.rb =================================================================== --- mvm/test/ruby/test_io_m17n.rb (revision 19235) +++ mvm/test/ruby/test_io_m17n.rb (revision 19236) @@ -1459,5 +1459,38 @@ } end + def test_w_xml_attr + with_tmpdir { + open("raw.txt", "wb", xml: :attr) {|f| f.print '&<>"\''; f.puts "\u4E02\u3042" } + content = File.read("raw.txt", :mode=>"rb:ascii-8bit") + assert_equal("\"&<>"'\u4E02\u3042\n\"".force_encoding("ascii-8bit"), content) + + open("ascii.txt", "wb:us-ascii", xml: :attr) {|f| f.print '&<>"\''; f.puts "\u4E02\u3042" } + content = File.read("ascii.txt", :mode=>"rb:ascii-8bit") + assert_equal("\"&<>"'丂あ\n\"".force_encoding("ascii-8bit"), content) + + open("iso-2022-jp.txt", "wb:iso-2022-jp", xml: :attr) {|f| f.print '&<>"\''; f.puts "\u4E02\u3042" } + content = File.read("iso-2022-jp.txt", :mode=>"rb:ascii-8bit") + assert_equal("\"&<>"'丂\e$B$\"\e(B\n\"".force_encoding("ascii-8bit"), content) + + open("eucjp.txt", "w:euc-jp:utf-8", xml: :attr) {|f| + f.print "\u4E02" # U+4E02 is 0x3021 in JIS X 0212 + } + content = File.read("eucjp.txt", :mode=>"rb:ascii-8bit") + assert_equal("\"\x8F\xB0\xA1\"".force_encoding("ascii-8bit"), content) + + open("sjis.txt", "w:sjis:utf-8", xml: :attr) {|f| + f.print "\u4E02" # U+4E02 is 0x3021 in JIS X 0212 + } + content = File.read("sjis.txt", :mode=>"rb:ascii-8bit") + assert_equal("\"丂\"".force_encoding("ascii-8bit"), content) + + open("iso-2022-jp.txt", "w:iso-2022-jp:utf-8", xml: :attr) {|f| + f.print "\u4E02" # U+4E02 is 0x3021 in JIS X 0212 + } + content = File.read("iso-2022-jp.txt", :mode=>"rb:ascii-8bit") + assert_equal("\"丂\"".force_encoding("ascii-8bit"), content) + } + end end Index: mvm/test/ruby/test_econv.rb =================================================================== --- mvm/test/ruby/test_econv.rb (revision 19235) +++ mvm/test/ruby/test_econv.rb (revision 19236) @@ -28,13 +28,13 @@ end def test_s_stateless_encoding - assert_equal(Encoding::EUC_JP, Encoding::Converter.stateless_encoding("ISO-2022-JP")) - assert_equal(Encoding::EUC_JP, Encoding::Converter.stateless_encoding(Encoding::ISO_2022_JP)) + assert_equal(Encoding::STATELESS_ISO_2022_JP, Encoding::Converter.stateless_encoding("ISO-2022-JP")) + assert_equal(Encoding::STATELESS_ISO_2022_JP, Encoding::Converter.stateless_encoding(Encoding::ISO_2022_JP)) assert_nil(Encoding::Converter.stateless_encoding("EUC-JP")) assert_nil(Encoding::Converter.stateless_encoding("UTF-8")) assert_nil(Encoding::Converter.stateless_encoding("UTF-16BE")) assert_nil(Encoding::Converter.stateless_encoding(Encoding::UTF_8)) - assert_nil(Encoding::Converter.stateless_encoding("html-attr-escaped")) + assert_nil(Encoding::Converter.stateless_encoding("xml-attr-escaped")) end def test_stateless_encoding_iso2022jp @@ -728,51 +728,74 @@ assert_equal("&", ec.convert("&")) end - def test_html_escape_text + def test_xml_escape_text ec = Encoding::Converter.new("", "amp-escaped") assert_equal('&<>"', ec.convert("&<>\"")) assert_equal('', ec.finish) - ec = Encoding::Converter.new("", "html-text-escaped") + ec = Encoding::Converter.new("", "xml-text-escaped") assert_equal('&<>"', ec.convert("&<>\"")) assert_equal('', ec.finish) end - def test_html_escape_attr - ec = Encoding::Converter.new("", "html-attr-escaped") + def test_xml_escape_attr_content + ec = Encoding::Converter.new("", "xml-attr-content-escaped") + assert_equal('', ec.finish) + + ec = Encoding::Converter.new("", "xml-attr-content-escaped") + assert_equal('', ec.convert("")) + assert_equal('', ec.finish) + + ec = Encoding::Converter.new("", "xml-attr-content-escaped") + assert_equal('"', ec.convert('"')) + assert_equal('', ec.finish) + + ec = Encoding::Converter.new("", "xml-attr-content-escaped") + assert_equal('&<>"', ec.convert("&<>\"")) + assert_equal('', ec.finish) + end + + def test_xml_escape_attr_quote + ec = Encoding::Converter.new("", "xml-attr-quoted") assert_equal('""', ec.finish) - ec = Encoding::Converter.new("", "html-attr-escaped") + ec = Encoding::Converter.new("", "xml-attr-quoted") assert_equal('', ec.convert("")) assert_equal('""', ec.finish) - ec = Encoding::Converter.new("", "html-attr-escaped") - assert_equal('""', ec.convert('"')) + ec = Encoding::Converter.new("", "xml-attr-quoted") + assert_equal('""', ec.convert('"')) assert_equal('"', ec.finish) - ec = Encoding::Converter.new("", "html-attr-escaped") - assert_equal('"&<>"', ec.convert("&<>\"")) + ec = Encoding::Converter.new("", "xml-attr-quoted") + assert_equal('"&<>"', ec.convert("&<>\"")) assert_equal('"', ec.finish) end - def test_html_escape_with_charref - ec = Encoding::Converter.new("utf-8", "euc-jp", Encoding::Converter::HTML_TEXT_ENCODER|Encoding::Converter::UNDEF_HEX_CHARREF) + def test_xml_escape_with_charref + ec = Encoding::Converter.new("utf-8", "euc-jp", Encoding::Converter::XML_TEXT_ENCODER|Encoding::Converter::UNDEF_HEX_CHARREF) assert_equal('<♥>&"♡"', ec.convert("<\u2665>&\"\u2661\"")) assert_equal('', ec.finish) - ec = Encoding::Converter.new("utf-8", "euc-jp", Encoding::Converter::HTML_ATTR_ENCODER|Encoding::Converter::UNDEF_HEX_CHARREF) + ec = Encoding::Converter.new("utf-8", "euc-jp", + Encoding::Converter::XML_ATTR_CONTENT_ENCODER| + Encoding::Converter::XML_ATTR_QUOTE_ENCODER| + Encoding::Converter::UNDEF_HEX_CHARREF) assert_equal('"<♥>&"♡"', ec.convert("<\u2665>&\"\u2661\"")) assert_equal('"', ec.finish) - ec = Encoding::Converter.new("utf-8", "iso-2022-jp", Encoding::Converter::HTML_TEXT_ENCODER) + ec = Encoding::Converter.new("utf-8", "iso-2022-jp", Encoding::Converter::XML_TEXT_ENCODER) assert_equal("&\e$B$&\e(B&".force_encoding("iso-2022-jp"), ec.convert("&\u3046&")) assert_equal('', ec.finish) end - def test_html_hasharg + def test_xml_hasharg assert_equal("&\e$B$&\e(B♥&\"'".force_encoding("iso-2022-jp"), - "&\u3046\u2665&\"'".encode("iso-2022-jp", html: :text)) + "&\u3046\u2665&\"'".encode("iso-2022-jp", xml: :text)) assert_equal("\"&\e$B$&\e(B♡&"'\"".force_encoding("iso-2022-jp"), - "&\u3046\u2661&\"'".encode("iso-2022-jp", html: :attr)) + "&\u3046\u2661&\"'".encode("iso-2022-jp", xml: :attr)) + + assert_equal("&\u3046\u2661&\"'".force_encoding("utf-8"), + "&\u3046\u2661&\"'".encode("utf-8", xml: :text)) end end Index: mvm/test/ruby/test_complex.rb =================================================================== --- mvm/test/ruby/test_complex.rb (revision 19235) +++ mvm/test/ruby/test_complex.rb (revision 19236) @@ -631,9 +631,6 @@ end def test_parse - assert_equal(Complex(0), ''.to_c) - assert_equal(Complex(0), ' '.to_c) - assert_equal(Complex(5), "\f\n\r\t\v5\0".to_c) assert_equal(Complex(5), '5'.to_c) assert_equal(Complex(-5), '-5'.to_c) assert_equal(Complex(5,3), '5+3i'.to_c) @@ -674,6 +671,12 @@ assert_equal(Complex(0.0,3.0), '3e0i'.to_c) assert_equal(Complex(0.0,-3.0), '-3e0i'.to_c) + assert_equal(Complex(0.33), '.33'.to_c) + assert_equal(Complex(0.33), '0.33'.to_c) + assert_equal(Complex(-0.33), '-.33'.to_c) + assert_equal(Complex(-0.33), '-0.33'.to_c) + assert_equal(Complex(-0.33), '-0.3_3'.to_c) + assert_equal(Complex.polar(10,10), '10@10'.to_c) assert_equal(Complex.polar(-10,-10), '-10@-10'.to_c) assert_equal(Complex.polar(10.5,10.5), '10.5@1...'.to_c) @@ -719,11 +722,20 @@ assert_equal(Complex(0.0,3.0), Complex('3e0i')) assert_equal(Complex(0.0,-3.0), Complex('-3e0i')) + assert_equal(Complex(0.33), Complex('.33')) + assert_equal(Complex(0.33), Complex('0.33')) + assert_equal(Complex(-0.33), Complex('-.33')) + assert_equal(Complex(-0.33), Complex('-0.33')) + assert_equal(Complex(-0.33), Complex('-0.3_3')) + assert_equal(Complex.polar(10,10), Complex('10@10')) assert_equal(Complex.polar(-10,-10), Complex('-10@-10')) assert_equal(Complex.polar(10.5,10.5), Complex('10.5@1...')) assert_equal(Complex.polar(-10.5,-10.5), Complex('-10.5@-...')) + assert_equal(Complex(0), ''.to_c) + assert_equal(Complex(0), ' '.to_c) + assert_equal(Complex(5), "\f\n\r\t\v5\0".to_c) assert_equal(Complex(0), '_'.to_c) assert_equal(Complex(0), '_5'.to_c) assert_equal(Complex(5), '5_'.to_c) @@ -734,6 +746,7 @@ assert_equal(Complex(5,3), '5+3ix'.to_c) assert_raise(ArgumentError){ Complex('')} assert_raise(ArgumentError){ Complex('_')} + assert_raise(ArgumentError){ Complex("\f\n\r\t\v5\0")} assert_raise(ArgumentError){ Complex('_5')} assert_raise(ArgumentError){ Complex('5_')} assert_raise(ArgumentError){ Complex('5x')} @@ -741,7 +754,6 @@ assert_raise(ArgumentError){ Complex('5+3_i')} assert_raise(ArgumentError){ Complex('5+3i_')} assert_raise(ArgumentError){ Complex('5+3ix')} - assert_raise(ArgumentError){ Complex("5\0")} if defined?(Rational) && defined?(''.to_r) assert_equal(Complex(Rational(1,5)), '1/5'.to_c) Index: mvm/test/ruby/test_rational.rb =================================================================== --- mvm/test/ruby/test_rational.rb (revision 19235) +++ mvm/test/ruby/test_rational.rb (revision 19236) @@ -866,9 +866,6 @@ end def test_parse - assert_equal(Rational(0), ''.to_r) - assert_equal(Rational(0), ' '.to_r) - assert_equal(Rational(5), "\f\n\r\t\v5\0".to_r) assert_equal(Rational(5), '5'.to_r) assert_equal(Rational(-5), '-5'.to_r) assert_equal(Rational(5,3), '5/3'.to_r) @@ -890,7 +887,9 @@ # assert_equal(Rational(5,-3), '5e0/-3'.to_r) # assert_equal(Rational(-5,-3), '-5e0/-3'.to_r) + assert_equal(Rational(33,100), '.33'.to_r) assert_equal(Rational(33,100), '0.33'.to_r) + assert_equal(Rational(-33,100), '-.33'.to_r) assert_equal(Rational(-33,100), '-0.33'.to_r) assert_equal(Rational(-33,100), '-0.3_3'.to_r) @@ -911,24 +910,39 @@ # assert_equal(Rational(5,-3), Rational('5/-3')) # assert_equal(Rational(-5,-3), Rational('-5/-3')) + assert_equal(Rational(5), Rational('5.0')) + assert_equal(Rational(-5), Rational('-5.0')) + assert_equal(Rational(5,3), Rational('5.0/3')) + assert_equal(Rational(-5,3), Rational('-5.0/3')) +# assert_equal(Rational(5,-3), Rational('5.0/-3')) +# assert_equal(Rational(-5,-3), Rational('-5.0/-3')) + + assert_equal(Rational(5), Rational('5e0')) + assert_equal(Rational(-5), Rational('-5e0')) + assert_equal(Rational(5,3), Rational('5e0/3')) + assert_equal(Rational(-5,3), Rational('-5e0/3')) +# assert_equal(Rational(5,-3), Rational('5e0/-3')) +# assert_equal(Rational(-5,-3), Rational('-5e0/-3')) + + assert_equal(Rational(33,100), Rational('.33')) assert_equal(Rational(33,100), Rational('0.33')) + assert_equal(Rational(-33,100), Rational('-.33')) assert_equal(Rational(-33,100), Rational('-0.33')) assert_equal(Rational(-33,100), Rational('-0.3_3')) assert_equal(Rational(1,2), Rational('5e-1')) + assert_equal(Rational(50), Rational('5e+1')) + assert_equal(Rational(1,2), Rational('5.0e-1')) + assert_equal(Rational(50), Rational('5.0e+1')) assert_equal(Rational(50), Rational('5e1')) assert_equal(Rational(50), Rational('5E1')) assert_equal(Rational(500), Rational('5e2')) assert_equal(Rational(5000), Rational('5e3')) assert_equal(Rational(500000000000), Rational('5e1_1')) - assert_equal(Rational(5.0), Rational('5.0')) - assert_equal(Rational(-5.0), Rational('-5.0')) - assert_equal(Rational(5.0,3), Rational('5.0/3')) - assert_equal(Rational(-5.0,3), Rational('-5.0/3')) -# assert_equal(Rational(5.0,-3), Rational('5.0/-3')) -# assert_equal(Rational(-5.0,-3), Rational('-5.0/-3')) - + assert_equal(Rational(0), ''.to_r) + assert_equal(Rational(0), ' '.to_r) + assert_equal(Rational(5), "\f\n\r\t\v5\0".to_r) assert_equal(Rational(0), '_'.to_r) assert_equal(Rational(0), '_5'.to_r) assert_equal(Rational(5), '5_'.to_r) @@ -939,6 +953,7 @@ assert_equal(Rational(5,3), '5/3x'.to_r) assert_raise(ArgumentError){ Rational('')} assert_raise(ArgumentError){ Rational('_')} + assert_raise(ArgumentError){ Rational("\f\n\r\t\v5\0")} assert_raise(ArgumentError){ Rational('_5')} assert_raise(ArgumentError){ Rational('5_')} assert_raise(ArgumentError){ Rational('5x')} @@ -946,7 +961,6 @@ assert_raise(ArgumentError){ Rational('5/3_')} assert_raise(ArgumentError){ Rational('5/3.3')} assert_raise(ArgumentError){ Rational('5/3x')} - assert_raise(ArgumentError){ Rational("5\0")} end =begin Index: mvm/test/ruby/test_parse.rb =================================================================== --- mvm/test/ruby/test_parse.rb (revision 19235) +++ mvm/test/ruby/test_parse.rb (revision 19236) @@ -105,7 +105,7 @@ a = nil assert_nothing_raised do t.instance_eval <<-END - a = bar "foo" { "bar" } + a = bar "foo" do "bar" end END end assert_equal("foobar", a) @@ -113,7 +113,7 @@ a = nil assert_nothing_raised do eval <<-END - a = t::bar "foo" { "bar" } + a = t::bar "foo" do "bar" end END end assert_equal("foobar", a) @@ -260,7 +260,7 @@ a = nil assert_nothing_raised do eval <<-END - o.foo 1 {|; a| a = 42 } + o.foo 1 do|; a| a = 42 end END end assert_nil(a) Index: mvm/rational.c =================================================================== --- mvm/rational.c (revision 19235) +++ mvm/rational.c (revision 19236) @@ -24,9 +24,9 @@ #define ONE INT2FIX(1) #define TWO INT2FIX(2) -static ID id_Unify, id_abs, id_cmp, id_convert, id_equal_p, - id_expt, id_floor, id_format, id_idiv, id_inspect, id_negate, id_new, - id_new_bang, id_to_f, id_to_i, id_to_s, id_truncate; +static ID id_Unify, id_abs, id_cmp, id_convert, id_equal_p, id_expt, + id_floor, id_format, id_idiv, id_inspect, id_negate, id_new, id_new_bang, + id_to_f, id_to_i, id_to_s, id_truncate; #define f_boolcast(x) ((x) ? Qtrue : Qfalse) @@ -325,6 +325,8 @@ return nurat_s_new_internal(klass, ZERO, ONE); } +#define rb_raise_zerodiv() rb_raise(rb_eZeroDivError, "divided by zero") + static VALUE nurat_s_new_bang(int argc, VALUE *argv, VALUE klass) { @@ -348,7 +350,7 @@ den = f_negate(den); break; case 0: - rb_raise(rb_eZeroDivError, "devided by zero"); + rb_raise_zerodiv(); break; } break; @@ -396,7 +398,7 @@ den = f_negate(den); break; case 0: - rb_raise(rb_eZeroDivError, "devided by zero"); + rb_raise_zerodiv(); break; } @@ -418,7 +420,7 @@ den = f_negate(den); break; case 0: - rb_raise(rb_eZeroDivError, "devided by zero"); + rb_raise_zerodiv(); break; } @@ -723,7 +725,7 @@ case T_FIXNUM: case T_BIGNUM: if (f_zero_p(other)) - rb_raise(rb_eZeroDivError, "devided by zero"); + rb_raise_zerodiv(); { get_dat1(self); @@ -735,7 +737,7 @@ return rb_funcall(f_to_f(self), '/', 1, other); case T_RATIONAL: if (f_zero_p(other)) - rb_raise(rb_eZeroDivError, "devided by zero"); + rb_raise_zerodiv(); { get_dat2(self, other); @@ -1025,7 +1027,7 @@ { VALUE num, den; int minus = 0; - long nl, dl, ml, ne, de; + long nl, dl, ne, de; int e; double f; @@ -1046,7 +1048,6 @@ nl = i_ilog2(num); dl = i_ilog2(den); - ml = (long)(log(DBL_MAX) / log(2.0) - 1); /* should be a static */ ne = 0; if (nl > ml) { @@ -1122,7 +1123,7 @@ dat->den = RARRAY_PTR(a)[1]; if (f_zero_p(dat->den)) - rb_raise(rb_eZeroDivError, "devided by zero"); + rb_raise_zerodiv(); return self; } @@ -1185,8 +1186,8 @@ return rb_rational_new1(self); } -static VALUE -float_decode(VALUE self) +static void +float_decode_internal(VALUE self, VALUE *rf, VALUE *rn) { double f; int n; @@ -1194,15 +1195,28 @@ f = frexp(RFLOAT_VALUE(self), &n); f = ldexp(f, DBL_MANT_DIG); n -= DBL_MANT_DIG; - return rb_assoc_new(f_to_i(rb_float_new(f)), INT2FIX(n)); + *rf = rb_dbl2big(f); + *rn = INT2FIX(n); } +#if 0 static VALUE +float_decode(VALUE self) +{ + VALUE f, n; + + float_decode_internal(self, &f, &n); + return rb_assoc_new(f, n); +} +#endif + +static VALUE float_to_r(VALUE self) { - VALUE a = float_decode(self); - return f_mul(RARRAY_PTR(a)[0], - f_expt(INT2FIX(FLT_RADIX), RARRAY_PTR(a)[1])); + VALUE f, n; + + float_decode_internal(self, &f, &n); + return f_mul(f, f_expt(INT2FIX(FLT_RADIX), n)); } static int vmkey_rat_pat, vmkey_an_e_pat, vmkey_a_dot_pat, @@ -1322,10 +1336,14 @@ v = f_add(v, f_to_i(fp)); v = f_div(v, l); } + if (!NIL_P(si) && *StringValuePtr(si) == '-') + v = f_negate(v); if (!NIL_P(exp)) v = f_mul(v, f_expt(INT2FIX(10), f_to_i(exp))); - if (!NIL_P(si) && *StringValuePtr(si) == '-') - v = f_negate(v); +#if 0 + if (!NIL_P(de) && (!NIL_P(fp) || !NIL_P(exp))) + return rb_assoc_new(v, rb_str_new2("dummy")); +#endif if (!NIL_P(de)) v = f_div(v, f_to_i(de)); Index: mvm/file.c =================================================================== --- mvm/file.c (revision 19235) +++ mvm/file.c (revision 19236) @@ -639,10 +639,10 @@ * * File.stat("/etc/passwd").inspect * #=> "#<File::Stat dev=0xe000005, ino=1078078, mode=0100644, - * nlink=1, uid=0, gid=0, rdev=0x0, size=1374, blksize=4096, - * blocks=8, atime=Wed Dec 10 10:16:12 CST 2003, - * mtime=Fri Sep 12 15:41:41 CDT 2003, - * ctime=Mon Oct 27 11:20:27 CST 2003>" + * # nlink=1, uid=0, gid=0, rdev=0x0, size=1374, blksize=4096, + * # blocks=8, atime=Wed Dec 10 10:16:12 CST 2003, + * # mtime=Fri Sep 12 15:41:41 CDT 2003, + * # ctime=Mon Oct 27 11:20:27 CST 2003>" */ static VALUE @@ -2775,8 +2775,7 @@ if (p > buf && p[-1] == '/') --p; else { - ++buflen; - BUFCHECK(bdiff >= buflen); + BUFCHECK(bdiff + 1 >= buflen); *p = '/'; } Index: mvm/transcode.c =================================================================== --- mvm/transcode.c (revision 19235) +++ mvm/transcode.c (revision 19236) @@ -21,7 +21,7 @@ VALUE rb_cEncodingConverter; static VALUE sym_invalid, sym_undef, sym_ignore, sym_replace; -static VALUE sym_html, sym_text, sym_attr; +static VALUE sym_xml, sym_text, sym_attr; static VALUE sym_universal_newline_decoder; static VALUE sym_crlf_newline_encoder; static VALUE sym_cr_newline_encoder; @@ -534,6 +534,7 @@ case 25: goto resume_label25; case 26: goto resume_label26; case 27: goto resume_label27; + case 28: goto resume_label28; } while (1) { @@ -602,6 +603,13 @@ SUSPEND_OBUF(18); *out_p++ = getBT2(next_info); SUSPEND_OBUF(19); *out_p++ = getBT3(next_info); continue; + case STR1: + next_byte = 0; /* index */ + while (next_byte < BYTE_ADDR(STR1_BYTEINDEX(next_info))[0]) { + SUSPEND_OBUF(28); *out_p++ = BYTE_ADDR(STR1_BYTEINDEX(next_info))[1+next_byte]; + next_byte++; + } + continue; case FUNii: next_info = (VALUE)(*tr->func_ii)(TRANSCODING_STATE(tc), next_info); goto follow_info; @@ -880,7 +888,6 @@ transcoder_entry_t **entries = NULL; int num_trans; static rb_econv_t *ec; - int universal_newline_decoder_added = 0; rb_encoding *senc, *denc; int sidx, didx; @@ -896,8 +903,8 @@ (ecflags & ECONV_UNIVERSAL_NEWLINE_DECODER)) return NULL; - if ((ecflags & ECONV_HTML_TEXT_ENCODER) && - (ecflags & ECONV_HTML_ATTR_ENCODER)) + if ((ecflags & ECONV_XML_TEXT_ENCODER) && + (ecflags & ECONV_XML_ATTR_CONTENT_ENCODER)) return NULL; num_encoders = 0; @@ -907,12 +914,15 @@ if (ecflags & ECONV_CR_NEWLINE_ENCODER) if (!(encoders[num_encoders++] = get_transcoder_entry("", "cr_newline"))) return NULL; - if (ecflags & ECONV_HTML_TEXT_ENCODER) - if (!(encoders[num_encoders++] = get_transcoder_entry("", "html-text-escaped"))) + if (ecflags & ECONV_XML_TEXT_ENCODER) + if (!(encoders[num_encoders++] = get_transcoder_entry("", "xml-text-escaped"))) return NULL; - if (ecflags & ECONV_HTML_ATTR_ENCODER) - if (!(encoders[num_encoders++] = get_transcoder_entry("", "html-attr-escaped"))) + if (ecflags & ECONV_XML_ATTR_CONTENT_ENCODER) + if (!(encoders[num_encoders++] = get_transcoder_entry("", "xml-attr-content-escaped"))) return NULL; + if (ecflags & ECONV_XML_ATTR_QUOTE_ENCODER) + if (!(encoders[num_encoders++] = get_transcoder_entry("", "xml-attr-quoted"))) + return NULL; num_decoders = 0; if (ecflags & ECONV_UNIVERSAL_NEWLINE_DECODER) @@ -977,9 +987,9 @@ ec->last_tc = NULL; ec->last_trans_index = -1; } - else if (universal_newline_decoder_added) { - ec->last_tc = ec->elems[ec->num_trans-2].tc; - ec->last_trans_index = ec->num_trans-2; + else { + ec->last_trans_index = ec->num_trans-1-num_decoders; + ec->last_tc = ec->elems[ec->last_trans_index].tc; } return ec; @@ -1445,7 +1455,7 @@ res = rb_econv_convert(ec, &sp, str+len, &dp, dst_str+dst_bufsize, 0); dst_len = dp - dst_str; while (res == econv_destination_buffer_full) { - if (dst_bufsize * 2 < dst_bufsize) { + if (SIZE_MAX/2 < dst_bufsize) { goto fail; } dst_bufsize *= 2; @@ -1727,25 +1737,48 @@ void rb_econv_binmode(rb_econv_t *ec) { + const rb_transcoder *trs[3]; + int n, i, j; + transcoder_entry_t *entry; + + n = 0; if (ec->flags & ECONV_UNIVERSAL_NEWLINE_DECODER) { - int i = ec->num_trans-1; - rb_transcoding_close(ec->elems[i].tc); - xfree(ec->elems[i].out_buf_start); - ec->elems[i].tc = NULL; - ec->elems[i].out_buf_start = NULL; - ec->elems[i].out_data_start = NULL; - ec->elems[i].out_data_end = NULL; - ec->elems[i].out_buf_end = NULL; - ec->num_trans--; - ec->flags &= ~ECONV_UNIVERSAL_NEWLINE_DECODER; + entry = get_transcoder_entry("universal_newline", ""); + if (entry->transcoder) + trs[n++] = entry->transcoder; } - if (ec->flags & (ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER)) { - rb_transcoding_close(ec->elems[0].tc); - xfree(ec->elems[0].out_buf_start); - MEMMOVE(&ec->elems[0], &ec->elems[1], rb_econv_elem_t, ec->num_trans-1); - ec->num_trans--; - ec->flags &= ~(ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER); + if (ec->flags & ECONV_CRLF_NEWLINE_ENCODER) { + entry = get_transcoder_entry("", "crlf_newline"); + if (entry->transcoder) + trs[n++] = entry->transcoder; } + if (ec->flags & ECONV_CR_NEWLINE_ENCODER) { + entry = get_transcoder_entry("", "cr_newline"); + if (entry->transcoder) + trs[n++] = entry->transcoder; + } + + j = 0; + for (i = 0; i < ec->num_trans; i++) { + int k; + for (k = 0; k < n; k++) + if (trs[k] == ec->elems[i].tc->transcoder) + break; + if (k == n) { + if (ec->last_tc == ec->elems[i].tc) + ec->last_trans_index = j; + ec->elems[j] = ec->elems[i]; + j++; + } + else { + rb_transcoding_close(ec->elems[i].tc); + xfree(ec->elems[i].out_buf_start); + ec->num_trans--; + } + } + + ec->flags &= ~(ECONV_UNIVERSAL_NEWLINE_DECODER|ECONV_CRLF_NEWLINE_ENCODER|ECONV_CR_NEWLINE_ENCODER); + } static VALUE @@ -1768,13 +1801,16 @@ if (ecflags & (ECONV_UNIVERSAL_NEWLINE_DECODER| ECONV_CRLF_NEWLINE_ENCODER| - ECONV_CR_NEWLINE_ENCODER)) { + ECONV_CR_NEWLINE_ENCODER| + ECONV_XML_TEXT_ENCODER| + ECONV_XML_ATTR_CONTENT_ENCODER| + ECONV_XML_ATTR_QUOTE_ENCODER)) { const char *pre = ""; if (has_description) rb_str_cat2(mesg, " with "); if (ecflags & ECONV_UNIVERSAL_NEWLINE_DECODER) { rb_str_cat2(mesg, pre); pre = ","; - rb_str_cat2(mesg, "Universal-newline"); + rb_str_cat2(mesg, "universal-newline"); } if (ecflags & ECONV_CRLF_NEWLINE_ENCODER) { rb_str_cat2(mesg, pre); pre = ","; @@ -1784,6 +1820,18 @@ rb_str_cat2(mesg, pre); pre = ","; rb_str_cat2(mesg, "CR-newline"); } + if (ecflags & ECONV_XML_TEXT_ENCODER) { + rb_str_cat2(mesg, pre); pre = ","; + rb_str_cat2(mesg, "XML-text"); + } + if (ecflags & ECONV_XML_ATTR_CONTENT_ENCODER) { + rb_str_cat2(mesg, pre); pre = ","; + rb_str_cat2(mesg, "XML-attr-content"); + } + if (ecflags & ECONV_XML_ATTR_QUOTE_ENCODER) { + rb_str_cat2(mesg, pre); pre = ","; + rb_str_cat2(mesg, "XML-attr-quote"); + } has_description = 1; } if (!has_description) { @@ -1932,7 +1980,7 @@ } int -rb_econv_set_replacemenet(rb_econv_t *ec, +rb_econv_set_replacement(rb_econv_t *ec, const unsigned char *str, size_t len, const char *encname) { unsigned char *str2; @@ -2134,17 +2182,17 @@ rb_raise(rb_eArgError, "unknown value for undefined character option"); } - v = rb_hash_aref(opt, sym_html); + v = rb_hash_aref(opt, sym_xml); if (!NIL_P(v)) { v = rb_convert_type(v, T_SYMBOL, "Symbol", "to_sym"); if (v==sym_text) { - ecflags |= ECONV_HTML_TEXT_ENCODER|ECONV_UNDEF_HEX_CHARREF; + ecflags |= ECONV_XML_TEXT_ENCODER|ECONV_UNDEF_HEX_CHARREF; } else if (v==sym_attr) { - ecflags |= ECONV_HTML_ATTR_ENCODER|ECONV_UNDEF_HEX_CHARREF; + ecflags |= ECONV_XML_ATTR_CONTENT_ENCODER|ECONV_XML_ATTR_QUOTE_ENCODER|ECONV_UNDEF_HEX_CHARREF; } else { - rb_raise(rb_eArgError, "unexpected value for html option: %s", rb_id2name(SYM2ID(v))); + rb_raise(rb_eArgError, "unexpected value for xml option: %s", rb_id2name(SYM2ID(v))); } } @@ -2212,7 +2260,7 @@ int ret; rb_encoding *enc = rb_enc_get(replacement); - ret = rb_econv_set_replacemenet(ec, + ret = rb_econv_set_replacement(ec, (const unsigned char *)RSTRING_PTR(replacement), RSTRING_LEN(replacement), enc->name); @@ -2295,7 +2343,10 @@ if ((ecflags & (ECONV_UNIVERSAL_NEWLINE_DECODER| ECONV_CRLF_NEWLINE_ENCODER| - ECONV_CR_NEWLINE_ENCODER)) == 0) { + ECONV_CR_NEWLINE_ENCODER| + ECONV_XML_TEXT_ENCODER| + ECONV_XML_ATTR_CONTENT_ENCODER| + ECONV_XML_ATTR_QUOTE_ENCODER)) == 0) { if (senc && senc == denc) { return -1; } @@ -2467,15 +2518,14 @@ * It returns nil if the argument is not a stateful encoding. * * "corresponding stateless encoding" is a stateless encoding which - * can represent all characters in the statefull encoding. + * represents same characters in the statefull encoding. * - * So, no conversion undefined error occur from the stateful encoding to the stateless encoding. + * So, no conversion undefined error occur between the stateful encoding and the stateless encoding. * - * Currently, EUC-JP is the corresponding stateless encoding of ISO-2022-JP. + * For ISO-2022-JP, the dedicated stateless encoding, stateless-ISO-2022-JP, is defined. * - * Encoding::Converter.stateless_encoding("ISO-2022-JP") #=> #<Encoding:EUC-JP> + * Encoding::Converter.stateless_encoding("ISO-2022-JP") #=> #<Encoding:stateless-ISO-2022-JP> * - * (This may be changed in future because EUC-JP cannot distinguish JIS X 0208 1978 and 1983.) */ static VALUE econv_s_stateless_encoding(VALUE klass, VALUE arg) @@ -3307,7 +3357,7 @@ StringValue(string); enc = rb_enc_get(string); - ret = rb_econv_set_replacemenet(ec, + ret = rb_econv_set_replacement(ec, (const unsigned char *)RSTRING_PTR(string), RSTRING_LEN(string), enc->name); @@ -3492,7 +3542,7 @@ sym_undef = ID2SYM(rb_intern("undef")); sym_ignore = ID2SYM(rb_intern("ignore")); sym_replace = ID2SYM(rb_intern("replace")); - sym_html = ID2SYM(rb_intern("html")); + sym_xml = ID2SYM(rb_intern("xml")); sym_text = ID2SYM(rb_intern("text")); sym_attr = ID2SYM(rb_intern("attr")); @@ -3538,8 +3588,9 @@ rb_define_const(rb_cEncodingConverter, "UNIVERSAL_NEWLINE_DECODER", INT2FIX(ECONV_UNIVERSAL_NEWLINE_DECODER)); rb_define_const(rb_cEncodingConverter, "CRLF_NEWLINE_ENCODER", INT2FIX(ECONV_CRLF_NEWLINE_ENCODER)); rb_define_const(rb_cEncodingConverter, "CR_NEWLINE_ENCODER", INT2FIX(ECONV_CR_NEWLINE_ENCODER)); - rb_define_const(rb_cEncodingConverter, "HTML_TEXT_ENCODER", INT2FIX(ECONV_HTML_TEXT_ENCODER)); - rb_define_const(rb_cEncodingConverter, "HTML_ATTR_ENCODER", INT2FIX(ECONV_HTML_ATTR_ENCODER)); + rb_define_const(rb_cEncodingConverter, "XML_TEXT_ENCODER", INT2FIX(ECONV_XML_TEXT_ENCODER)); + rb_define_const(rb_cEncodingConverter, "XML_ATTR_CONTENT_ENCODER", INT2FIX(ECONV_XML_ATTR_CONTENT_ENCODER)); + rb_define_const(rb_cEncodingConverter, "XML_ATTR_QUOTE_ENCODER", INT2FIX(ECONV_XML_ATTR_QUOTE_ENCODER)); rb_define_method(rb_eConversionUndefined, "source_encoding_name", ecerr_source_encoding_name, 0); rb_define_method(rb_eConversionUndefined, "destination_encoding_name", ecerr_destination_encoding_name, 0); -- ML: ruby-changes@q... Info: http://www.atdot.net/~ko1/quickml/