From: nobu.nakada@... Date: 2002-03-04T02:24:20+09:00 Subject: [ruby-dev:16188] Re: Defining (Python) Source Code Encoding なかだです。 At Sun, 3 Mar 2002 16:14:58 +0900, TAKAHASHI Masayoshi wrote: > > > PEP(RCRのPython版)の263番で、「Defining Python Source Code Encoding」 > > > というdraftが出ています。要するに、ソースコードのencodingの判別に、 > > > > > > #!/usr/bin/python > > > # -*- coding: -*- > > > > > > というEmacs互換(?)な感じのコメントを書いておけば、処理系側でも > > > その値を使うようにする、というものです。 > > > > この形式も考えてはいたんですが、Emacsってencodingも-*-で指定で > > きましたっけ。 > > python-dev では「GNU Emacs21ならutf-8でもおーけー。XEmacs > はだめみたいだけど、どうするつもりかXEmacs communityに聞いて > みる」と言っています。vim6ではpluginで対応できるそうです。 > > この辺は仕様が乱立してもうれしくないので、協調してほしいところ > ですね。 なるほど。とりあえず合わせてみますか。ってかなり手抜き。あと、 かなり謎なmodesetという単語を、もうちょっとマシなものにしないと。 > # なお、彼らは「JapaneseCodesも取り込めば、Rubyも敵じゃないよん」 > # (超意訳)とかゆってます :-) > # http://mail.python.org/pipermail/python-dev/2002-February/020483.html Rubyの場合、Unicodizationを考えない分codecのサイズとかは気にす る必要はないわけですが、個別の対応が要りますからねぇ。そろそろ m17nを取り込みたいところです。 Index: intern.h =================================================================== RCS file: /cvs/ruby/src/ruby/intern.h,v retrieving revision 1.81 diff -u -2 -p -r1.81 intern.h --- intern.h 2002/02/20 06:33:24 1.81 +++ intern.h 2002/03/03 10:13:34 @@ -332,4 +332,5 @@ void ruby_load_script _((void)); void ruby_init_loadpath _((void)); void ruby_incpush _((const char*)); +void ruby_modeset _((const char*, int)); /* signal.c */ VALUE rb_f_kill _((int, VALUE*)); Index: parse.y =================================================================== RCS file: /cvs/ruby/src/ruby/parse.y,v retrieving revision 1.156 diff -u -2 -p -r1.156 parse.y --- parse.y 2002/02/20 04:31:50 1.156 +++ parse.y 2002/03/03 14:54:31 @@ -2985,7 +2985,7 @@ yylex() case '#': /* it's a comment */ - while ((c = nextc()) != '\n') { - if (c == -1) - return 0; + while (lex_p < lex_pend) { + ruby_modeset(lex_p, lex_pend - lex_p); + lex_p = lex_pend; } /* fall through */ Index: ruby.c =================================================================== RCS file: /cvs/ruby/src/ruby/ruby.c,v retrieving revision 1.56 diff -u -2 -p -r1.56 ruby.c --- ruby.c 2002/02/10 07:55:40 1.56 +++ ruby.c 2002/03/03 17:08:44 @@ -19,4 +19,5 @@ #include "dln.h" #include "node.h" +#include "regex.h" #include #include @@ -335,5 +336,82 @@ require_libraries() } +/* emacsen -*- hack */ +typedef void (*rb_modeset_setter_t) _((const char *val, const char *name)); + +struct modeset { + const char *name; + rb_modeset_setter_t func; +}; + +static const struct modeset modesets[] = { + {"coding", (rb_modeset_setter_t)rb_set_kcode}, +}; + +static const char modeset_pattern[] = ".*-\\*-\\s*(.*?)\\s*-\\*-"; +static struct re_pattern_buffer modeset_re; + +static const char modeset_scan_pattern[] = +"([^\\s\'\":;]+)\\s*:\\s*(\"(?:\\\\.|[^\"])*\"|[^\"\\s;]+)[\\s;]*"; +static struct re_pattern_buffer modeset_scan_re; + static void +Init_modeset _((void)) +{ + re_compile_pattern(modeset_pattern, + sizeof(modeset_pattern) - 1, + &modeset_re); + re_compile_pattern(modeset_scan_pattern, + sizeof(modeset_scan_pattern) - 1, + &modeset_scan_re); +} + +void +ruby_modeset(str, len) + const char *str; + int len; +{ +#define str_copy(_s, _p, _n) ((_s) \ + ? (rb_str_resize((_s), (_n)), \ + MEMCPY(RSTRING(_s)->ptr, (_p), char, (_n)), (_s)) \ + : ((_s) = rb_str_new((_p), (_n)))) +#define match(_re, _p, _n) (MEMZERO(®s, struct re_registers, 1), \ + re_match(&(_re), (_p), (_n), 0, ®s)) + struct re_registers regs; + VALUE name = 0, val = 0; + + if (match(modeset_re, str, len) < 0) return; + + len = regs.end[1] - regs.beg[1]; + str += regs.beg[1]; + re_free_registers(®s); + + while (match(modeset_scan_re, str, len) >= 0) { + const struct modeset *p = modesets; + int e0 = regs.end[0]; + int n1 = regs.end[1] - regs.beg[1]; + int s2 = regs.beg[2]; + int n2 = regs.end[2] - s2; + re_free_registers(®s); + + str_copy(name, str, n1); + rb_funcall(name, rb_intern("downcase!"), 0); + + do { + if (strncmp(p->name, RSTRING(name)->ptr, n1) == 0) { + str_copy(val, str + s2, n2); + (*p->func)(RSTRING(val)->ptr, RSTRING(name)->ptr); + break; + } + } while (++p < modesets + sizeof(modesets) / sizeof(*p)); + + len -= e0; + str += e0; + } + + if (name) rb_gc_force_recycle(name); + if (val) rb_gc_force_recycle(val); +} + +static void process_sflag() { @@ -843,4 +921,7 @@ load_file(fname, script) } } + if (RSTRING(line)->len > 1) { + ruby_modeset(RSTRING(line)->ptr, RSTRING(line)->len); + } } else if (!NIL_P(c)) { @@ -1007,4 +1088,6 @@ ruby_prog_init() rb_define_readonly_variable("$-a", &do_split); rb_global_variable(&rb_argv0); + + Init_modeset(); #ifdef MSDOS -- --- 僕の前にBugはない。 --- 僕の後ろにBugはできる。 中田 伸悦