yarv-diff:126
From: ko1 atdot.net
Date: 27 Oct 2005 23:53:46 -0000
Subject: [yarv-diff:126] r282 - in trunk: . benchmark lib rb yarvtest
Author: ko1
Date: 2005-10-28 08:53:45 +0900 (Fri, 28 Oct 2005)
New Revision: 282
Added:
trunk/lib/getoptlong.rb
trunk/lib/getopts.rb
trunk/lib/mkmf.rb
trunk/lib/rational.rb
Modified:
trunk/ChangeLog
trunk/benchmark/bmx_temp.rb
trunk/benchmark/run_rite.rb
trunk/common.mk
trunk/compile.c
trunk/error.c
trunk/eval.c
trunk/eval_load.c
trunk/eval_method.h
trunk/eval_proc.c
trunk/insns.def
trunk/lib/fileutils.rb
trunk/parse.y
trunk/rb/yasm.rb
trunk/test.rb
trunk/vm.c
trunk/vm.h
trunk/vm_dump.c
trunk/vm_macro.def
trunk/yarvcore.c
trunk/yarvtest/test_massign.rb
trunk/yarvtest/test_method.rb
Log:
* benchmark/run_rite.rb : add -I options to run benchmark
* common.mk : pass options to some rules with RUNOPT
and add -I options
* compile.c : fix massign with constant
* yarvtest/test_massign.rb : add tests for above
* eval_load.c : fix load_wait()
* eval_method.h : support ruby_cbase()
* lib/*.rb : add or modify libraries to run on yarv
* parse.y : change to ANSI C style
* vm.c : fix making proc process under cfunc/ifunc environment
* vm_macro.def : fix block pass
* yarvtest/test_method.rb : add tests for above
* yarvcore.c : add yarv_obj_is_proc()
* eval.c : fix rb_obj_is_proc to use yarv_obj_is_proc()
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/ChangeLog 2005-10-27 23:53:45 UTC (rev 282)
@@ -4,6 +4,35 @@
# from Mon, 03 May 2004 01:24:19 +0900
#
+2005-10-28(Fri) 08:43:29 +0900 Koichi Sasada <ko1 atdot.net>
+
+ * benchmark/run_rite.rb : add -I options to run benchmark
+
+ * common.mk : pass options to some rules with RUNOPT
+ and add -I options
+
+ * compile.c : fix massign with constant
+
+ * yarvtest/test_massign.rb : add tests for above
+
+ * eval_load.c : fix load_wait()
+
+ * eval_method.h : support ruby_cbase()
+
+ * lib/*.rb : add or modify libraries to run on yarv
+ * parse.y : change to ANSI C style
+
+ * vm.c : fix making proc process under cfunc/ifunc environment
+
+ * vm_macro.def : fix block pass
+
+ * yarvtest/test_method.rb : add tests for above
+
+ * yarvcore.c : add yarv_obj_is_proc()
+
+ * eval.c : fix rb_obj_is_proc to use yarv_obj_is_proc()
+
+
2005-10-27(Thu) 11:50:15 +0900 Koichi Sasada <ko1 atdot.net>
* some files : import from ruby 1.9.0 (2005-10-12)
Modified: trunk/benchmark/bmx_temp.rb
===================================================================
--- trunk/benchmark/bmx_temp.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/benchmark/bmx_temp.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -1,7 +1,10 @@
-Array.new(100000000).each{}
-__END__
+require 'rational'
-10000000.times{
-}
+a = Rational(1, 2)
+b = Rational(3, 4)
+i = 0
+while i<100000
+ i+=1
+ a-b
+end
-
Modified: trunk/benchmark/run_rite.rb
===================================================================
--- trunk/benchmark/run_rite.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/benchmark/run_rite.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -45,7 +45,7 @@
def benchmark file, bin
m = Benchmark.measure{
- `#{bin} #{file}`
+ `#{bin} #{$opts} #{file}`
}
sec = '%.3f' % m.real
puts " #{sec}"
@@ -69,6 +69,8 @@
$yarv_program = $1
when /\A--ruby-program=(.+)/
$ruby_program = $1
+ when /\A--opts=(.+)/
+ $opts = $1
when /\A(--yarv)|(-y)/
$yarvonly = true
when /\A(--ruby)|(-r)/
Modified: trunk/common.mk
===================================================================
--- trunk/common.mk 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/common.mk 2005-10-27 23:53:45 UTC (rev 282)
@@ -429,7 +429,7 @@
$(BASERUBY) -I$(srcdir)/lib $(srcdir)/test.rb $(MINIRUBY) $(BASERUBY) $(RUNOPT)
run: all
- $(MINIRUBY) $(srcdir)/test.rb
+ $(MINIRUBY) -I$(srcdir)/lib $(srcdir)/test.rb $(RUNOPT)
parse: all
$(MINIRUBY) $(srcdir)/rb/parse.rb $(srcdir)/test.rb
@@ -442,10 +442,10 @@
$(MINIRUBY) $(srcdir)/sample/test.rb
benchmark: all
- $(BASERUBY) -I$(srcdir) $(srcdir)/benchmark/run_rite.rb $(OPT) $(ITEMS) --yarv-program=$(MINIRUBY) --ruby-program=$(BASERUBY)
+ $(BASERUBY) -I$(srcdir) -I$(srcdir)/lib $(srcdir)/benchmark/run_rite.rb $(OPT) $(ITEMS) --yarv-program=$(MINIRUBY) --ruby-program=$(BASERUBY) --opts=-I$(srcdir)/lib
tbench: all
- $(BASERUBY) -I$(srcdir) $(srcdir)/benchmark/run_rite.rb bmx $(OPT) --yarv-program=$(MINIRUBY) --ruby-program=$(BASERUBY)
+ $(BASERUBY) -I$(srcdir) -I$(srcdir)/lib $(srcdir)/benchmark/run_rite.rb bmx $(OPT) --yarv-program=$(MINIRUBY) --ruby-program=$(BASERUBY) --opts=-I$(srcdir)/lib
bench-item: all
$(BASERUBY) -I$(srcdir) $(srcdir)/benchmark/run_rite.rb bm_$(ITEM) $(OPT) --yarv-program=$(MINIRUBY) --ruby-program=$(BASERUBY)
@@ -461,4 +461,4 @@
echo run > run.gdb
gdb: all run.gdb
- gdb -x run.gdb --quiet --args $(MINIRUBY) -I$(srcdir) $(srcdir)/test.rb
+ gdb -x run.gdb --quiet --args $(MINIRUBY) -I$(srcdir)/lib $(srcdir)/test.rb
Modified: trunk/compile.c
===================================================================
--- trunk/compile.c 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/compile.c 2005-10-27 23:53:45 UTC (rev 282)
@@ -331,8 +331,9 @@
{
#if CPDEBUG > 0
int flag = 0;
- LINK_ELEMENT* list = anchor->anchor.next,
- * plist= &anchor->anchor;
+ LINK_ELEMENT* list = anchor->anchor.next,
+ * plist = &anchor->anchor;
+
while(list){
if(plist != list->prev){
flag += 1;
@@ -1903,9 +1904,12 @@
default:{
DECL_ANCHOR(anchor);
-
COMPILE_POPED(anchor, "masgn lhs", node);
- ADD_ELEM(ret, LAST_ELEMENT(anchor));
+ // dump_disasm_list(FIRST_ELEMENT(anchor));
+ REMOVE_ELEM(FIRST_ELEMENT(anchor));
+ // dump_disasm_list(FIRST_ELEMENT(anchor));
+ ADD_SEQ(ret, anchor);
+ // ADD_ELEM(ret, LAST_ELEMENT(anchor));
}
}
@@ -2069,6 +2073,7 @@
estr = "false";
break;
case NODE_STR:
+ case NODE_LIT:
estr = "expression";
break;
@@ -3062,6 +3067,8 @@
VALUE parent_block = iseqobj->compile_data->current_block;
iseqobj->compile_data->current_block = Qfalse;
+
+#if SUPPORT_JOKE
if(nd_type(node) == NODE_VCALL){
if(node->nd_mid ==idBitblt){
ADD_INSN(ret, nd_line(node), bitblt);
@@ -3072,8 +3079,6 @@
break;
}
}
-
-#if SUPPORT_GOTO
/* only joke */
{
static ID goto_id;
@@ -3130,10 +3135,16 @@
flag |= VM_CALL_ARGS_SPLAT_BIT;
}
else if(nd_type(node->nd_args) == NODE_ARGSCAT){
+ NODE *t = node->nd_args->nd_head;
+ for(argc = 0; t; argc++, t = t->nd_next){
+ /* */
+ }
+ argc = I2F(argc+1);
+
compile_array(self, iseqobj, args, node->nd_args->nd_head, Qfalse);
POP_ELEMENT(args);
- argc = I2F(LIST_SIZE(args) + 1);
+ // argc = I2F(LIST_SIZE(args) + 1);
COMPILE(args, "args(cat: splat)", node->nd_args->nd_body);
flag |= VM_CALL_ARGS_SPLAT_BIT;
Modified: trunk/error.c
===================================================================
--- trunk/error.c 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/error.c 2005-10-27 23:53:45 UTC (rev 282)
@@ -147,24 +147,27 @@
return Qnil;
}
+void yarv_bug();
+
void
rb_bug(const char *fmt, ...)
{
- char buf[BUFSIZ];
- va_list args;
- FILE *out = stderr;
- int len = err_position(buf, BUFSIZ);
-
- if (fwrite(buf, 1, len, out) == len ||
- fwrite(buf, 1, len, (out = stdout)) == len) {
- fputs("[BUG] ", out);
- va_start(args, fmt);
- vfprintf(out, fmt, args);
- va_end(args);
- fprintf(out, "\nruby %s (%s) [%s]\n\n",
- ruby_version, ruby_release_date, ruby_platform);
- }
- abort();
+ char buf[BUFSIZ];
+ va_list args;
+ FILE *out = stderr;
+ int len = err_position(buf, BUFSIZ);
+
+ if (fwrite(buf, 1, len, out) == len ||
+ fwrite(buf, 1, len, (out = stdout)) == len) {
+ yarv_bug();
+ fputs("[BUG] ", out);
+ va_start(args, fmt);
+ vfprintf(out, fmt, args);
+ va_end(args);
+ fprintf(out, "\nruby %s (%s) [%s]\n\n",
+ ruby_version, ruby_release_date, ruby_platform);
+ }
+ abort();
}
static struct types {
Modified: trunk/eval.c
===================================================================
--- trunk/eval.c 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/eval.c 2005-10-27 23:53:45 UTC (rev 282)
@@ -487,8 +487,7 @@
rb_obj_is_proc(proc)
VALUE proc;
{
- // TODO: fix me
- return Qtrue;
+ return yarv_obj_is_proc(proc);
}
void
Modified: trunk/eval_load.c
===================================================================
--- trunk/eval_load.c 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/eval_load.c 2005-10-27 23:53:45 UTC (rev 282)
@@ -208,11 +208,22 @@
}
static int
-load_wait(ftptr)
- char *ftptr;
+load_wait(char *ftptr)
{
// TODO: fix me
+ return Qfalse;
+ /*
+ st_data_t th;
+
+ if (!loading_tbl) return Qfalse;
+ if (!st_lookup(loading_tbl, (st_data_t)ftptr, &th)) return Qfalse;
+ if ((rb_thread_t)th == curr_thread) return Qtrue;
+ do {
+ CHECK_INTS;
+ rb_thread_schedule();
+ } while (st_lookup(loading_tbl, (st_data_t)ftptr, &th));
return Qtrue;
+ */
}
/*
@@ -331,82 +342,80 @@
}
VALUE
-rb_require_safe(fname, safe)
- VALUE fname;
- int safe;
+rb_require_safe(VALUE fname, int safe)
{
- VALUE result = Qnil;
- volatile VALUE errinfo = GET_THREAD()->errinfo;
- int state;
- struct {
- NODE *node;
- ID this_func, callee;
- int vmode, safe;
- } volatile saved;
- char *volatile ftptr = 0;
+ VALUE result = Qnil;
+ volatile VALUE errinfo = GET_THREAD()->errinfo;
+ int state;
+ struct {
+ NODE *node;
+ ID this_func, callee;
+ int vmode, safe;
+ } volatile saved;
+ char *volatile ftptr = 0;
- saved.vmode = scope_vmode;
- saved.node = ruby_current_node;
- saved.safe = ruby_safe_level;
- PUSH_TAG(PROT_NONE);
- if ((state = EXEC_TAG()) == 0) {
- VALUE path;
- long handle;
- int found;
+ saved.vmode = scope_vmode;
+ saved.node = ruby_current_node;
+ saved.safe = ruby_safe_level;
+ PUSH_TAG(PROT_NONE);
+ if ((state = EXEC_TAG()) == 0) {
+ VALUE path;
+ long handle;
+ int found;
- ruby_safe_level = safe;
- FilePathValue(fname);
- *(volatile VALUE *)&fname = rb_str_new4(fname);
- found = search_required(fname, &path);
- if (found) {
- if (!path || load_wait(RSTRING(path)->ptr)) {
- result = Qfalse;
- }
- else {
- ruby_safe_level = 0;
- switch (found) {
- case 'r':
- /* loading ruby library should be serialized. */
- if (!loading_tbl) {
- loading_tbl = st_init_strtable();
- }
- /* partial state */
- ftptr = ruby_strdup(RSTRING(path)->ptr);
- st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)rb_vm_curr_thread());
- rb_load(path, 0);
- break;
+ ruby_safe_level = safe;
+ FilePathValue(fname);
+ *(volatile VALUE *)&fname = rb_str_new4(fname);
+ found = search_required(fname, &path);
+ if (found) {
+ if (!path || load_wait(RSTRING(path)->ptr)) {
+ result = Qfalse;
+ }
+ else {
+ ruby_safe_level = 0;
+ switch (found) {
+ case 'r':
+ /* loading ruby library should be serialized. */
+ if (!loading_tbl) {
+ loading_tbl = st_init_strtable();
+ }
+ /* partial state */
+ ftptr = ruby_strdup(RSTRING(path)->ptr);
+ st_insert(loading_tbl, (st_data_t)ftptr, (st_data_t)rb_vm_curr_thread());
+ rb_load(path, 0);
+ break;
- case 's':
- ruby_current_node = 0;
- ruby_sourcefile = rb_source_filename(RSTRING(path)->ptr);
- ruby_sourceline = 0;
- SCOPE_SET(SCOPE_PUBLIC);
- handle = (long)dln_load(RSTRING(path)->ptr);
- rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
- break;
- }
- rb_provide_feature(path);
- result = Qtrue;
- }
- }
+ case 's':
+ ruby_current_node = 0;
+ ruby_sourcefile = rb_source_filename(RSTRING(path)->ptr);
+ ruby_sourceline = 0;
+ SCOPE_SET(SCOPE_PUBLIC);
+ handle = (long)dln_load(RSTRING(path)->ptr);
+ rb_ary_push(ruby_dln_librefs, LONG2NUM(handle));
+ break;
+ }
+ rb_provide_feature(path);
+ result = Qtrue;
+ }
}
- POP_TAG();
- ruby_current_node = saved.node;
- ruby_set_current_source();
- SCOPE_SET(saved.vmode);
- ruby_safe_level = saved.safe;
- if (ftptr) {
- if (st_delete(loading_tbl, (st_data_t *)&ftptr, 0)) { /* loading done */
- free(ftptr);
- }
+ }
+ POP_TAG();
+ ruby_current_node = saved.node;
+ ruby_set_current_source();
+ SCOPE_SET(saved.vmode);
+ ruby_safe_level = saved.safe;
+ if (ftptr) {
+ if (st_delete(loading_tbl, (st_data_t *)&ftptr, 0)) { /* loading done */
+ free(ftptr);
}
- if (state) JUMP_TAG(state);
- if (NIL_P(result)) {
- load_failed(fname);
- }
- GET_THREAD()->errinfo = errinfo;
+ }
+ if (state) JUMP_TAG(state);
+ if (NIL_P(result)) {
+ load_failed(fname);
+ }
+ GET_THREAD()->errinfo = errinfo;
- return result;
+ return result;
}
VALUE
Modified: trunk/eval_method.h
===================================================================
--- trunk/eval_method.h 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/eval_method.h 2005-10-27 23:53:45 UTC (rev 282)
@@ -413,8 +413,17 @@
static VALUE
ruby_cbase(){
- UNSUPPORTED(ruby_cbase);
- return Qnil;
+ yarv_thread_t *th = GET_THREAD();
+ yarv_iseq_t *iseq = th->cfp->iseq;
+ VALUE cref;
+
+ if(iseq->klass_nest_stack){
+ cref = iseq->klass_nest_stack;
+ }
+ else{
+ cref = th->klass_nest_stack;
+ }
+ return rb_ary_entry(cref, -1);
}
static NODE *
@@ -424,52 +433,50 @@
}
void
-rb_undef(klass, id)
- VALUE klass;
- ID id;
+rb_undef(VALUE klass, ID id)
{
- VALUE origin;
- NODE *body;
+ VALUE origin;
+ NODE *body;
- if (ruby_cbase() == rb_cObject && klass == rb_cObject) {
- rb_secure(4);
- }
- if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {
- rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'", rb_id2name(id));
- }
- rb_frozen_class_p(klass);
- if (id == __id__ || id == __send__ || id == init) {
- rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
- }
- body = search_method(klass, id, &origin);
- if (!body || !body->nd_body) {
- char *s0 = " class";
- VALUE c = klass;
+ if (ruby_cbase() == rb_cObject && klass == rb_cObject) {
+ rb_secure(4);
+ }
+ if (ruby_safe_level >= 4 && !OBJ_TAINTED(klass)) {
+ rb_raise(rb_eSecurityError, "Insecure: can't undef `%s'", rb_id2name(id));
+ }
+ rb_frozen_class_p(klass);
+ if (id == __id__ || id == __send__ || id == init) {
+ rb_warn("undefining `%s' may cause serious problem", rb_id2name(id));
+ }
+ body = search_method(klass, id, &origin);
+ if (!body || !body->nd_body) {
+ char *s0 = " class";
+ VALUE c = klass;
- if (FL_TEST(c, FL_SINGLETON)) {
- VALUE obj = rb_iv_get(klass, "__attached__");
+ if (FL_TEST(c, FL_SINGLETON)) {
+ VALUE obj = rb_iv_get(klass, "__attached__");
- switch (TYPE(obj)) {
- case T_MODULE:
- case T_CLASS:
- c = obj;
- s0 = "";
- }
- }
- else if (TYPE(c) == T_MODULE) {
- s0 = " module";
- }
- rb_name_error(id, "undefined method `%s' for%s `%s'",
- rb_id2name(id),s0,rb_class2name(c));
+ switch (TYPE(obj)) {
+ case T_MODULE:
+ case T_CLASS:
+ c = obj;
+ s0 = "";
+ }
}
- rb_add_method(klass, id, 0, NOEX_PUBLIC);
- if (FL_TEST(klass, FL_SINGLETON)) {
- rb_funcall(rb_iv_get(klass, "__attached__"),
- singleton_undefined, 1, ID2SYM(id));
+ else if (TYPE(c) == T_MODULE) {
+ s0 = " module";
}
- else {
- rb_funcall(klass, undefined, 1, ID2SYM(id));
- }
+ rb_name_error(id, "undefined method `%s' for%s `%s'",
+ rb_id2name(id),s0,rb_class2name(c));
+ }
+ rb_add_method(klass, id, 0, NOEX_PUBLIC);
+ if (FL_TEST(klass, FL_SINGLETON)) {
+ rb_funcall(rb_iv_get(klass, "__attached__"),
+ singleton_undefined, 1, ID2SYM(id));
+ }
+ else {
+ rb_funcall(klass, undefined, 1, ID2SYM(id));
+ }
}
/*
Modified: trunk/eval_proc.c
===================================================================
--- trunk/eval_proc.c 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/eval_proc.c 2005-10-27 23:53:45 UTC (rev 282)
@@ -151,7 +151,6 @@
}
cfp = YARV_PREVIOUS_CONTROL_FRAME(cfp);
procval = th_make_proc(th, cfp, block);
-
if(is_lambda){
// TODO: lambda or proc
}
Modified: trunk/insns.def
===================================================================
--- trunk/insns.def 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/insns.def 2005-10-27 23:53:45 UTC (rev 282)
@@ -1354,7 +1354,6 @@
}
}
-
/**
@c method/iterator
@e return from this scope.
Modified: trunk/lib/fileutils.rb
===================================================================
--- trunk/lib/fileutils.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/lib/fileutils.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -1488,7 +1488,7 @@
METHODS = singleton_methods() - %w( private_module_function
commands options have_option? options_of collect_method )
-
+if false
#
# This module has all methods of FileUtils module, but it outputs messages
# before acting. This equates to passing the <tt>:verbose</tt> flag to
@@ -1564,5 +1564,5 @@
end
end
end
-
end
+end
Added: trunk/lib/getoptlong.rb
===================================================================
--- trunk/lib/getoptlong.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/lib/getoptlong.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -0,0 +1,481 @@
+# -*- Ruby -*-
+# Copyright (C) 1998, 1999, 2000 Motoyuki Kasahara
+#
+# You may redistribute it and/or modify it under the same license
+# terms as Ruby.
+#
+
+#
+# Documents and latest version of `getoptlong.rb' are found at:
+# http://www.sra.co.jp/people/m-kasahr/ruby/getoptlong/
+#
+
+#
+# Parse command line options just like GNU getopt_long().
+#
+class GetoptLong
+ #
+ # Orderings.
+ #
+ ORDERINGS = [REQUIRE_ORDER = 0, PERMUTE = 1, RETURN_IN_ORDER = 2]
+
+ #
+ # Argument flags.
+ #
+ ARGUMENT_FLAGS = [NO_ARGUMENT = 0, REQUIRED_ARGUMENT = 1,
+ OPTIONAL_ARGUMENT = 2]
+
+ #
+ # Status codes.
+ #
+ STATUS_YET, STATUS_STARTED, STATUS_TERMINATED = 0, 1, 2
+
+ #
+ # Error types.
+ #
+ class Error < StandardError; end
+ class AmbiguousOption < Error; end
+ class NeedlessArgument < Error; end
+ class MissingArgument < Error; end
+ class InvalidOption < Error; end
+
+ #
+ # The arguments are passed to new() as an array of arrays. Each
+ # subarray has a number of option names which carry the same
+ # meaning, and a ARGUMENT_FLAG, being one of
+ # GetoptLong::NO_ARGUMENT, GetoptLong::REQUIRED_ARGUMENT or
+ # GetoptLong::OPTIONAL_ARGUMENT. These determine whether the
+ # option takes an argument or not, or whether it is optional The
+ # actual processing is done later with #each().
+ #
+ def initialize(*arguments)
+ #
+ # Current ordering.
+ #
+ if ENV.include?('POSIXLY_CORRECT')
+ @ordering = REQUIRE_ORDER
+ else
+ @ordering = PERMUTE
+ end
+
+ #
+ # Hash table of option names.
+ # Keys of the table are option names, and their values are canonical
+ # names of the options.
+ #
+ @canonical_names = Hash.new
+
+ #
+ # Hash table of argument flags.
+ # Keys of the table are option names, and their values are argument
+ # flags of the options.
+ #
+ @argument_flags = Hash.new
+
+ #
+ # Whether error messages are output to $deferr.
+ #
+ @quiet = FALSE
+
+ #
+ # Status code.
+ #
+ @status = STATUS_YET
+
+ #
+ # Error code.
+ #
+ @error = nil
+
+ #
+ # Error message.
+ #
+ @error_message = nil
+
+ #
+ # Rest of catenated short options.
+ #
+ @rest_singles = ''
+
+ #
+ # List of non-option-arguments.
+ # Append them to ARGV when option processing is terminated.
+ #
+ @non_option_arguments = Array.new
+
+ if 0 < arguments.length
+ set_options(*arguments)
+ end
+ end
+
+ #
+ # Set the handling of the ordering of options. The supplied
+ # argument ordering must be a member of ORDERINGS, i.e one of
+ # GetoptLong::REQUIRE_ORDER, GetoptLong::PERMUTE,
+ # GetoptLong::RETURN_IN_ORDER. A RuntimeError is raised if
+ # option processing has already started.
+ #
+ def ordering=(ordering)
+ #
+ # The method is failed if option processing has already started.
+ #
+ if @status != STATUS_YET
+ set_error(ArgumentError, "argument error")
+ raise RuntimeError,
+ "invoke ordering=, but option processing has already started"
+ end
+
+ #
+ # Check ordering.
+ #
+ if !ORDERINGS.include?(ordering)
+ raise ArgumentError, "invalid ordering `#{ordering}'"
+ end
+ if ordering == PERMUTE && ENV.include?('POSIXLY_CORRECT')
+ @ordering = REQUIRE_ORDER
+ else
+ @ordering = ordering
+ end
+ end
+
+ #
+ # Return ordering.
+ #
+ attr_reader :ordering
+
+ #
+ # Set options
+ #
+ def set_options(*arguments)
+ #
+ # The method is failed if option processing has already started.
+ #
+ if @status != STATUS_YET
+ raise RuntimeError,
+ "invoke set_options, but option processing has already started"
+ end
+
+ #
+ # Clear tables of option names and argument flags.
+ #
+ @canonical_names.clear
+ @argument_flags.clear
+
+ arguments.each do |arg|
+ #
+ # Each argument must be an Array.
+ #
+ if !arg.is_a?(Array)
+ raise ArgumentError, "the option list contains non-Array argument"
+ end
+
+ #
+ # Find an argument flag and it set to `argument_flag'.
+ #
+ argument_flag = nil
+ arg.each do |i|
+ if ARGUMENT_FLAGS.include?(i)
+ if argument_flag != nil
+ raise ArgumentError, "too many argument-flags"
+ end
+ argument_flag = i
+ end
+ end
+ raise ArgumentError, "no argument-flag" if argument_flag == nil
+
+ canonical_name = nil
+ arg.each do |i|
+ #
+ # Check an option name.
+ #
+ next if i == argument_flag
+ begin
+ if !i.is_a?(String) || i !~ /^-([^-]|-.+)$/
+ raise ArgumentError, "an invalid option `#{i}'"
+ end
+ if ( canonical_names.include?(i))
+ raise ArgumentError, "option redefined `#{i}'"
+ end
+ rescue
+ @canonical_names.clear
+ @argument_flags.clear
+ raise
+ end
+
+ #
+ # Register the option (`i') to the `@canonical_names' and
+ # `@canonical_names' Hashes.
+ #
+ if canonical_name == nil
+ canonical_name = i
+ end
+ @canonical_names[i] = canonical_name
+ @argument_flags[i] = argument_flag
+ end
+ raise ArgumentError, "no option name" if canonical_name == nil
+ end
+ return self
+ end
+
+ #
+ # Set/Unset `quiet' mode.
+ #
+ attr_writer :quiet
+
+ #
+ # Return the flag of `quiet' mode.
+ #
+ attr_reader :quiet
+
+ #
+ # `quiet?' is an alias of `quiet'.
+ #
+ alias quiet? quiet
+
+ #
+ # Terminate option processing.
+ #
+ def terminate
+ return nil if @status == STATUS_TERMINATED
+ raise RuntimeError, "an error has occured" if @error != nil
+
+ @status = STATUS_TERMINATED
+ @non_option_arguments.reverse_each do |argument|
+ ARGV.unshift(argument)
+ end
+
+ @canonical_names = nil
+ @argument_flags = nil
+ @rest_singles = nil
+ @non_option_arguments = nil
+
+ return self
+ end
+
+ #
+ # Examine whether option processing is terminated or not.
+ #
+ def terminated?
+ return @status == STATUS_TERMINATED
+ end
+
+ #
+ # Set an error (a protected method).
+ #
+ def set_error(type, message)
+ $deferr.print("#{$0}: #{message}\n") if !@quiet
+
+ @error = type
+ @error_message = message
+ @canonical_names = nil
+ @argument_flags = nil
+ @rest_singles = nil
+ @non_option_arguments = nil
+
+ raise type, message
+ end
+ protected :set_error
+
+ #
+ # Examine whether an option processing is failed.
+ #
+ attr_reader :error
+
+ #
+ # `error?' is an alias of `error'.
+ #
+ alias error? error
+
+ #
+ # Return an error message.
+ #
+ def error_message
+ return @error_message
+ end
+
+ #
+ # Get next option name and its argument as an array.
+ # Return nil if the processing is complete (as determined by
+ # STATUS_TERMINATED).
+ #
+ def get
+ option_name, option_argument = nil, ''
+
+ #
+ # Check status.
+ #
+ return nil if @error != nil
+ case @status
+ when STATUS_YET
+ @status = STATUS_STARTED
+ when STATUS_TERMINATED
+ return nil
+ end
+
+ #
+ # Get next option argument.
+ #
+ if 0 < @rest_singles.length
+ argument = '-' + @rest_singles
+ elsif (ARGV.length == 0)
+ terminate
+ return nil
+ elsif @ordering == PERMUTE
+ while 0 < ARGV.length && ARGV[0] !~ /^-./
+ @non_option_arguments.push(ARGV.shift)
+ end
+ if ARGV.length == 0
+ terminate
+ return nil
+ end
+ argument = ARGV.shift
+ elsif @ordering == REQUIRE_ORDER
+ if (ARGV[0] !~ /^-./)
+ terminate
+ return nil
+ end
+ argument = ARGV.shift
+ else
+ argument = ARGV.shift
+ end
+
+ #
+ # Check the special argument `--'.
+ # `--' indicates the end of the option list.
+ #
+ if argument == '--' && @rest_singles.length == 0
+ terminate
+ return nil
+ end
+
+ #
+ # Check for long and short options.
+ #
+ if argument =~ /^(--[^=]+)/ && @rest_singles.length == 0
+ #
+ # This is a long style option, which start with `--'.
+ #
+ pattern = $1
+ if @canonical_names.include?(pattern)
+ option_name = pattern
+ else
+ #
+ # The option `option_name' is not registered in `@canonical_names'.
+ # It may be an abbreviated.
+ #
+ matches = []
+ @canonical_names.each_key do |key|
+ if key.index(pattern) == 0
+ option_name = key
+ matches << key
+ end
+ end
+ if 2 <= matches.length
+ set_error(AmbiguousOption, "option `#{argument}' is ambiguous between #{matches.join(', ')}")
+ elsif matches.length == 0
+ set_error(InvalidOption, "unrecognized option `#{argument}'")
+ end
+ end
+
+ #
+ # Check an argument to the option.
+ #
+ if @argument_flags[option_name] == REQUIRED_ARGUMENT
+ if argument =~ /=(.*)$/
+ option_argument = $1
+ elsif 0 < ARGV.length
+ option_argument = ARGV.shift
+ else
+ set_error(MissingArgument,
+ "option `#{argument}' requires an argument")
+ end
+ elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
+ if argument =~ /=(.*)$/
+ option_argument = $1
+ elsif 0 < ARGV.length && ARGV[0] !~ /^-./
+ option_argument = ARGV.shift
+ else
+ option_argument = ''
+ end
+ elsif argument =~ /=(.*)$/
+ set_error(NeedlessArgument,
+ "option `#{option_name}' doesn't allow an argument")
+ end
+
+ elsif argument =~ /^(-(.))(.*)/
+ #
+ # This is a short style option, which start with `-' (not `--').
+ # Short options may be catenated (e.g. `-l -g' is equivalent to
+ # `-lg').
+ #
+ option_name, ch, @rest_singles = $1, $2, $3
+
+ if @canonical_names.include?(option_name)
+ #
+ # The option `option_name' is found in `@canonical_names'.
+ # Check its argument.
+ #
+ if @argument_flags[option_name] == REQUIRED_ARGUMENT
+ if 0 < @rest_singles.length
+ option_argument = @rest_singles
+ @rest_singles = ''
+ elsif 0 < ARGV.length
+ option_argument = ARGV.shift
+ else
+ # 1003.2 specifies the format of this message.
+ set_error(MissingArgument, "option requires an argument -- #{ch}")
+ end
+ elsif @argument_flags[option_name] == OPTIONAL_ARGUMENT
+ if 0 < @rest_singles.length
+ option_argument = @rest_singles
+ @rest_singles = ''
+ elsif 0 < ARGV.length && ARGV[0] !~ /^-./
+ option_argument = ARGV.shift
+ else
+ option_argument = ''
+ end
+ end
+ else
+ #
+ # This is an invalid option.
+ # 1003.2 specifies the format of this message.
+ #
+ if ENV.include?('POSIXLY_CORRECT')
+ set_error(InvalidOption, "illegal option -- #{ch}")
+ else
+ set_error(InvalidOption, "invalid option -- #{ch}")
+ end
+ end
+ else
+ #
+ # This is a non-option argument.
+ # Only RETURN_IN_ORDER falled into here.
+ #
+ return '', argument
+ end
+
+ return @canonical_names[option_name], option_argument
+ end
+
+ #
+ # `get_option' is an alias of `get'.
+ #
+ alias get_option get
+
+ #
+ # Iterator version of `get', passes the option and the
+ # corresponding argument to the supplied block for processing.
+ #
+ def each
+ loop do
+ option_name, option_argument = get_option
+ break if option_name == nil
+ yield option_name, option_argument
+ end
+ end
+
+ #
+ # `each_option' is an alias of `each'.
+ #
+ alias each_option each
+end
Added: trunk/lib/getopts.rb
===================================================================
--- trunk/lib/getopts.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/lib/getopts.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -0,0 +1,126 @@
+#
+# getopts.rb -
+# $Release Version: $
+# $Revision: 1.11 $
+# $Date: 2004/11/04 23:43:39 $
+# by Yasuo OHBA(SHL Japan Inc. Technology Dept.)
+#
+# --
+# this is obsolete; use getoptlong
+#
+# 2000-03-21
+# modified by Minero Aoki <aamine dp.u-netsurf.ne.jp>
+#
+# 2002-03-05
+# rewritten by Akinori MUSHA <knu ruby-lang.org>
+#
+
+warn "Warning:#{caller[0].sub(/:in `.*'\z/, '')}: getopts is deprecated after Ruby 1.8.1; use optparse instead" if caller[0]
+
+$RCS_ID=%q$Header: /src/ruby/lib/getopts.rb,v 1.11 2004/11/04 23:43:39 matz Exp $
+
+
+def getopts(single_options, *options)
+ boolopts = {}
+ valopts = {}
+
+ #
+ # set defaults
+ #
+ single_options.scan(/.:?/) do |opt|
+ if opt.size == 1
+ boolopts[opt] = false
+ else
+ valopts[opt[0, 1]] = nil
+ end
+ end if single_options
+
+ options.each do |arg|
+ opt, val = arg.split(':', 2)
+
+ if val
+ valopts[opt] = val.empty? ? nil : val
+ else
+ boolopts[opt] = false
+ end
+ end
+
+ #
+ # scan
+ #
+ c = 0
+ argv = ARGV
+
+ while arg = argv.shift
+ case arg
+ when /\A--(.*)/
+ if $1.empty? # xinit -- -bpp 24
+ break
+ end
+
+ opt, val = $1.split('=', 2)
+
+ if opt.size == 1
+ argv.unshift arg
+ return nil
+ elsif valopts.key? opt # imclean --src +trash
+ valopts[opt] = val || argv.shift or return nil
+ elsif boolopts.key? opt # ruby --verbose
+ boolopts[opt] = true
+ else
+ argv.unshift arg
+ return nil
+ end
+
+ c += 1
+ when /\A-(.+)/
+ opts = $1
+
+ until opts.empty?
+ opt = opts.slice!(0, 1)
+
+ if valopts.key? opt
+ val = opts
+
+ if val.empty? # ruby -e 'p $:'
+ valopts[opt] = argv.shift or return nil
+ else # cc -ohello ...
+ valopts[opt] = val
+ end
+
+ c += 1
+ break
+ elsif boolopts.key? opt
+ boolopts[opt] = true # ruby -h
+ c += 1
+ else
+ argv.unshift arg
+ return nil
+ end
+ end
+ else
+ argv.unshift arg
+ break
+ end
+ end
+
+ #
+ # set
+ #
+ $OPT = {}
+
+ boolopts.each do |opt, val|
+ $OPT[opt] = val
+
+ sopt = opt.gsub(/[^A-Za-z0-9_]/, '_')
+ eval "$OPT_#{sopt} = val"
+ end
+ valopts.each do |opt, val|
+ $OPT[opt] = val
+
+ sopt = opt.gsub(/[^A-Za-z0-9_]/, '_')
+ eval "$OPT_#{sopt} = val"
+ end
+
+ c
+end
Added: trunk/lib/mkmf.rb
===================================================================
--- trunk/lib/mkmf.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/lib/mkmf.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -0,0 +1,1386 @@
+# module to create Makefile for extension modules
+# invoke like: ruby -r mkmf extconf.rb
+
+require 'rbconfig'
+require 'fileutils'
+require 'shellwords'
+
+CONFIG = Config::MAKEFILE_CONFIG
+ORIG_LIBPATH = ENV['LIB']
+
+CXX_EXT = %w[cc cxx cpp]
+if /mswin|bccwin|mingw|msdosdjgpp|human|os2/ !~ CONFIG['build_os']
+ CXX_EXT.concat(%w[C])
+end
+SRC_EXT = %w[c m] << CXX_EXT
+$static = $config_h = nil
+
+unless defined? $configure_args
+ $configure_args = {}
+ args = CONFIG["configure_args"]
+ if ENV["CONFIGURE_ARGS"]
+ args << " " << ENV["CONFIGURE_ARGS"]
+ end
+ for arg in Shellwords::shellwords(args)
+ arg, val = arg.split('=', 2)
+ next unless arg
+ arg.tr!('_', '-')
+ if arg.sub!(/^(?!--)/, '--')
+ val or next
+ arg.downcase!
+ end
+ next if /^--(?:top|topsrc|src|cur)dir$/ =~ arg
+ $configure_args[arg] = val || true
+ end
+ for arg in ARGV
+ arg, val = arg.split('=', 2)
+ next unless arg
+ arg.tr!('_', '-')
+ if arg.sub!(/^(?!--)/, '--')
+ val or next
+ arg.downcase!
+ end
+ $configure_args[arg] = val || true
+ end
+end
+
+$libdir = CONFIG["libdir"]
+$rubylibdir = CONFIG["rubylibdir"]
+$archdir = CONFIG["archdir"]
+$sitedir = CONFIG["sitedir"]
+$sitelibdir = CONFIG["sitelibdir"]
+$sitearchdir = CONFIG["sitearchdir"]
+
+$mswin = /mswin/ =~ RUBY_PLATFORM
+$bccwin = /bccwin/ =~ RUBY_PLATFORM
+$mingw = /mingw/ =~ RUBY_PLATFORM
+$cygwin = /cygwin/ =~ RUBY_PLATFORM
+$human = /human/ =~ RUBY_PLATFORM
+$netbsd = /netbsd/ =~ RUBY_PLATFORM
+$os2 = /os2/ =~ RUBY_PLATFORM
+$beos = /beos/ =~ RUBY_PLATFORM
+$solaris = /solaris/ =~ RUBY_PLATFORM
+
+def config_string(key, config = CONFIG)
+ s = config[key] and !s.empty? and block_given? ? yield(s) : s
+end
+
+def dir_re(dir)
+ Regexp.new('\$(?:\('+dir+'\)|\{'+dir+'\})(?:\$\(target_prefix\)|\{target_prefix\})?')
+end
+
+INSTALL_DIRS = [
+ [dir_re('commondir'), "$(RUBYCOMMONDIR)"],
+ [dir_re("sitedir"), "$(RUBYCOMMONDIR)"],
+ [dir_re('rubylibdir'), "$(RUBYLIBDIR)"],
+ [dir_re('archdir'), "$(RUBYARCHDIR)"],
+ [dir_re('sitelibdir'), "$(RUBYLIBDIR)"],
+ [dir_re('sitearchdir'), "$(RUBYARCHDIR)"]
+]
+
+def install_dirs(target_prefix = nil)
+ if $extout
+ dirs = [
+ ['RUBYCOMMONDIR', '$(extout)'],
+ ['RUBYLIBDIR', '$(extout)$(target_prefix)'],
+ ['RUBYARCHDIR', '$(extout)/$(arch)$(target_prefix)'],
+ ['extout', "#$extout"],
+ ['extout_prefix', "#$extout_prefix"],
+ ]
+ elsif $extmk
+ dirs = [
+ ['RUBYCOMMONDIR', '$(rubylibdir)'],
+ ['RUBYLIBDIR', '$(rubylibdir)$(target_prefix)'],
+ ['RUBYARCHDIR', '$(archdir)$(target_prefix)'],
+ ]
+ else
+ dirs = [
+ ['RUBYCOMMONDIR', '$(sitedir)$(target_prefix)'],
+ ['RUBYLIBDIR', '$(sitelibdir)$(target_prefix)'],
+ ['RUBYARCHDIR', '$(sitearchdir)$(target_prefix)'],
+ ]
+ end
+ dirs << ['target_prefix', (target_prefix ? "/#{target_prefix}" : "")]
+ dirs
+end
+
+def map_dir(dir, map = nil)
+ map ||= INSTALL_DIRS
+ map.inject(dir) {|dir, (orig, new)| dir.gsub(orig, new)}
+end
+
+topdir = File.dirname(libdir = File.dirname(__FILE__))
+extdir = File.expand_path("ext", topdir)
+$extmk = File.expand_path($0)[0, extdir.size+1] == extdir+"/"
+if not $extmk and File.exist?(Config::CONFIG["archdir"] + "/ruby.h")
+ $hdrdir = $topdir = Config::CONFIG["archdir"]
+elsif File.exist?(($top_srcdir ||= topdir) + "/ruby.h") and
+ File.exist?(($topdir ||= Config::CONFIG["topdir"]) + "/config.h")
+ $hdrdir = $top_srcdir
+else
+ abort "can't find header files for ruby."
+end
+
+OUTFLAG = CONFIG['OUTFLAG']
+CPPOUTFILE = CONFIG['CPPOUTFILE']
+
+CONFTEST_C = "conftest.c"
+
+class String
+ def quote
+ /\s/ =~ self ? "\"#{self}\"" : self
+ end
+end
+class Array
+ def quote
+ map {|s| s.quote}
+ end
+end
+
+def rm_f(*files)
+ FileUtils.rm_f(Dir[files.join("\0")])
+end
+
+def modified?(target, times)
+ (t = File.mtime(target)) rescue return nil
+ Array === times or times = [times]
+ t if times.all? {|n| n <= t}
+end
+
+def merge_libs(*libs)
+ libs.inject([]) do |x, y|
+ xy = x & y
+ xn = yn = 0
+ y = y.inject([]) {|ary, e| ary.last == e ? ary : ary << e}
+ y.each_with_index do |v, yi|
+ if xy.include?(v)
+ xi = [x.index(v), xn].max()
+ x[xi, 1] = y[yn..yi]
+ xn, yn = xi + (yi - yn + 1), yi + 1
+ end
+ end
+ x.concat(y[yn..-1] || [])
+ end
+end
+
+module Logging
+ @log = nil
+ @logfile = 'mkmf.log'
+ @orgerr = $stderr.dup
+ @orgout = $stdout.dup
+ @postpone = 0
+
+ def self::open
+ @log ||= File::open(@logfile, 'w')
+ @log.sync = true
+ $stderr.reopen(@log)
+ $stdout.reopen(@log)
+ yield
+ ensure
+ $stderr.reopen(@orgerr)
+ $stdout.reopen(@orgout)
+ end
+
+ def self::message(*s)
+ @log ||= File::open(@logfile, 'w')
+ @log.sync = true
+ @log.printf(*s)
+ end
+
+ def self::logfile file
+ @logfile = file
+ if @log and not @log.closed?
+ @log.flush
+ @log.close
+ @log = nil
+ end
+ end
+
+ def self::postpone
+ tmplog = "mkmftmp#{@postpone += 1}.log"
+ open do
+ log, *save = @log, @logfile, @orgout, @orgerr
+ @log, @logfile, @orgout, @orgerr = nil, tmplog, log, log
+ begin
+ log.print(open {yield})
+ @log.close
+ File::open(tmplog) {|t| FileUtils.copy_stream(t, log)}
+ ensure
+ @log, @logfile, @orgout, @orgerr = log, *save
+ @postpone -= 1
+ rm_f tmplog
+ end
+ end
+ end
+end
+
+def xsystem command
+ Logging::open do
+ puts command.quote
+ system(command)
+ end
+end
+
+def xpopen command, *mode, &block
+ Logging::open do
+ case mode[0]
+ when nil, /^r/
+ puts "#{command} |"
+ else
+ puts "| #{command}"
+ end
+ IO.popen(command, *mode, &block)
+ end
+end
+
+def log_src(src)
+ Logging::message <<"EOM", src
+checked program was:
+/* begin */
+%s/* end */
+
+EOM
+end
+
+def create_tmpsrc(src)
+ src = yield(src) if block_given?
+ src = src.sub(/[^\n]\z/, "\\&\n")
+ open(CONFTEST_C, "wb") do |cfile|
+ cfile.print src
+ end
+ src
+end
+
+def try_do(src, command, &b)
+ src = create_tmpsrc(src, &b)
+ xsystem(command)
+ensure
+ log_src(src)
+end
+
+def link_command(ldflags, opt="", libpath=$LIBPATH)
+ Config::expand(TRY_LINK.dup,
+ CONFIG.merge('hdrdir' => $hdrdir.quote,
+ 'src' => CONFTEST_C,
+ 'INCFLAGS' => $INCFLAGS,
+ 'CPPFLAGS' => $CPPFLAGS,
+ 'CFLAGS' => "#$CFLAGS",
+ 'ARCH_FLAG' => "#$ARCH_FLAG",
+ 'LDFLAGS' => "#$LDFLAGS #{ldflags}",
+ 'LIBPATH' => libpathflag(libpath),
+ 'LOCAL_LIBS' => "#$LOCAL_LIBS #$libs",
+ 'LIBS' => "#$LIBRUBYARG_STATIC #{opt} #$LIBS"))
+end
+
+def cc_command(opt="")
+ Config::expand("$(CC) -c #$INCFLAGS -I$(hdrdir) " \
+ "#$CPPFLAGS #$CFLAGS #$ARCH_FLAG #{opt} #{CONFTEST_C}",
+ CONFIG.merge('hdrdir' => $hdrdir.quote))
+end
+
+def cpp_command(outfile, opt="")
+ Config::expand("$(CPP) #$INCFLAGS -I$(hdrdir) " \
+ "#$CPPFLAGS #$CFLAGS #{opt} #{CONFTEST_C} #{outfile}",
+ CONFIG.merge('hdrdir' => $hdrdir.quote))
+end
+
+def libpathflag(libpath=$LIBPATH)
+ libpath.map{|x|
+ (x == "$(topdir)" ? LIBPATHFLAG : LIBPATHFLAG+RPATHFLAG) % x.quote
+ }.join
+end
+
+def try_link0(src, opt="", &b)
+ try_do(src, link_command("", opt), &b)
+end
+
+def try_link(src, opt="", &b)
+ try_link0(src, opt, &b)
+ensure
+ rm_f "conftest*", "c0x32*"
+end
+
+def try_compile(src, opt="", &b)
+ try_do(src, cc_command(opt), &b)
+ensure
+ rm_f "conftest*"
+end
+
+def try_cpp(src, opt="", &b)
+ try_do(src, cpp_command(CPPOUTFILE, opt), &b)
+ensure
+ rm_f "conftest*"
+end
+
+def cpp_include(header)
+ if header
+ header = [header] unless header.kind_of? Array
+ header.map {|h| "#include <#{h}>\n"}.join
+ else
+ ""
+ end
+end
+
+def with_cppflags(flags)
+ cppflags = $CPPFLAGS
+ $CPPFLAGS = flags
+ ret = yield
+ensure
+ $CPPFLAGS = cppflags unless ret
+end
+
+def with_cflags(flags)
+ cflags = $CFLAGS
+ $CFLAGS = flags
+ ret = yield
+ensure
+ $CFLAGS = cflags unless ret
+end
+
+def with_ldflags(flags)
+ ldflags = $LDFLAGS
+ $LDFLAGS = flags
+ ret = yield
+ensure
+ $LDFLAGS = ldflags unless ret
+end
+
+def try_static_assert(expr, headers = nil, opt = "", &b)
+ headers = cpp_include(headers)
+ try_compile(<<SRC, opt, &b)
+#{COMMON_HEADERS}
+#{headers}
+/*top*/
+int conftest_const[(#{expr}) ? 1 : -1];
+SRC
+end
+
+def try_constant(const, headers = nil, opt = "", &b)
+ includes = cpp_include(headers)
+ if CROSS_COMPILING
+ if try_static_assert("#{const} > 0", headers, opt)
+ # positive constant
+ elsif try_static_assert("#{const} < 0", headers, opt)
+ neg = true
+ const = "-(#{const})"
+ elsif try_static_assert("#{const} == 0", headers, opt)
+ return 0
+ else
+ # not a constant
+ return nil
+ end
+ upper = 1
+ until try_static_assert("#{const} <= #{upper}", headers, opt)
+ lower = upper
+ upper <<= 1
+ end
+ return nil unless lower
+ while upper > lower + 1
+ mid = (upper + lower) / 2
+ if try_static_assert("#{const} > #{mid}", headers, opt)
+ lower = mid
+ else
+ upper = mid
+ end
+ end
+ unless upper == lower
+ if try_static_assert("#{const} == #{lower}", headers, opt)
+ upper = lower
+ end
+ end
+ upper = -upper if neg
+ return upper
+ else
+ src = %{#{COMMON_HEADERS}
+#{includes}
+#include <stdio.h>
+/*top*/
+int conftest_const = (int)(#{const});
+int main() {printf("%d\\n", conftest_const); return 0;}
+}
+ if try_link0(src, opt, &b)
+ xpopen("./conftest") do |f|
+ return Integer(f.gets)
+ end
+ end
+ end
+ nil
+end
+
+def try_func(func, libs, headers = nil, &b)
+ headers = cpp_include(headers)
+ try_link(<<"SRC", libs, &b) or try_link(<<"SRC", libs, &b)
+#{headers}
+/*top*/
+int main() { return 0; }
+int t() { #{func}(); return 0; }
+SRC
+#{COMMON_HEADERS}
+#{headers}
+/*top*/
+int main() { return 0; }
+int t() { void ((*volatile p)()); p = (void ((*)()))#{func}; return 0; }
+SRC
+end
+
+def try_var(var, headers = nil, &b)
+ headers = cpp_include(headers)
+ try_compile(<<"SRC", &b)
+#{COMMON_HEADERS}
+#{headers}
+/*top*/
+int main() { return 0; }
+int t() { void *volatile p; p = (void *)&#{var}; return 0; }
+SRC
+end
+
+def egrep_cpp(pat, src, opt = "", &b)
+ src = create_tmpsrc(src, &b)
+ xpopen(cpp_command('', opt)) do |f|
+ if Regexp === pat
+ puts(" ruby -ne 'print if #{pat.inspect}'")
+ f.grep(pat) {|l|
+ puts "#{f.lineno}: #{l}"
+ return true
+ }
+ false
+ else
+ puts(" egrep '#{pat}'")
+ begin
+ stdin = $stdin.dup
+ $stdin.reopen(f)
+ system("egrep", pat)
+ ensure
+ $stdin.reopen(stdin)
+ end
+ end
+ end
+ensure
+ rm_f "conftest*"
+ log_src(src)
+end
+
+def macro_defined?(macro, src, opt = "", &b)
+ src = src.sub(/[^\n]\z/, "\\&\n")
+ try_compile(src + <<"SRC", opt, &b)
+/*top*/
+#ifndef #{macro}
+# error
+>>>>>> #{macro} undefined <<<<<<
+#endif
+SRC
+end
+
+def try_run(src, opt = "", &b)
+ if try_link0(src, opt, &b)
+ xsystem("./conftest")
+ else
+ nil
+ end
+ensure
+ rm_f "conftest*"
+end
+
+def install_files(mfile, ifiles, map = nil, srcprefix = nil)
+ ifiles or return
+ srcprefix ||= '$(srcdir)'
+ Config::expand(srcdir = srcprefix.dup)
+ dirs = []
+ path = Hash.new {|h, i| h[i] = dirs.push([i])[-1]}
+ ifiles.each do |files, dir, prefix|
+ dir = map_dir(dir, map)
+ prefix = %r|\A#{Regexp.quote(prefix)}/?| if prefix
+ if /\A\.\// =~ files
+ # install files which are in current working directory.
+ files = files[2..-1]
+ len = nil
+ else
+ # install files which are under the $(srcdir).
+ files = File.join(srcdir, files)
+ len = srcdir.size
+ end
+ f = nil
+ Dir.glob(files) do |f|
+ f[0..len] = "" if len
+ d = File.dirname(f)
+ d.sub!(prefix, "") if prefix
+ d = (d.empty? || d == ".") ? dir : File.join(dir, d)
+ f = File.join(srcprefix, f) if len
+ path[d] << f
+ end
+ unless len or f
+ d = File.dirname(files)
+ d.sub!(prefix, "") if prefix
+ d = (d.empty? || d == ".") ? dir : File.join(dir, d)
+ path[d] << files
+ end
+ end
+ dirs
+end
+
+def install_rb(mfile, dest, srcdir = nil)
+ install_files(mfile, [["lib/**/*.rb", dest, "lib"]], nil, srcdir)
+end
+
+def append_library(libs, lib)
+ format(LIBARG, lib) + " " + libs
+end
+
+def message(*s)
+ unless $extmk and not $VERBOSE
+ printf(*s)
+ $stdout.flush
+ end
+end
+
+def checking_for(m, fmt = nil)
+ f = caller[0][/in `(.*)'$/, 1] and f << ": " #` for vim, ' for xyzzy
+ m = "checking for #{m}... "
+ message "%s", m
+ a = r = nil
+ Logging::postpone do
+ r = yield
+ a = (fmt ? fmt % r : r ? "yes" : "no") << "\n"
+ "#{f}#{m}-------------------- #{a}\n"
+ end
+ message(a)
+ Logging::message "--------------------\n\n"
+ r
+end
+
+def have_macro(macro, headers = nil, opt = "", &b)
+ m = "#{macro}"
+ m << " in #{headers.inspect}" if headers
+ checking_for m do
+ macro_defined?(macro, cpp_include(headers), opt, &b)
+ end
+end
+
+def have_library(lib, func = nil, header=nil, &b)
+ func = "main" if !func or func.empty?
+ lib = with_config(lib+'lib', lib)
+ checking_for "#{func}() in #{LIBARG%lib}" do
+ if COMMON_LIBS.include?(lib)
+ true
+ else
+ libs = append_library($libs, lib)
+ if try_func(func, libs, header, &b)
+ $libs = libs
+ true
+ else
+ false
+ end
+ end
+ end
+end
+
+def find_library(lib, func, *paths, &b)
+ func = "main" if !func or func.empty?
+ lib = with_config(lib+'lib', lib)
+ paths = paths.collect {|path| path.split(File::PATH_SEPARATOR)}.flatten
+ checking_for "#{func}() in #{LIBARG%lib}" do
+ libpath = $LIBPATH
+ libs = append_library($libs, lib)
+ begin
+ until r = try_func(func, libs, &b) or paths.empty?
+ $LIBPATH = libpath | [paths.shift]
+ end
+ if r
+ $libs = libs
+ libpath = nil
+ end
+ ensure
+ $LIBPATH = libpath if libpath
+ end
+ r
+ end
+end
+
+def have_func(func, headers = nil, &b)
+ checking_for "#{func}()" do
+ if try_func(func, $libs, headers, &b)
+ $defs.push(format("-DHAVE_%s", func.upcase))
+ true
+ else
+ false
+ end
+ end
+end
+
+def have_var(var, headers = nil, &b)
+ checking_for "#{var}" do
+ if try_var(var, headers, &b)
+ $defs.push(format("-DHAVE_%s", var.upcase))
+ true
+ else
+ false
+ end
+ end
+end
+
+def have_header(header, &b)
+ checking_for header do
+ if try_cpp(cpp_include(header), &b)
+ $defs.push(format("-DHAVE_%s", header.tr("a-z./\055", "A-Z___")))
+ true
+ else
+ false
+ end
+ end
+end
+
+def find_header(header, *paths)
+ checking_for header do
+ if try_cpp(cpp_include(header))
+ true
+ else
+ found = false
+ paths.each do |dir|
+ opt = "-I#{dir}".quote
+ if try_cpp(cpp_include(header), opt)
+ $INCFLAGS << " " << opt
+ found = true
+ break
+ end
+ end
+ found
+ end
+ end
+end
+
+def have_struct_member(type, member, header = nil, &b)
+ checking_for "#{type}.#{member}" do
+ if try_compile(<<"SRC", &b)
+#{COMMON_HEADERS}
+#{cpp_include(header)}
+/*top*/
+int main() { return 0; }
+int s = (char *)&((#{type}*)0)->#{member} - (char *)0;
+SRC
+ $defs.push(format("-DHAVE_ST_%s", member.upcase))
+ true
+ else
+ false
+ end
+ end
+end
+
+def have_type(type, header = nil, opt = "", &b)
+ checking_for type do
+ header = cpp_include(header)
+ if try_compile(<<"SRC", opt, &b) or (/\A\w+\z/n =~ type && try_compile(<<"SRC", opt, &b))
+#{COMMON_HEADERS}
+#{header}
+/*top*/
+static #{type} t;
+SRC
+#{COMMON_HEADERS}
+#{header}
+/*top*/
+static #{type} *t;
+SRC
+ $defs.push(format("-DHAVE_TYPE_%s", type.strip.upcase.tr_s("^A-Z0-9_", "_")))
+ true
+ else
+ false
+ end
+ end
+end
+
+def check_sizeof(type, header = nil, &b)
+ expr = "sizeof(#{type})"
+ m = "checking size of #{type}... "
+ message "%s", m
+ a = size = nil
+ Logging::postpone do
+ if size = try_constant(expr, header, &b)
+ $defs.push(format("-DSIZEOF_%s=%d", type.upcase.tr_s("^A-Z0-9_", "_"), size))
+ a = "#{size}\n"
+ else
+ a = "failed\n"
+ end
+ "check_sizeof: #{m}-------------------- #{a}\n"
+ end
+ message(a)
+ Logging::message "--------------------\n\n"
+ size
+end
+
+def scalar_ptr_type?(type, member = nil, headers = nil, &b)
+ try_compile(<<"SRC", &b) # pointer
+#{COMMON_HEADERS}
+#{cpp_include(headers)}
+/*top*/
+volatile #{type} conftestval;
+int main() { return 0; }
+int t() {return (int)(1-*(conftestval#{member ? ".#{member}" : ""}));}
+SRC
+end
+
+def scalar_type?(type, member = nil, headers = nil, &b)
+ try_compile(<<"SRC", &b) # pointer
+#{COMMON_HEADERS}
+#{cpp_include(headers)}
+/*top*/
+volatile #{type} conftestval;
+int main() { return 0; }
+int t() {return (int)(1-(conftestval#{member ? ".#{member}" : ""}));}
+SRC
+end
+
+def what_type?(type, member = nil, headers = nil, &b)
+ m = "#{type}"
+ name = type
+ if member
+ m << "." << member
+ name = "(((#{type} *)0)->#{member})"
+ end
+ m << " in #{headers.inspect}" if headers
+ fmt = "seems %s"
+ def fmt.%(x)
+ x ? super : "unknown"
+ end
+ checking_for m, fmt do
+ if scalar_ptr_type?(type, member, headers, &b)
+ if try_static_assert("sizeof(*#{name}) == 1", headers)
+ "string"
+ end
+ elsif scalar_type?(type, member, headers, &b)
+ if try_static_assert("sizeof(#{name}) > sizeof(long)", headers)
+ "long long"
+ elsif try_static_assert("sizeof(#{name}) > sizeof(int)", headers)
+ "long"
+ elsif try_static_assert("sizeof(#{name}) > sizeof(short)", headers)
+ "int"
+ elsif try_static_assert("sizeof(#{name}) > 1", headers)
+ "short"
+ else
+ "char"
+ end
+ end
+ end
+end
+
+def find_executable0(bin, path = nil)
+ ext = config_string('EXEEXT')
+ if File.expand_path(bin) == bin
+ return bin if File.executable?(bin)
+ return file if ext and File.executable?(file = bin + ext)
+ return nil
+ end
+ if path ||= ENV['PATH']
+ path = path.split(File::PATH_SEPARATOR)
+ else
+ path = %w[/usr/local/bin /usr/ucb /usr/bin /bin]
+ end
+ file = nil
+ path.each do |dir|
+ return file if File.executable?(file = File.join(dir, bin))
+ return file if ext and File.executable?(file << ext)
+ end
+ nil
+end
+
+def find_executable(bin, path = nil)
+ checking_for bin do
+ find_executable0(bin, path)
+ end
+end
+
+def arg_config(config, *defaults, &block)
+ $arg_config << [config, *defaults]
+ defaults << nil if !block and defaults.empty?
+ $configure_args.fetch(config.tr('_', '-'), *defaults, &block)
+end
+
+def with_config(config, *defaults, &block)
+ unless /^--with[-_]/ =~ config
+ config = '--with-' + config
+ end
+ arg_config(config, *defaults, &block)
+end
+
+def enable_config(config, *defaults)
+ if arg_config("--enable-"+config)
+ true
+ elsif arg_config("--disable-"+config)
+ false
+ elsif block_given?
+ yield(config, *defaults)
+ else
+ return *defaults
+ end
+end
+
+def create_header(header = "extconf.h")
+ message "creating %s\n", header
+ if $defs.length > 0
+ sym = header.tr("a-z./\055", "A-Z___")
+ open(header, "w") do |hfile|
+ hfile.print "#ifndef #{sym}\n#define #{sym}\n"
+ for line in $defs
+ case line
+ when /^-D([^=]+)(?:=(.*))?/
+ hfile.print "#define #$1 #{$2 || 1}\n"
+ when /^-U(.*)/
+ hfile.print "#undef #$1\n"
+ end
+ end
+ hfile.print "#endif\n"
+ end
+ end
+end
+
+def dir_config(target, idefault=nil, ldefault=nil)
+ if dir = with_config(target + "-dir", (idefault unless ldefault))
+ defaults = Array === dir ? dir : dir.split(File::PATH_SEPARATOR)
+ idefault = ldefault = nil
+ end
+
+ idir = with_config(target + "-include", idefault)
+ $arg_config.last[1] ||= "${#{target}-dir}/include"
+ ldir = with_config(target + "-lib", ldefault)
+ $arg_config.last[1] ||= "${#{target}-dir}/lib"
+
+ idirs = idir ? Array === idir ? idir : idir.split(File::PATH_SEPARATOR) : []
+ if defaults
+ idirs.concat(defaults.collect {|dir| dir + "/include"})
+ idir = ([idir] + idirs).compact.join(File::PATH_SEPARATOR)
+ end
+ unless idirs.empty?
+ idirs.collect! {|dir| "-I" + dir}
+ idirs -= Shellwords.shellwords($CPPFLAGS)
+ unless idirs.empty?
+ $CPPFLAGS = (idirs.quote << $CPPFLAGS).join(" ")
+ end
+ end
+
+ ldirs = ldir ? Array === ldir ? ldir : ldir.split(File::PATH_SEPARATOR) : []
+ if defaults
+ ldirs.concat(defaults.collect {|dir| dir + "/lib"})
+ ldir = ([ldir] + ldirs).compact.join(File::PATH_SEPARATOR)
+ end
+ $LIBPATH = ldirs | $LIBPATH
+
+ [idir, ldir]
+end
+
+def pkg_config(pkg)
+ unless defined?($PKGCONFIG)
+ if pkgconfig = with_config("pkg-config", !CROSS_COMPILING && "pkg-config")
+ find_executable0(pkgconfig) or pkgconfig = nil
+ end
+ $PKGCONFIG = pkgconfig
+ end
+ if $PKGCONFIG and system("#{$PKGCONFIG} --exists #{pkg}")
+ cflags = `#{$PKGCONFIG} --cflags #{pkg}`.chomp
+ ldflags = `#{$PKGCONFIG} --libs #{pkg}`.chomp
+ libs = `#{$PKGCONFIG} --libs-only-l #{pkg}`.chomp
+ ldflags = (Shellwords.shellwords(ldflags) - Shellwords.shellwords(libs)).quote.join(" ")
+ $CFLAGS += " " << cflags
+ $LDFLAGS += " " << ldflags
+ $libs += " " << libs
+ Logging::message "package configuration for %s\n", pkg
+ Logging::message "cflags: %s\nldflags: %s\nlibs: %s\n\n",
+ cflags, ldflags, libs
+ [cflags, ldflags, libs]
+ end
+end
+
+def with_destdir(dir)
+ /^\$[\(\{]/ =~ dir ? dir : "$(DESTDIR)"+dir
+end
+
+def winsep(s)
+ s.tr('/', '\\')
+end
+
+def configuration(srcdir)
+ mk = []
+ vpath = %w[$(srcdir) $(topdir) $(hdrdir)]
+ if !CROSS_COMPILING
+ case CONFIG['build_os']
+ when 'cygwin'
+ if CONFIG['target_os'] != 'cygwin'
+ vpath.each {|p| p.sub!(/.*/, '$(shell cygpath -u \&)')}
+ end
+ when 'msdosdjgpp', 'mingw32'
+ CONFIG['PATH_SEPARATOR'] = ';'
+ end
+ end
+ mk << %{
+SHELL = /bin/sh
+
+#### Start of system configuration section. ####
+
+srcdir = #{srcdir.gsub(/\$\((srcdir)\)|\$\{(srcdir)\}/) {CONFIG[$1||$2]}.quote}
+topdir = #{($extmk ? CONFIG["topdir"] : $topdir).quote}
+hdrdir = #{$extmk ? CONFIG["hdrdir"].quote : '$(topdir)'}
+VPATH = #{vpath.join(CONFIG['PATH_SEPARATOR'])}
+}
+ drive = File::PATH_SEPARATOR == ';' ? /\A\w:/ : /\A/
+ if destdir = CONFIG["prefix"].scan(drive)[0] and !destdir.empty?
+ mk << "\nDESTDIR = #{destdir}\n"
+ end
+ CONFIG.each do |key, var|
+ next unless /prefix$/ =~ key
+ mk << "#{key} = #{with_destdir(var.sub(drive, ''))}\n"
+ end
+ CONFIG.each do |key, var|
+ next if /^abs_/ =~ key
+ next unless /^(?:src|top|hdr|(.*))dir$/ =~ key and $1
+ mk << "#{key} = #{with_destdir(var.sub(drive, ''))}\n"
+ end
+ if !$extmk and !$configure_args.has_key?('--ruby') and
+ sep = config_string('BUILD_FILE_SEPARATOR')
+ sep = ":/=#{sep}"
+ else
+ sep = ""
+ end
+ mk << %{
+CC = #{CONFIG['CC']}
+CXX = #{CONFIG['CXX']}
+LIBRUBY = #{CONFIG['LIBRUBY']}
+LIBRUBY_A = #{CONFIG['LIBRUBY_A']}
+LIBRUBYARG_SHARED = #$LIBRUBYARG_SHARED
+LIBRUBYARG_STATIC = #$LIBRUBYARG_STATIC
+
+CFLAGS = #{CONFIG['CCDLFLAGS'] unless $static} #$CFLAGS #$ARCH_FLAG
+CPPFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir) #{$defs.join(" ")} #{$CPPFLAGS}
+CXXFLAGS = $(CFLAGS) #{CONFIG['CXXFLAGS']}
+DLDFLAGS = #$LDFLAGS #$DLDFLAGS #$ARCH_FLAG
+LDSHARED = #{CONFIG['LDSHARED']}
+LDSHAREDXX = #{config_string('LDSHAREDXX') || '$(LDSHARED)'}
+AR = #{CONFIG['AR']}
+EXEEXT = #{CONFIG['EXEEXT']}
+
+RUBY_INSTALL_NAME = #{CONFIG['RUBY_INSTALL_NAME']}
+RUBY_SO_NAME = #{CONFIG['RUBY_SO_NAME']}
+arch = #{CONFIG['arch']}
+sitearch = #{CONFIG['sitearch']}
+ruby_version = #{Config::CONFIG['ruby_version']}
+ruby = #{$ruby}
+RUBY = $(ruby#{sep})
+RM = #{config_string('RM') || '$(RUBY) -run -e rm -- -f'}
+MAKEDIRS = #{config_string('MAKEDIRS') || '@$(RUBY) -run -e mkdir -- -p'}
+INSTALL = #{config_string('INSTALL') || '@$(RUBY) -run -e install -- -vp'}
+INSTALL_PROG = #{config_string('INSTALL_PROG') || '$(INSTALL) -m 0755'}
+INSTALL_DATA = #{config_string('INSTALL_DATA') || '$(INSTALL) -m 0644'}
+COPY = #{config_string('CP') || '@$(RUBY) -run -e cp -- -v'}
+
+#### End of system configuration section. ####
+
+preload = #{$preload.join(" ") if $preload}
+}
+ if $nmake == ?b
+ mk.each do |x|
+ x.gsub!(/^(MAKEDIRS|INSTALL_(?:PROG|DATA))+\s*=.*\n/) do
+ "!ifndef " + $1 + "\n" +
+ $& +
+ "!endif\n"
+ end
+ end
+ end
+ mk
+end
+
+def dummy_makefile(srcdir)
+ configuration(srcdir) << <<RULES << CLEANINGS
+CLEANFILES = #{$cleanfiles.join(' ')}
+DISTCLEANFILES = #{$distcleanfiles.join(' ')}
+
+all install static install-so install-rb: Makefile
+
+RULES
+end
+
+def create_makefile(target, srcprefix = nil)
+ $target = target
+ libpath = $LIBPATH
+ message "creating Makefile\n"
+ rm_f "conftest*"
+ if CONFIG["DLEXT"] == $OBJEXT
+ for lib in libs = $libs.split
+ lib.sub!(/-l(.*)/, %%"lib\\1.#{$LIBEXT}"%)
+ end
+ $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
+ end
+
+ if target.include?('/')
+ target_prefix, target = File.split(target)
+ target_prefix[0,0] = '/'
+ else
+ target_prefix = ""
+ end
+
+ srcprefix ||= '$(srcdir)'
+ Config::expand(srcdir = srcprefix.dup)
+
+ if not $objs
+ $objs = []
+ srcs = Dir[File.join(srcdir, "*.{#{SRC_EXT.join(%q{,})}}")]
+ for f in srcs
+ obj = File.basename(f, ".*") << ".o"
+ $objs.push(obj) unless $objs.index(obj)
+ end
+ elsif !(srcs = $srcs)
+ srcs = $objs.collect {|obj| obj.sub(/\.o\z/, '.c')}
+ end
+ for i in $objs
+ i.sub!(/\.o\z/, ".#{$OBJEXT}")
+ end
+ $objs = $objs.join(" ")
+
+ target = nil if $objs == ""
+
+ if target and EXPORT_PREFIX
+ if File.exist?(File.join(srcdir, target + '.def'))
+ deffile = "$(srcdir)/$(TARGET).def"
+ unless EXPORT_PREFIX.empty?
+ makedef = %{-pe "sub!(/^(?=\\w)/,'#{EXPORT_PREFIX}') unless 1../^EXPORTS$/i"}
+ end
+ else
+ makedef = %{-e "puts 'EXPORTS', '#{EXPORT_PREFIX}Init_$(TARGET)'"}
+ end
+ if makedef
+ $distcleanfiles << '$(DEFFILE)'
+ origdef = deffile
+ deffile = "$(TARGET)-$(arch).def"
+ end
+ end
+
+ libpath = libpathflag(libpath)
+
+ dllib = target ? "$(TARGET).#{CONFIG['DLEXT']}" : ""
+ staticlib = target ? "$(TARGET).#$LIBEXT" : ""
+ mfile = open("Makefile", "wb")
+ mfile.print configuration(srcprefix)
+ mfile.print %{
+libpath = #{$LIBPATH.join(" ")}
+LIBPATH = #{libpath}
+DEFFILE = #{deffile}
+
+CLEANFILES = #{$cleanfiles.join(' ')}
+DISTCLEANFILES = #{$distcleanfiles.join(' ')}
+
+extout = #{$extout}
+extout_prefix = #{$extout_prefix}
+target_prefix = #{target_prefix}
+LOCAL_LIBS = #{$LOCAL_LIBS}
+LIBS = #{$LIBRUBYARG} #{$libs} #{$LIBS}
+SRCS = #{srcs.collect(&File.method(:basename)).join(' ')}
+OBJS = #{$objs}
+TARGET = #{target}
+DLLIB = #{dllib}
+STATIC_LIB = #{staticlib unless $static.nil?}
+
+}
+ install_dirs.each {|d| mfile.print("%-14s= %s\n" % d) if /^[[:upper:]]/ =~ d[0]}
+ n = ($extout ? '$(RUBYARCHDIR)/' : '') + '$(TARGET).'
+ mfile.print %{
+TARGET_SO = #{($extout ? '$(RUBYARCHDIR)/' : '')}$(DLLIB)
+CLEANLIBS = #{n}#{CONFIG['DLEXT']} #{n}il? #{n}tds #{n}map
+CLEANOBJS = *.#{$OBJEXT} *.#{$LIBEXT} *.s[ol] *.pdb *.exp *.bak
+
+all: #{target ? $extout ? "install" : "$(DLLIB)" : "Makefile"}
+static: $(STATIC_LIB)#{$extout ? " install-rb" : ""}
+}
+ mfile.print CLEANINGS
+ dirs = []
+ mfile.print "install: install-so install-rb\n\n"
+ sodir = dir = "$(RUBYARCHDIR)"
+ mfile.print("install-so: #{dir}\n")
+ if target
+ f = "$(DLLIB)"
+ dest = "#{dir}/#{f}"
+ mfile.print "install-so: #{dest}\n"
+ unless $extout
+ mfile.print "#{dest}: #{f}\n"
+ if (sep = config_string('BUILD_FILE_SEPARATOR'))
+ f.gsub!("/", sep)
+ dir.gsub!("/", sep)
+ sep = ":/="+sep
+ f.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
+ f.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
+ dir.gsub!(/(\$\(\w+)(\))/) {$1+sep+$2}
+ dir.gsub!(/(\$\{\w+)(\})/) {$1+sep+$2}
+ end
+ mfile.print "\t$(INSTALL_PROG) #{f} #{dir}\n"
+ end
+ end
+ dirs << (dir = "$(RUBYLIBDIR)")
+ mfile.print("install-rb: pre-install-rb install-rb-default\n")
+ mfile.print("install-rb-default: pre-install-rb-default\n")
+ mfile.print("pre-install-rb pre-install-rb-default: #{dir}\n")
+ for sfx, i in [["-default", [["lib/**/*.rb", "$(RUBYLIBDIR)", "lib"]]], ["", $INSTALLFILES]]
+ files = install_files(mfile, i, nil, srcprefix) or next
+ for dir, *files in files
+ unless dirs.include?(dir)
+ dirs << dir
+ mfile.print "pre-install-rb#{sfx}: #{dir}\n"
+ end
+ files.each do |f|
+ dest = "#{dir}/#{File.basename(f)}"
+ mfile.print("install-rb#{sfx}: #{dest}\n")
+ mfile.print("#{dest}: #{f}\n\t$(#{$extout ? 'COPY' : 'INSTALL_DATA'}) ")
+ sep = config_string('BUILD_FILE_SEPARATOR')
+ if sep
+ f = f.gsub("/", sep)
+ sep = ":/="+sep
+ f = f.gsub(/(\$\(\w+)(\))/) {$1+sep+$2}
+ f = f.gsub(/(\$\{\w+)(\})/) {$1+sep+$2}
+ else
+ sep = ""
+ end
+ mfile.print("#{f} $(@D#{sep})\n")
+ end
+ end
+ end
+ dirs.unshift(sodir) if target and !dirs.include?(sodir)
+ dirs.each {|dir| mfile.print "#{dir}:\n\t$(MAKEDIRS) $@\n"}
+
+ mfile.print <<-SITEINSTALL
+
+site-install: site-install-so site-install-rb
+site-install-so: install-so
+site-install-rb: install-rb
+
+ SITEINSTALL
+
+ return unless target
+
+ mfile.puts SRC_EXT.collect {|ext| ".path.#{ext} = $(VPATH)"} if $nmake == ?b
+ mfile.print ".SUFFIXES: .#{SRC_EXT.join(' .')} .#{$OBJEXT}\n"
+ mfile.print "\n"
+
+ CXX_EXT.each do |ext|
+ COMPILE_RULES.each do |rule|
+ mfile.printf(rule, ext, $OBJEXT)
+ mfile.printf("\n\t%s\n\n", COMPILE_CXX)
+ end
+ end
+ %w[c].each do |ext|
+ COMPILE_RULES.each do |rule|
+ mfile.printf(rule, ext, $OBJEXT)
+ mfile.printf("\n\t%s\n\n", COMPILE_C)
+ end
+ end
+
+ mfile.print "$(RUBYARCHDIR)/" if $extout
+ mfile.print "$(DLLIB): ", (makedef ? "$(DEFFILE) " : ""), "$(OBJS)\n\t"
+ mfile.print "@-$(RM) $@\n\t"
+ mfile.print "@-$(MAKEDIRS) $(@D)\n\t" if $extout
+ link_so = LINK_SO
+ if srcs.any?(&%r"\.(?:#{CXX_EXT.join('|')})\z".method(:===))
+ link_so = link_so.sub(/\bLDSHARED\b/, '\&XX')
+ end
+ mfile.print link_so, "\n\n"
+ unless $static.nil?
+ mfile.print "$(STATIC_LIB): $(OBJS)\n\t"
+ mfile.print "$(AR) #{config_string('ARFLAGS') || 'cru '}$@ $(OBJS)"
+ config_string('RANLIB') do |ranlib|
+ mfile.print "\n\t@-#{ranlib} $(DLLIB) 2> /dev/null || true"
+ end
+ end
+ mfile.print "\n\n"
+ if makedef
+ mfile.print "$(DEFFILE): #{origdef}\n"
+ mfile.print "\t$(RUBY) #{makedef} #{origdef} > $@\n\n"
+ end
+
+ depend = File.join(srcdir, "depend")
+ if File.exist?(depend)
+ suffixes = []
+ depout = []
+ open(depend, "r") do |dfile|
+ mfile.printf "###\n"
+ cont = implicit = nil
+ impconv = proc do
+ COMPILE_RULES.each {|rule| depout << (rule % implicit[0]) << implicit[1]}
+ implicit = nil
+ end
+ ruleconv = proc do |line|
+ if implicit
+ if /\A\t/ =~ line
+ implicit[1] << line
+ next
+ else
+ impconv[]
+ end
+ end
+ if m = /\A\.(\w+)\.(\w+)(?:\s*:)/.match(line)
+ suffixes << m[1] << m[2]
+ implicit = [[m[1], m[2]], [m.post_match]]
+ next
+ elsif RULE_SUBST and /\A[$\w][^#]*:/ =~ line
+ line.gsub!(%r"(?<=\s)(?!\.)([^$(){}+=:\s\/\\,]+)(?=\s|\z)") {|*m| RULE_SUBST % m}
+ end
+ depout << line
+ end
+ while line = dfile.gets()
+ line.gsub!(/\.o\b/, ".#{$OBJEXT}")
+ line.gsub!(/\$\(hdrdir\)\/config.h/, $config_h) if $config_h
+ if /(?:^|[^\\])(?:\\\\)*\\$/ =~ line
+ (cont ||= []) << line
+ next
+ elsif cont
+ line = (cont << line).join
+ cont = nil
+ end
+ ruleconv.call(line)
+ end
+ if cont
+ ruleconv.call(cont.join)
+ elsif implicit
+ impconv.call
+ end
+ end
+ unless suffixes.empty?
+ mfile.print ".SUFFIXES: .", suffixes.uniq.join(" ."), "\n\n"
+ end
+ mfile.print depout
+ else
+ headers = %w[ruby.h defines.h]
+ if RULE_SUBST
+ headers.each {|h| h.sub!(/.*/) {|*m| RULE_SUBST % m}}
+ end
+ headers << $config_h if $config_h
+ mfile.print "$(OBJS): ", headers.join(' '), "\n"
+ end
+
+ $makefile_created = true
+ensure
+ mfile.close if mfile
+end
+
+def init_mkmf(config = CONFIG)
+ $makefile_created = false
+ $arg_config = []
+ $enable_shared = config['ENABLE_SHARED'] == 'yes'
+ $defs = []
+ $CFLAGS = with_config("cflags", arg_config("CFLAGS", config["CFLAGS"])).dup
+ $ARCH_FLAG = with_config("arch_flag", arg_config("ARCH_FLAG", config["ARCH_FLAG"])).dup
+ $CPPFLAGS = with_config("cppflags", arg_config("CPPFLAGS", config["CPPFLAGS"])).dup
+ $LDFLAGS = (with_config("ldflags") || "").dup
+ $INCFLAGS = "-I$(topdir)"
+ $DLDFLAGS = with_config("dldflags", arg_config("DLDFLAGS", config["DLDFLAGS"])).dup
+ $LIBEXT = config['LIBEXT'].dup
+ $OBJEXT = config["OBJEXT"].dup
+ $LIBS = "#{config['LIBS']} #{config['DLDLIBS']}"
+ $LIBRUBYARG = ""
+ $LIBRUBYARG_STATIC = config['LIBRUBYARG_STATIC']
+ $LIBRUBYARG_SHARED = config['LIBRUBYARG_SHARED']
+ $LIBPATH = $extmk ? ["$(topdir)"] : CROSS_COMPILING ? [] : ["$(libdir)"]
+ $INSTALLFILES = nil
+
+ $objs = nil
+ $srcs = nil
+ $libs = ""
+ if $enable_shared or Config.expand(config["LIBRUBY"].dup) != Config.expand(config["LIBRUBY_A"].dup)
+ $LIBRUBYARG = config['LIBRUBYARG']
+ end
+
+ $LOCAL_LIBS = ""
+
+ $cleanfiles = config_string('CLEANFILES') {|s| Shellwords.shellwords(s)} || []
+ $distcleanfiles = config_string('DISTCLEANFILES') {|s| Shellwords.shellwords(s)} || []
+
+ $extout ||= nil
+ $extout_prefix ||= nil
+
+ $arg_config.clear
+ dir_config("opt")
+end
+
+FailedMessage = <<MESSAGE
+Could not create Makefile due to some reason, probably lack of
+necessary libraries and/or headers. Check the mkmf.log file for more
+details. You may need configuration options.
+
+Provided configuration options:
+MESSAGE
+
+def mkmf_failed(path)
+ unless $makefile_created or File.exist?("Makefile")
+ opts = $arg_config.collect {|t, n| "\t#{t}#{"=#{n}" if n}\n"}
+ abort "*** #{path} failed ***\n" + FailedMessage + opts.join
+ end
+end
+
+init_mkmf
+
+$make = with_config("make-prog", ENV["MAKE"] || "make")
+make, = Shellwords.shellwords($make)
+$nmake = nil
+case
+when $mswin
+ $nmake = ?m if /nmake/i =~ make
+when $bccwin
+ $nmake = ?b if /Borland/i =~ `#{make} -h`
+end
+
+Config::CONFIG["srcdir"] = CONFIG["srcdir"] =
+ $srcdir = arg_config("--srcdir", File.dirname($0))
+$configure_args["--topsrcdir"] ||= $srcdir
+if $curdir = arg_config("--curdir")
+ Config.expand(curdir = $curdir.dup)
+else
+ curdir = $curdir = "."
+end
+unless File.expand_path(Config::CONFIG["topdir"]) == File.expand_path(curdir)
+ CONFIG["topdir"] = $curdir
+ Config::CONFIG["topdir"] = curdir
+end
+$configure_args["--topdir"] ||= $curdir
+$ruby = arg_config("--ruby", File.join(Config::CONFIG["bindir"], CONFIG["ruby_install_name"]))
+
+split = Shellwords.method(:shellwords).to_proc
+
+EXPORT_PREFIX = config_string('EXPORT_PREFIX') {|s| s.strip}
+
+hdr = []
+config_string('COMMON_MACROS') do |s|
+ Shellwords.shellwords(s).each do |s|
+ /(.*?)(?:=(.*))/ =~ s
+ hdr << "#define #$1 #$2"
+ end
+end
+config_string('COMMON_HEADERS') do |s|
+ Shellwords.shellwords(s).each {|s| hdr << "#include <#{s}>"}
+end
+COMMON_HEADERS = (hdr.join("\n") unless hdr.empty?)
+COMMON_LIBS = config_string('COMMON_LIBS', &split) || []
+
+COMPILE_RULES = config_string('COMPILE_RULES', &split) || %w[.%s.%s:]
+RULE_SUBST = config_string('RULE_SUBST')
+COMPILE_C = config_string('COMPILE_C') || '$(CC) $(CFLAGS) $(CPPFLAGS) -c $<'
+COMPILE_CXX = config_string('COMPILE_CXX') || '$(CXX) $(CXXFLAGS) $(CPPFLAGS) -c $<'
+TRY_LINK = config_string('TRY_LINK') ||
+ "$(CC) #{OUTFLAG}conftest $(INCFLAGS) -I$(hdrdir) $(CPPFLAGS) " \
+ "$(CFLAGS) $(src) $(LIBPATH) $(LDFLAGS) $(ARCH_FLAG) $(LOCAL_LIBS) $(LIBS)"
+LINK_SO = config_string('LINK_SO') ||
+ if CONFIG["DLEXT"] == $OBJEXT
+ "ld $(DLDFLAGS) -r -o $@ $(OBJS)\n"
+ else
+ "$(LDSHARED) $(DLDFLAGS) $(LIBPATH) #{OUTFLAG}$@ " \
+ "$(OBJS) $(LOCAL_LIBS) $(LIBS)"
+ end
+LIBPATHFLAG = config_string('LIBPATHFLAG') || ' -L"%s"'
+RPATHFLAG = config_string('RPATHFLAG') || ''
+LIBARG = config_string('LIBARG') || '-l%s'
+
+sep = File::ALT_SEPARATOR ? ":/=#{File::ALT_SEPARATOR}" : ''
+CLEANINGS = "
+clean:
+ @-$(RM) $(CLEANLIBS#{sep}) $(CLEANOBJS#{sep}) $(CLEANFILES#{sep})
+
+distclean: clean
+ @-$(RM) Makefile extconf.h conftest.* mkmf.log
+ @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES#{sep})
+
+realclean: distclean
+"
+
+if not $extmk and /\A(extconf|makefile).rb\z/ =~ File.basename($0)
+ # END {mkmf_failed($0)}
+end
Added: trunk/lib/rational.rb
===================================================================
--- trunk/lib/rational.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/lib/rational.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -0,0 +1,376 @@
+#
+# rational.rb -
+# $Release Version: 0.5 $
+# $Revision: 1.7 $
+# $Date: 1999/08/24 12:49:28 $
+# by Keiju ISHITSUKA(SHL Japan Inc.)
+#
+# --
+# Usage:
+# class Rational < Numeric
+# (include Comparable)
+#
+# Rational(a, b) --> a/b
+#
+# Rational::+
+# Rational::-
+# Rational::*
+# Rational::/
+# Rational::**
+# Rational::%
+# Rational::divmod
+# Rational::abs
+# Rational::<=>
+# Rational::to_i
+# Rational::to_f
+# Rational::to_s
+#
+# Integer::gcd
+# Integer::lcm
+# Integer::gcdlcm
+# Integer::to_r
+#
+# Fixnum::**
+# Fixnum::quo
+# Bignum::**
+# Bignum::quo
+#
+
+def Rational(a, b = 1)
+ if a.kind_of?(Rational) && b == 1
+ a
+ else
+ Rational.reduce(a, b)
+ end
+end
+
+class Rational < Numeric
+ @RCS_ID='-$Id: rational.rb,v 1.7 1999/08/24 12:49:28 keiju Exp keiju $-'
+
+ def Rational.reduce(num, den = 1)
+ raise ZeroDivisionError, "denominator is zero" if den == 0
+
+ if den < 0
+ num = -num
+ den = -den
+ end
+ gcd = num.gcd(den)
+ num = num.div(gcd)
+ den = den.div(gcd)
+ if den == 1 && defined?(Unify)
+ num
+ else
+ new!(num, den)
+ end
+ end
+
+ def Rational.new!(num, den = 1)
+ new(num, den)
+ end
+
+ # private_class_method :new
+
+ def initialize(num, den)
+ if den < 0
+ num = -num
+ den = -den
+ end
+ if num.kind_of?(Integer) and den.kind_of?(Integer)
+ @numerator = num
+ @denominator = den
+ else
+ @numerator = num.to_i
+ @denominator = den.to_i
+ end
+ end
+
+ def + (a)
+ if a.kind_of?(Rational)
+ num = @numerator * a.denominator
+ num_a = a.numerator * @denominator
+ Rational(num + num_a, @denominator * a.denominator)
+ elsif a.kind_of?(Integer)
+ self + Rational.new!(a, 1)
+ elsif a.kind_of?(Float)
+ Float(self) + a
+ else
+ x, y = a.coerce(self)
+ x + y
+ end
+ end
+
+ def - (a)
+ if a.kind_of?(Rational)
+ num = @numerator * a.denominator
+ num_a = a.numerator * @denominator
+ Rational(num - num_a, @denominator*a.denominator)
+ elsif a.kind_of?(Integer)
+ self - Rational.new!(a, 1)
+ elsif a.kind_of?(Float)
+ Float(self) - a
+ else
+ x, y = a.coerce(self)
+ x - y
+ end
+ end
+
+ def * (a)
+ if a.kind_of?(Rational)
+ num = @numerator * a.numerator
+ den = @denominator * a.denominator
+ Rational(num, den)
+ elsif a.kind_of?(Integer)
+ self * Rational.new!(a, 1)
+ elsif a.kind_of?(Float)
+ Float(self) * a
+ else
+ x, y = a.coerce(self)
+ x * y
+ end
+ end
+
+ def / (a)
+ if a.kind_of?(Rational)
+ num = @numerator * a.denominator
+ den = @denominator * a.numerator
+ Rational(num, den)
+ elsif a.kind_of?(Integer)
+ raise ZeroDivisionError, "division by zero" if a == 0
+ self / Rational.new!(a, 1)
+ elsif a.kind_of?(Float)
+ Float(self) / a
+ else
+ x, y = a.coerce(self)
+ x / y
+ end
+ end
+
+ def ** (other)
+ if other.kind_of?(Rational)
+ Float(self) ** other
+ elsif other.kind_of?(Integer)
+ if other > 0
+ num = @numerator ** other
+ den = @denominator ** other
+ elsif other < 0
+ num = @denominator ** -other
+ den = @numerator ** -other
+ elsif other == 0
+ num = 1
+ den = 1
+ end
+ Rational.new!(num, den)
+ elsif other.kind_of?(Float)
+ Float(self) ** other
+ else
+ x, y = other.coerce(self)
+ x ** y
+ end
+ end
+
+ def % (other)
+ value = (self / other).to_i
+ return self - other * value
+ end
+
+ def divmod(other)
+ value = (self / other).to_i
+ return value, self - other * value
+ end
+
+ def abs
+ if @numerator > 0
+ Rational.new!(@numerator, @denominator)
+ else
+ Rational.new!(-@numerator, @denominator)
+ end
+ end
+
+ def == (other)
+ if other.kind_of?(Rational)
+ @numerator == other.numerator and @denominator == other.denominator
+ elsif other.kind_of?(Integer)
+ self == Rational.new!(other, 1)
+ elsif other.kind_of?(Float)
+ Float(self) == other
+ else
+ other == self
+ end
+ end
+
+ def <=> (other)
+ if other.kind_of?(Rational)
+ num = @numerator * other.denominator
+ num_a = other.numerator * @denominator
+ v = num - num_a
+ if v > 0
+ return 1
+ elsif v < 0
+ return -1
+ else
+ return 0
+ end
+ elsif other.kind_of?(Integer)
+ return self <=> Rational.new!(other, 1)
+ elsif other.kind_of?(Float)
+ return Float(self) <=> other
+ elsif defined? other.coerce
+ x, y = other.coerce(self)
+ return x <=> y
+ else
+ return nil
+ end
+ end
+
+ def coerce(other)
+ if other.kind_of?(Float)
+ return other, self.to_f
+ elsif other.kind_of?(Integer)
+ return Rational.new!(other, 1), self
+ else
+ super
+ end
+ end
+
+ def to_i
+ Integer( numerator.div( denominator))
+ end
+
+ def to_f
+ @numerator.to_f/ denominator.to_f
+ end
+
+ def to_s
+ if @denominator == 1
+ @numerator.to_s
+ else
+ @numerator.to_s+"/"+ denominator.to_s
+ end
+ end
+
+ def to_r
+ self
+ end
+
+ def inspect
+ sprintf("Rational(%s, %s)", @numerator.inspect, @denominator.inspect)
+ end
+
+ def hash
+ @numerator.hash ^ @denominator.hash
+ end
+
+ attr :numerator
+ attr :denominator
+
+ private :initialize
+end
+
+class Integer
+ def numerator
+ self
+ end
+
+ def denominator
+ 1
+ end
+
+ def to_r
+ Rational(self, 1)
+ end
+
+ def gcd(n)
+ m = self.abs
+ n = n.abs
+
+ return n if m == 0
+ return m if n == 0
+
+ b = 0
+ while n[0] == 0 && m[0] == 0
+ b += 1; n >>= 1; m >>= 1
+ end
+ m >>= 1 while m[0] == 0
+ n >>= 1 while n[0] == 0
+ while m != n
+ m, n = n, m if n > m
+ m -= n; m >>= 1 while m[0] == 0
+ end
+ m << b
+ end
+
+ def gcd2(int)
+ a = self.abs
+ b = int.abs
+
+ a, b = b, a if a < b
+
+ while b != 0
+ void, a = a.divmod(b)
+ a, b = b, a
+ end
+ return a
+ end
+
+ def lcm(other)
+ if self.zero? or other.zero?
+ 0
+ else
+ (self.div(self.gcd(other)) * other).abs
+ end
+ end
+
+ def gcdlcm(other)
+ gcd = self.gcd(other)
+ if self.zero? or other.zero?
+ [gcd, 0]
+ else
+ [gcd, (self.div(gcd) * other).abs]
+ end
+ end
+end
+
+class Fixnum
+ undef quo
+ def quo(other)
+ Rational.new!(self,1) / other
+ end
+ alias rdiv quo
+
+ def rpower (other)
+ if other >= 0
+ self.power!(other)
+ else
+ Rational.new!(self,1)**other
+ end
+ end
+
+ unless defined? 1.power!
+ alias power! **
+ alias ** rpower
+ end
+end
+
+class Bignum
+ unless defined? Complex
+ alias power! **
+ end
+
+ undef quo
+ def quo(other)
+ Rational.new!(self,1) / other
+ end
+ alias rdiv quo
+
+ def rpower (other)
+ if other >= 0
+ self.power!(other)
+ else
+ Rational.new!(self, 1)**other
+ end
+ end
+
+ unless defined? Complex
+ alias ** rpower
+ end
+end
Modified: trunk/parse.y
===================================================================
--- trunk/parse.y 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/parse.y 2005-10-27 23:53:45 UTC (rev 282)
@@ -4648,9 +4648,7 @@
static VALUE lex_get_str(struct parser_params *, VALUE);
static VALUE
-lex_get_str(parser, s)
- struct parser_params *parser;
- VALUE s;
+lex_get_str(struct parser_params *parser, VALUE s)
{
char *beg, *end, *pend;
@@ -7978,10 +7976,7 @@
}
static NODE*
-new_call(r,m,a)
- NODE *r;
- ID m;
- NODE *a;
+new_call(NODE *r,ID m, NODE *a)
{
if (a && nd_type(a) == NODE_BLOCK_PASS) {
a->nd_iter = NEW_CALL(r,m,a->nd_head);
@@ -7991,10 +7986,7 @@
}
static NODE*
-new_fcall_gen(parser, m, a)
- struct parser_params *parser;
- ID m;
- NODE *a;
+new_fcall_gen(struct parser_params *parser, ID m, NODE *a)
{
if (a && nd_type(a) == NODE_BLOCK_PASS) {
a->nd_iter = NEW_FCALL(m,a->nd_head);
@@ -8004,8 +7996,7 @@
}
static NODE*
-new_super(a)
- NODE *a;
+new_super(NODE *a)
{
if (a && nd_type(a) == NODE_BLOCK_PASS) {
a->nd_iter = NEW_SUPER(a->nd_head);
@@ -8173,17 +8164,14 @@
}
static int
-dyna_push_gen(parser)
- struct parser_params *parser;
+dyna_push_gen(struct parser_params *parser)
{
lvtbl->dvars = vtable_alloc(lvtbl->dvars);
return 0;
}
static void
-dyna_pop_gen(parser, vars)
- struct parser_params *parser;
- struct RVarmap* vars;
+dyna_pop_gen(struct parser_params *parser, struct RVarmap* vars)
{
struct vtable *tmp = lvtbl->dvars;
lvtbl->dvars = lvtbl->dvars->prev;
@@ -8191,17 +8179,13 @@
}
static int
-dyna_in_block_gen(parser)
- struct parser_params *parser;
+dyna_in_block_gen(struct parser_params *parser)
{
return lvtbl->dvars != 0;
}
static NODE *
-dyna_init_gen(parser, node, pre_cnt)
- struct parser_params *parser;
- NODE *node;
- int pre_cnt;
+dyna_init_gen(struct parser_params *parser, NODE *node, int pre_cnt)
{
NODE *var;
int post_cnt = vtable_size(lvtbl->dvars);
@@ -8214,9 +8198,7 @@
}
static int
-dvar_defined_gen(parser, id)
- struct parser_params *parser;
- ID id;
+dvar_defined_gen(struct parser_params *parser, ID id)
{
struct vtable *dvars = lvtbl->dvars;
while((VALUE)dvars & ~3){
@@ -8232,21 +8214,18 @@
}
static int
-dvar_curr_gen(parser, id)
- struct parser_params *parser;
- ID id;
+dvar_curr_gen(struct parser_params *parser, ID id)
{
return vtable_included(lvtbl->dvars, id);
}
void
-rb_gc_mark_parser()
+rb_gc_mark_parser(void)
{
}
NODE*
-rb_parser_append_print(node)
- NODE *node;
+rb_parser_append_print(NODE *node)
{
NODE *prelude = 0;
@@ -8502,40 +8481,35 @@
}
int
-rb_is_const_id(id)
- ID id;
+rb_is_const_id(ID id)
{
if (is_const_id(id)) return Qtrue;
return Qfalse;
}
int
-rb_is_class_id(id)
- ID id;
+rb_is_class_id(ID id)
{
if (is_class_id(id)) return Qtrue;
return Qfalse;
}
int
-rb_is_instance_id(id)
- ID id;
+rb_is_instance_id(ID id)
{
if (is_instance_id(id)) return Qtrue;
return Qfalse;
}
int
-rb_is_local_id(id)
- ID id;
+rb_is_local_id(ID id)
{
if (is_local_id(id)) return Qtrue;
return Qfalse;
}
int
-rb_is_junk_id(id)
- ID id;
+rb_is_junk_id(ID id)
{
if (is_junk_id(id)) return Qtrue;
return Qfalse;
@@ -8544,8 +8518,7 @@
#endif /* !RIPPER */
static void
-parser_initialize(parser)
- struct parser_params *parser;
+parser_initialize(struct parser_params *parser)
{
parser->eofp = Qfalse;
Modified: trunk/rb/yasm.rb
===================================================================
--- trunk/rb/yasm.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/rb/yasm.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -310,3 +310,7 @@
end
end
+hoge.each{|i|
+
+}
+
Modified: trunk/test.rb
===================================================================
--- trunk/test.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/test.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -1,6 +1,3 @@
-p 0*1
-__END__
-p bitblt
-p the_answer_to_life_the_universe_and_everything
-
+require 'mkmf'
+create_makefile('hoge')
Modified: trunk/vm.c
===================================================================
--- trunk/vm.c 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/vm.c 2005-10-27 23:53:45 UTC (rev 282)
@@ -195,13 +195,16 @@
env->local_size = local_size;
env->env = ALLOC_N(VALUE, env->env_size);
env->prev_envval = penvval;
-
+
for(i=0; i<=local_size; i++){
env->env[i] = envptr[-local_size + i];
- envptr[-local_size + i] = 0;
+ if(cfp->iseq != 0 && !CMETHOD_INFO_P(cfp->iseq)){
+ /* clear value stack for GC */
+ envptr[-local_size + i] = 0;
+ }
}
+
*envptr = envval; /* GC mark */
-
nenvptr = &env->env[i-1];
nenvptr[1] = Qfalse; /* frame is not orphan */
nenvptr[2] = Qundef; /* frame is in heap */
@@ -331,9 +334,7 @@
GetProcVal(proc->blockprocval, p);
*cfp->lfp = GC_GUARDED_PTR(&p->block);
}
-
envval = th_make_env_object(th, cfp);
-
proc->block.self = block->self;
proc->block.lfp = block->lfp;
proc->block.dfp = block->dfp;
Modified: trunk/vm.h
===================================================================
--- trunk/vm.h 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/vm.h 2005-10-27 23:53:45 UTC (rev 282)
@@ -33,7 +33,7 @@
#if 0
#undef VMDEBUG
-#define VMDEBUG 10
+#define VMDEBUG 3
#endif
// #define COLLECT_USAGE_ANALYSIS
Modified: trunk/vm_dump.c
===================================================================
--- trunk/vm_dump.c 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/vm_dump.c 2005-10-27 23:53:45 UTC (rev 282)
@@ -53,7 +53,7 @@
}
else{
pc = cfp->pc - cfp->iseq->iseq_encoded;
- iseq_name = "";//RSTRING(cfp->iseq->name)->ptr;
+ iseq_name = RSTRING(cfp->iseq->name)->ptr;
}
}
@@ -186,7 +186,10 @@
cfp->magic == FRAME_MAGIC_TOP ||
cfp->magic == FRAME_MAGIC_BLOCK ||
cfp->magic == FRAME_MAGIC_CLASS ||
- cfp->magic == FRAME_MAGIC_PROC){
+ cfp->magic == FRAME_MAGIC_PROC ||
+ cfp->magic == FRAME_MAGIC_CFUNC ||
+ cfp->magic == FRAME_MAGIC_IFUNC ||
+ cfp->magic == FRAME_MAGIC_EVAL){
if(cfp->pc){
stack_dump_each(th, cfp+1);
@@ -299,6 +302,7 @@
printf(" sc reg B: %s\n", StringValueCStr(rstr));
}
#endif
+ printf("--------------------------------------------------------------\n");
#endif
#if VMDEBUG > 9
@@ -478,3 +482,9 @@
return Qnil;
}
+void
+yarv_bug(){
+ yarv_thread_t *th = GET_THREAD();
+ dp(th_backtrace(th, 0));
+ SDR();
+}
Modified: trunk/vm_macro.def
===================================================================
--- trunk/vm_macro.def 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/vm_macro.def 2005-10-27 23:53:45 UTC (rev 282)
@@ -10,8 +10,17 @@
VALUE proc;
proc = TOPN(0);
- GetProcVal(proc, po);
- blockptr = &po->block;
+ if(proc != Qnil){
+ if(!yarv_obj_is_proc(proc)){
+ proc = rb_check_convert_type(proc, T_DATA, "Proc", "to_proc");
+ if(!yarv_obj_is_proc(proc)){
+ rb_raise(rb_eTypeError, "wrong argument type %s (expected Proc)",
+ rb_obj_classname(proc));
+ }
+ }
+ GetProcVal(proc, po);
+ blockptr = &po->block;
+ }
INC_SP(-1);
}
else if(blockval){
@@ -239,11 +248,18 @@
case NODE_SCOPE:{
dpi(id);
SDR();
- rb_bug("eval_invoke_method: NODE_SCOPE");
+ rb_bug("eval_invoke_method: NODE_SCOPE should not be appear");
/* unreachable */
break;
}
+ case NODE_ZSUPER:{
+ int *a = 0;
+ dpi(id);
+ SDR();
+ *a = 0;
+ }
default:{
+ printf("node: %s\n", node_name(nd_type(mn)));
rb_bug("eval_invoke_method: unreachable");
/* unreachable */
break;
Modified: trunk/yarvcore.c
===================================================================
--- trunk/yarvcore.c 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/yarvcore.c 2005-10-27 23:53:45 UTC (rev 282)
@@ -797,10 +797,15 @@
return th_invoke_proc(GET_THREAD(), proc, argc, argv);
}
-static VALUE akr(VALUE self){
- volatile int *a = 0;
- *a = 0;
- return 0;
+VALUE
+yarv_obj_is_proc(VALUE proc){
+ if (TYPE(proc) == T_DATA &&
+ RDATA(proc)->dfree == (RUBY_DATA_FUNC)proc_free){
+ return Qtrue;
+ }
+ else{
+ return Qfalse;
+ }
}
/********************************************************************/
@@ -923,7 +928,6 @@
rb_define_global_function("once", yarv_once, 0);
rb_define_global_function("cfunc", cfunc, 0);
rb_define_global_function("yarv_caller", yarv_caller, 1);
- rb_define_global_function("akr", akr, 0);
/* Integer#times */
rb_define_method(rb_cInteger, "times", yarv_Integer_times, 0);
Modified: trunk/yarvtest/test_massign.rb
===================================================================
--- trunk/yarvtest/test_massign.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/yarvtest/test_massign.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -360,28 +360,39 @@
# ignore
def _test_massign_value
- # Value of this massign statement should be [1, 2, 3]
- ae %q{
- a, b, c = [1, 2, 3]
- }
- end
-
- def test_nested_splat
- # Somewhat obscure nested splat
- ae %q{
- a = *[*[1]]
- a
- }
- end
-
- def test_calls_to_a
- # Should be result of calling to_a on arg, ie [[1, 2], [3, 4]]
- ae %q{
- x=*{1=>2,3=>4}
- x
- }
- end
-
+ # Value of this massign statement should be [1, 2, 3]
+ ae %q{
+ a, b, c = [1, 2, 3]
+ }
+ end
+
+ def test_nested_splat
+ # Somewhat obscure nested splat
+ ae %q{
+ a = *[*[1]]
+ a
+ }
+ end
+
+ def test_calls_to_a
+ # Should be result of calling to_a on arg, ie [[1, 2], [3, 4]]
+ ae %q{
+ x=*{1=>2,3=>4}
+ x
+ }
+ end
+
+ def test_const_massign
+ ae %q{
+ class C
+ class D
+ end
+ end
+
+ X, Y = 1, 2
+ Z, C::Const, C::D::Const, ::C::Const2 = 3, 4, 5, 6
+ [X, Y, Z, C::Const, C::D::Const, ::C::Const2]
+ }
+ end
end
-
Modified: trunk/yarvtest/test_method.rb
===================================================================
--- trunk/yarvtest/test_method.rb 2005-10-27 02:54:30 UTC (rev 281)
+++ trunk/yarvtest/test_method.rb 2005-10-27 23:53:45 UTC (rev 282)
@@ -363,6 +363,24 @@
[x+y, x*y]
}
}
+ ae %q{
+ def m &b
+ b
+ end
+ m(&nil)
+ }
+ ae %q{
+ def m a, &b
+ [a, b]
+ end
+ m(1, &nil)
+ }
+ ae %q{
+ def m
+ [a, block_given?]
+ end
+ m(&nil)
+ }
end
def test_method_missing
--
ML: yarv-diff quickml.atdot.net
Info: http://www.atdot.net/~ko1/quickml