diff --git a/.cvsignore b/.cvsignore index 52a5620133..309f85c515 100644 --- a/.cvsignore +++ b/.cvsignore @@ -5,6 +5,7 @@ *~ .ccmalloc .ppack +.ext COPYING.LIB ChangeLog.pre-alpha ChangeLog.pre1_1 @@ -22,7 +23,6 @@ config.h.in config.log config.status configure -foo.rb libruby.so.* miniruby miniruby.elhash @@ -30,7 +30,6 @@ miniruby.elhash2 miniruby.orig2 miniruby.plhash miniruby.plhash2 -modex.rb newdate.rb newver.rb parse.c diff --git a/ChangeLog b/ChangeLog index d2341966db..2564052797 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,8 @@ +Tue Feb 17 23:40:34 2004 Guy Decoux + + * sprintf.c (rb_f_sprintf): preserve original val for + format_integer. [ruby-talk:92975] + Tue Feb 17 23:28:45 2004 NAKAMURA, Hiroshi * test/soap/marshal/test_marshal.rb, test/ruby/test_marshal.rb: do $: diff --git a/lib/pstore.rb b/lib/pstore.rb index 93795495fc..0be5e5a083 100644 --- a/lib/pstore.rb +++ b/lib/pstore.rb @@ -35,7 +35,11 @@ class PStore def in_transaction raise PStore::Error, "not in transaction" unless @transaction end - private :in_transaction + def in_transaction_wr() + in_transaction() + raise PStore::Error, "in read-only transaction" if @rdonly + end + private :in_transaction, :in_transaction_wr def [](name) in_transaction @@ -52,11 +56,11 @@ class PStore self[name] end def []=(name, value) - in_transaction + in_transaction_wr() @table[name] = value end def delete(name) - in_transaction + in_transaction_wr() @table.delete name end @@ -86,27 +90,38 @@ class PStore def transaction(read_only=false) raise PStore::Error, "nested transaction" if @transaction begin + @rdonly = read_only + @abort = false @transaction = true value = nil - backup = @filename+"~" - begin - file = File::open(@filename, read_only ? "rb" : "rb+") - orig = true - rescue Errno::ENOENT - raise if read_only - file = File::open(@filename, "wb+") + new_file = @filename + ".new" + + content = nil + file = File.open(@filename, File::RDWR | File::CREAT) + if !read_only + file.flock(File::LOCK_EX) + commit_new() if FileTest.exist?(new_file) + content = file.read() + else + file.flock(File::LOCK_SH) + if FileTest.exist?(new_file) + File.open(new_file) {|fp| content = fp.read()} + else + content = file.read() + end end - file.flock(read_only ? File::LOCK_SH : File::LOCK_EX) - if read_only - @table = Marshal::load(file) - elsif orig and (content = file.read) != "" + + if content != "" @table = Marshal::load(content) - size = content.size - md5 = Digest::MD5.digest(content) - content = nil # unreference huge data + if !read_only + size = content.size + md5 = Digest::MD5.digest(content) + end else @table = {} end + content = nil # unreference huge data + begin catch(:pstore_abort_transaction) do value = yield(self) @@ -116,24 +131,17 @@ class PStore raise ensure if !read_only and !@abort - file.rewind + tmp_file = @filename + ".tmp" content = Marshal::dump(@table) if !md5 || size != content.size || md5 != Digest::MD5.digest(content) - File::copy @filename, backup - begin - file.write(content) - file.truncate(file.pos) - content = nil # unreference huge data - rescue - File::rename backup, @filename if File::exist?(backup) - raise - end - end + File.open(tmp_file, "w") {|t| + t.write(content) + } + File.rename(tmp_file, new_file) + commit_new() + end + content = nil # unreference huge data end - if @abort and !orig - File.unlink(@filename) - end - @abort = false end ensure @table = nil @@ -142,6 +150,15 @@ class PStore end value end + + private + def commit_new() + new_file = @filename + ".new" + if !File.copy(new_file, @filename) + raise IOError + end + File.unlink(new_file) + end end if __FILE__ == $0 diff --git a/sprintf.c b/sprintf.c index e1069a3318..dc27bac118 100644 --- a/sprintf.c +++ b/sprintf.c @@ -444,6 +444,7 @@ rb_f_sprintf(argc, argv) long v = 0; int base, bignum = 0; int len, pos; + VALUE tmp; switch (*p) { case 'd': @@ -571,8 +572,8 @@ rb_f_sprintf(argc, argv) } if (sign) { - val = rb_big2str(val, base); - s = RSTRING(val)->ptr; + tmp = rb_big2str(val, base); + s = RSTRING(tmp)->ptr; if (s[0] == '-') { s++; sc = '-'; @@ -592,8 +593,8 @@ rb_f_sprintf(argc, argv) val = rb_big_clone(val); rb_big_2comp(val); } - val = rb_big2str(val, base); - s = RSTRING(val)->ptr; + tmp = rb_big2str(val, base); + s = RSTRING(tmp)->ptr; if (*s == '-') { if (base == 10) { rb_warning("negative number for %%u specifier"); @@ -601,8 +602,8 @@ rb_f_sprintf(argc, argv) } else { remove_sign_bits(++s, base); - val = rb_str_new(0, 3+strlen(s)); - t = RSTRING(val)->ptr; + tmp = rb_str_new(0, 3+strlen(s)); + t = RSTRING(tmp)->ptr; if (!(flags&FPREC)) { strcpy(t, ".."); t += 2; @@ -619,7 +620,7 @@ rb_f_sprintf(argc, argv) bignum = 2; } } - s = RSTRING(val)->ptr; + s = RSTRING(tmp)->ptr; format_integer: pos = -1;