close後のStringIO#string
Fixnum#==
使用可能な拡張ライブラリを全部スタティックにリンクしたrubyを作ってみる。 ただし、bccというかBorland makeは不可。
Index: common.mk
===================================================================
RCS file: /cvs/ruby/src/ruby/common.mk,v
retrieving revision 1.19
diff -U2 -p -r1.19 common.mk
--- common.mk 25 Jul 2005 12:29:34 -0000 1.19
+++ common.mk 3 Aug 2005 10:47:00 -0000
@@ -5,4 +5,6 @@ dll: $(LIBRUBY_SO);
RUBYOPT =
+STATIC_RUBY = static-ruby
+
EXTCONF = extconf.rb
RBCONFIG = ./.rbconfig.time
@@ -10,4 +12,6 @@ RBCONFIG = ./.rbconfig.time
DMYEXT = dmyext.$(OBJEXT)
MAINOBJ = main.$(OBJEXT)
+EXTOBJS =
+DLDOBJS = dmyext.$(OBJEXT)
OBJS = array.$(OBJEXT) \
@@ -76,7 +80,12 @@ prog: $(PROGRAM) $(WPROGRAM)
$(LIBRUBY_SO): $(OBJS) $(DLDOBJS) $(LIBRUBY_A) $(PREP) $(ARCHFILE)
-static-ruby: $(MAINOBJ) $(EXTOBJS) $(LIBRUBY_A)
+$(STATIC_RUBY)$(EXEEXT): $(MAINOBJ) $(EXTOBJS) $(CONFOBJ) $(LIBRUBY_A)
@$(RM) $@
- $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY_A) $(LIBS) $(OUTFLAG)$@
+ $(PURIFY) $(CC) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY_A) $(MAINLIBS) $(LIBS) $(OUTFLAG)$@ $(LDFLAGS) $(XLDFLAGS)
+
+whole: $(MKFILES) $(PREP) $(RBCONFIG) $(LIBRUBY)
+ @$(MINIRUBY) $(srcdir)/ext/extmk.rb $(SCRIPT_ARGS) \
+ --extout="$(EXTOUT)" --extension $(EXTS) --extstatic=static \
+ --mflags="STATIC_RUBY=$@-ruby" --ruby=$@-ruby
ruby.imp: $(LIBRUBY_A)
Index: Makefile.in
===================================================================
RCS file: /cvs/ruby/src/ruby/Makefile.in,v
retrieving revision 1.73
diff -U2 -p -r1.73 Makefile.in
--- Makefile.in 13 Jul 2005 13:44:21 -0000 1.73
+++ Makefile.in 2 Aug 2005 09:18:44 -0000
@@ -79,10 +79,4 @@ RANLIB = @RANLIB@
OBJEXT = @OBJEXT@
-
-EXTOBJS =
-DLDOBJS = $(DMYEXT)
-
-MAINOBJ = main.$(OBJEXT)
-
MANTYPE = @MANTYPE@
Index: cygwin/GNUmakefile.in
===================================================================
RCS file: /cvs/ruby/src/ruby/cygwin/GNUmakefile.in,v
retrieving revision 1.33
diff -U2 -p -r1.33 GNUmakefile.in
--- cygwin/GNUmakefile.in 20 Apr 2005 14:22:59 -0000 1.33
+++ cygwin/GNUmakefile.in 3 Aug 2005 10:14:31 -0000
@@ -60,4 +60,7 @@ $(RUBY_EXP): $(LIBRUBY_A)
@rm -f $(PROGRAM)
+$(STATIC_RUBY).rc: $(RUBY_INSTALL_NAME).rc
+ cp $< $@
+
GNUmakefile: $(srcdir)/cygwin/GNUmakefile.in
Index: ext/extmk.rb
===================================================================
RCS file: /cvs/ruby/src/ruby/ext/extmk.rb,v
retrieving revision 1.79
diff -U2 -p -r1.79 extmk.rb
--- ext/extmk.rb 13 May 2005 14:44:42 -0000 1.79
+++ ext/extmk.rb 3 Aug 2005 10:47:24 -0000
@@ -159,5 +160,5 @@ def extmake(target)
args = sysquote($mflags)
unless $destdir.to_s.empty? or $mflags.include?("DESTDIR")
- args << sysquote("DESTDIR=" + relative_from($destdir, "../"+prefix))
+ args += sysquote("DESTDIR=" + relative_from($destdir, "../"+prefix))
end
if $static
@@ -430,5 +431,5 @@ SRC
$extflags = libpathflag($extpath) << " " << $extflags.strip
conf = [
- ['SETUP', $setup], [$enable_shared ? 'DLDOBJS' : 'EXTOBJS', $extobjs],
+ ['SETUP', $setup], [$enable_shared && !$force_static ? 'DLDOBJS' : 'EXTOBJS', $extobjs],
['EXTLIBS', $extlibs.join(' ')], ['EXTLDFLAGS', $extflags]
].map {|n, v|
@@ -457,4 +458,7 @@ $stdout.flush
$mflags.concat(rubies)
+if $nmake == ?b
+ $mflags.collect {|flag| flag.sub!(/\A(?=\w+=)/, "-D")}
+end
system($make, *sysquote($mflags)) or exit($?.exitstatus)
stripするとこんなもん。
$ ll .i686-*/whole-ruby.exe -rwxr-xr-x 1 nakada users 1967616 2005-08-03 19:57:53.667750000 +0900 .i686-cygwin/whole-ruby.exe* -rwxr-xr-x 1 nakada users 1725440 2005-08-03 19:57:27.792750000 +0900 .i686-mingw32/whole-ruby.exe* -rwxr-xr-x 1 nakada users 1720320 2005-08-03 19:52:53.402125000 +0900 .i686-mswin32-71/whole-ruby.exe* -rwxr-xr-x 1 nakada users 2170960 2005-08-03 19:52:16.105250000 +0900 .i686-mswin32/whole-ruby.exe*
あれ、Makefileとか書き換えなくてもできるようにしてあったはずだけど、いつの間にかまたできなくなってる?
[なかむら(う)さんのツッコミより引用]
たぶん--with-static-linked-extのことをいってるんじゃないかと思うけど、 やりたかったのはそれじゃなくて全部一つにリンクしたexeをmake一発で作ることなんで。
それはそれとして今朝のコミットしたのは少々バグってたんで、とりあえずこんなところかな。
Index: common.mk
===================================================================
RCS file: /cvs/ruby/src/ruby/common.mk,v
retrieving revision 1.20
diff -U2 -p -r1.20 common.mk
--- common.mk 3 Aug 2005 15:26:14 -0000 1.20
+++ common.mk 4 Aug 2005 08:57:32 -0000
@@ -78,7 +78,7 @@ $(LIBRUBY_A): $(OBJS) $(DMYEXT)
$(LIBRUBY_SO): $(OBJS) $(DLDOBJS) $(LIBRUBY_A) $(PREP) $(ARCHFILE)
-static-ruby: $(MAINOBJ) $(EXTOBJS) $(LIBRUBY_A)
+static-ruby$(EXEEXT): $(MAINOBJ) $(EXTOBJS) $(LIBRUBY_A)
@$(RM) $@
- $(PURIFY) $(CC) $(LDFLAGS) $(XLDFLAGS) $(MAINLIBS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY_A) $(LIBS) $(OUTFLAG)$@
+ $(PURIFY) $(CC) $(MAINLIBS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY_A) $(LIBS) $(OUTFLAG)$@ $(LDFLAGS) $(XLDFLAGS)
ruby.imp: $(LIBRUBY_A)
Index: ext/extmk.rb
===================================================================
RCS file: /cvs/ruby/src/ruby/ext/extmk.rb,v
retrieving revision 1.80
diff -U2 -p -r1.80 extmk.rb
--- ext/extmk.rb 3 Aug 2005 23:04:02 -0000 1.80
+++ ext/extmk.rb 4 Aug 2005 08:57:32 -0000
@@ -159,5 +159,5 @@ def extmake(target)
args = sysquote($mflags)
unless $destdir.to_s.empty? or $mflags.include?("DESTDIR")
- args += sysquote("DESTDIR=" + relative_from($destdir, "../"+prefix))
+ args += [sysquote("DESTDIR=" + relative_from($destdir, "../"+prefix))]
end
if $static
@@ -430,5 +430,5 @@ SRC
$extflags = libpathflag($extpath) << " " << $extflags.strip
conf = [
- ['SETUP', $setup], [$enable_shared && !$force_static ? 'DLDOBJS' : 'EXTOBJS', $extobjs],
+ ['SETUP', $setup], [enable_config("shared", $enable_shared) ? 'DLDOBJS' : 'EXTOBJS', $extobjs],
['EXTLIBS', $extlibs.join(' ')], ['EXTLDFLAGS', $extflags]
].map {|n, v|
bit or式はデフォルト値式に直接書けなくなってもかまわなかったのか。 なら閉じるほうのトークンを変えればできないのかなぁ。
Index: parse.y
===================================================================
RCS file: /cvs/ruby/src/ruby/parse.y,v
retrieving revision 1.399
diff -U2 -p -r1.399 parse.y
--- parse.y 4 Aug 2005 15:18:38 -0000 1.399
+++ parse.y 5 Aug 2005 06:04:58 -0000
@@ -127,4 +127,6 @@ struct parser_params {
stack_type parser_cmdarg_stack;
int parser_class_nest;
+ int parser_paren_nest;
+ int parser_bpar_beg;
int parser_in_single;
int parser_in_def;
@@ -183,4 +185,6 @@ static int parser_yyerror _((struct pars
#define cmdarg_stack (parser->parser_cmdarg_stack)
#define class_nest (parser->parser_class_nest)
+#define paren_nest (parser->parser_paren_nest)
+#define bpar_beg (parser->parser_bpar_beg)
#define in_single (parser->parser_in_single)
#define in_def (parser->parser_in_def)
@@ -554,5 +558,5 @@ static void ripper_compile_error _((stru
%token tLAMBDA_ARG /* -> */
%token tSYMBEG tSTRING_BEG tXSTRING_BEG tREGEXP_BEG tWORDS_BEG tQWORDS_BEG
-%token tSTRING_DBEG tSTRING_DVAR tSTRING_END
+%token tSTRING_DBEG tSTRING_DVAR tSTRING_END tBPAREND
/*
@@ -3105,8 +3109,15 @@ opt_block_param : none
;
-block_param_def : '|' opt_bv_decl '|'
+block_param_def : '|'
{
+ $<num>$ = bpar_beg;
+ bpar_beg = ++paren_nest;
+ }
+ opt_bv_decl tBPAREND
+ {
+ bpar_beg = $<num>2;
+ --paren_nest;
/*%%%*/
- $$ = NEW_ITER((NODE*)1, 0, $2);
+ $$ = NEW_ITER((NODE*)1, 0, $3);
/*%
$$ = blockvar_new(mlhs_new());
@@ -3121,10 +3132,17 @@ block_param_def : '|' opt_bv_decl '|'
%*/
}
- | '|' block_param opt_bv_decl '|'
+ | '|'
+ {
+ $<num>$ = bpar_beg;
+ bpar_beg = ++paren_nest;
+ }
+ block_param opt_bv_decl tBPAREND
{
+ bpar_beg = $<num>2;
+ --paren_nest;
/*%%%*/
- $$ = NEW_ITER($2, 0, $3);
+ $$ = NEW_ITER($3, 0, $4);
/*%
- $$ = blockvar_new($2);
+ $$ = blockvar_new($3);
%*/
}
@@ -6006,4 +6024,8 @@ parser_yylex(parser)
case '|':
+ if (bpar_beg && bpar_beg == paren_nest) {
+ lex_state = EXPR_BEG;
+ return tBPAREND;
+ }
if ((c = nextc()) == '|') {
lex_state = EXPR_BEG;
@@ -6336,7 +6358,8 @@ parser_yylex(parser)
}
+ case ')':
+ paren_nest--;
case ']':
case '}':
- case ')':
COND_LEXPOP();
CMDARG_LEXPOP();
@@ -6456,4 +6479,5 @@ parser_yylex(parser)
}
}
+ paren_nest++;
COND_PUSH(0);
CMDARG_PUSH(0);
ついでに作ったstruct parser_paramsをちょっとだけ小さくするパッチ。
Index: parse.y
===================================================================
RCS file: /cvs/ruby/src/ruby/parse.y,v
retrieving revision 1.399
diff -U2 -p -r1.399 parse.y
--- parse.y 4 Aug 2005 15:18:38 -0000 1.399
+++ parse.y 5 Aug 2005 06:04:58 -0000
@@ -129,7 +129,6 @@ struct parser_params {
int parser_in_single;
int parser_in_def;
- int parser_compile_for_eval;
+ int parser_stateflags;
VALUE parser_cur_mid;
- int parser_in_defined;
char *parser_tokenbuf;
int parser_tokidx;
@@ -176,4 +175,7 @@ static int parser_yyerror _((struct pars
#define parser ((struct parser_params*)parser_v)
+#define COMPILE_FOR_EVAL 001
+#define IN_DEFINED 002
+
#define ruby_eval_tree (parser->parser_eval_tree)
#define ruby_eval_tree_begin (parser->parser_eval_tree_begin)
@@ -185,7 +187,7 @@ static int parser_yyerror _((struct pars
#define in_single (parser->parser_in_single)
#define in_def (parser->parser_in_def)
-#define compile_for_eval (parser->parser_compile_for_eval)
+#define compile_for_eval (parser->parser_stateflags & COMPILE_FOR_EVAL)
+#define in_defined (parser->parser_stateflags & IN_DEFINED)
#define cur_mid (parser->parser_cur_mid)
-#define in_defined (parser->parser_in_defined)
#define tokenbuf (parser->parser_tokenbuf)
#define tokidx (parser->parser_tokidx)
@@ -2031,11 +2033,10 @@ arg : lhs '=' arg
%*/
}
- | kDEFINED opt_nl {in_defined = 1;} arg
+ | kDEFINED opt_nl {parser->parser_stateflags |= IN_DEFINED;} arg
{
+ parser->parser_stateflags &= ~IN_DEFINED;
/*%%%*/
- in_defined = 0;
$$ = NEW_DEFINED($4);
/*%
- in_defined = 0;
$$ = dispatch1(defined, $4);
%*/
@@ -2567,11 +2568,10 @@ primary : literal
%*/
}
- | kDEFINED opt_nl '(' {in_defined = 1;} expr rparen
+ | kDEFINED opt_nl '(' {parser->parser_stateflags |= IN_DEFINED;} expr rparen
{
+ parser->parser_stateflags &= ~IN_DEFINED;
/*%%%*/
- in_defined = 0;
$$ = NEW_DEFINED($5);
/*%
- in_defined = 0;
$$ = dispatch1(defined, $5);
%*/
@@ -4556,5 +4556,5 @@ yycompile(parser, f, line)
n = yyparse((void*)parser);
ruby_debug_lines = 0;
- compile_for_eval = 0;
+ parser->parser_stateflags = 0;
rb_set_kcode(kcode_save);
@@ -4641,5 +4641,8 @@ rb_parser_compile_string(vparser, f, s,
lex_input = s;
lex_pbeg = lex_p = lex_pend = 0;
- compile_for_eval = ruby_in_eval;
+ if (ruby_in_eval)
+ parser->parser_stateflags |= COMPILE_FOR_EVAL;
+ else
+ parser->parser_stateflags &= ~COMPILE_FOR_EVAL;
return yycompile(parser, f, line);
@@ -8712,6 +8715,5 @@ parser_initialize(parser)
parser->parser_in_single = 0;
parser->parser_in_def = 0;
- parser->parser_in_defined = 0;
- parser->parser_compile_for_eval = 0;
+ parser->parser_stateflags = 0;
parser->parser_cur_mid = 0;
parser->parser_tokenbuf = NULL;
未解決のバグも115件と結構たまったもんだと思ったが、 よく見ると修正済みなのにそのままになってるのもいくつかあるような。
[ruby-dev:26274]の修正で、
NODE_BLOCK_PASSとNODE_CALLなどを入れ替えられないかと思ってparse.yを見直していたら、
ブロックを渡さず引数だけをそのまま渡す方法がないことに気づいた。
つまり
class B
def foo(a, b, c)
p [block_given?, a, b, c]
end
end
class C < B
def foo(*)
super(&nil)
end
end
C.new.foo(1, 2, 3) {|x| p x}
ではB#fooにはC#fooへの引数は渡されない。
class C < B
def foo(*args)
super(*args, &nil)
end
end
と明示しなければならない。
意図的なのかなぁ。
close後のStringIO#stringあまり考えていなかったけれど、closeしてもそのまま取り出せたほうがいいのかな?
この例でいうと、元々こういう使い方を想定していたんだけど。
def foo(str) gz = Zlib::GzipWriter.new(StringIO.new(buff = "")) gz.write(str) gz.finish buff end
直すの自体は簡単。
Index: ext/stringio/stringio.c
===================================================================
RCS file: /cvs/ruby/src/ruby/ext/stringio/stringio.c,v
retrieving revision 1.42
diff -U2 -p -r1.42 stringio.c
--- ext/stringio/stringio.c 30 Apr 2005 04:11:10 -0000 1.42
+++ ext/stringio/stringio.c 11 Aug 2005 06:32:14 -0000
@@ -383,8 +383,7 @@ strio_close(self)
{
struct StringIO *ptr = StringIO(self);
- if (CLOSED(ptr)) {
+ if (CLOSED(ptr) || !(ptr->flags & FMODE_READWRITE)) {
rb_raise(rb_eIOError, "closed stream");
}
- ptr->string = Qnil;
ptr->flags &= ~FMODE_READWRITE;
return Qnil;
@@ -406,7 +405,5 @@ strio_close_read(self)
rb_raise(rb_eIOError, "closing non-duplex IO for reading");
}
- if (!((ptr->flags &= ~FMODE_READABLE) & FMODE_READWRITE)) {
- ptr->string = Qnil;
- }
+ ptr->flags &= ~FMODE_READABLE;
return Qnil;
}
@@ -427,7 +424,5 @@ strio_close_write(self)
rb_raise(rb_eIOError, "closing non-duplex IO for writing");
}
- if (!((ptr->flags &= ~FMODE_WRITABLE) & FMODE_READWRITE)) {
- ptr->string = Qnil;
- }
+ ptr->flags &= ~FMODE_WRITABLE;
return Qnil;
}
Wikipediaに登録されてるとは気づかなんだ。 しかし、やけに詳しいな。 ついでにCategory:気球にはメジャーな競技の説明まであるし。
Fixnum#==というかNumeric全般だけど、比較対象について知らない場合は、交換則を前提に相手に比較をまかせてしまうわけです。
x = Foo.new(1) y = Foo.new(1)
とすると
x == y 1(x.core) == y y == 1(x.core) 1(y.core) == 1(x.core)
たしか、しばらく前に仕事で行ってたビルの入り口がそんな感じだったような。 もちろん「改札」はしないけど形が。
もう大学生ではない日誌経由。
そうか、PAGE_GUARDのせいだったのか。
じゃぁ、こんなのを用意しておけばなんとかなるかな。
LONG WINAPI
rb_w32_catch_stack_overflow(EXCEPTION_POINTERS *ep)
{
EXCEPTION_RECORD *er = ep->ExceptionRecord;
MEMORY_BASIC_INFORMATION mi;
char *page;
if (er->ExceptionCode != EXCEPTION_STACK_OVERFLOW)
return EXCEPTION_CONTINUE_SEARCH;
VirtualQuery(exception_address = &ep, &mi, sizeof(mi));
page = (char *)mi.BaseAddress - pagesize;
if (!VirtualFree(mi.AllocationBase, page - (char *)mi.AllocationBase, MEM_DECOMMIT)) {
return EXCEPTION_CONTINUE_SEARCH;
}
if (!VirtualProtect(page, pagesize, PAGE_GUARD | mi.AllocationProtect, &mi.Protect)) {
return EXCEPTION_CONTINUE_SEARCH;
}
return EXCEPTION_EXECUTE_HANDLER;
}
LONG WINAPI
rb_w32_handle_stack_overflow(EXCEPTION_POINTERS *ep)
{
LONG e = rb_w32_catch_stack_overflow(ep);
if (e == EXCEPTION_EXECUTE_HANDLER)
rb_exc_raise(sysstack_error);
return e;
}
sigaltstack()はstack overflowと通常のSEGVをどう区別するかが悩みどころだな。
自分でguard pageを用意するのはたしかに可能なんだけど、
それで本当にたまたまアクセスしちゃった場合と区別できるかがちょっと疑問。
そんな可能性は充分に低いかな。
POSIXでSIGSTACKでも追加してくれればよかったのになぁ。
ちょっとCSSを編集しようとして探してみると、 いくつかヒットするもののみんな Not found とか DNS Errorとかで名前だけ。
とりあえず
ここにあったサンプルを
試してみた。
なぜかbottomがハイライトされないのでcssm-propertiesに追加と、
font-lock-constant-faceは古いといわれるのでcssm-font-lock-keywordsをfont-lock-constant-faceを使うように変更。
追加した設定は以下の二つ。
(setq cssm-indent-level 4) (setq cssm-indent-function #'cssm-c-style-indenter)
今日授賞式だったらしいけど、web上では公表してないのかな? 日本OSS推進フォーラムのページを見ても何も書いてないし。
追記: ほとんど入れ違いでプレス発表が追加されてた。
いきなりprototype形式になったりしちゃったので、 いっそ全部prototype宣言とK&R定義に統一させてみようかと思ったが、 cygwinのprotoizeがまともに動かない。
$ cat x.c
test()
{
char a;
a='a';
}
$ protoize x.c
protoize: `/home/nakada/tmp/x.c' をコンパイル中
protoize: /h/home/nakada/tmp/x.c: 状態を取得できません: No such file or directory
protoize: `/h/home/nakada/tmp/x.c' は変換されていません
なんだこの/hは。
これか?
全然違った。ドライブレター絡みのバグ。問題が出るのはcygwinのみかな。
$ diff -u2p protoize.c{~,}
--- protoize.c~ 2003-08-14 15:04:46.000000000 +0900
+++ protoize.c 2005-08-31 14:50:44.550125000 +0900
@@ -1091,5 +1091,5 @@ abspath (const char *cwd, const char *re
}
#ifdef HAVE_DOS_BASED_FILE_SYSTEM
- else if (IS_DIR_SEPARATOR (rel_filename[0]))
+ else if (IS_DIR_SEPARATOR (rel_filename[0]) && cwd2[1] == ':')
{
/* A path starting with a directory separator is considered absolute
メモ。
| 鹿沼→大阪 | 11,000 |
|---|---|
| 鹿沼インター | 22:05 |
| なんばOCATビル | 7:07 |
と
| 大阪→佐賀 | 9,990 |
|---|---|
| なんば(OCATビル) | 21:45 |
| なんば高速バスターミナル | 22:00 |
| 武雄温泉駅前 | 6:42 |
さすがに武雄までいっちゃうと大変すぎるな…。
| 大阪→福岡 | 10000 |
|---|---|
| 大阪(阪急梅田) | 22:00 |
| 新大阪(阪急バスターミナル) | 22:09 |
| 博多駅交通センター | 7:30 |
| 西鉄天神バスセンター | 7:40 |
昼間もあるのか。
| 大阪→福岡 | 7000 |
|---|---|
| なんば(OCATビル) | 9:00 |
| 大阪駅桜橋口 | 9:20 |
| 小倉南インター | 17:18 |
| 博多駅交通センター | 18:07 |
_ なかむら(う) [あれ、Makefileとか書き換えなくてもできるようにしてあったはず..]