summaryrefslogtreecommitdiff
path: root/jni/ruby/tool
diff options
context:
space:
mode:
authorJari Vetoniemi <jari.vetoniemi@indooratlas.com>2020-03-16 18:49:26 +0900
committerJari Vetoniemi <jari.vetoniemi@indooratlas.com>2020-03-30 00:39:06 +0900
commitfcbf63e62c627deae76c1b8cb8c0876c536ed811 (patch)
tree64cb17de3f41a2b6fef2368028fbd00349946994 /jni/ruby/tool
Fresh start
Diffstat (limited to 'jni/ruby/tool')
-rw-r--r--jni/ruby/tool/asm_parse.rb51
-rwxr-xr-xjni/ruby/tool/bisect.sh42
-rwxr-xr-xjni/ruby/tool/build-transcode16
-rwxr-xr-xjni/ruby/tool/change_maker.rb34
-rwxr-xr-xjni/ruby/tool/config.guess1438
-rwxr-xr-xjni/ruby/tool/config.sub1813
-rw-r--r--jni/ruby/tool/downloader.rb178
-rw-r--r--jni/ruby/tool/enc-emoji-citrus-gen.rb131
-rw-r--r--jni/ruby/tool/enc-emoji4unicode.rb133
-rwxr-xr-xjni/ruby/tool/enc-unicode.rb371
-rw-r--r--jni/ruby/tool/eval.rb159
-rwxr-xr-xjni/ruby/tool/expand-config.rb7
-rwxr-xr-xjni/ruby/tool/extlibs.rb143
-rw-r--r--jni/ruby/tool/fake.rb30
-rwxr-xr-xjni/ruby/tool/file2lastrev.rb68
-rwxr-xr-xjni/ruby/tool/gen_dummy_probes.rb28
-rwxr-xr-xjni/ruby/tool/gen_ruby_tapset.rb105
-rw-r--r--jni/ruby/tool/generic_erb.rb42
-rwxr-xr-xjni/ruby/tool/id2token.rb24
-rwxr-xr-xjni/ruby/tool/ifchange61
-rwxr-xr-xjni/ruby/tool/insns2vm.rb15
-rw-r--r--jni/ruby/tool/install-sh17
-rwxr-xr-xjni/ruby/tool/instruction.rb1343
-rw-r--r--jni/ruby/tool/jisx0208.rb84
-rwxr-xr-xjni/ruby/tool/make-snapshot378
-rwxr-xr-xjni/ruby/tool/mdoc2man.rb465
-rwxr-xr-xjni/ruby/tool/merger.rb259
-rwxr-xr-xjni/ruby/tool/mkconfig.rb290
-rwxr-xr-xjni/ruby/tool/mkrunnable.rb122
-rwxr-xr-xjni/ruby/tool/node_name.rb6
-rw-r--r--jni/ruby/tool/parse.rb13
-rw-r--r--jni/ruby/tool/probes_to_wiki.rb16
-rwxr-xr-xjni/ruby/tool/rbinstall.rb763
-rwxr-xr-xjni/ruby/tool/rbuninstall.rb67
-rwxr-xr-xjni/ruby/tool/redmine-backporter.rb416
-rwxr-xr-xjni/ruby/tool/release.sh38
-rwxr-xr-xjni/ruby/tool/rmdirs11
-rwxr-xr-xjni/ruby/tool/rubytest.rb30
-rwxr-xr-xjni/ruby/tool/runruby.rb99
-rwxr-xr-xjni/ruby/tool/strip-rdoc.rb23
-rw-r--r--jni/ruby/tool/test/test_jisx0208.rb40
-rw-r--r--jni/ruby/tool/transcode-tblgen.rb1074
-rwxr-xr-xjni/ruby/tool/update-deps615
-rw-r--r--jni/ruby/tool/vcs.rb256
-rw-r--r--jni/ruby/tool/vpath.rb87
-rw-r--r--jni/ruby/tool/vtlh.rb15
-rwxr-xr-xjni/ruby/tool/ytab.sed37
47 files changed, 11453 insertions, 0 deletions
diff --git a/jni/ruby/tool/asm_parse.rb b/jni/ruby/tool/asm_parse.rb
new file mode 100644
index 0000000..e39580c
--- /dev/null
+++ b/jni/ruby/tool/asm_parse.rb
@@ -0,0 +1,51 @@
+stat = {}
+
+while line = ARGF.gets
+ if /\[start\] (\w+)/ =~ line
+ name = $1
+ puts '--------------------------------------------------------------'
+ puts line
+ size = 0
+ len = 0
+
+ while line = ARGF.gets
+ if /\[start\] (\w+)/ =~ line
+ puts "\t; # length: #{len}, size: #{size}"
+ puts "\t; # !!"
+ stat[name] = [len, size]
+ #
+ name = $1
+ puts '--------------------------------------------------------------'
+ puts line
+ size = 0
+ len = 0
+ next
+ end
+
+ unless /(\ALM)|(\ALB)|(\A\.)|(\A\/)/ =~ line
+ puts line
+ if /\[length = (\d+)\]/ =~ line
+ len += $1.to_i
+ size += 1
+ end
+ end
+
+
+ if /__NEXT_INSN__/ !~ line && /\[end \] (\w+)/ =~ line
+ ename = $1
+ if name != ename
+ puts "!! start with #{name}, but end with #{ename}"
+ end
+ stat[ename] = [len, size]
+ puts "\t; # length: #{len}, size: #{size}"
+ break
+ end
+ end
+ end
+end
+
+stat.sort_by{|a, b| -b[0] * 1000 - a[0]}.each{|a, b|
+ puts "#{a}\t#{b.join("\t")}"
+}
+puts "total length :\t#{stat.inject(0){|r, e| r+e[1][0]}}"
+puts "total size :\t#{stat.inject(0){|r, e| r+e[1][1]}}"
diff --git a/jni/ruby/tool/bisect.sh b/jni/ruby/tool/bisect.sh
new file mode 100755
index 0000000..fb22bf4
--- /dev/null
+++ b/jni/ruby/tool/bisect.sh
@@ -0,0 +1,42 @@
+#!/bin/sh
+# usage:
+# edit $(srcdir)/test.rb
+# git bisect start `git svn find-rev <rBADREV>` `git svn find-rev <rGOODREV>`
+# cd <builddir>
+# make bisect (or bisect-ruby for full ruby)
+
+if [ "x" = "x$MAKE" ]; then
+ MAKE=make
+fi
+
+case $1 in
+ miniruby | ruby ) # (miniruby|ruby) <srcdir>
+ srcdir=$2
+ builddir=`pwd` # assume pwd is builddir
+ path=$builddir/_bisect.sh
+ echo "path: $path"
+ cp $0 $path
+ cd $srcdir
+ echo "git bisect run $path run-$1"
+ git bisect run $path run-$1
+ ;;
+ run-miniruby )
+ cd ${0%/*} # assume a copy of this script is in builddir
+ $MAKE Makefile
+ $MAKE mini || exit 125
+ $MAKE run || exit 1
+ ;;
+ run-ruby )
+ cd ${0%/*} # assume a copy of this script is in builddir
+ $MAKE Makefile
+ $MAKE program || exit 125
+ $MAKE runruby || exit 1
+ ;;
+ "" )
+ echo foo bar
+ ;;
+ * )
+ echo unkown command "'$cmd'"
+ ;;
+esac
+exit 0
diff --git a/jni/ruby/tool/build-transcode b/jni/ruby/tool/build-transcode
new file mode 100755
index 0000000..fa71155
--- /dev/null
+++ b/jni/ruby/tool/build-transcode
@@ -0,0 +1,16 @@
+#!/bin/sh
+
+[ "$1" -a -d "$1" ] && { cd "$1" || exit $?; } && shift
+[ "$#" = 0 ] && set enc/trans/*.trans
+for src; do
+ case "$src" in
+ *.trans)
+ c="`dirname $src`/`basename $src .trans`.c"
+ ${BASERUBY-ruby} tool/transcode-tblgen.rb -vo "$c" "$src"
+ ;;
+ *)
+ echo "$0: don't know how to deal with $src"
+ continue
+ ;;
+ esac
+done
diff --git a/jni/ruby/tool/change_maker.rb b/jni/ruby/tool/change_maker.rb
new file mode 100755
index 0000000..2bbc275
--- /dev/null
+++ b/jni/ruby/tool/change_maker.rb
@@ -0,0 +1,34 @@
+#! ./miniruby
+
+def diff2index(cmd, *argv)
+ lines = []
+ path = nil
+ output = `#{cmd} #{argv.join(" ")}`
+ if defined? Encoding::BINARY
+ output.force_encoding Encoding::BINARY
+ end
+ output.each_line do |line|
+ case line
+ when /^Index: (\S*)/, /^diff --git [a-z]\/(\S*) [a-z]\/\1/
+ path = $1
+ when /^@@\s*-[,\d]+ +\+(\d+)[,\d]*\s*@@(?: +([A-Za-z_][A-Za-z_0-9 ]*[A-Za-z_0-9]))?/
+ line = $1.to_i
+ ent = "\t* #{path}"
+ ent << " (#{$2})" if $2
+ lines << "#{ent}:"
+ end
+ end
+ lines.uniq!
+ lines.empty? ? nil : lines
+end
+
+if `svnversion` =~ /^\d+/
+ cmd = "svn diff --diff-cmd=diff -x-pU0"
+ change = diff2index(cmd, ARGV)
+elsif File.directory?(".git")
+ cmd = "git diff -U0"
+ change = diff2index(cmd, ARGV) || diff2index(cmd, "--cached", ARGV)
+else
+ abort "does not seem to be under a vcs"
+end
+puts change if change
diff --git a/jni/ruby/tool/config.guess b/jni/ruby/tool/config.guess
new file mode 100755
index 0000000..fddac42
--- /dev/null
+++ b/jni/ruby/tool/config.guess
@@ -0,0 +1,1438 @@
+#! /bin/sh
+# Attempt to guess a canonical system name.
+# Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-07-03'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+#
+# Originally written by Per Bothner; maintained since 2000 by Ben Elliston.
+#
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+#
+# Please send patches to <config-patches@gnu.org>.
+
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION]
+
+Output the configuration name of the system \`$me' is run on.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.guess ($timestamp)
+
+Originally written by Per Bothner.
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help" >&2
+ exit 1 ;;
+ * )
+ break ;;
+ esac
+done
+
+if test $# != 0; then
+ echo "$me: too many arguments$help" >&2
+ exit 1
+fi
+
+trap 'exit 1' 1 2 15
+
+# CC_FOR_BUILD -- compiler used by this script. Note that the use of a
+# compiler to aid in system detection is discouraged as it requires
+# temporary files to be created and, as you can see below, it is a
+# headache to deal with in a portable fashion.
+
+# Historically, `CC_FOR_BUILD' used to be named `HOST_CC'. We still
+# use `HOST_CC' if defined, but it is deprecated.
+
+# Portable tmp directory creation inspired by the Autoconf team.
+
+set_cc_for_build='
+trap "exitcode=\$?; (rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null) && exit \$exitcode" 0 ;
+trap "rm -f \$tmpfiles 2>/dev/null; rmdir \$tmp 2>/dev/null; exit 1" 1 2 13 15 ;
+: ${TMPDIR=/tmp} ;
+ { tmp=`(umask 077 && mktemp -d "$TMPDIR/cgXXXXXX") 2>/dev/null` && test -n "$tmp" && test -d "$tmp" ; } ||
+ { test -n "$RANDOM" && tmp=$TMPDIR/cg$$-$RANDOM && (umask 077 && mkdir $tmp) ; } ||
+ { tmp=$TMPDIR/cg-$$ && (umask 077 && mkdir $tmp) && echo "Warning: creating insecure temp directory" >&2 ; } ||
+ { echo "$me: cannot create a temporary directory in $TMPDIR" >&2 ; exit 1 ; } ;
+dummy=$tmp/dummy ;
+tmpfiles="$dummy.c $dummy.o $dummy.rel $dummy" ;
+case $CC_FOR_BUILD,$HOST_CC,$CC in
+ ,,) echo "int x;" > $dummy.c ;
+ for c in cc gcc c89 c99 ; do
+ if ($c -c -o $dummy.o $dummy.c) >/dev/null 2>&1 ; then
+ CC_FOR_BUILD="$c"; break ;
+ fi ;
+ done ;
+ if test x"$CC_FOR_BUILD" = x ; then
+ CC_FOR_BUILD=no_compiler_found ;
+ fi
+ ;;
+ ,,*) CC_FOR_BUILD=$CC ;;
+ ,*,*) CC_FOR_BUILD=$HOST_CC ;;
+esac ; set_cc_for_build= ;'
+
+# This is needed to find uname on a Pyramid OSx when run in the BSD universe.
+# (ghazi@noc.rutgers.edu 1994-08-24)
+if (test -f /.attbin/uname) >/dev/null 2>&1 ; then
+ PATH=$PATH:/.attbin ; export PATH
+fi
+
+UNAME_MACHINE=`(uname -m) 2>/dev/null` || UNAME_MACHINE=unknown
+UNAME_RELEASE=`(uname -r) 2>/dev/null` || UNAME_RELEASE=unknown
+UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_SYSTEM=unknown
+UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown
+
+case "${UNAME_SYSTEM}" in
+Linux|GNU|GNU/*)
+ # If the system lacks a compiler, then just pick glibc.
+ # We could probably try harder.
+ LIBC=gnu
+
+ eval $set_cc_for_build
+ cat <<-EOF > $dummy.c
+ #include <features.h>
+ #if defined(__UCLIBC__)
+ LIBC=uclibc
+ #elif defined(__dietlibc__)
+ LIBC=dietlibc
+ #else
+ LIBC=gnu
+ #endif
+ EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^LIBC' | sed 's, ,,g'`
+ ;;
+esac
+
+# Note: order is significant - the case branches are not exclusive.
+
+case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
+ *:NetBSD:*:*)
+ # NetBSD (nbsd) targets should (where applicable) match one or
+ # more of the tuples: *-*-netbsdelf*, *-*-netbsdaout*,
+ # *-*-netbsdecoff* and *-*-netbsd*. For targets that recently
+ # switched to ELF, *-*-netbsd* would select the old
+ # object file format. This provides both forward
+ # compatibility and a consistent mechanism for selecting the
+ # object file format.
+ #
+ # Note: NetBSD doesn't particularly care about the vendor
+ # portion of the name. We always set it to "unknown".
+ sysctl="sysctl -n hw.machine_arch"
+ UNAME_MACHINE_ARCH=`(uname -p 2>/dev/null || \
+ /sbin/$sysctl 2>/dev/null || \
+ /usr/sbin/$sysctl 2>/dev/null || \
+ echo unknown)`
+ case "${UNAME_MACHINE_ARCH}" in
+ armeb) machine=armeb-unknown ;;
+ arm*) machine=arm-unknown ;;
+ sh3el) machine=shl-unknown ;;
+ sh3eb) machine=sh-unknown ;;
+ sh5el) machine=sh5le-unknown ;;
+ earmv*)
+ arch=`echo ${UNAME_MACHINE_ARCH} | sed -e 's,^e\(armv[0-9]\).*$,\1,'`
+ endian=`echo ${UNAME_MACHINE_ARCH} | sed -ne 's,^.*\(eb\)$,\1,p'`
+ machine=${arch}${endian}-unknown
+ ;;
+ *) machine=${UNAME_MACHINE_ARCH}-unknown ;;
+ esac
+ # The Operating System including object format, if it has switched
+ # to ELF recently, or will in the future.
+ case "${UNAME_MACHINE_ARCH}" in
+ arm*|earm*|i386|m68k|ns32k|sh3*|sparc|vax)
+ eval $set_cc_for_build
+ if echo __ELF__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ELF__
+ then
+ # Once all utilities can be ECOFF (netbsdecoff) or a.out (netbsdaout).
+ # Return netbsd for either. FIX?
+ os=netbsd
+ else
+ os=netbsdelf
+ fi
+ ;;
+ *)
+ os=netbsd
+ ;;
+ esac
+ # Determine ABI tags.
+ case "${UNAME_MACHINE_ARCH}" in
+ earm*)
+ expr='s/^earmv[0-9]/-eabi/;s/eb$//'
+ abi=`echo ${UNAME_MACHINE_ARCH} | sed -e "$expr"`
+ ;;
+ esac
+ # The OS release
+ # Debian GNU/NetBSD machines have a different userland, and
+ # thus, need a distinct triplet. However, they do not need
+ # kernel version information, so it can be replaced with a
+ # suitable tag, in the style of linux-gnu.
+ case "${UNAME_VERSION}" in
+ Debian*)
+ release='-gnu'
+ ;;
+ *)
+ release=`echo ${UNAME_RELEASE} | sed -e 's/[-_].*//' | cut -d. -f1,2`
+ ;;
+ esac
+ # Since CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM:
+ # contains redundant information, the shorter form:
+ # CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM is used.
+ echo "${machine}-${os}${release}${abi}"
+ exit ;;
+ *:Bitrig:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/Bitrig.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-bitrig${UNAME_RELEASE}
+ exit ;;
+ *:OpenBSD:*:*)
+ UNAME_MACHINE_ARCH=`arch | sed 's/OpenBSD.//'`
+ echo ${UNAME_MACHINE_ARCH}-unknown-openbsd${UNAME_RELEASE}
+ exit ;;
+ *:ekkoBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-ekkobsd${UNAME_RELEASE}
+ exit ;;
+ *:SolidBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-solidbsd${UNAME_RELEASE}
+ exit ;;
+ macppc:MirBSD:*:*)
+ echo powerpc-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ *:MirBSD:*:*)
+ echo ${UNAME_MACHINE}-unknown-mirbsd${UNAME_RELEASE}
+ exit ;;
+ alpha:OSF1:*:*)
+ case $UNAME_RELEASE in
+ *4.0)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
+ ;;
+ *5.*)
+ UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $4}'`
+ ;;
+ esac
+ # According to Compaq, /usr/sbin/psrinfo has been available on
+ # OSF/1 and Tru64 systems produced since 1995. I hope that
+ # covers most systems running today. This code pipes the CPU
+ # types through head -n 1, so we only detect the type of CPU 0.
+ ALPHA_CPU_TYPE=`/usr/sbin/psrinfo -v | sed -n -e 's/^ The alpha \(.*\) processor.*$/\1/p' | head -n 1`
+ case "$ALPHA_CPU_TYPE" in
+ "EV4 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "EV4.5 (21064)")
+ UNAME_MACHINE="alpha" ;;
+ "LCA4 (21066/21068)")
+ UNAME_MACHINE="alpha" ;;
+ "EV5 (21164)")
+ UNAME_MACHINE="alphaev5" ;;
+ "EV5.6 (21164A)")
+ UNAME_MACHINE="alphaev56" ;;
+ "EV5.6 (21164PC)")
+ UNAME_MACHINE="alphapca56" ;;
+ "EV5.7 (21164PC)")
+ UNAME_MACHINE="alphapca57" ;;
+ "EV6 (21264)")
+ UNAME_MACHINE="alphaev6" ;;
+ "EV6.7 (21264A)")
+ UNAME_MACHINE="alphaev67" ;;
+ "EV6.8CB (21264C)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8AL (21264B)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.8CX (21264D)")
+ UNAME_MACHINE="alphaev68" ;;
+ "EV6.9A (21264/EV69A)")
+ UNAME_MACHINE="alphaev69" ;;
+ "EV7 (21364)")
+ UNAME_MACHINE="alphaev7" ;;
+ "EV7.9 (21364A)")
+ UNAME_MACHINE="alphaev79" ;;
+ esac
+ # A Pn.n version is a patched version.
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
+ # 1.2 uses "1.2" for uname -r.
+ echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[PVTX]//' | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ # Reset EXIT trap before exiting to avoid spurious non-zero exit code.
+ exitcode=$?
+ trap '' 0
+ exit $exitcode ;;
+ Alpha\ *:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # Should we change UNAME_MACHINE based on the output of uname instead
+ # of the specific Alpha model?
+ echo alpha-pc-interix
+ exit ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-unknown-sysv4
+ exit ;;
+ *:[Aa]miga[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-amigaos
+ exit ;;
+ *:[Mm]orph[Oo][Ss]:*:*)
+ echo ${UNAME_MACHINE}-unknown-morphos
+ exit ;;
+ *:OS/390:*:*)
+ echo i370-ibm-openedition
+ exit ;;
+ *:z/VM:*:*)
+ echo s390-ibm-zvmoe
+ exit ;;
+ *:OS400:*:*)
+ echo powerpc-ibm-os400
+ exit ;;
+ arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
+ echo arm-acorn-riscix${UNAME_RELEASE}
+ exit ;;
+ arm*:riscos:*:*|arm*:RISCOS:*:*)
+ echo arm-unknown-riscos
+ exit ;;
+ SR2?01:HI-UX/MPP:*:* | SR8000:HI-UX/MPP:*:*)
+ echo hppa1.1-hitachi-hiuxmpp
+ exit ;;
+ Pyramid*:OSx*:*:* | MIS*:OSx*:*:* | MIS*:SMP_DC-OSx*:*:*)
+ # akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
+ if test "`(/bin/universe) 2>/dev/null`" = att ; then
+ echo pyramid-pyramid-sysv3
+ else
+ echo pyramid-pyramid-bsd
+ fi
+ exit ;;
+ NILE*:*:*:dcosx)
+ echo pyramid-pyramid-svr4
+ exit ;;
+ DRS?6000:unix:4.0:6*)
+ echo sparc-icl-nx6
+ exit ;;
+ DRS?6000:UNIX_SV:4.2*:7* | DRS?6000:isis:4.2*:7*)
+ case `/usr/bin/uname -p` in
+ sparc) echo sparc-icl-nx7; exit ;;
+ esac ;;
+ s390x:SunOS:*:*)
+ echo ${UNAME_MACHINE}-ibm-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4H:SunOS:5.*:*)
+ echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
+ echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ i86pc:AuroraUX:5.*:* | i86xen:AuroraUX:5.*:*)
+ echo i386-pc-auroraux${UNAME_RELEASE}
+ exit ;;
+ i86pc:SunOS:5.*:* | i86xen:SunOS:5.*:*)
+ eval $set_cc_for_build
+ SUN_ARCH="i386"
+ # If there is a compiler, see if it is configured for 64-bit objects.
+ # Note that the Sun cc does not turn __LP64__ into 1 like gcc does.
+ # This test works for both compilers.
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __amd64'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ SUN_ARCH="x86_64"
+ fi
+ fi
+ echo ${SUN_ARCH}-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:6*:*)
+ # According to config.sub, this is the proper way to canonicalize
+ # SunOS6. Hard to guess exactly what SunOS6 will be like, but
+ # it's likely to be more like Solaris than SunOS4.
+ echo sparc-sun-solaris3`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ sun4*:SunOS:*:*)
+ case "`/usr/bin/arch -k`" in
+ Series*|S4*)
+ UNAME_RELEASE=`uname -v`
+ ;;
+ esac
+ # Japanese Language versions have a version number like `4.1.3-JL'.
+ echo sparc-sun-sunos`echo ${UNAME_RELEASE}|sed -e 's/-/_/'`
+ exit ;;
+ sun3*:SunOS:*:*)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ exit ;;
+ sun*:*:4.2BSD:*)
+ UNAME_RELEASE=`(sed 1q /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
+ test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
+ case "`/bin/arch`" in
+ sun3)
+ echo m68k-sun-sunos${UNAME_RELEASE}
+ ;;
+ sun4)
+ echo sparc-sun-sunos${UNAME_RELEASE}
+ ;;
+ esac
+ exit ;;
+ aushp:SunOS:*:*)
+ echo sparc-auspex-sunos${UNAME_RELEASE}
+ exit ;;
+ # The situation for MiNT is a little confusing. The machine name
+ # can be virtually everything (everything which is not
+ # "atarist" or "atariste" at least should have a processor
+ # > m68000). The system name ranges from "MiNT" over "FreeMiNT"
+ # to the lowercase version "mint" (or "freemint"). Finally
+ # the system name "TOS" denotes a system which is actually not
+ # MiNT. But MiNT is downward compatible to TOS, so this should
+ # be no problem.
+ atarist[e]:*MiNT:*:* | atarist[e]:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ atari*:*MiNT:*:* | atari*:*mint:*:* | atarist[e]:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ *falcon*:*MiNT:*:* | *falcon*:*mint:*:* | *falcon*:*TOS:*:*)
+ echo m68k-atari-mint${UNAME_RELEASE}
+ exit ;;
+ milan*:*MiNT:*:* | milan*:*mint:*:* | *milan*:*TOS:*:*)
+ echo m68k-milan-mint${UNAME_RELEASE}
+ exit ;;
+ hades*:*MiNT:*:* | hades*:*mint:*:* | *hades*:*TOS:*:*)
+ echo m68k-hades-mint${UNAME_RELEASE}
+ exit ;;
+ *:*MiNT:*:* | *:*mint:*:* | *:*TOS:*:*)
+ echo m68k-unknown-mint${UNAME_RELEASE}
+ exit ;;
+ m68k:machten:*:*)
+ echo m68k-apple-machten${UNAME_RELEASE}
+ exit ;;
+ powerpc:machten:*:*)
+ echo powerpc-apple-machten${UNAME_RELEASE}
+ exit ;;
+ RISC*:Mach:*:*)
+ echo mips-dec-mach_bsd4.3
+ exit ;;
+ RISC*:ULTRIX:*:*)
+ echo mips-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ VAX*:ULTRIX*:*:*)
+ echo vax-dec-ultrix${UNAME_RELEASE}
+ exit ;;
+ 2020:CLIX:*:* | 2430:CLIX:*:*)
+ echo clipper-intergraph-clix${UNAME_RELEASE}
+ exit ;;
+ mips:*:*:UMIPS | mips:*:*:RISCos)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+#ifdef __cplusplus
+#include <stdio.h> /* for printf() prototype */
+ int main (int argc, char *argv[]) {
+#else
+ int main (argc, argv) int argc; char *argv[]; {
+#endif
+ #if defined (host_mips) && defined (MIPSEB)
+ #if defined (SYSTYPE_SYSV)
+ printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_SVR4)
+ printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
+ #endif
+ #if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
+ printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
+ #endif
+ #endif
+ exit (-1);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c &&
+ dummyarg=`echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` &&
+ SYSTEM_NAME=`$dummy $dummyarg` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo mips-mips-riscos${UNAME_RELEASE}
+ exit ;;
+ Motorola:PowerMAX_OS:*:*)
+ echo powerpc-motorola-powermax
+ exit ;;
+ Motorola:*:4.3:PL8-*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:*:*:PowerMAX_OS | Synergy:PowerMAX_OS:*:*)
+ echo powerpc-harris-powermax
+ exit ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit ;;
+ m88k:CX/UX:7*:*)
+ echo m88k-harris-cxux7
+ exit ;;
+ m88k:*:4*:R4*)
+ echo m88k-motorola-sysv4
+ exit ;;
+ m88k:*:3*:R3*)
+ echo m88k-motorola-sysv3
+ exit ;;
+ AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 ] || [ $UNAME_PROCESSOR = mc88110 ]
+ then
+ if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx ] || \
+ [ ${TARGET_BINARY_INTERFACE}x = x ]
+ then
+ echo m88k-dg-dgux${UNAME_RELEASE}
+ else
+ echo m88k-dg-dguxbcs${UNAME_RELEASE}
+ fi
+ else
+ echo i586-dg-dgux${UNAME_RELEASE}
+ fi
+ exit ;;
+ M88*:DolphinOS:*:*) # DolphinOS (SVR3)
+ echo m88k-dolphin-sysv3
+ exit ;;
+ M88*:*:R3*:*)
+ # Delta 88k system running SVR3
+ echo m88k-motorola-sysv3
+ exit ;;
+ XD88*:*:*:*) # Tektronix XD88 system running UTekV (SVR3)
+ echo m88k-tektronix-sysv3
+ exit ;;
+ Tek43[0-9][0-9]:UTek:*:*) # Tektronix 4300 system running UTek (BSD)
+ echo m68k-tektronix-bsd
+ exit ;;
+ *:IRIX*:*:*)
+ echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
+ exit ;;
+ ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
+ echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
+ exit ;; # Note that: echo "'`uname -s`'" gives 'AIX '
+ i*86:AIX:*:*)
+ echo i386-ibm-aix
+ exit ;;
+ ia64:AIX:*:*)
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${UNAME_MACHINE}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:2:3)
+ if grep bos325 /usr/include/stdio.h >/dev/null 2>&1; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <sys/systemcfg.h>
+
+ main()
+ {
+ if (!__power_pc())
+ exit(1);
+ puts("powerpc-ibm-aix3.2.5");
+ exit(0);
+ }
+EOF
+ if $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy`
+ then
+ echo "$SYSTEM_NAME"
+ else
+ echo rs6000-ibm-aix3.2.5
+ fi
+ elif grep bos324 /usr/include/stdio.h >/dev/null 2>&1; then
+ echo rs6000-ibm-aix3.2.4
+ else
+ echo rs6000-ibm-aix3.2
+ fi
+ exit ;;
+ *:AIX:*:[4567])
+ IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | sed 1q | awk '{ print $1 }'`
+ if /usr/sbin/lsattr -El ${IBM_CPU_ID} | grep ' POWER' >/dev/null 2>&1; then
+ IBM_ARCH=rs6000
+ else
+ IBM_ARCH=powerpc
+ fi
+ if [ -x /usr/bin/lslpp ] ; then
+ IBM_REV=`/usr/bin/lslpp -Lqc bos.rte.libc |
+ awk -F: '{ print $3 }' | sed s/[0-9]*$/0/`
+ else
+ IBM_REV=${UNAME_VERSION}.${UNAME_RELEASE}
+ fi
+ echo ${IBM_ARCH}-ibm-aix${IBM_REV}
+ exit ;;
+ *:AIX:*:*)
+ echo rs6000-ibm-aix
+ exit ;;
+ ibmrt:4.4BSD:*|romp-ibm:BSD:*)
+ echo romp-ibm-bsd4.4
+ exit ;;
+ ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC BSD and
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ exit ;; # report: romp-ibm BSD 4.3
+ *:BOSX:*:*)
+ echo rs6000-bull-bosx
+ exit ;;
+ DPX/2?00:B.O.S.:*:*)
+ echo m68k-bull-sysv3
+ exit ;;
+ 9000/[34]??:4.3bsd:1.*:*)
+ echo m68k-hp-bsd
+ exit ;;
+ hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
+ echo m68k-hp-bsd4.4
+ exit ;;
+ 9000/[34678]??:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ case "${UNAME_MACHINE}" in
+ 9000/31? ) HP_ARCH=m68000 ;;
+ 9000/[34]?? ) HP_ARCH=m68k ;;
+ 9000/[678][0-9][0-9])
+ if [ -x /usr/bin/getconf ]; then
+ sc_cpu_version=`/usr/bin/getconf SC_CPU_VERSION 2>/dev/null`
+ sc_kernel_bits=`/usr/bin/getconf SC_KERNEL_BITS 2>/dev/null`
+ case "${sc_cpu_version}" in
+ 523) HP_ARCH="hppa1.0" ;; # CPU_PA_RISC1_0
+ 528) HP_ARCH="hppa1.1" ;; # CPU_PA_RISC1_1
+ 532) # CPU_PA_RISC2_0
+ case "${sc_kernel_bits}" in
+ 32) HP_ARCH="hppa2.0n" ;;
+ 64) HP_ARCH="hppa2.0w" ;;
+ '') HP_ARCH="hppa2.0" ;; # HP-UX 10.20
+ esac ;;
+ esac
+ fi
+ if [ "${HP_ARCH}" = "" ]; then
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+
+ #define _HPUX_SOURCE
+ #include <stdlib.h>
+ #include <unistd.h>
+
+ int main ()
+ {
+ #if defined(_SC_KERNEL_BITS)
+ long bits = sysconf(_SC_KERNEL_BITS);
+ #endif
+ long cpu = sysconf (_SC_CPU_VERSION);
+
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
+ case CPU_PA_RISC2_0:
+ #if defined(_SC_KERNEL_BITS)
+ switch (bits)
+ {
+ case 64: puts ("hppa2.0w"); break;
+ case 32: puts ("hppa2.0n"); break;
+ default: puts ("hppa2.0"); break;
+ } break;
+ #else /* !defined(_SC_KERNEL_BITS) */
+ puts ("hppa2.0"); break;
+ #endif
+ default: puts ("hppa1.0"); break;
+ }
+ exit (0);
+ }
+EOF
+ (CCOPTS= $CC_FOR_BUILD -o $dummy $dummy.c 2>/dev/null) && HP_ARCH=`$dummy`
+ test -z "$HP_ARCH" && HP_ARCH=hppa
+ fi ;;
+ esac
+ if [ ${HP_ARCH} = "hppa2.0w" ]
+ then
+ eval $set_cc_for_build
+
+ # hppa2.0w-hp-hpux* has a 64-bit kernel and a compiler generating
+ # 32-bit code. hppa64-hp-hpux* has the same kernel and a compiler
+ # generating 64-bit code. GNU and HP use different nomenclature:
+ #
+ # $ CC_FOR_BUILD=cc ./config.guess
+ # => hppa2.0w-hp-hpux11.23
+ # $ CC_FOR_BUILD="cc +DA2.0w" ./config.guess
+ # => hppa64-hp-hpux11.23
+
+ if echo __LP64__ | (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) |
+ grep -q __LP64__
+ then
+ HP_ARCH="hppa2.0w"
+ else
+ HP_ARCH="hppa64"
+ fi
+ fi
+ echo ${HP_ARCH}-hp-hpux${HPUX_REV}
+ exit ;;
+ ia64:HP-UX:*:*)
+ HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
+ echo ia64-hp-hpux${HPUX_REV}
+ exit ;;
+ 3050*:HI-UX:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #include <unistd.h>
+ int
+ main ()
+ {
+ long cpu = sysconf (_SC_CPU_VERSION);
+ /* The order matters, because CPU_IS_HP_MC68K erroneously returns
+ true for CPU_PA_RISC1_0. CPU_IS_PA_RISC returns correct
+ results, however. */
+ if (CPU_IS_PA_RISC (cpu))
+ {
+ switch (cpu)
+ {
+ case CPU_PA_RISC1_0: puts ("hppa1.0-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC1_1: puts ("hppa1.1-hitachi-hiuxwe2"); break;
+ case CPU_PA_RISC2_0: puts ("hppa2.0-hitachi-hiuxwe2"); break;
+ default: puts ("hppa-hitachi-hiuxwe2"); break;
+ }
+ }
+ else if (CPU_IS_HP_MC68K (cpu))
+ puts ("m68k-hitachi-hiuxwe2");
+ else puts ("unknown-hitachi-hiuxwe2");
+ exit (0);
+ }
+EOF
+ $CC_FOR_BUILD -o $dummy $dummy.c && SYSTEM_NAME=`$dummy` &&
+ { echo "$SYSTEM_NAME"; exit; }
+ echo unknown-hitachi-hiuxwe2
+ exit ;;
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
+ echo hppa1.1-hp-bsd
+ exit ;;
+ 9000/8??:4.3bsd:*:*)
+ echo hppa1.0-hp-bsd
+ exit ;;
+ *9??*:MPE/iX:*:* | *3000*:MPE/iX:*:*)
+ echo hppa1.0-hp-mpeix
+ exit ;;
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
+ echo hppa1.1-hp-osf
+ exit ;;
+ hp8??:OSF1:*:*)
+ echo hppa1.0-hp-osf
+ exit ;;
+ i*86:OSF1:*:*)
+ if [ -x /usr/sbin/sysversion ] ; then
+ echo ${UNAME_MACHINE}-unknown-osf1mk
+ else
+ echo ${UNAME_MACHINE}-unknown-osf1
+ fi
+ exit ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit ;;
+ C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
+ echo c1-convex-bsd
+ exit ;;
+ C2*:ConvexOS:*:* | convex:ConvexOS:C2*:*)
+ if getsysinfo -f scalar_acc
+ then echo c32-convex-bsd
+ else echo c2-convex-bsd
+ fi
+ exit ;;
+ C34*:ConvexOS:*:* | convex:ConvexOS:C34*:*)
+ echo c34-convex-bsd
+ exit ;;
+ C38*:ConvexOS:*:* | convex:ConvexOS:C38*:*)
+ echo c38-convex-bsd
+ exit ;;
+ C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
+ echo c4-convex-bsd
+ exit ;;
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*[A-Z]90:*:*:*)
+ echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
+ | sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
+ -e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/ \
+ -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*TS:*:*:*)
+ echo t90-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*T3E:*:*:*)
+ echo alphaev5-cray-unicosmk${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ CRAY*SV1:*:*:*)
+ echo sv1-cray-unicos${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ *:UNICOS/mp:*:*)
+ echo craynv-cray-unicosmp${UNAME_RELEASE} | sed -e 's/\.[^.]*$/.X/'
+ exit ;;
+ F30[01]:UNIX_System_V:*:* | F700:UNIX_System_V:*:*)
+ FUJITSU_PROC=`uname -m | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz'`
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
+ echo "${FUJITSU_PROC}-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ 5000:UNIX_System_V:4.*:*)
+ FUJITSU_SYS=`uname -p | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/\///'`
+ FUJITSU_REL=`echo ${UNAME_RELEASE} | tr 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' 'abcdefghijklmnopqrstuvwxyz' | sed -e 's/ /_/'`
+ echo "sparc-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
+ exit ;;
+ i*86:BSD/386:*:* | i*86:BSD/OS:*:* | *:Ascend\ Embedded/OS:*:*)
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
+ exit ;;
+ sparc*:BSD/OS:*:*)
+ echo sparc-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:BSD/OS:*:*)
+ echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ exit ;;
+ *:FreeBSD:*:*)
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ case ${UNAME_PROCESSOR} in
+ amd64)
+ echo x86_64-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ *)
+ echo ${UNAME_PROCESSOR}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` ;;
+ esac
+ exit ;;
+ i*:CYGWIN*:*)
+ echo ${UNAME_MACHINE}-pc-cygwin
+ exit ;;
+ *:MINGW64*:*)
+ echo ${UNAME_MACHINE}-pc-mingw64
+ exit ;;
+ *:MINGW*:*)
+ echo ${UNAME_MACHINE}-pc-mingw32
+ exit ;;
+ *:MSYS*:*)
+ echo ${UNAME_MACHINE}-pc-msys
+ exit ;;
+ i*:windows32*:*)
+ # uname -m includes "-pc" on this system.
+ echo ${UNAME_MACHINE}-mingw32
+ exit ;;
+ i*:PW*:*)
+ echo ${UNAME_MACHINE}-pc-pw32
+ exit ;;
+ *:Interix*:*)
+ case ${UNAME_MACHINE} in
+ x86)
+ echo i586-pc-interix${UNAME_RELEASE}
+ exit ;;
+ authenticamd | genuineintel | EM64T)
+ echo x86_64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ IA64)
+ echo ia64-unknown-interix${UNAME_RELEASE}
+ exit ;;
+ esac ;;
+ [345]86:Windows_95:* | [345]86:Windows_98:* | [345]86:Windows_NT:*)
+ echo i${UNAME_MACHINE}-pc-mks
+ exit ;;
+ 8664:Windows_NT:*)
+ echo x86_64-pc-mks
+ exit ;;
+ i*:Windows_NT*:* | Pentium*:Windows_NT*:*)
+ # How do we know it's Interix rather than the generic POSIX subsystem?
+ # It also conflicts with pre-2.0 versions of AT&T UWIN. Should we
+ # UNAME_MACHINE based on the output of uname instead of i386?
+ echo i586-pc-interix
+ exit ;;
+ i*:UWIN*:*)
+ echo ${UNAME_MACHINE}-pc-uwin
+ exit ;;
+ amd64:CYGWIN*:*:* | x86_64:CYGWIN*:*:*)
+ echo x86_64-unknown-cygwin
+ exit ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin
+ exit ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit ;;
+ *:GNU:*:*)
+ # the GNU system
+ echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-${LIBC}`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
+ exit ;;
+ *:GNU/*:*:*)
+ # other systems with GNU libc and userland
+ echo ${UNAME_MACHINE}-unknown-`echo ${UNAME_SYSTEM} | sed 's,^[^/]*/,,' | tr '[A-Z]' '[a-z]'``echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`-${LIBC}
+ exit ;;
+ i*86:Minix:*:*)
+ echo ${UNAME_MACHINE}-pc-minix
+ exit ;;
+ aarch64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ aarch64_be:Linux:*:*)
+ UNAME_MACHINE=aarch64_be
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ alpha:Linux:*:*)
+ case `sed -n '/^cpu model/s/^.*: \(.*\)/\1/p' < /proc/cpuinfo` in
+ EV5) UNAME_MACHINE=alphaev5 ;;
+ EV56) UNAME_MACHINE=alphaev56 ;;
+ PCA56) UNAME_MACHINE=alphapca56 ;;
+ PCA57) UNAME_MACHINE=alphapca56 ;;
+ EV6) UNAME_MACHINE=alphaev6 ;;
+ EV67) UNAME_MACHINE=alphaev67 ;;
+ EV68*) UNAME_MACHINE=alphaev68 ;;
+ esac
+ objdump --private-headers /bin/sh | grep -q ld.so.1
+ if test "$?" = 0 ; then LIBC="gnulibc1" ; fi
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arc:Linux:*:* | arceb:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ arm*:Linux:*:*)
+ eval $set_cc_for_build
+ if echo __ARM_EABI__ | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_EABI__
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ else
+ if echo __ARM_PCS_VFP | $CC_FOR_BUILD -E - 2>/dev/null \
+ | grep -q __ARM_PCS_VFP
+ then
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabi
+ else
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}eabihf
+ fi
+ fi
+ exit ;;
+ avr32*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ cris:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ crisv32:Linux:*:*)
+ echo ${UNAME_MACHINE}-axis-linux-${LIBC}
+ exit ;;
+ e2k:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ frv:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ hexagon:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ ia64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m32r*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ m68*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ mips:Linux:*:* | mips64:Linux:*:*)
+ eval $set_cc_for_build
+ sed 's/^ //' << EOF >$dummy.c
+ #undef CPU
+ #undef ${UNAME_MACHINE}
+ #undef ${UNAME_MACHINE}el
+ #if defined(__MIPSEL__) || defined(__MIPSEL) || defined(_MIPSEL) || defined(MIPSEL)
+ CPU=${UNAME_MACHINE}el
+ #else
+ #if defined(__MIPSEB__) || defined(__MIPSEB) || defined(_MIPSEB) || defined(MIPSEB)
+ CPU=${UNAME_MACHINE}
+ #else
+ CPU=
+ #endif
+ #endif
+EOF
+ eval `$CC_FOR_BUILD -E $dummy.c 2>/dev/null | grep '^CPU'`
+ test x"${CPU}" != x && { echo "${CPU}-unknown-linux-${LIBC}"; exit; }
+ ;;
+ openrisc*:Linux:*:*)
+ echo or1k-unknown-linux-${LIBC}
+ exit ;;
+ or32:Linux:*:* | or1k*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ padre:Linux:*:*)
+ echo sparc-unknown-linux-${LIBC}
+ exit ;;
+ parisc64:Linux:*:* | hppa64:Linux:*:*)
+ echo hppa64-unknown-linux-${LIBC}
+ exit ;;
+ parisc:Linux:*:* | hppa:Linux:*:*)
+ # Look for CPU level
+ case `grep '^cpu[^a-z]*:' /proc/cpuinfo 2>/dev/null | cut -d' ' -f2` in
+ PA7*) echo hppa1.1-unknown-linux-${LIBC} ;;
+ PA8*) echo hppa2.0-unknown-linux-${LIBC} ;;
+ *) echo hppa-unknown-linux-${LIBC} ;;
+ esac
+ exit ;;
+ ppc64:Linux:*:*)
+ echo powerpc64-unknown-linux-${LIBC}
+ exit ;;
+ ppc:Linux:*:*)
+ echo powerpc-unknown-linux-${LIBC}
+ exit ;;
+ ppc64le:Linux:*:*)
+ echo powerpc64le-unknown-linux-${LIBC}
+ exit ;;
+ ppcle:Linux:*:*)
+ echo powerpcle-unknown-linux-${LIBC}
+ exit ;;
+ s390:Linux:*:* | s390x:Linux:*:*)
+ echo ${UNAME_MACHINE}-ibm-linux-${LIBC}
+ exit ;;
+ sh64*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sh*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ sparc:Linux:*:* | sparc64:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ tile*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ vax:Linux:*:*)
+ echo ${UNAME_MACHINE}-dec-linux-${LIBC}
+ exit ;;
+ x86_64:Linux:*:*)
+ echo ${UNAME_MACHINE}-pc-linux-${LIBC}
+ exit ;;
+ xtensa*:Linux:*:*)
+ echo ${UNAME_MACHINE}-unknown-linux-${LIBC}
+ exit ;;
+ i*86:DYNIX/ptx:4*:*)
+ # ptx 4.0 does uname -s correctly, with DYNIX/ptx in there.
+ # earlier versions are messed up and put the nodename in both
+ # sysname and nodename.
+ echo i386-sequent-sysv4
+ exit ;;
+ i*86:UNIX_SV:4.2MP:2.*)
+ # Unixware is an offshoot of SVR4, but it has its own version
+ # number series starting with 2...
+ # I am not positive that other SVR4 systems won't match this,
+ # I just have to hope. -- rms.
+ # Use sysv4.2uw... so that sysv4* matches it.
+ echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
+ exit ;;
+ i*86:OS/2:*:*)
+ # If we were able to find `uname', then EMX Unix compatibility
+ # is probably installed.
+ echo ${UNAME_MACHINE}-pc-os2-emx
+ exit ;;
+ i*86:XTS-300:*:STOP)
+ echo ${UNAME_MACHINE}-unknown-stop
+ exit ;;
+ i*86:atheos:*:*)
+ echo ${UNAME_MACHINE}-unknown-atheos
+ exit ;;
+ i*86:syllable:*:*)
+ echo ${UNAME_MACHINE}-pc-syllable
+ exit ;;
+ i*86:LynxOS:2.*:* | i*86:LynxOS:3.[01]*:* | i*86:LynxOS:4.[02]*:*)
+ echo i386-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ i*86:*DOS:*:*)
+ echo ${UNAME_MACHINE}-pc-msdosdjgpp
+ exit ;;
+ i*86:*:4.*:* | i*86:SYSTEM_V:4.*:*)
+ UNAME_REL=`echo ${UNAME_RELEASE} | sed 's/\/MP$//'`
+ if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
+ echo ${UNAME_MACHINE}-univel-sysv${UNAME_REL}
+ else
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_REL}
+ fi
+ exit ;;
+ i*86:*:5:[678]*)
+ # UnixWare 7.x, OpenUNIX and OpenServer 6.
+ case `/bin/uname -X | grep "^Machine"` in
+ *486*) UNAME_MACHINE=i486 ;;
+ *Pentium) UNAME_MACHINE=i586 ;;
+ *Pent*|*Celeron) UNAME_MACHINE=i686 ;;
+ esac
+ echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}${UNAME_SYSTEM}${UNAME_VERSION}
+ exit ;;
+ i*86:*:3.2:*)
+ if test -f /usr/options/cb.name; then
+ UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
+ elif /bin/uname -X 2>/dev/null >/dev/null ; then
+ UNAME_REL=`(/bin/uname -X|grep Release|sed -e 's/.*= //')`
+ (/bin/uname -X|grep i80486 >/dev/null) && UNAME_MACHINE=i486
+ (/bin/uname -X|grep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ (/bin/uname -X|grep '^Machine.*Pent *II' >/dev/null) \
+ && UNAME_MACHINE=i686
+ (/bin/uname -X|grep '^Machine.*Pentium Pro' >/dev/null) \
+ && UNAME_MACHINE=i686
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
+ else
+ echo ${UNAME_MACHINE}-pc-sysv32
+ fi
+ exit ;;
+ pc:*:*:*)
+ # Left here for compatibility:
+ # uname -m prints for DJGPP always 'pc', but it prints nothing about
+ # the processor, so we play safe by assuming i586.
+ # Note: whatever this is, it MUST be the same as what config.sub
+ # prints for the "djgpp" host, or else GDB configury will decide that
+ # this is a cross-build.
+ echo i586-pc-msdosdjgpp
+ exit ;;
+ Intel:Mach:3*:*)
+ echo i386-pc-mach3
+ exit ;;
+ paragon:*:*:*)
+ echo i860-intel-osf1
+ exit ;;
+ i860:*:4.*:*) # i860-SVR4
+ if grep Stardent /usr/include/sys/uadmin.h >/dev/null 2>&1 ; then
+ echo i860-stardent-sysv${UNAME_RELEASE} # Stardent Vistra i860-SVR4
+ else # Add other i860-SVR4 vendors below as they are discovered.
+ echo i860-unknown-sysv${UNAME_RELEASE} # Unknown i860-SVR4
+ fi
+ exit ;;
+ mini*:CTIX:SYS*5:*)
+ # "miniframe"
+ echo m68010-convergent-sysv
+ exit ;;
+ mc68k:UNIX:SYSTEM5:3.51m)
+ echo m68k-convergent-sysv
+ exit ;;
+ M680?0:D-NIX:5.3:*)
+ echo m68k-diab-dnix
+ exit ;;
+ M68*:*:R3V[5678]*:*)
+ test -r /sysV68 && { echo 'm68k-motorola-sysv'; exit; } ;;
+ 3[345]??:*:4.0:3.0 | 3[34]??A:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 3[34]??/*:*:4.0:3.0 | 4400:*:4.0:3.0 | 4850:*:4.0:3.0 | SKA40:*:4.0:3.0 | SDS2:*:4.0:3.0 | SHG2:*:4.0:3.0 | S7501*:*:4.0:3.0)
+ OS_REL=''
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4; exit; } ;;
+ NCR*:*:4.2:* | MPRAS*:*:4.2:*)
+ OS_REL='.3'
+ test -r /etc/.relid \
+ && OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
+ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
+ && { echo i486-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; }
+ /bin/uname -p 2>/dev/null | /bin/grep pteron >/dev/null \
+ && { echo i586-ncr-sysv4.3${OS_REL}; exit; } ;;
+ m68*:LynxOS:2.*:* | m68*:LynxOS:3.0*:*)
+ echo m68k-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ mc68030:UNIX_System_V:4.*:*)
+ echo m68k-atari-sysv4
+ exit ;;
+ TSUNAMI:LynxOS:2.*:*)
+ echo sparc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ rs6000:LynxOS:2.*:*)
+ echo rs6000-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ PowerPC:LynxOS:2.*:* | PowerPC:LynxOS:3.[01]*:* | PowerPC:LynxOS:4.[02]*:*)
+ echo powerpc-unknown-lynxos${UNAME_RELEASE}
+ exit ;;
+ SM[BE]S:UNIX_SV:*:*)
+ echo mips-dde-sysv${UNAME_RELEASE}
+ exit ;;
+ RM*:ReliantUNIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ RM*:SINIX-*:*:*)
+ echo mips-sni-sysv4
+ exit ;;
+ *:SINIX-*:*:*)
+ if uname -p 2>/dev/null >/dev/null ; then
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ echo ${UNAME_MACHINE}-sni-sysv4
+ else
+ echo ns32k-sni-sysv
+ fi
+ exit ;;
+ PENTIUM:*:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
+ # says <Richard.M.Bartel@ccMail.Census.GOV>
+ echo i586-unisys-sysv4
+ exit ;;
+ *:UNIX_System_V:4*:FTX*)
+ # From Gerald Hewes <hewes@openmarket.com>.
+ # How about differentiating between stratus architectures? -djm
+ echo hppa1.1-stratus-sysv4
+ exit ;;
+ *:*:*:FTX*)
+ # From seanf@swdc.stratus.com.
+ echo i860-stratus-sysv4
+ exit ;;
+ i*86:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo ${UNAME_MACHINE}-stratus-vos
+ exit ;;
+ *:VOS:*:*)
+ # From Paul.Green@stratus.com.
+ echo hppa1.1-stratus-vos
+ exit ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit ;;
+ news*:NEWS-OS:6*:*)
+ echo mips-sony-newsos6
+ exit ;;
+ R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R*000:UNIX_SV:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit ;;
+ BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
+ echo powerpc-be-beos
+ exit ;;
+ BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
+ echo powerpc-apple-beos
+ exit ;;
+ BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
+ echo i586-pc-beos
+ exit ;;
+ BePC:Haiku:*:*) # Haiku running on Intel PC compatible.
+ echo i586-pc-haiku
+ exit ;;
+ x86_64:Haiku:*:*)
+ echo x86_64-unknown-haiku
+ exit ;;
+ SX-4:SUPER-UX:*:*)
+ echo sx4-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-5:SUPER-UX:*:*)
+ echo sx5-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-6:SUPER-UX:*:*)
+ echo sx6-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-7:SUPER-UX:*:*)
+ echo sx7-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8:SUPER-UX:*:*)
+ echo sx8-nec-superux${UNAME_RELEASE}
+ exit ;;
+ SX-8R:SUPER-UX:*:*)
+ echo sx8r-nec-superux${UNAME_RELEASE}
+ exit ;;
+ Power*:Rhapsody:*:*)
+ echo powerpc-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Rhapsody:*:*)
+ echo ${UNAME_MACHINE}-apple-rhapsody${UNAME_RELEASE}
+ exit ;;
+ *:Darwin:*:*)
+ UNAME_PROCESSOR=`uname -p` || UNAME_PROCESSOR=unknown
+ eval $set_cc_for_build
+ if test "$UNAME_PROCESSOR" = unknown ; then
+ UNAME_PROCESSOR=powerpc
+ fi
+ if test `echo "$UNAME_RELEASE" | sed -e 's/\..*//'` -le 10 ; then
+ if [ "$CC_FOR_BUILD" != 'no_compiler_found' ]; then
+ if (echo '#ifdef __LP64__'; echo IS_64BIT_ARCH; echo '#endif') | \
+ (CCOPTS= $CC_FOR_BUILD -E - 2>/dev/null) | \
+ grep IS_64BIT_ARCH >/dev/null
+ then
+ case $UNAME_PROCESSOR in
+ i386) UNAME_PROCESSOR=x86_64 ;;
+ powerpc) UNAME_PROCESSOR=powerpc64 ;;
+ esac
+ fi
+ fi
+ elif test "$UNAME_PROCESSOR" = i386 ; then
+ # Avoid executing cc on OS X 10.9, as it ships with a stub
+ # that puts up a graphical alert prompting to install
+ # developer tools. Any system running Mac OS X 10.7 or
+ # later (Darwin 11 and later) is required to have a 64-bit
+ # processor. This is not true of the ARM version of Darwin
+ # that Apple uses in portable devices.
+ UNAME_PROCESSOR=x86_64
+ fi
+ echo ${UNAME_PROCESSOR}-apple-darwin${UNAME_RELEASE}
+ exit ;;
+ *:procnto*:*:* | *:QNX:[0123456789]*:*)
+ UNAME_PROCESSOR=`uname -p`
+ if test "$UNAME_PROCESSOR" = "x86"; then
+ UNAME_PROCESSOR=i386
+ UNAME_MACHINE=pc
+ fi
+ echo ${UNAME_PROCESSOR}-${UNAME_MACHINE}-nto-qnx${UNAME_RELEASE}
+ exit ;;
+ *:QNX:*:4*)
+ echo i386-pc-qnx
+ exit ;;
+ NEO-?:NONSTOP_KERNEL:*:*)
+ echo neo-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSE-*:NONSTOP_KERNEL:*:*)
+ echo nse-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ NSR-?:NONSTOP_KERNEL:*:*)
+ echo nsr-tandem-nsk${UNAME_RELEASE}
+ exit ;;
+ *:NonStop-UX:*:*)
+ echo mips-compaq-nonstopux
+ exit ;;
+ BS2000:POSIX*:*:*)
+ echo bs2000-siemens-sysv
+ exit ;;
+ DS/*:UNIX_System_V:*:*)
+ echo ${UNAME_MACHINE}-${UNAME_SYSTEM}-${UNAME_RELEASE}
+ exit ;;
+ *:Plan9:*:*)
+ # "uname -m" is not consistent, so use $cputype instead. 386
+ # is converted to i386 for consistency with other x86
+ # operating systems.
+ if test "$cputype" = "386"; then
+ UNAME_MACHINE=i386
+ else
+ UNAME_MACHINE="$cputype"
+ fi
+ echo ${UNAME_MACHINE}-unknown-plan9
+ exit ;;
+ *:TOPS-10:*:*)
+ echo pdp10-unknown-tops10
+ exit ;;
+ *:TENEX:*:*)
+ echo pdp10-unknown-tenex
+ exit ;;
+ KS10:TOPS-20:*:* | KL10:TOPS-20:*:* | TYPE4:TOPS-20:*:*)
+ echo pdp10-dec-tops20
+ exit ;;
+ XKL-1:TOPS-20:*:* | TYPE5:TOPS-20:*:*)
+ echo pdp10-xkl-tops20
+ exit ;;
+ *:TOPS-20:*:*)
+ echo pdp10-unknown-tops20
+ exit ;;
+ *:ITS:*:*)
+ echo pdp10-unknown-its
+ exit ;;
+ SEI:*:*:SEIUX)
+ echo mips-sei-seiux${UNAME_RELEASE}
+ exit ;;
+ *:DragonFly:*:*)
+ echo ${UNAME_MACHINE}-unknown-dragonfly`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
+ exit ;;
+ *:*VMS:*:*)
+ UNAME_MACHINE=`(uname -p) 2>/dev/null`
+ case "${UNAME_MACHINE}" in
+ A*) echo alpha-dec-vms ; exit ;;
+ I*) echo ia64-dec-vms ; exit ;;
+ V*) echo vax-dec-vms ; exit ;;
+ esac ;;
+ *:XENIX:*:SysV)
+ echo i386-pc-xenix
+ exit ;;
+ i*86:skyos:*:*)
+ echo ${UNAME_MACHINE}-pc-skyos`echo ${UNAME_RELEASE}` | sed -e 's/ .*$//'
+ exit ;;
+ i*86:rdos:*:*)
+ echo ${UNAME_MACHINE}-pc-rdos
+ exit ;;
+ i*86:AROS:*:*)
+ echo ${UNAME_MACHINE}-pc-aros
+ exit ;;
+ x86_64:VMkernel:*:*)
+ echo ${UNAME_MACHINE}-unknown-esx
+ exit ;;
+esac
+
+cat >&2 <<EOF
+$0: unable to guess system type
+
+This script, last modified $timestamp, has failed to recognize
+the operating system you are using. It is advised that you
+download the most up to date version of the config scripts from
+
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.guess;hb=HEAD
+and
+ http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+If the version you run ($0) is already up to date, please
+send the following data and any information you think might be
+pertinent to <config-patches@gnu.org> in order to provide the needed
+information to handle your system.
+
+config.guess timestamp = $timestamp
+
+uname -m = `(uname -m) 2>/dev/null || echo unknown`
+uname -r = `(uname -r) 2>/dev/null || echo unknown`
+uname -s = `(uname -s) 2>/dev/null || echo unknown`
+uname -v = `(uname -v) 2>/dev/null || echo unknown`
+
+/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null`
+/bin/uname -X = `(/bin/uname -X) 2>/dev/null`
+
+hostinfo = `(hostinfo) 2>/dev/null`
+/bin/universe = `(/bin/universe) 2>/dev/null`
+/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null`
+/bin/arch = `(/bin/arch) 2>/dev/null`
+/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null`
+/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null`
+
+UNAME_MACHINE = ${UNAME_MACHINE}
+UNAME_RELEASE = ${UNAME_RELEASE}
+UNAME_SYSTEM = ${UNAME_SYSTEM}
+UNAME_VERSION = ${UNAME_VERSION}
+EOF
+
+exit 1
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/jni/ruby/tool/config.sub b/jni/ruby/tool/config.sub
new file mode 100755
index 0000000..f018151
--- /dev/null
+++ b/jni/ruby/tool/config.sub
@@ -0,0 +1,1813 @@
+#! /bin/sh
+# Configuration validation subroutine script.
+# Copyright 1992-2015 Free Software Foundation, Inc.
+
+timestamp='2015-07-28'
+
+# This file is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, see <http://www.gnu.org/licenses/>.
+#
+# As a special exception to the GNU General Public License, if you
+# distribute this file as part of a program that contains a
+# configuration script generated by Autoconf, you may include it under
+# the same distribution terms that you use for the rest of that
+# program. This Exception is an additional permission under section 7
+# of the GNU General Public License, version 3 ("GPLv3").
+
+
+# Please send patches to <config-patches@gnu.org>.
+#
+# Configuration subroutine to validate and canonicalize a configuration type.
+# Supply the specified configuration type as an argument.
+# If it is invalid, we print an error message on stderr and exit with code 1.
+# Otherwise, we print the canonical config type on stdout and succeed.
+
+# You can get the latest version of this script from:
+# http://git.savannah.gnu.org/gitweb/?p=config.git;a=blob_plain;f=config.sub;hb=HEAD
+
+# This file is supposed to be the same for all GNU packages
+# and recognize all the CPU types, system types and aliases
+# that are meaningful with *any* GNU software.
+# Each package is responsible for reporting which valid configurations
+# it does not support. The user should be able to distinguish
+# a failure to support a valid configuration from a meaningless
+# configuration.
+
+# The goal of this file is to map all the various variations of a given
+# machine specification into a single specification in the form:
+# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+# It is wrong to echo any other type of specification.
+
+me=`echo "$0" | sed -e 's,.*/,,'`
+
+usage="\
+Usage: $0 [OPTION] CPU-MFR-OPSYS
+ $0 [OPTION] ALIAS
+
+Canonicalize a configuration name.
+
+Operation modes:
+ -h, --help print this help, then exit
+ -t, --time-stamp print date of last modification, then exit
+ -v, --version print version number, then exit
+
+Report bugs and patches to <config-patches@gnu.org>."
+
+version="\
+GNU config.sub ($timestamp)
+
+Copyright 1992-2015 Free Software Foundation, Inc.
+
+This is free software; see the source for copying conditions. There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE."
+
+help="
+Try \`$me --help' for more information."
+
+# Parse command line
+while test $# -gt 0 ; do
+ case $1 in
+ --time-stamp | --time* | -t )
+ echo "$timestamp" ; exit ;;
+ --version | -v )
+ echo "$version" ; exit ;;
+ --help | --h* | -h )
+ echo "$usage"; exit ;;
+ -- ) # Stop option processing
+ shift; break ;;
+ - ) # Use stdin as input.
+ break ;;
+ -* )
+ echo "$me: invalid option $1$help"
+ exit 1 ;;
+
+ *local*)
+ # First pass through any local machine types.
+ echo $1
+ exit ;;
+
+ * )
+ break ;;
+ esac
+done
+
+case $# in
+ 0) echo "$me: missing argument$help" >&2
+ exit 1;;
+ 1) ;;
+ *) echo "$me: too many arguments$help" >&2
+ exit 1;;
+esac
+
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ nto-qnx* | linux-gnu* | linux-android* | linux-dietlibc | linux-newlib* | \
+ linux-musl* | linux-uclibc* | uclinux-uclibc* | uclinux-gnu* | kfreebsd*-gnu* | \
+ knetbsd*-gnu* | netbsd*-gnu* | netbsd*-eabi* | \
+ kopensolaris*-gnu* | \
+ storm-chaos* | os2-emx* | rtmk-nova*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ android-linux)
+ os=-linux-android
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`-unknown
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
+
+### Let's recognize common machines as not being operating systems so
+### that things like config.sub decstation-3100 work. We also
+### recognize some manufacturers as not being operating systems, so we
+### can provide default operating systems below.
+case $os in
+ -sun*os*)
+ # Prevent following clause from handling this invalid input.
+ ;;
+ -dec* | -mips* | -sequent* | -encore* | -pc532* | -sgi* | -sony* | \
+ -att* | -7300* | -3300* | -delta* | -motorola* | -sun[234]* | \
+ -unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
+ -convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
+ -c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple | -axis | -knuth | -cray | -microblaze*)
+ os=
+ basic_machine=$1
+ ;;
+ -bluegene*)
+ os=-cnk
+ ;;
+ -sim | -cisco | -oki | -wec | -winbond)
+ os=
+ basic_machine=$1
+ ;;
+ -scout)
+ ;;
+ -wrs)
+ os=-vxworks
+ basic_machine=$1
+ ;;
+ -chorusos*)
+ os=-chorusos
+ basic_machine=$1
+ ;;
+ -chorusrdb)
+ os=-chorusrdb
+ basic_machine=$1
+ ;;
+ -hiux*)
+ os=-hiuxwe2
+ ;;
+ -sco6)
+ os=-sco5v6
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5)
+ os=-sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco4)
+ os=-sco3.2v4
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2.[4-9]*)
+ os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco3.2v[4-9]*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco5v6*)
+ # Don't forget version if it is 3.2v4 or newer.
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -sco*)
+ os=-sco3.2v2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -udk*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -isc)
+ os=-isc2.2
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -clix*)
+ basic_machine=clipper-intergraph
+ ;;
+ -isc*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
+ -lynx*178)
+ os=-lynxos178
+ ;;
+ -lynx*5)
+ os=-lynxos5
+ ;;
+ -lynx*)
+ os=-lynxos
+ ;;
+ -ptx*)
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-sequent/'`
+ ;;
+ -windowsnt*)
+ os=`echo $os | sed -e 's/windowsnt/winnt/'`
+ ;;
+ -psos*)
+ os=-psos
+ ;;
+ -mint | -mint[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+esac
+
+# Decode aliases for certain CPU-COMPANY combinations.
+case $basic_machine in
+ # Recognize the basic CPU types without company name.
+ # Some are omitted here because they have special meanings below.
+ 1750a | 580 \
+ | a29k \
+ | aarch64 | aarch64_be \
+ | alpha | alphaev[4-8] | alphaev56 | alphaev6[78] | alphapca5[67] \
+ | alpha64 | alpha64ev[4-8] | alpha64ev56 | alpha64ev6[78] | alpha64pca5[67] \
+ | am33_2.0 \
+ | arc | arceb \
+ | arm | arm[bl]e | arme[lb] | armv[2-8] | armv[3-8][lb] | armv7[arm] \
+ | avr | avr32 \
+ | ba \
+ | be32 | be64 \
+ | bfin \
+ | c4x | c8051 | clipper \
+ | d10v | d30v | dlx | dsp16xx \
+ | e2k | epiphany \
+ | fido | fr30 | frv | ft32 \
+ | h8300 | h8500 | hppa | hppa1.[01] | hppa2.0 | hppa2.0[nw] | hppa64 \
+ | hexagon \
+ | i370 | i860 | i960 | ia64 \
+ | ip2k | iq2000 \
+ | k1om \
+ | le32 | le64 \
+ | lm32 \
+ | m32c | m32r | m32rle | m68000 | m68k | m88k \
+ | maxq | mb | microblaze | microblazeel | mcore | mep | metag \
+ | mips | mipsbe | mipseb | mipsel | mipsle \
+ | mips16 \
+ | mips64 | mips64el \
+ | mips64octeon | mips64octeonel \
+ | mips64orion | mips64orionel \
+ | mips64r5900 | mips64r5900el \
+ | mips64vr | mips64vrel \
+ | mips64vr4100 | mips64vr4100el \
+ | mips64vr4300 | mips64vr4300el \
+ | mips64vr5000 | mips64vr5000el \
+ | mips64vr5900 | mips64vr5900el \
+ | mipsisa32 | mipsisa32el \
+ | mipsisa32r2 | mipsisa32r2el \
+ | mipsisa32r6 | mipsisa32r6el \
+ | mipsisa64 | mipsisa64el \
+ | mipsisa64r2 | mipsisa64r2el \
+ | mipsisa64r6 | mipsisa64r6el \
+ | mipsisa64sb1 | mipsisa64sb1el \
+ | mipsisa64sr71k | mipsisa64sr71kel \
+ | mipsr5900 | mipsr5900el \
+ | mipstx39 | mipstx39el \
+ | mn10200 | mn10300 \
+ | moxie \
+ | mt \
+ | msp430 \
+ | nds32 | nds32le | nds32be \
+ | nios | nios2 | nios2eb | nios2el \
+ | ns16k | ns32k \
+ | open8 | or1k | or1knd | or32 \
+ | pdp10 | pdp11 | pj | pjl \
+ | powerpc | powerpc64 | powerpc64le | powerpcle \
+ | pyramid \
+ | riscv32 | riscv64 \
+ | rl78 | rx \
+ | score \
+ | sh | sh[1234] | sh[24]a | sh[24]aeb | sh[23]e | sh[34]eb | sheb | shbe | shle | sh[1234]le | sh3ele \
+ | sh64 | sh64le \
+ | sparc | sparc64 | sparc64b | sparc64v | sparc86x | sparclet | sparclite \
+ | sparcv8 | sparcv9 | sparcv9b | sparcv9v \
+ | spu \
+ | tahoe | tic4x | tic54x | tic55x | tic6x | tic80 | tron \
+ | ubicom32 \
+ | v850 | v850e | v850e1 | v850e2 | v850es | v850e2v3 \
+ | visium \
+ | we32k \
+ | x86 | xc16x | xstormy16 | xtensa \
+ | z8k | z80)
+ basic_machine=$basic_machine-unknown
+ ;;
+ c54x)
+ basic_machine=tic54x-unknown
+ ;;
+ c55x)
+ basic_machine=tic55x-unknown
+ ;;
+ c6x)
+ basic_machine=tic6x-unknown
+ ;;
+ leon|leon[3-9])
+ basic_machine=sparc-$basic_machine
+ ;;
+ m6811 | m68hc11 | m6812 | m68hc12 | m68hcs12x | nvptx | picochip)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ m88110 | m680[12346]0 | m683?2 | m68360 | m5200 | v70 | w65 | z8k)
+ ;;
+ ms1)
+ basic_machine=mt-unknown
+ ;;
+
+ strongarm | thumb | xscale)
+ basic_machine=arm-unknown
+ ;;
+ xgate)
+ basic_machine=$basic_machine-unknown
+ os=-none
+ ;;
+ xscaleeb)
+ basic_machine=armeb-unknown
+ ;;
+
+ xscaleel)
+ basic_machine=armel-unknown
+ ;;
+
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i*86 | x86_64)
+ basic_machine=$basic_machine-pc
+ ;;
+ # Object if more than one company name word.
+ *-*-*)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+ # Recognize the basic CPU types with company name.
+ 580-* \
+ | a29k-* \
+ | aarch64-* | aarch64_be-* \
+ | alpha-* | alphaev[4-8]-* | alphaev56-* | alphaev6[78]-* \
+ | alpha64-* | alpha64ev[4-8]-* | alpha64ev56-* | alpha64ev6[78]-* \
+ | alphapca5[67]-* | alpha64pca5[67]-* | arc-* | arceb-* \
+ | arm-* | armbe-* | armle-* | armeb-* | armv*-* \
+ | avr-* | avr32-* \
+ | ba-* \
+ | be32-* | be64-* \
+ | bfin-* | bs2000-* \
+ | c[123]* | c30-* | [cjt]90-* | c4x-* \
+ | c8051-* | clipper-* | craynv-* | cydra-* \
+ | d10v-* | d30v-* | dlx-* \
+ | e2k-* | elxsi-* \
+ | f30[01]-* | f700-* | fido-* | fr30-* | frv-* | fx80-* \
+ | h8300-* | h8500-* \
+ | hppa-* | hppa1.[01]-* | hppa2.0-* | hppa2.0[nw]-* | hppa64-* \
+ | hexagon-* \
+ | i*86-* | i860-* | i960-* | ia64-* \
+ | ip2k-* | iq2000-* \
+ | k1om-* \
+ | le32-* | le64-* \
+ | lm32-* \
+ | m32c-* | m32r-* | m32rle-* \
+ | m68000-* | m680[012346]0-* | m68360-* | m683?2-* | m68k-* \
+ | m88110-* | m88k-* | maxq-* | mcore-* | metag-* \
+ | microblaze-* | microblazeel-* \
+ | mips-* | mipsbe-* | mipseb-* | mipsel-* | mipsle-* \
+ | mips16-* \
+ | mips64-* | mips64el-* \
+ | mips64octeon-* | mips64octeonel-* \
+ | mips64orion-* | mips64orionel-* \
+ | mips64r5900-* | mips64r5900el-* \
+ | mips64vr-* | mips64vrel-* \
+ | mips64vr4100-* | mips64vr4100el-* \
+ | mips64vr4300-* | mips64vr4300el-* \
+ | mips64vr5000-* | mips64vr5000el-* \
+ | mips64vr5900-* | mips64vr5900el-* \
+ | mipsisa32-* | mipsisa32el-* \
+ | mipsisa32r2-* | mipsisa32r2el-* \
+ | mipsisa32r6-* | mipsisa32r6el-* \
+ | mipsisa64-* | mipsisa64el-* \
+ | mipsisa64r2-* | mipsisa64r2el-* \
+ | mipsisa64r6-* | mipsisa64r6el-* \
+ | mipsisa64sb1-* | mipsisa64sb1el-* \
+ | mipsisa64sr71k-* | mipsisa64sr71kel-* \
+ | mipsr5900-* | mipsr5900el-* \
+ | mipstx39-* | mipstx39el-* \
+ | mmix-* \
+ | mt-* \
+ | msp430-* \
+ | nds32-* | nds32le-* | nds32be-* \
+ | nios-* | nios2-* | nios2eb-* | nios2el-* \
+ | none-* | np1-* | ns16k-* | ns32k-* \
+ | open8-* \
+ | or1k*-* \
+ | orion-* \
+ | pdp10-* | pdp11-* | pj-* | pjl-* | pn-* | power-* \
+ | powerpc-* | powerpc64-* | powerpc64le-* | powerpcle-* \
+ | pyramid-* \
+ | riscv32-* | riscv64-* \
+ | rl78-* | romp-* | rs6000-* | rx-* \
+ | sh-* | sh[1234]-* | sh[24]a-* | sh[24]aeb-* | sh[23]e-* | sh[34]eb-* | sheb-* | shbe-* \
+ | shle-* | sh[1234]le-* | sh3ele-* | sh64-* | sh64le-* \
+ | sparc-* | sparc64-* | sparc64b-* | sparc64v-* | sparc86x-* | sparclet-* \
+ | sparclite-* \
+ | sparcv8-* | sparcv9-* | sparcv9b-* | sparcv9v-* | sv1-* | sx*-* \
+ | tahoe-* \
+ | tic30-* | tic4x-* | tic54x-* | tic55x-* | tic6x-* | tic80-* \
+ | tile*-* \
+ | tron-* \
+ | ubicom32-* \
+ | v850-* | v850e-* | v850e1-* | v850es-* | v850e2-* | v850e2v3-* \
+ | vax-* \
+ | visium-* \
+ | we32k-* \
+ | x86-* | x86_64-* | xc16x-* | xps100-* \
+ | xstormy16-* | xtensa*-* \
+ | ymp-* \
+ | z8k-* | z80-*)
+ ;;
+ # Recognize the basic CPU types without company name, with glob match.
+ xtensa*)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # Recognize the various machine names and aliases which stand
+ # for a CPU type and a company and sometimes even an OS.
+ 386bsd)
+ basic_machine=i386-unknown
+ os=-bsd
+ ;;
+ 3b1 | 7300 | 7300-att | att-7300 | pc7300 | safari | unixpc)
+ basic_machine=m68000-att
+ ;;
+ 3b*)
+ basic_machine=we32k-att
+ ;;
+ a29khif)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ abacus)
+ basic_machine=abacus-unknown
+ ;;
+ adobe68k)
+ basic_machine=m68010-adobe
+ os=-scout
+ ;;
+ alliant | fx80)
+ basic_machine=fx80-alliant
+ ;;
+ altos | altos3068)
+ basic_machine=m68k-altos
+ ;;
+ am29k)
+ basic_machine=a29k-none
+ os=-bsd
+ ;;
+ amd64)
+ basic_machine=x86_64-pc
+ ;;
+ amd64-*)
+ basic_machine=x86_64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ amdahl)
+ basic_machine=580-amdahl
+ os=-sysv
+ ;;
+ amiga | amiga-*)
+ basic_machine=m68k-unknown
+ ;;
+ amigaos | amigados)
+ basic_machine=m68k-unknown
+ os=-amigaos
+ ;;
+ amigaunix | amix)
+ basic_machine=m68k-unknown
+ os=-sysv4
+ ;;
+ apollo68)
+ basic_machine=m68k-apollo
+ os=-sysv
+ ;;
+ apollo68bsd)
+ basic_machine=m68k-apollo
+ os=-bsd
+ ;;
+ aros)
+ basic_machine=i386-pc
+ os=-aros
+ ;;
+ asmjs)
+ basic_machine=asmjs-unknown
+ ;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
+ balance)
+ basic_machine=ns32k-sequent
+ os=-dynix
+ ;;
+ blackfin)
+ basic_machine=bfin-unknown
+ os=-linux
+ ;;
+ blackfin-*)
+ basic_machine=bfin-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ bluegene*)
+ basic_machine=powerpc-ibm
+ os=-cnk
+ ;;
+ c54x-*)
+ basic_machine=tic54x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c55x-*)
+ basic_machine=tic55x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c6x-*)
+ basic_machine=tic6x-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ c90)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
+ cegcc)
+ basic_machine=arm-unknown
+ os=-cegcc
+ ;;
+ convex-c1)
+ basic_machine=c1-convex
+ os=-bsd
+ ;;
+ convex-c2)
+ basic_machine=c2-convex
+ os=-bsd
+ ;;
+ convex-c32)
+ basic_machine=c32-convex
+ os=-bsd
+ ;;
+ convex-c34)
+ basic_machine=c34-convex
+ os=-bsd
+ ;;
+ convex-c38)
+ basic_machine=c38-convex
+ os=-bsd
+ ;;
+ cray | j90)
+ basic_machine=j90-cray
+ os=-unicos
+ ;;
+ craynv)
+ basic_machine=craynv-cray
+ os=-unicosmp
+ ;;
+ cr16 | cr16-*)
+ basic_machine=cr16-unknown
+ os=-elf
+ ;;
+ crds | unos)
+ basic_machine=m68k-crds
+ ;;
+ crisv32 | crisv32-* | etraxfs*)
+ basic_machine=crisv32-axis
+ ;;
+ cris | cris-* | etrax*)
+ basic_machine=cris-axis
+ ;;
+ crx)
+ basic_machine=crx-unknown
+ os=-elf
+ ;;
+ da30 | da30-*)
+ basic_machine=m68k-da30
+ ;;
+ decstation | decstation-3100 | pmax | pmax-* | pmin | dec3100 | decstatn)
+ basic_machine=mips-dec
+ ;;
+ decsystem10* | dec10*)
+ basic_machine=pdp10-dec
+ os=-tops10
+ ;;
+ decsystem20* | dec20*)
+ basic_machine=pdp10-dec
+ os=-tops20
+ ;;
+ delta | 3300 | motorola-3300 | motorola-delta \
+ | 3300-motorola | delta-motorola)
+ basic_machine=m68k-motorola
+ ;;
+ delta88)
+ basic_machine=m88k-motorola
+ os=-sysv3
+ ;;
+ dicos)
+ basic_machine=i686-pc
+ os=-dicos
+ ;;
+ djgpp)
+ basic_machine=i586-pc
+ os=-msdosdjgpp
+ ;;
+ dpx20 | dpx20-*)
+ basic_machine=rs6000-bull
+ os=-bosx
+ ;;
+ dpx2* | dpx2*-bull)
+ basic_machine=m68k-bull
+ os=-sysv3
+ ;;
+ ebmon29k)
+ basic_machine=a29k-amd
+ os=-ebmon
+ ;;
+ elxsi)
+ basic_machine=elxsi-elxsi
+ os=-bsd
+ ;;
+ encore | umax | mmax)
+ basic_machine=ns32k-encore
+ ;;
+ es1800 | OSE68k | ose68k | ose | OSE)
+ basic_machine=m68k-ericsson
+ os=-ose
+ ;;
+ fx2800)
+ basic_machine=i860-alliant
+ ;;
+ genix)
+ basic_machine=ns32k-ns
+ ;;
+ gmicro)
+ basic_machine=tron-gmicro
+ os=-sysv
+ ;;
+ go32)
+ basic_machine=i386-pc
+ os=-go32
+ ;;
+ h3050r* | hiux*)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ h8300hms)
+ basic_machine=h8300-hitachi
+ os=-hms
+ ;;
+ h8300xray)
+ basic_machine=h8300-hitachi
+ os=-xray
+ ;;
+ h8500hms)
+ basic_machine=h8500-hitachi
+ os=-hms
+ ;;
+ harris)
+ basic_machine=m88k-harris
+ os=-sysv3
+ ;;
+ hp300-*)
+ basic_machine=m68k-hp
+ ;;
+ hp300bsd)
+ basic_machine=m68k-hp
+ os=-bsd
+ ;;
+ hp300hpux)
+ basic_machine=m68k-hp
+ os=-hpux
+ ;;
+ hp3k9[0-9][0-9] | hp9[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k2[0-9][0-9] | hp9k31[0-9])
+ basic_machine=m68000-hp
+ ;;
+ hp9k3[2-9][0-9])
+ basic_machine=m68k-hp
+ ;;
+ hp9k6[0-9][0-9] | hp6[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hp9k7[0-79][0-9] | hp7[0-79][0-9])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k78[0-9] | hp78[0-9])
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[67]1 | hp8[67]1 | hp9k80[24] | hp80[24] | hp9k8[78]9 | hp8[78]9 | hp9k893 | hp893)
+ # FIXME: really hppa2.0-hp
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][13679] | hp8[0-9][13679])
+ basic_machine=hppa1.1-hp
+ ;;
+ hp9k8[0-9][0-9] | hp8[0-9][0-9])
+ basic_machine=hppa1.0-hp
+ ;;
+ hppa-next)
+ os=-nextstep3
+ ;;
+ hppaosf)
+ basic_machine=hppa1.1-hp
+ os=-osf
+ ;;
+ hppro)
+ basic_machine=hppa1.1-hp
+ os=-proelf
+ ;;
+ i370-ibm* | ibm*)
+ basic_machine=i370-ibm
+ ;;
+ i*86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv32
+ ;;
+ i*86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv4
+ ;;
+ i*86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-sysv
+ ;;
+ i*86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
+ os=-solaris2
+ ;;
+ i386mach)
+ basic_machine=i386-mach
+ os=-mach
+ ;;
+ i386-vsta | vsta)
+ basic_machine=i386-unknown
+ os=-vsta
+ ;;
+ iris | iris4d)
+ basic_machine=mips-sgi
+ case $os in
+ -irix*)
+ ;;
+ *)
+ os=-irix4
+ ;;
+ esac
+ ;;
+ isi68 | isi)
+ basic_machine=m68k-isi
+ os=-sysv
+ ;;
+ leon-*|leon[3-9]-*)
+ basic_machine=sparc-`echo $basic_machine | sed 's/-.*//'`
+ ;;
+ m68knommu)
+ basic_machine=m68k-unknown
+ os=-linux
+ ;;
+ m68knommu-*)
+ basic_machine=m68k-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ m88k-omron*)
+ basic_machine=m88k-omron
+ ;;
+ magnum | m3230)
+ basic_machine=mips-mips
+ os=-sysv
+ ;;
+ merlin)
+ basic_machine=ns32k-utek
+ os=-sysv
+ ;;
+ microblaze*)
+ basic_machine=microblaze-xilinx
+ ;;
+ mingw64)
+ basic_machine=x86_64-pc
+ os=-mingw64
+ ;;
+ mingw32)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ mingw32ce)
+ basic_machine=arm-unknown
+ os=-mingw32ce
+ ;;
+ miniframe)
+ basic_machine=m68000-convergent
+ ;;
+ *mint | -mint[0-9]* | *MiNT | *MiNT[0-9]*)
+ basic_machine=m68k-atari
+ os=-mint
+ ;;
+ mips3*-*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
+ ;;
+ mips3*)
+ basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`-unknown
+ ;;
+ monitor)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ morphos)
+ basic_machine=powerpc-unknown
+ os=-morphos
+ ;;
+ moxiebox)
+ basic_machine=moxie-unknown
+ os=-moxiebox
+ ;;
+ msdos)
+ basic_machine=i386-pc
+ os=-msdos
+ ;;
+ ms1-*)
+ basic_machine=`echo $basic_machine | sed -e 's/ms1-/mt-/'`
+ ;;
+ msys)
+ basic_machine=i686-pc
+ os=-msys
+ ;;
+ mvs)
+ basic_machine=i370-ibm
+ os=-mvs
+ ;;
+ nacl)
+ basic_machine=le32-unknown
+ os=-nacl
+ ;;
+ ncr3000)
+ basic_machine=i486-ncr
+ os=-sysv4
+ ;;
+ netbsd386)
+ basic_machine=i386-unknown
+ os=-netbsd
+ ;;
+ netwinder)
+ basic_machine=armv4l-rebel
+ os=-linux
+ ;;
+ news | news700 | news800 | news900)
+ basic_machine=m68k-sony
+ os=-newsos
+ ;;
+ news1000)
+ basic_machine=m68030-sony
+ os=-newsos
+ ;;
+ news-3600 | risc-news)
+ basic_machine=mips-sony
+ os=-newsos
+ ;;
+ necv70)
+ basic_machine=v70-nec
+ os=-sysv
+ ;;
+ next | m*-next )
+ basic_machine=m68k-next
+ case $os in
+ -nextstep* )
+ ;;
+ -ns2*)
+ os=-nextstep2
+ ;;
+ *)
+ os=-nextstep3
+ ;;
+ esac
+ ;;
+ nh3000)
+ basic_machine=m68k-harris
+ os=-cxux
+ ;;
+ nh[45]000)
+ basic_machine=m88k-harris
+ os=-cxux
+ ;;
+ nindy960)
+ basic_machine=i960-intel
+ os=-nindy
+ ;;
+ mon960)
+ basic_machine=i960-intel
+ os=-mon960
+ ;;
+ nonstopux)
+ basic_machine=mips-compaq
+ os=-nonstopux
+ ;;
+ np1)
+ basic_machine=np1-gould
+ ;;
+ neo-tandem)
+ basic_machine=neo-tandem
+ ;;
+ nse-tandem)
+ basic_machine=nse-tandem
+ ;;
+ nsr-tandem)
+ basic_machine=nsr-tandem
+ ;;
+ op50n-* | op60c-*)
+ basic_machine=hppa1.1-oki
+ os=-proelf
+ ;;
+ openrisc | openrisc-*)
+ basic_machine=or32-unknown
+ ;;
+ os400)
+ basic_machine=powerpc-ibm
+ os=-os400
+ ;;
+ OSE68000 | ose68000)
+ basic_machine=m68000-ericsson
+ os=-ose
+ ;;
+ os68k)
+ basic_machine=m68k-none
+ os=-os68k
+ ;;
+ pa-hitachi)
+ basic_machine=hppa1.1-hitachi
+ os=-hiuxwe2
+ ;;
+ paragon)
+ basic_machine=i860-intel
+ os=-osf
+ ;;
+ parisc)
+ basic_machine=hppa-unknown
+ os=-linux
+ ;;
+ parisc-*)
+ basic_machine=hppa-`echo $basic_machine | sed 's/^[^-]*-//'`
+ os=-linux
+ ;;
+ pbd)
+ basic_machine=sparc-tti
+ ;;
+ pbb)
+ basic_machine=m68k-tti
+ ;;
+ pc532 | pc532-*)
+ basic_machine=ns32k-pc532
+ ;;
+ pc98)
+ basic_machine=i386-pc
+ ;;
+ pc98-*)
+ basic_machine=i386-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium | p5 | k5 | k6 | nexgen | viac3)
+ basic_machine=i586-pc
+ ;;
+ pentiumpro | p6 | 6x86 | athlon | athlon_*)
+ basic_machine=i686-pc
+ ;;
+ pentiumii | pentium2 | pentiumiii | pentium3)
+ basic_machine=i686-pc
+ ;;
+ pentium4)
+ basic_machine=i786-pc
+ ;;
+ pentium-* | p5-* | k5-* | k6-* | nexgen-* | viac3-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-* | 6x86-* | athlon-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumii-* | pentium2-* | pentiumiii-* | pentium3-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentium4-*)
+ basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pn)
+ basic_machine=pn-gould
+ ;;
+ power) basic_machine=power-ibm
+ ;;
+ ppc | ppcbe) basic_machine=powerpc-unknown
+ ;;
+ ppc-* | ppcbe-*)
+ basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64) basic_machine=powerpc64-unknown
+ ;;
+ ppc64-*) basic_machine=powerpc64-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppc64le | powerpc64little | ppc64-le | powerpc64-little)
+ basic_machine=powerpc64le-unknown
+ ;;
+ ppc64le-* | powerpc64little-*)
+ basic_machine=powerpc64le-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ps2)
+ basic_machine=i386-ibm
+ ;;
+ pw32)
+ basic_machine=i586-unknown
+ os=-pw32
+ ;;
+ rdos | rdos64)
+ basic_machine=x86_64-pc
+ os=-rdos
+ ;;
+ rdos32)
+ basic_machine=i386-pc
+ os=-rdos
+ ;;
+ rom68k)
+ basic_machine=m68k-rom68k
+ os=-coff
+ ;;
+ rm[46]00)
+ basic_machine=mips-siemens
+ ;;
+ rtpc | rtpc-*)
+ basic_machine=romp-ibm
+ ;;
+ s390 | s390-*)
+ basic_machine=s390-ibm
+ ;;
+ s390x | s390x-*)
+ basic_machine=s390x-ibm
+ ;;
+ sa29200)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ sb1)
+ basic_machine=mipsisa64sb1-unknown
+ ;;
+ sb1el)
+ basic_machine=mipsisa64sb1el-unknown
+ ;;
+ sde)
+ basic_machine=mipsisa32-sde
+ os=-elf
+ ;;
+ sei)
+ basic_machine=mips-sei
+ os=-seiux
+ ;;
+ sequent)
+ basic_machine=i386-sequent
+ ;;
+ sh)
+ basic_machine=sh-hitachi
+ os=-hms
+ ;;
+ sh5el)
+ basic_machine=sh5le-unknown
+ ;;
+ sh64)
+ basic_machine=sh64-unknown
+ ;;
+ sparclite-wrs | simso-wrs)
+ basic_machine=sparclite-wrs
+ os=-vxworks
+ ;;
+ sps7)
+ basic_machine=m68k-bull
+ os=-sysv2
+ ;;
+ spur)
+ basic_machine=spur-unknown
+ ;;
+ st2000)
+ basic_machine=m68k-tandem
+ ;;
+ stratus)
+ basic_machine=i860-stratus
+ os=-sysv4
+ ;;
+ strongarm-* | thumb-*)
+ basic_machine=arm-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ sun2)
+ basic_machine=m68000-sun
+ ;;
+ sun2os3)
+ basic_machine=m68000-sun
+ os=-sunos3
+ ;;
+ sun2os4)
+ basic_machine=m68000-sun
+ os=-sunos4
+ ;;
+ sun3os3)
+ basic_machine=m68k-sun
+ os=-sunos3
+ ;;
+ sun3os4)
+ basic_machine=m68k-sun
+ os=-sunos4
+ ;;
+ sun4os3)
+ basic_machine=sparc-sun
+ os=-sunos3
+ ;;
+ sun4os4)
+ basic_machine=sparc-sun
+ os=-sunos4
+ ;;
+ sun4sol2)
+ basic_machine=sparc-sun
+ os=-solaris2
+ ;;
+ sun3 | sun3-*)
+ basic_machine=m68k-sun
+ ;;
+ sun4)
+ basic_machine=sparc-sun
+ ;;
+ sun386 | sun386i | roadrunner)
+ basic_machine=i386-sun
+ ;;
+ sv1)
+ basic_machine=sv1-cray
+ os=-unicos
+ ;;
+ symmetry)
+ basic_machine=i386-sequent
+ os=-dynix
+ ;;
+ t3e)
+ basic_machine=alphaev5-cray
+ os=-unicos
+ ;;
+ t90)
+ basic_machine=t90-cray
+ os=-unicos
+ ;;
+ tile*)
+ basic_machine=$basic_machine-unknown
+ os=-linux-gnu
+ ;;
+ tx39)
+ basic_machine=mipstx39-unknown
+ ;;
+ tx39el)
+ basic_machine=mipstx39el-unknown
+ ;;
+ toad1)
+ basic_machine=pdp10-xkl
+ os=-tops20
+ ;;
+ tower | tower-32)
+ basic_machine=m68k-ncr
+ ;;
+ tpf)
+ basic_machine=s390x-ibm
+ os=-tpf
+ ;;
+ udi29k)
+ basic_machine=a29k-amd
+ os=-udi
+ ;;
+ ultra3)
+ basic_machine=a29k-nyu
+ os=-sym1
+ ;;
+ v810 | necv810)
+ basic_machine=v810-nec
+ os=-none
+ ;;
+ vaxv)
+ basic_machine=vax-dec
+ os=-sysv
+ ;;
+ vms)
+ basic_machine=vax-dec
+ os=-vms
+ ;;
+ vpp*|vx|vx-*)
+ basic_machine=f301-fujitsu
+ ;;
+ vxworks960)
+ basic_machine=i960-wrs
+ os=-vxworks
+ ;;
+ vxworks68)
+ basic_machine=m68k-wrs
+ os=-vxworks
+ ;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
+ w65*)
+ basic_machine=w65-wdc
+ os=-none
+ ;;
+ w89k-*)
+ basic_machine=hppa1.1-winbond
+ os=-proelf
+ ;;
+ xbox)
+ basic_machine=i686-pc
+ os=-mingw32
+ ;;
+ xps | xps100)
+ basic_machine=xps100-honeywell
+ ;;
+ xscale-* | xscalee[bl]-*)
+ basic_machine=`echo $basic_machine | sed 's/^xscale/arm/'`
+ ;;
+ ymp)
+ basic_machine=ymp-cray
+ os=-unicos
+ ;;
+ z8k-*-coff)
+ basic_machine=z8k-unknown
+ os=-sim
+ ;;
+ z80-*-coff)
+ basic_machine=z80-unknown
+ os=-sim
+ ;;
+ none)
+ basic_machine=none-none
+ os=-none
+ ;;
+
+# Here we handle the default manufacturer of certain CPU types. It is in
+# some cases the only manufacturer, in others, it is the most popular.
+ w89k)
+ basic_machine=hppa1.1-winbond
+ ;;
+ op50n)
+ basic_machine=hppa1.1-oki
+ ;;
+ op60c)
+ basic_machine=hppa1.1-oki
+ ;;
+ romp)
+ basic_machine=romp-ibm
+ ;;
+ mmix)
+ basic_machine=mmix-knuth
+ ;;
+ rs6000)
+ basic_machine=rs6000-ibm
+ ;;
+ vax)
+ basic_machine=vax-dec
+ ;;
+ pdp10)
+ # there are many clones, so DEC is not a safe bet
+ basic_machine=pdp10-unknown
+ ;;
+ pdp11)
+ basic_machine=pdp11-dec
+ ;;
+ we32k)
+ basic_machine=we32k-att
+ ;;
+ sh[1234] | sh[24]a | sh[24]aeb | sh[34]eb | sh[1234]le | sh[23]ele)
+ basic_machine=sh-unknown
+ ;;
+ sparc | sparcv8 | sparcv9 | sparcv9b | sparcv9v)
+ basic_machine=sparc-sun
+ ;;
+ cydra)
+ basic_machine=cydra-cydrome
+ ;;
+ orion)
+ basic_machine=orion-highlevel
+ ;;
+ orion105)
+ basic_machine=clipper-highlevel
+ ;;
+ mac | mpw | mac-mpw)
+ basic_machine=m68k-apple
+ ;;
+ pmac | pmac-mpw)
+ basic_machine=powerpc-apple
+ ;;
+ *-unknown)
+ # Make sure to match an already-canonicalized machine name.
+ ;;
+ *)
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+
+# Here we canonicalize certain aliases for manufacturers.
+case $basic_machine in
+ *-digital*)
+ basic_machine=`echo $basic_machine | sed 's/digital.*/dec/'`
+ ;;
+ *-commodore*)
+ basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
+ ;;
+ *)
+ ;;
+esac
+
+# Decode manufacturer-specific aliases for certain operating systems.
+
+if [ x"$os" != x"" ]
+then
+case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
+ # -solaris* is a basic system type, with this one exception.
+ -auroraux)
+ os=-auroraux
+ ;;
+ -solaris1 | -solaris1.*)
+ os=`echo $os | sed -e 's|solaris1|sunos4|'`
+ ;;
+ -solaris)
+ os=-solaris2
+ ;;
+ -svr4*)
+ os=-sysv4
+ ;;
+ -unixware*)
+ os=-sysv4.2uw
+ ;;
+ -gnu/linux*)
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
+ ;;
+ # First accept the basic system types.
+ # The portable systems comes first.
+ # Each alternative MUST END IN A *, to match a version number.
+ # -sysv* is not here because it comes later, after sysvr4.
+ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -cnk* | -sunos | -sunos[34]*\
+ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -auroraux* | -solaris* \
+ | -sym* | -kopensolaris* | -plan9* \
+ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
+ | -aos* | -aros* | -cloudabi* \
+ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
+ | -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -hiux* | -386bsd* | -knetbsd* | -mirbsd* | -netbsd* \
+ | -bitrig* | -openbsd* | -solidbsd* \
+ | -ekkobsd* | -kfreebsd* | -freebsd* | -riscix* | -lynxos* \
+ | -bosx* | -nextstep* | -cxux* | -aout* | -elf* | -oabi* \
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -chorusos* | -chorusrdb* | -cegcc* \
+ | -cygwin* | -msys* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
+ | -mingw32* | -mingw64* | -linux-gnu* | -linux-android* \
+ | -linux-newlib* | -linux-musl* | -linux-uclibc* \
+ | -uxpv* | -beos* | -mpeix* | -udk* | -moxiebox* \
+ | -interix* | -uwin* | -mks* | -rhapsody* | -darwin* | -opened* \
+ | -openstep* | -oskit* | -conix* | -pw32* | -nonstopux* \
+ | -storm-chaos* | -tops10* | -tenex* | -tops20* | -its* \
+ | -os2* | -vos* | -palmos* | -uclinux* | -nucleus* \
+ | -morphos* | -superux* | -rtmk* | -rtmk-nova* | -windiss* \
+ | -powermax* | -dnix* | -nx6 | -nx7 | -sei* | -dragonfly* \
+ | -skyos* | -haiku* | -rdos* | -toppers* | -drops* | -es* | -tirtos*)
+ # Remember, each alternative MUST END IN *, to match a version number.
+ ;;
+ -qnx*)
+ case $basic_machine in
+ x86-* | i*86-*)
+ ;;
+ *)
+ os=-nto$os
+ ;;
+ esac
+ ;;
+ -nto-qnx*)
+ ;;
+ -nto*)
+ os=`echo $os | sed -e 's|nto|nto-qnx|'`
+ ;;
+ -sim | -es1800* | -hms* | -xray | -os68k* | -none* | -v88r* \
+ | -windows* | -osx | -abug | -netware* | -os9* | -beos* | -haiku* \
+ | -macos* | -mpw* | -magic* | -mmixware* | -mon960* | -lnews*)
+ ;;
+ -mac*)
+ os=`echo $os | sed -e 's|mac|macos|'`
+ ;;
+ -linux-dietlibc)
+ os=-linux-dietlibc
+ ;;
+ -linux*)
+ os=`echo $os | sed -e 's|linux|linux-gnu|'`
+ ;;
+ -sunos5*)
+ os=`echo $os | sed -e 's|sunos5|solaris2|'`
+ ;;
+ -sunos6*)
+ os=`echo $os | sed -e 's|sunos6|solaris3|'`
+ ;;
+ -opened*)
+ os=-openedition
+ ;;
+ -os400*)
+ os=-os400
+ ;;
+ -wince*)
+ os=-wince
+ ;;
+ -osfrose*)
+ os=-osfrose
+ ;;
+ -osf*)
+ os=-osf
+ ;;
+ -utek*)
+ os=-bsd
+ ;;
+ -dynix*)
+ os=-bsd
+ ;;
+ -acis*)
+ os=-aos
+ ;;
+ -atheos*)
+ os=-atheos
+ ;;
+ -syllable*)
+ os=-syllable
+ ;;
+ -386bsd)
+ os=-bsd
+ ;;
+ -ctix* | -uts*)
+ os=-sysv
+ ;;
+ -nova*)
+ os=-rtmk-nova
+ ;;
+ -ns2 )
+ os=-nextstep2
+ ;;
+ -nsk*)
+ os=-nsk
+ ;;
+ # Preserve the version number of sinix5.
+ -sinix5.*)
+ os=`echo $os | sed -e 's|sinix|sysv|'`
+ ;;
+ -sinix*)
+ os=-sysv4
+ ;;
+ -tpf*)
+ os=-tpf
+ ;;
+ -triton*)
+ os=-sysv3
+ ;;
+ -oss*)
+ os=-sysv3
+ ;;
+ -svr4)
+ os=-sysv4
+ ;;
+ -svr3)
+ os=-sysv3
+ ;;
+ -sysvr4)
+ os=-sysv4
+ ;;
+ # This must come after -sysvr4.
+ -sysv*)
+ ;;
+ -ose*)
+ os=-ose
+ ;;
+ -es1800*)
+ os=-ose
+ ;;
+ -xenix)
+ os=-xenix
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ os=-mint
+ ;;
+ -aros*)
+ os=-aros
+ ;;
+ -zvmoe)
+ os=-zvmoe
+ ;;
+ -dicos*)
+ os=-dicos
+ ;;
+ -nacl*)
+ ;;
+ -none)
+ ;;
+ *)
+ # Get rid of the `-' at the beginning of $os.
+ os=`echo $os | sed 's/[^-]*-//'`
+ echo Invalid configuration \`$1\': system \`$os\' not recognized 1>&2
+ exit 1
+ ;;
+esac
+else
+
+# Here we handle the default operating systems that come with various machines.
+# The value should be what the vendor currently ships out the door with their
+# machine or put another way, the most popular os provided with the machine.
+
+# Note that if you're going to try to match "-MANUFACTURER" here (say,
+# "-sun"), then you have to tell the case statement up towards the top
+# that MANUFACTURER isn't an operating system. Otherwise, code above
+# will signal an error saying that MANUFACTURER isn't an operating
+# system, and we'll never get to this point.
+
+case $basic_machine in
+ score-*)
+ os=-elf
+ ;;
+ spu-*)
+ os=-elf
+ ;;
+ *-acorn)
+ os=-riscix1.2
+ ;;
+ arm*-rebel)
+ os=-linux
+ ;;
+ arm*-semi)
+ os=-aout
+ ;;
+ c4x-* | tic4x-*)
+ os=-coff
+ ;;
+ c8051-*)
+ os=-elf
+ ;;
+ hexagon-*)
+ os=-elf
+ ;;
+ tic54x-*)
+ os=-coff
+ ;;
+ tic55x-*)
+ os=-coff
+ ;;
+ tic6x-*)
+ os=-coff
+ ;;
+ # This must come before the *-dec entry.
+ pdp10-*)
+ os=-tops20
+ ;;
+ pdp11-*)
+ os=-none
+ ;;
+ *-dec | vax-*)
+ os=-ultrix4.2
+ ;;
+ m68*-apollo)
+ os=-domain
+ ;;
+ i386-sun)
+ os=-sunos4.0.2
+ ;;
+ m68000-sun)
+ os=-sunos3
+ ;;
+ m68*-cisco)
+ os=-aout
+ ;;
+ mep-*)
+ os=-elf
+ ;;
+ mips*-cisco)
+ os=-elf
+ ;;
+ mips*-*)
+ os=-elf
+ ;;
+ or32-*)
+ os=-coff
+ ;;
+ *-tti) # must be before sparc entry or we get the wrong os.
+ os=-sysv3
+ ;;
+ sparc-* | *-sun)
+ os=-sunos4.1.1
+ ;;
+ *-be)
+ os=-beos
+ ;;
+ *-haiku)
+ os=-haiku
+ ;;
+ *-ibm)
+ os=-aix
+ ;;
+ *-knuth)
+ os=-mmixware
+ ;;
+ *-wec)
+ os=-proelf
+ ;;
+ *-winbond)
+ os=-proelf
+ ;;
+ *-oki)
+ os=-proelf
+ ;;
+ *-hp)
+ os=-hpux
+ ;;
+ *-hitachi)
+ os=-hiux
+ ;;
+ i860-* | *-att | *-ncr | *-altos | *-motorola | *-convergent)
+ os=-sysv
+ ;;
+ *-cbm)
+ os=-amigaos
+ ;;
+ *-dg)
+ os=-dgux
+ ;;
+ *-dolphin)
+ os=-sysv3
+ ;;
+ m68k-ccur)
+ os=-rtu
+ ;;
+ m88k-omron*)
+ os=-luna
+ ;;
+ *-next )
+ os=-nextstep
+ ;;
+ *-sequent)
+ os=-ptx
+ ;;
+ *-crds)
+ os=-unos
+ ;;
+ *-ns)
+ os=-genix
+ ;;
+ i370-*)
+ os=-mvs
+ ;;
+ *-next)
+ os=-nextstep3
+ ;;
+ *-gould)
+ os=-sysv
+ ;;
+ *-highlevel)
+ os=-bsd
+ ;;
+ *-encore)
+ os=-bsd
+ ;;
+ *-sgi)
+ os=-irix
+ ;;
+ *-siemens)
+ os=-sysv4
+ ;;
+ *-masscomp)
+ os=-rtu
+ ;;
+ f30[01]-fujitsu | f700-fujitsu)
+ os=-uxpv
+ ;;
+ *-rom68k)
+ os=-coff
+ ;;
+ *-*bug)
+ os=-coff
+ ;;
+ *-apple)
+ os=-macos
+ ;;
+ *-atari*)
+ os=-mint
+ ;;
+ *)
+ os=-none
+ ;;
+esac
+fi
+
+# Here we handle the case where we know the os, and the CPU type, but not the
+# manufacturer. We pick the logical manufacturer.
+vendor=unknown
+case $basic_machine in
+ *-unknown)
+ case $os in
+ -riscix*)
+ vendor=acorn
+ ;;
+ -sunos*)
+ vendor=sun
+ ;;
+ -cnk*|-aix*)
+ vendor=ibm
+ ;;
+ -beos*)
+ vendor=be
+ ;;
+ -hpux*)
+ vendor=hp
+ ;;
+ -mpeix*)
+ vendor=hp
+ ;;
+ -hiux*)
+ vendor=hitachi
+ ;;
+ -unos*)
+ vendor=crds
+ ;;
+ -dgux*)
+ vendor=dg
+ ;;
+ -luna*)
+ vendor=omron
+ ;;
+ -genix*)
+ vendor=ns
+ ;;
+ -mvs* | -opened*)
+ vendor=ibm
+ ;;
+ -os400*)
+ vendor=ibm
+ ;;
+ -ptx*)
+ vendor=sequent
+ ;;
+ -tpf*)
+ vendor=ibm
+ ;;
+ -vxsim* | -vxworks* | -windiss*)
+ vendor=wrs
+ ;;
+ -aux*)
+ vendor=apple
+ ;;
+ -hms*)
+ vendor=hitachi
+ ;;
+ -mpw* | -macos*)
+ vendor=apple
+ ;;
+ -*mint | -mint[0-9]* | -*MiNT | -MiNT[0-9]*)
+ vendor=atari
+ ;;
+ -vos*)
+ vendor=stratus
+ ;;
+ esac
+ basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
+ ;;
+esac
+
+echo $basic_machine$os
+exit
+
+# Local variables:
+# eval: (add-hook 'write-file-hooks 'time-stamp)
+# time-stamp-start: "timestamp='"
+# time-stamp-format: "%:y-%02m-%02d"
+# time-stamp-end: "'"
+# End:
diff --git a/jni/ruby/tool/downloader.rb b/jni/ruby/tool/downloader.rb
new file mode 100644
index 0000000..8f169d5
--- /dev/null
+++ b/jni/ruby/tool/downloader.rb
@@ -0,0 +1,178 @@
+require 'open-uri'
+begin
+ require 'net/https'
+ $rubygems_schema = 'https'
+
+ # open-uri of ruby 2.2.0 accept an array of PEMs as ssl_ca_cert, but old
+ # versions are not. so, patching OpenSSL::X509::Store#add_file instead.
+ class OpenSSL::X509::Store
+ alias orig_add_file add_file
+ def add_file(pems)
+ Array(pems).each do |pem|
+ if File.directory?(pem)
+ add_path pem
+ else
+ orig_add_file pem
+ end
+ end
+ end
+ end
+ # since open-uri internally checks ssl_ca_cert by File.directory?, to allow
+ # accept an array.
+ class <<File
+ alias orig_directory? directory?
+ def File.directory? files
+ files.is_a?(Array) ? false : orig_directory?(files)
+ end
+ end
+rescue LoadError
+ $rubygems_schema = 'http'
+end
+
+class Downloader
+ class GNU < self
+ def self.download(name, *rest)
+ super("http://gcc.gnu.org/git/?p=gcc.git;a=blob_plain;f=#{name};hb=master", name, *rest)
+ end
+ end
+
+ class RubyGems < self
+ def self.download(name, dir = nil, ims = true, options = {})
+ options[:ssl_ca_cert] = Dir.glob(File.expand_path("../lib/rubygems/ssl_certs/*.pem", File.dirname(__FILE__)))
+ if $rubygems_schema != 'https'
+ warn "*** using http instead of https ***"
+ end
+ super("#{$rubygems_schema}://rubygems.org/downloads/#{name}", name, dir, ims, options)
+ end
+ end
+
+ Gems = RubyGems
+
+ class Unicode < self
+ def self.download(name, *rest)
+ super("http://www.unicode.org/Public/#{name}", name, *rest)
+ end
+ end
+
+ def self.mode_for(data)
+ /\A#!/ =~ data ? 0755 : 0644
+ end
+
+ def self.http_options(file, since)
+ options = {}
+ if since
+ case since
+ when true
+ since = (File.mtime(file).httpdate rescue nil)
+ when Time
+ since = since.httpdate
+ end
+ if since
+ options['If-Modified-Since'] = since
+ end
+ end
+ options
+ end
+
+ # Downloader.download(url, name, [dir, [ims]])
+ #
+ # Update a file from url if newer version is available.
+ # Creates the file if the file doesn't yet exist; however, the
+ # directory where the file is being created has to exist already.
+ # If +ims+ is false, always download url regardless of its last
+ # modified time.
+ #
+ # Example usage:
+ # download 'http://www.unicode.org/Public/UCD/latest/ucd/UnicodeData.txt',
+ # 'UnicodeData.txt', 'enc/unicode/data'
+ def self.download(url, name, dir = nil, ims = true, options = {})
+ file = dir ? File.join(dir, File.basename(name)) : name
+ if ims.nil? and File.exist?(file)
+ if $VERBOSE
+ $stdout.puts "#{name} already exists"
+ $stdout.flush
+ end
+ return true
+ end
+ url = URI(url)
+ if $VERBOSE
+ $stdout.print "downloading #{name} ... "
+ $stdout.flush
+ end
+ begin
+ data = url.read(options.merge(http_options(file, ims.nil? ? true : ims)))
+ rescue OpenURI::HTTPError => http_error
+ if http_error.message =~ /^304 / # 304 Not Modified
+ if $VERBOSE
+ $stdout.puts "not modified"
+ $stdout.flush
+ end
+ return true
+ end
+ raise
+ rescue Timeout::Error
+ if ims.nil? and File.exist?(file)
+ puts "Request for #{url} timed out, using old version."
+ return true
+ end
+ raise
+ rescue SocketError
+ if ims.nil? and File.exist?(file)
+ puts "No network connection, unable to download #{url}, using old version."
+ return true
+ end
+ raise
+ end
+ mtime = nil
+ open(file, "wb", 0600) do |f|
+ f.write(data)
+ f.chmod(mode_for(data))
+ mtime = data.meta["last-modified"]
+ end
+ if mtime
+ mtime = Time.httpdate(mtime)
+ File.utime(mtime, mtime, file)
+ end
+ if $VERBOSE
+ $stdout.puts "done"
+ $stdout.flush
+ end
+ true
+ rescue => e
+ raise "failed to download #{name}\n#{e.message}: #{url}"
+ end
+end
+
+if $0 == __FILE__
+ ims = true
+ until ARGV.empty?
+ case ARGV[0]
+ when '-d'
+ destdir = ARGV[1]
+ ARGV.shift
+ when '-e'
+ ims = nil
+ when '-a'
+ ims = true
+ when /\A-/
+ abort "#{$0}: unknown option #{ARGV[0]}"
+ else
+ break
+ end
+ ARGV.shift
+ end
+ dl = Downloader.constants.find do |name|
+ ARGV[0].casecmp(name.to_s) == 0
+ end unless ARGV.empty?
+ $VERBOSE = true
+ if dl
+ dl = Downloader.const_get(dl)
+ ARGV.shift
+ ARGV.each do |name|
+ dl.download(name, destdir, ims)
+ end
+ else
+ abort "usage: #{$0} url name" unless ARGV.size == 2
+ Downloader.download(ARGV[0], ARGV[1], destdir, ims)
+ end
+end
diff --git a/jni/ruby/tool/enc-emoji-citrus-gen.rb b/jni/ruby/tool/enc-emoji-citrus-gen.rb
new file mode 100644
index 0000000..5037cbd
--- /dev/null
+++ b/jni/ruby/tool/enc-emoji-citrus-gen.rb
@@ -0,0 +1,131 @@
+require File.expand_path('../jisx0208', __FILE__)
+
+ENCODES = [
+ {
+ :name => "SHIFT_JIS-DOCOMO",
+ :src_zone => [0xF8..0xFC, 0x40..0xFC, 8],
+ :dst_ilseq => 0xFFFE,
+ :map => [
+ [0xE63E..0xE757, JISX0208::Char.from_sjis(0xF89F)],
+ ],
+ },
+ {
+ :name => "ISO-2022-JP-KDDI",
+ :src_zone => [0x21..0x7E, 0x21..0x7E, 8],
+ :dst_ilseq => 0xFFFE,
+ :map => [
+ [0xE468..0xE5B4, JISX0208::Char.new(0x7521)],
+ [0xE5B5..0xE5CC, JISX0208::Char.new(0x7867)],
+ [0xE5CD..0xE5DF, JISX0208::Char.new(0x7921)],
+ [0xEA80..0xEAFA, JISX0208::Char.new(0x7934)],
+ [0xEAFB..0xEB0D, JISX0208::Char.new(0x7854)],
+ [0xEB0E..0xEB8E, JISX0208::Char.new(0x7A51)],
+ ],
+ },
+ {
+ :name => "SHIFT_JIS-KDDI",
+ :src_zone => [0xF3..0xFC, 0x40..0xFC, 8],
+ :dst_ilseq => 0xFFFE,
+ :map => [
+ [0xE468..0xE5B4, JISX0208::Char.from_sjis(0xF640)],
+ [0xE5B5..0xE5CC, JISX0208::Char.from_sjis(0xF7E5)],
+ [0xE5CD..0xE5DF, JISX0208::Char.from_sjis(0xF340)],
+ [0xEA80..0xEAFA, JISX0208::Char.from_sjis(0xF353)],
+ [0xEAFB..0xEB0D, JISX0208::Char.from_sjis(0xF7D2)],
+ [0xEB0E..0xEB8E, JISX0208::Char.from_sjis(0xF3CF)],
+ ],
+ },
+ {
+ :name => "SHIFT_JIS-SOFTBANK",
+ :src_zone => [0xF3..0xFC, 0x40..0xFC, 8],
+ :dst_ilseq => 0xFFFE,
+ :map => [
+ [0xE001..0xE05A, JISX0208::Char.from_sjis(0xF941)],
+ [0xE101..0xE15A, JISX0208::Char.from_sjis(0xF741)],
+ [0xE201..0xE25A, JISX0208::Char.from_sjis(0xF7A1)],
+ [0xE301..0xE34D, JISX0208::Char.from_sjis(0xF9A1)],
+ [0xE401..0xE44C, JISX0208::Char.from_sjis(0xFB41)],
+ [0xE501..0xE53E, JISX0208::Char.from_sjis(0xFBA1)],
+ ],
+ },
+]
+
+def zone(*args)
+ bits = args.pop
+ [*args.map{|range| "0x%02X-0x%02X" % [range.begin, range.end] }, bits].join(' / ')
+end
+
+def header(params)
+ (<<END_HEADER_TEMPLATE % [params[:name], zone(*params[:src_zone]), params[:dst_ilseq]])
+# DO NOT EDIT THIS FILE DIRECTLY
+
+TYPE ROWCOL
+NAME %s
+SRC_ZONE %s
+OOB_MODE ILSEQ
+DST_ILSEQ 0x%04X
+DST_UNIT_BITS 16
+END_HEADER_TEMPLATE
+end
+
+def generate_to_ucs(params, pairs)
+ pairs.sort_by! {|u, c| c }
+ name = "EMOJI_#{params[:name]}%UCS"
+ open("#{name}.src", "w") do |io|
+ io.print header(params.merge(name: name.tr('%', '/')))
+ io.puts
+ io.puts "BEGIN_MAP"
+ io.print pairs.inject("") {|acc, uc| acc += "0x%04X = 0x%04X\n" % uc.reverse }
+ io.puts "END_MAP"
+ end
+end
+
+def generate_from_ucs(params, pairs)
+ pairs.sort_by! {|u, c| u }
+ name = "UCS%EMOJI_#{params[:name]}"
+ open("#{name}.src", "w") do |io|
+ io.print header(params.merge(name: name.tr('%', '/')))
+ io.puts
+ io.puts "BEGIN_MAP"
+ io.print pairs.inject("") {|acc, uc| acc += "0x%04X = 0x%04X\n" % uc }
+ io.puts "END_MAP"
+ end
+end
+
+def make_pairs(code_map)
+ pairs = code_map.inject([]) {|acc, (range, ch)|
+ acc += range.map{|uni| pair = [uni, Integer(ch)]; ch = ch.succ; next pair }
+ }
+end
+
+ENCODES.each do |params|
+ pairs = make_pairs(params[:map], &params[:conv])
+ generate_to_ucs(params, pairs)
+ generate_from_ucs(params, pairs)
+end
+
+# generate KDDI-UNDOC for Shift_JIS-KDDI
+kddi_sjis_map = ENCODES.select{|enc| enc[:name] == "SHIFT_JIS-KDDI"}.first[:map]
+pairs = kddi_sjis_map.inject([]) {|acc, (range, ch)|
+ acc += range.map{|uni| pair = [ch.to_sjis - 0x700, Integer(ch)]; ch = ch.succ; next pair }
+}
+params = {
+ :name => "SHIFT_JIS-KDDI-UNDOC",
+ :src_zone => [0xF3..0xFC, 0x40..0xFC, 8],
+ :dst_ilseq => 0xFFFE,
+}
+generate_from_ucs(params, pairs)
+generate_to_ucs(params, pairs)
+
+# generate KDDI-UNDOC for ISO-2022-JP-KDDI
+kddi_2022_map = ENCODES.select{|enc| enc[:name] == "ISO-2022-JP-KDDI"}.first[:map]
+pairs = kddi_2022_map.each_with_index.inject([]) {|acc, ((range, ch), i)|
+ sjis = kddi_sjis_map[i][1]
+ acc += range.map{|uni| pair = [sjis.to_sjis - 0x700, Integer(ch)]; ch = ch.succ; sjis = sjis.succ; next pair }
+}
+params = {
+ :name => "ISO-2022-JP-KDDI-UNDOC",
+ :src_zone => [0x21..0x7E, 0x21..0x7E, 8],
+ :dst_ilseq => 0xFFFE,
+}
+generate_from_ucs(params, pairs)
diff --git a/jni/ruby/tool/enc-emoji4unicode.rb b/jni/ruby/tool/enc-emoji4unicode.rb
new file mode 100644
index 0000000..1e7d459
--- /dev/null
+++ b/jni/ruby/tool/enc-emoji4unicode.rb
@@ -0,0 +1,133 @@
+#!/usr/bin/env ruby
+
+# example:
+# ./enc-emoji4unicode.rb emoji4unicode.xml > ../enc/trans/emoji-exchange-tbl.rb
+
+require 'rexml/document'
+require File.expand_path("../transcode-tblgen", __FILE__)
+
+class EmojiTable
+ VERBOSE_MODE = false
+
+ def initialize(xml_path)
+ @doc = REXML::Document.new File.open(xml_path)
+ @kddi_undoc = make_kddi_undoc_map()
+ end
+
+ def conversion(from_carrier, to_carrier, &block)
+ REXML::XPath.each(@doc.root, '//e') do |e|
+ from = e.attribute(from_carrier.downcase).to_s
+ to = e.attribute(to_carrier.downcase).to_s
+ text_fallback = e.attribute('text_fallback').to_s
+ name = e.attribute('name').to_s
+ if from =~ /^(?:\*|\+)(.+)$/ # proposed or unified
+ from = $1
+ end
+ if from.empty? || from !~ /^[0-9A-F]+$/
+ # do nothing
+ else
+ from_utf8 = [from.hex].pack("U").unpack("H*").first
+ if to =~ /^(?:&gt;|\*)?([0-9A-F\+]+)$/
+ str_to = $1
+ if str_to =~ /^\+/ # unicode "proposed" begins at "+"
+ proposal = true
+ str_to.sub!(/^\+/, '')
+ else
+ proposal = false
+ end
+ tos = str_to.split('+')
+ to_utf8 = tos.map(&:hex).pack("U*").unpack("H*").first
+ comment = "[%s] U+%X -> %s" % [name, from.hex, tos.map{|c| "U+%X"%c.hex}.join(' ')]
+ block.call(:from => from_utf8,
+ :to => to_utf8,
+ :comment => comment,
+ :fallback => false,
+ :proposal => proposal)
+ elsif to.empty?
+ if text_fallback.empty?
+ comment = "[%s] U+%X -> U+3013 (GETA)" % [name, from.hex]
+ block.call(:from => from_utf8,
+ :to => "\u{3013}".unpack("H*").first,
+ :comment => comment, # geta
+ :fallback => true,
+ :proposal => false)
+ else
+ to_utf8 = text_fallback.unpack("H*").first
+ comment = %([%s] U+%X -> "%s") % [name, from.hex, text_fallback]
+ block.call(:from => from_utf8,
+ :to => to_utf8,
+ :comment => comment,
+ :fallback => true,
+ :proposal => false)
+ end
+ else
+ raise "something wrong: %s -> %s" % [from, to]
+ end
+ end
+ end
+ end
+
+ def generate(io, from_carrier, to_carrier)
+ from_encoding = (from_carrier == "Unicode") ? "UTF-8" : "UTF8-"+from_carrier
+ to_encoding = (to_carrier == "Unicode" ) ? "UTF-8" : "UTF8-"+to_carrier
+ io.puts "EMOJI_EXCHANGE_TBL['#{from_encoding}']['#{to_encoding}'] = ["
+ io.puts " # for documented codepoints" if from_carrier == "KDDI"
+ self.conversion(from_carrier, to_carrier) do |params|
+ from, to = params[:from], %Q{"#{params[:to]}"}
+ to = ":undef" if params[:fallback] || params[:proposal]
+ io.puts %{ ["#{from}", #{to}], # #{params[:comment]}}
+ end
+ if from_carrier == "KDDI"
+ io.puts " # for undocumented codepoints"
+ self.conversion(from_carrier, to_carrier) do |params|
+ from, to = params[:from], %Q{"#{params[:to]}"}
+ to = ":undef" if params[:fallback] || params[:proposal]
+ unicode = utf8_to_ucs(from)
+ undoc = ucs_to_utf8(@kddi_undoc[unicode])
+ io.puts %{ ["#{undoc}", #{to}], # #{params[:comment]}}
+ end
+ end
+ io.puts "]"
+ io.puts
+ end
+
+ private
+
+ def utf8_to_ucs(cp)
+ return [cp].pack("H*").unpack("U*").first
+ end
+
+ def ucs_to_utf8(cp)
+ return [cp].pack("U*").unpack("H*").first
+ end
+
+ def make_kddi_undoc_map()
+ pub_to_sjis = citrus_decode_mapsrc(
+ "mskanji", 2, "UCS/EMOJI_SHIFT_JIS-KDDI").sort_by{|u, s| s}
+ sjis_to_undoc = citrus_decode_mapsrc(
+ "mskanji", 2, "EMOJI_SHIFT_JIS-KDDI-UNDOC/UCS").sort_by{|s, u| s}
+ return pub_to_sjis.zip(sjis_to_undoc).inject({}) {|h, rec|
+ raise "no match sjis codepoint" if rec[0][1] != rec[1][0]
+ h[rec[0][0]] = rec[1][1]
+ next h
+ }
+ end
+end
+
+if ARGV.empty?
+ puts "usage: #$0 [emoji4unicode.xml]"
+ exit 1
+end
+$srcdir = File.expand_path("../../enc/trans", __FILE__)
+emoji_table = EmojiTable.new(ARGV[0])
+
+companies = %w(DoCoMo KDDI SoftBank Unicode)
+
+io = STDOUT
+io.puts "EMOJI_EXCHANGE_TBL = Hash.new{|h,k| h[k] = {}}"
+companies.each do |from_company|
+ companies.each do |to_company|
+ next if from_company == to_company
+ emoji_table.generate(io, from_company, to_company)
+ end
+end
diff --git a/jni/ruby/tool/enc-unicode.rb b/jni/ruby/tool/enc-unicode.rb
new file mode 100755
index 0000000..38140ab
--- /dev/null
+++ b/jni/ruby/tool/enc-unicode.rb
@@ -0,0 +1,371 @@
+#!/usr/bin/env ruby
+
+# Creates the data structures needed by Onigurma to map Unicode codepoints to
+# property names and POSIX character classes
+#
+# To use this, get UnicodeData.txt, Scripts.txt, PropList.txt,
+# PropertyAliases.txt, PropertyValueAliases.txt, DerivedCoreProperties.txt,
+# DerivedAge.txt and Blocks.txt from unicode.org.
+# (http://unicode.org/Public/UNIDATA/) And run following command.
+# ruby1.9 tool/enc-unicode.rb data_dir > enc/unicode/name2ctype.kwd
+# You can get source file for gperf. After this, simply make ruby.
+
+unless ARGV.size == 1
+ $stderr.puts "Usage: #{$0} data_directory"
+ exit(1)
+end
+
+POSIX_NAMES = %w[NEWLINE Alpha Blank Cntrl Digit Graph Lower Print Punct Space Upper XDigit Word Alnum ASCII]
+
+def pair_codepoints(codepoints)
+
+ # We have a sorted Array of codepoints that we wish to partition into
+ # ranges such that the start- and endpoints form an inclusive set of
+ # codepoints with property _property_. Note: It is intended that some ranges
+ # will begin with the value with which they end, e.g. 0x0020 -> 0x0020
+
+ codepoints.sort!
+ last_cp = codepoints.first
+ pairs = [[last_cp, nil]]
+ codepoints[1..-1].each do |codepoint|
+ next if last_cp == codepoint
+
+ # If the current codepoint does not follow directly on from the last
+ # codepoint, the last codepoint represents the end of the current range,
+ # and the current codepoint represents the start of the next range.
+ if last_cp.next != codepoint
+ pairs[-1][-1] = last_cp
+ pairs << [codepoint, nil]
+ end
+ last_cp = codepoint
+ end
+
+ # The final pair has as its endpoint the last codepoint for this property
+ pairs[-1][-1] = codepoints.last
+ pairs
+end
+
+def parse_unicode_data(file)
+ last_cp = 0
+ data = {'Any' => (0x0000..0x10ffff).to_a, 'Assigned' => [],
+ 'ASCII' => (0..0x007F).to_a, 'NEWLINE' => [0x0a], 'Cn' => []}
+ beg_cp = nil
+ IO.foreach(file) do |line|
+ fields = line.split(';')
+ cp = fields[0].to_i(16)
+
+ case fields[1]
+ when /\A<(.*),\s*First>\z/
+ beg_cp = cp
+ next
+ when /\A<(.*),\s*Last>\z/
+ cps = (beg_cp..cp).to_a
+ else
+ beg_cp = cp
+ cps = [cp]
+ end
+
+ # The Cn category represents unassigned characters. These are not listed in
+ # UnicodeData.txt so we must derive them by looking for 'holes' in the range
+ # of listed codepoints. We increment the last codepoint seen and compare it
+ # with the current codepoint. If the current codepoint is less than
+ # last_cp.next we have found a hole, so we add the missing codepoint to the
+ # Cn category.
+ data['Cn'].concat((last_cp.next...beg_cp).to_a)
+
+ # Assigned - Defined in unicode.c; interpreted as every character in the
+ # Unicode range minus the unassigned characters
+ data['Assigned'].concat(cps)
+
+ # The third field denotes the 'General' category, e.g. Lu
+ (data[fields[2]] ||= []).concat(cps)
+
+ # The 'Major' category is the first letter of the 'General' category, e.g.
+ # 'Lu' -> 'L'
+ (data[fields[2][0,1]] ||= []).concat(cps)
+ last_cp = cp
+ end
+
+ # The last Cn codepoint should be 0x10ffff. If it's not, append the missing
+ # codepoints to Cn and C
+ cn_remainder = (last_cp.next..0x10ffff).to_a
+ data['Cn'] += cn_remainder
+ data['C'] += data['Cn']
+
+ # Special case for LC (Cased_Letter). LC = Ll + Lt + Lu
+ data['LC'] = data['Ll'] + data['Lt'] + data['Lu']
+
+ # Define General Category properties
+ gcps = data.keys.sort - POSIX_NAMES
+
+ # Returns General Category Property names and the data
+ [gcps, data]
+end
+
+def define_posix_props(data)
+ # We now derive the character classes (POSIX brackets), e.g. [[:alpha:]]
+ #
+
+ data['Alpha'] = data['Alphabetic']
+ data['Upper'] = data['Uppercase']
+ data['Lower'] = data['Lowercase']
+ data['Punct'] = data['Punctuation']
+ data['Digit'] = data['Decimal_Number']
+ data['XDigit'] = (0x0030..0x0039).to_a + (0x0041..0x0046).to_a +
+ (0x0061..0x0066).to_a
+ data['Alnum'] = data['Alpha'] + data['Digit']
+ data['Space'] = data['White_Space']
+ data['Blank'] = data['Space_Separator'] + [0x0009]
+ data['Cntrl'] = data['Cc']
+ data['Word'] = data['Alpha'] + data['Mark'] + data['Digit'] + data['Connector_Punctuation']
+ data['Graph'] = data['Any'] - data['Space'] - data['Cntrl'] -
+ data['Surrogate'] - data['Unassigned']
+ data['Print'] = data['Graph'] + data['Space_Separator']
+end
+
+def parse_scripts(data, categories)
+ files = [
+ {:fn => 'DerivedCoreProperties.txt', :title => 'Derived Property'},
+ {:fn => 'Scripts.txt', :title => 'Script'},
+ {:fn => 'PropList.txt', :title => 'Binary Property'}
+ ]
+ current = nil
+ cps = []
+ names = {}
+ files.each do |file|
+ IO.foreach(get_file(file[:fn])) do |line|
+ if /^# Total code points: / =~ line
+ data[current] = cps
+ categories[current] = file[:title]
+ (names[file[:title]] ||= []) << current
+ cps = []
+ elsif /^([0-9a-fA-F]+)(?:..([0-9a-fA-F]+))?\s*;\s*(\w+)/ =~ line
+ current = $3
+ $2 ? cps.concat(($1.to_i(16)..$2.to_i(16)).to_a) : cps.push($1.to_i(16))
+ end
+ end
+ end
+ # All code points not explicitly listed for Script
+ # have the value Unknown (Zzzz).
+ data['Unknown'] = (0..0x10ffff).to_a - data.values_at(*names['Script']).flatten
+ categories['Unknown'] = 'Script'
+ names.values.flatten << 'Unknown'
+end
+
+def parse_aliases(data)
+ kv = {}
+ IO.foreach(get_file('PropertyAliases.txt')) do |line|
+ next unless /^(\w+)\s*; (\w+)/ =~ line
+ data[$1] = data[$2]
+ kv[normalize_propname($1)] = normalize_propname($2)
+ end
+ IO.foreach(get_file('PropertyValueAliases.txt')) do |line|
+ next unless /^(sc|gc)\s*; (\w+)\s*; (\w+)(?:\s*; (\w+))?/ =~ line
+ if $1 == 'gc'
+ data[$3] = data[$2]
+ data[$4] = data[$2]
+ kv[normalize_propname($3)] = normalize_propname($2)
+ kv[normalize_propname($4)] = normalize_propname($2) if $4
+ else
+ data[$2] = data[$3]
+ data[$4] = data[$3]
+ kv[normalize_propname($2)] = normalize_propname($3)
+ kv[normalize_propname($4)] = normalize_propname($3) if $4
+ end
+ end
+ kv
+end
+
+# According to Unicode6.0.0/ch03.pdf, Section 3.1, "An update version
+# never involves any additions to the character repertoire." Versions
+# in DerivedAge.txt should always be /\d+\.\d+/
+def parse_age(data)
+ current = nil
+ last_constname = nil
+ cps = []
+ ages = []
+ IO.foreach(get_file('DerivedAge.txt')) do |line|
+ if /^# Total code points: / =~ line
+ constname = constantize_agename(current)
+ # each version matches all previous versions
+ cps.concat(data[last_constname]) if last_constname
+ data[constname] = cps
+ make_const(constname, cps, "Derived Age #{current}")
+ ages << current
+ last_constname = constname
+ cps = []
+ elsif /^([0-9a-fA-F]+)(?:..([0-9a-fA-F]+))?\s*;\s*(\d+\.\d+)/ =~ line
+ current = $3
+ $2 ? cps.concat(($1.to_i(16)..$2.to_i(16)).to_a) : cps.push($1.to_i(16))
+ end
+ end
+ ages
+end
+
+def parse_block(data)
+ current = nil
+ last_constname = nil
+ cps = []
+ blocks = []
+ IO.foreach(get_file('Blocks.txt')) do |line|
+ if /^([0-9a-fA-F]+)\.\.([0-9a-fA-F]+);\s*(.*)/ =~ line
+ cps = ($1.to_i(16)..$2.to_i(16)).to_a
+ constname = constantize_blockname($3)
+ data[constname] = cps
+ make_const(constname, cps, "Block")
+ blocks << constname
+ end
+ end
+
+ # All code points not belonging to any of the named blocks
+ # have the value No_Block.
+ no_block = (0..0x10ffff).to_a - data.values_at(*blocks).flatten
+ constname = constantize_blockname("No_Block")
+ make_const(constname, no_block, "Block")
+ blocks << constname
+end
+
+# shim for Ruby 1.8
+unless {}.respond_to?(:key)
+ class Hash
+ alias key index
+ end
+end
+
+$const_cache = {}
+# make_const(property, pairs, name): Prints a 'static const' structure for a
+# given property, group of paired codepoints, and a human-friendly name for
+# the group
+def make_const(prop, data, name)
+ puts "\n/* '#{prop}': #{name} */"
+ if origprop = $const_cache.key(data)
+ puts "#define CR_#{prop} CR_#{origprop}"
+ else
+ $const_cache[prop] = data
+ pairs = pair_codepoints(data)
+ puts "static const OnigCodePoint CR_#{prop}[] = {"
+ # The first element of the constant is the number of pairs of codepoints
+ puts "\t#{pairs.size},"
+ pairs.each do |pair|
+ pair.map! { |c| c == 0 ? '0x0000' : sprintf("%0#6x", c) }
+ puts "\t#{pair.first}, #{pair.last},"
+ end
+ puts "}; /* CR_#{prop} */"
+ end
+end
+
+def normalize_propname(name)
+ name = name.downcase
+ name.delete!('- _')
+ name
+end
+
+def constantize_agename(name)
+ "Age_#{name.sub(/\./, '_')}"
+end
+
+def constantize_blockname(name)
+ "In_#{name.gsub(/\W/, '_')}"
+end
+
+def get_file(name)
+ File.join(ARGV[0], name)
+end
+
+
+# Write Data
+puts '%{'
+puts '#define long size_t'
+props, data = parse_unicode_data(get_file('UnicodeData.txt'))
+categories = {}
+props.concat parse_scripts(data, categories)
+aliases = parse_aliases(data)
+define_posix_props(data)
+POSIX_NAMES.each do |name|
+ make_const(name, data[name], "[[:#{name}:]]")
+end
+print "\n#ifdef USE_UNICODE_PROPERTIES"
+props.each do |name|
+ category = categories[name] ||
+ case name.size
+ when 1 then 'Major Category'
+ when 2 then 'General Category'
+ else '-'
+ end
+ make_const(name, data[name], category)
+end
+print "\n#ifdef USE_UNICODE_AGE_PROPERTIES"
+ages = parse_age(data)
+puts "#endif /* USE_UNICODE_AGE_PROPERTIES */"
+blocks = parse_block(data)
+puts '#endif /* USE_UNICODE_PROPERTIES */'
+puts(<<'__HEREDOC')
+
+static const OnigCodePoint* const CodeRanges[] = {
+__HEREDOC
+POSIX_NAMES.each{|name|puts" CR_#{name},"}
+puts "#ifdef USE_UNICODE_PROPERTIES"
+props.each{|name| puts" CR_#{name},"}
+puts "#ifdef USE_UNICODE_AGE_PROPERTIES"
+ages.each{|name| puts" CR_#{constantize_agename(name)},"}
+puts "#endif /* USE_UNICODE_AGE_PROPERTIES */"
+blocks.each{|name|puts" CR_#{name},"}
+
+puts(<<'__HEREDOC')
+#endif /* USE_UNICODE_PROPERTIES */
+};
+struct uniname2ctype_struct {
+ int name, ctype;
+};
+
+static const struct uniname2ctype_struct *uniname2ctype_p(const char *, unsigned int);
+%}
+struct uniname2ctype_struct;
+%%
+__HEREDOC
+i = -1
+name_to_index = {}
+POSIX_NAMES.each do |name|
+ i += 1
+ next if name == 'NEWLINE'
+ name = normalize_propname(name)
+ name_to_index[name] = i
+ puts"%-40s %3d" % [name + ',', i]
+end
+puts "#ifdef USE_UNICODE_PROPERTIES"
+props.each do |name|
+ i += 1
+ name = normalize_propname(name)
+ name_to_index[name] = i
+ puts "%-40s %3d" % [name + ',', i]
+end
+aliases.each_pair do |k, v|
+ next if name_to_index[k]
+ next unless v = name_to_index[v]
+ puts "%-40s %3d" % [k + ',', v]
+end
+puts "#ifdef USE_UNICODE_AGE_PROPERTIES"
+ages.each do |name|
+ i += 1
+ name = "age=#{name}"
+ name_to_index[name] = i
+ puts "%-40s %3d" % [name + ',', i]
+end
+puts "#endif /* USE_UNICODE_AGE_PROPERTIES */"
+blocks.each do |name|
+ i += 1
+ name = normalize_propname(name)
+ name_to_index[name] = i
+ puts "%-40s %3d" % [name + ',', i]
+end
+puts(<<'__HEREDOC')
+#endif /* USE_UNICODE_PROPERTIES */
+%%
+static int
+uniname2ctype(const UChar *name, unsigned int len)
+{
+ const struct uniname2ctype_struct *p = uniname2ctype_p((const char *)name, len);
+ if (p) return p->ctype;
+ return -1;
+}
+__HEREDOC
diff --git a/jni/ruby/tool/eval.rb b/jni/ruby/tool/eval.rb
new file mode 100644
index 0000000..18e645a
--- /dev/null
+++ b/jni/ruby/tool/eval.rb
@@ -0,0 +1,159 @@
+
+require './rbconfig'
+require 'fileutils'
+require 'pp'
+
+Ruby = ENV['RUBY'] || RbConfig.ruby
+#
+
+OPTIONS = %w{
+ opt-direct-threaded-code
+ opt-basic-operations
+ opt-operands-unification
+ opt-instructions-unification
+ opt-inline-method-cache
+ opt-stack-caching
+}.map{|opt|
+ '--disable-' + opt
+}
+
+opts = OPTIONS.dup
+Configs = OPTIONS.map{|opt|
+ o = opts.dup
+ opts.delete(opt)
+ o
+} + [[]]
+
+pp Configs if $DEBUG
+
+
+def exec_cmd(cmd)
+ puts cmd
+ unless system(cmd)
+ p cmd
+ raise "error"
+ end
+end
+
+def dirname idx
+ "ev-#{idx}"
+end
+
+def build
+ Configs.each_with_index{|config, idx|
+ dir = dirname(idx)
+ FileUtils.rm_rf(dir) if FileTest.exist?(dir)
+ Dir.mkdir(dir)
+ FileUtils.cd(dir){
+ exec_cmd("#{Ruby} ../extconf.rb " + config.join(" "))
+ exec_cmd("make clean test-all")
+ }
+ }
+end
+
+def check
+ Configs.each_with_index{|c, idx|
+ puts "= #{idx}"
+ system("#{Ruby} -r ev-#{idx}/yarvcore -e 'puts YARVCore::OPTS'")
+ }
+end
+
+def bench_each idx
+ puts "= #{idx}"
+ 5.times{|count|
+ print count
+ FileUtils.cd(dirname(idx)){
+ exec_cmd("make benchmark OPT=-y ITEMS=#{ENV['ITEMS']} > ../b#{idx}-#{count}")
+ }
+ }
+ puts
+end
+
+def bench
+ # return bench_each(6)
+ Configs.each_with_index{|c, idx|
+ bench_each idx
+ }
+end
+
+def parse_result data
+ flag = false
+ stat = []
+ data.each{|line|
+ if flag
+ if /(\w+)\t([\d\.]+)/ =~ line
+ stat << [$1, $2.to_f]
+ else
+ raise "not a data"
+ end
+
+ end
+ if /benchmark summary/ =~ line
+ flag = true
+ end
+ }
+ stat
+end
+
+def calc_each data
+ data.sort!
+ data.pop # remove max
+ data.shift # remove min
+
+ data.inject(0.0){|res, e|
+ res += e
+ } / data.size
+end
+
+def calc_stat stats
+ stat = []
+ stats[0].each_with_index{|e, idx|
+ bm = e[0]
+ vals = stats.map{|st|
+ st[idx][1]
+ }
+ [bm, calc_each(vals)]
+ }
+end
+
+def stat
+ total = []
+ Configs.each_with_index{|c, idx|
+ stats = []
+ 5.times{|count|
+ file = "b#{idx}-#{count}"
+ # p file
+ open(file){|f|
+ stats << parse_result(f.read)
+ }
+ }
+ # merge stats
+ total << calc_stat(stats)
+ total
+ }
+ # pp total
+ total[0].each_with_index{|e, idx|
+ bm = e[0]
+ # print "#{bm}\t"
+ total.each{|st|
+ print st[idx][1], "\t"
+ }
+ puts
+ }
+end
+
+ARGV.each{|cmd|
+ case cmd
+ when 'build'
+ build
+ when 'check'
+ check
+ when 'bench'
+ bench
+ when 'stat'
+ stat
+ else
+ raise
+ end
+}
+
diff --git a/jni/ruby/tool/expand-config.rb b/jni/ruby/tool/expand-config.rb
new file mode 100755
index 0000000..fb2edd0
--- /dev/null
+++ b/jni/ruby/tool/expand-config.rb
@@ -0,0 +1,7 @@
+STDOUT.binmode
+ARGF.each do |line|
+ line.gsub!(/@([a-z_]\w*)@/i) {
+ (RbConfig::MAKEFILE_CONFIG[$1] or "").gsub(/\$\((.+?)\)/, %Q[${\\1}])
+ }
+ puts line
+end
diff --git a/jni/ruby/tool/extlibs.rb b/jni/ruby/tool/extlibs.rb
new file mode 100755
index 0000000..09db055
--- /dev/null
+++ b/jni/ruby/tool/extlibs.rb
@@ -0,0 +1,143 @@
+#!/usr/bin/ruby
+require 'fileutils'
+require 'digest'
+require_relative 'downloader'
+
+cache_dir = ".downloaded-cache"
+FileUtils.mkdir_p(cache_dir)
+
+def do_download(url, base, cache_dir)
+ Downloader.download(url, base, cache_dir, nil)
+end
+
+def do_checksum(cache, chksums)
+ chksums.each do |sum|
+ name, sum = sum.split(/:/)
+ if $VERBOSE
+ $stdout.print "checking #{name} of #{cache} ..."
+ $stdout.flush
+ end
+ hd = Digest(name.upcase).file(cache).hexdigest
+ if hd == sum
+ if $VERBOSE
+ $stdout.puts " OK"
+ $stdout.flush
+ end
+ else
+ if $VERBOSE
+ $stdout.puts " NG"
+ $stdout.flush
+ end
+ raise "checksum mismatch: #{cache}, #{name}:#{hd}, expected #{sum}"
+ end
+ end
+end
+
+def do_extract(cache, dir)
+ if $VERBOSE
+ $stdout.puts "extracting #{cache} into #{dir}"
+ $stdout.flush
+ end
+ ext = File.extname(cache)
+ case ext
+ when '.gz', '.tgz'
+ f = IO.popen(["gzip", "-dc", cache])
+ cache = cache.chomp('.gz')
+ when '.bz2', '.tbz'
+ f = IO.popen(["bzip2", "-dc", cache])
+ cache = cache.chomp('.bz2')
+ when '.xz', '.txz'
+ f = IO.popen(["xz", "-dc", cache])
+ cache = cache.chomp('.xz')
+ else
+ inp = cache
+ end
+ inp ||= f.binmode
+ ext = File.extname(cache)
+ case ext
+ when '.tar', /\A\.t[gbx]z\z/
+ pid = Process.spawn("tar", "xpf", "-", in: inp, chdir: dir)
+ when '.zip'
+ pid = Process.spawn("unzip", inp, "-d", dir)
+ end
+ f.close if f
+ Process.wait(pid)
+ $?.success? or raise "failed to extract #{cache}"
+end
+
+def do_patch(dest, patch, args)
+ if $VERBOSE
+ $stdout.puts "applying #{patch} under #{dest}"
+ $stdout.flush
+ end
+ Process.wait(Process.spawn("patch", *args, in: File.join(dest, patch), chdir: dest))
+ $?.success? or raise "failed to patch #{patch}"
+end
+
+case ARGV[0]
+when '--download'
+ mode = :download
+ ARGV.shift
+when '--extract'
+ mode = :extract
+ ARGV.shift
+when '--patch'
+ mode = :patch
+ ARGV.shift
+when '--all'
+ mode = :all
+ ARGV.shift
+else
+ mode = :all
+end
+
+success = true
+ARGV.each do |dir|
+ Dir.glob("#{dir}/**/extlibs") do |list|
+ if $VERBOSE
+ $stdout.puts "downloading for #{list}"
+ $stdout.flush
+ end
+ extracted = false
+ dest = File.dirname(list)
+ IO.foreach(list) do |line|
+ line.sub!(/\s*#.*/, '')
+ if /^\t/ =~ line
+ if extracted and (mode == :all or mode == :patch)
+ patch, *args = line.split
+ do_patch(dest, patch, args)
+ end
+ next
+ end
+ url, *chksums = line.split(' ')
+ next unless url
+ extracted = false
+ base = File.basename(url)
+ cache = File.join(cache_dir, base)
+ target = File.join(dest, base[/.*(?=\.tar(?:\.\w+)?\z)/])
+ begin
+ case mode
+ when :download
+ do_download(url, base, cache_dir)
+ do_checksum(cache, chksums)
+ when :extract
+ unless File.directory?(target)
+ do_checksum(cache, chksums)
+ extracted = do_extract(cache, dest)
+ end
+ when :all
+ do_download(url, base, cache_dir)
+ unless File.directory?(target)
+ do_checksum(cache, chksums)
+ extracted = do_extract(cache, dest)
+ end
+ end
+ rescue => e
+ warn e.inspect
+ success = false
+ end
+ end
+ end
+end
+
+exit(success)
diff --git a/jni/ruby/tool/fake.rb b/jni/ruby/tool/fake.rb
new file mode 100644
index 0000000..7d3a471
--- /dev/null
+++ b/jni/ruby/tool/fake.rb
@@ -0,0 +1,30 @@
+class File
+ sep = ("\\" if RUBY_PLATFORM =~ /mswin|bccwin|mingw/)
+ if sep != ALT_SEPARATOR
+ remove_const :ALT_SEPARATOR
+ ALT_SEPARATOR = sep
+ end
+end
+
+$:.unshift(builddir)
+posthook = proc do
+ mkconfig = RbConfig::MAKEFILE_CONFIG
+ extout = File.expand_path(mkconfig["EXTOUT"], builddir)
+ $arch_hdrdir = "#{extout}/include/$(arch)"
+ $ruby = baseruby
+ untrace_var(:$ruby, posthook)
+end
+prehook = proc do |extmk|
+ unless extmk
+ config = RbConfig::CONFIG
+ mkconfig = RbConfig::MAKEFILE_CONFIG
+ mkconfig["top_srcdir"] = $top_srcdir = top_srcdir
+ mkconfig["rubyhdrdir"] = "$(top_srcdir)/include"
+ mkconfig["builddir"] = config["builddir"] = builddir
+ config["rubyhdrdir"] = File.join(mkconfig["top_srcdir"], "include")
+ mkconfig["libdir"] = config["libdir"] = mkconfig["topdir"]
+ trace_var(:$ruby, posthook)
+ end
+ untrace_var(:$extmk, prehook)
+end
+trace_var(:$extmk, prehook)
diff --git a/jni/ruby/tool/file2lastrev.rb b/jni/ruby/tool/file2lastrev.rb
new file mode 100755
index 0000000..616c5f7
--- /dev/null
+++ b/jni/ruby/tool/file2lastrev.rb
@@ -0,0 +1,68 @@
+#!/usr/bin/env ruby
+
+require 'optparse'
+
+# this file run with BASERUBY, which may be older than 1.9, so no
+# require_relative
+require File.expand_path('../vcs', __FILE__)
+
+Program = $0
+
+@output = nil
+def self.output=(output)
+ if @output and @output != output
+ raise "you can specify only one of --changed, --revision.h and --doxygen"
+ end
+ @output = output
+end
+@suppress_not_found = false
+
+srcdir = nil
+parser = OptionParser.new {|opts|
+ opts.on("--srcdir=PATH", "use PATH as source directory") do |path|
+ srcdir = path
+ end
+ opts.on("--changed", "changed rev") do
+ self.output = :changed
+ end
+ opts.on("--revision.h", "RUBY_REVISION macro") do
+ self.output = :revision_h
+ end
+ opts.on("--doxygen", "Doxygen format") do
+ self.output = :doxygen
+ end
+ opts.on("--modified", "modified time") do
+ self.output = :modified
+ end
+ opts.on("-q", "--suppress_not_found") do
+ @suppress_not_found = true
+ end
+}
+parser.parse! rescue abort "#{File.basename(Program)}: #{$!}\n#{parser}"
+
+srcdir ||= File.dirname(File.dirname(Program))
+begin
+ vcs = VCS.detect(srcdir)
+rescue VCS::NotFoundError => e
+ abort "#{File.basename(Program)}: #{e.message}" unless @suppress_not_found
+else
+ begin
+ last, changed, modified = vcs.get_revisions(ARGV.shift)
+ rescue => e
+ abort "#{File.basename(Program)}: #{e.message}" unless @suppress_not_found
+ exit false
+ end
+end
+
+case @output
+when :changed, nil
+ puts changed
+when :revision_h
+ puts "#define RUBY_REVISION #{changed.to_i}"
+when :doxygen
+ puts "r#{changed}/r#{last}"
+when :modified
+ puts modified.strftime('%Y-%m-%dT%H:%M:%S%z')
+else
+ raise "unknown output format `#{@output}'"
+end
diff --git a/jni/ruby/tool/gen_dummy_probes.rb b/jni/ruby/tool/gen_dummy_probes.rb
new file mode 100755
index 0000000..c19f9d5
--- /dev/null
+++ b/jni/ruby/tool/gen_dummy_probes.rb
@@ -0,0 +1,28 @@
+#!/usr/bin/ruby
+# -*- coding: us-ascii -*-
+
+text = ARGF.read
+text.gsub!(/^(?!#)(.*)/){$1.upcase}
+
+# remove comments
+text.gsub!(%r'(?:^ *)?/\*.*?\*/\n?'m, '')
+
+# remove the pragma declarations
+text.gsub!(/^#pragma.*\n/, '')
+
+# replace the provider section with the start of the header file
+text.gsub!(/PROVIDER RUBY \{/, "#ifndef\t_PROBES_H\n#define\t_PROBES_H\n#define DTRACE_PROBES_DISABLED 1\n")
+
+# finish up the #ifndef sandwich
+text.gsub!(/\};/, "\n#endif\t/* _PROBES_H */")
+
+text.gsub!(/__/, '_')
+
+text.gsub!(/\((.+?)(?=\);)/) {
+ "(arg" << (0..$1.count(',')).to_a.join(", arg")
+}
+
+text.gsub!(/ *PROBE ([^\(]*)(\([^\)]*\));/, "#define RUBY_DTRACE_\\1_ENABLED() 0\n#define RUBY_DTRACE_\\1\\2\ do \{ \} while\(0\)")
+puts "/* -*- c -*- */"
+print text
+
diff --git a/jni/ruby/tool/gen_ruby_tapset.rb b/jni/ruby/tool/gen_ruby_tapset.rb
new file mode 100755
index 0000000..c34fb88
--- /dev/null
+++ b/jni/ruby/tool/gen_ruby_tapset.rb
@@ -0,0 +1,105 @@
+#!/usr/bin/ruby
+# -*- coding: us-ascii -*-
+# usage: ./ruby gen_ruby_tapset.rb --ruby-path=/path/to/ruby probes.d > output
+
+require "optparse"
+
+def set_argument (argname, nth)
+ # remove C style type info
+ argname.gsub!(/.+ (.+)/, '\1') # e.g. char *hoge -> *hoge
+ argname.gsub!(/^\*/, '') # e.g. *filename -> filename
+
+ "#{argname} = $arg#{nth}"
+end
+
+ruby_path = "/usr/local/ruby"
+
+opts = OptionParser.new
+opts.on("--ruby-path=PATH"){|v| ruby_path = v}
+opts.parse!(ARGV)
+
+text = ARGF.read
+
+# remove preprocessor directives
+text.gsub!(/^#.*$/, '')
+
+# remove provider name
+text.gsub!(/^provider ruby \{/, "")
+text.gsub!(/^\};/, "")
+
+# probename()
+text.gsub!(/probe (.+)\( *\);/) {
+ probe_name = $1
+ probe = <<-End
+ probe #{probe_name} = process("ruby").provider("ruby").mark("#{probe_name}")
+ {
+ }
+ End
+}
+
+# probename(arg1)
+text.gsub!(/ *probe (.+)\(([^,)]+)\);/) {
+ probe_name = $1
+ arg1 = $2
+
+ probe = <<-End
+ probe #{probe_name} = process("ruby").provider("ruby").mark("#{probe_name}")
+ {
+ #{set_argument(arg1, 1)}
+ }
+ End
+}
+
+# probename(arg1, arg2)
+text.gsub!(/ *probe (.+)\(([^,)]+),([^,)]+)\);/) {
+ probe_name = $1
+ arg1 = $2
+ arg2 = $3
+
+ probe = <<-End
+ probe #{probe_name} = process("#{ruby_path}").provider("ruby").mark("#{probe_name}")
+ {
+ #{set_argument(arg1, 1)}
+ #{set_argument(arg2, 2)}
+ }
+ End
+}
+
+# probename(arg1, arg2, arg3)
+text.gsub!(/ *probe (.+)\(([^,)]+),([^,)]+),([^,)]+)\);/) {
+ probe_name = $1
+ arg1 = $2
+ arg2 = $3
+ arg3 = $4
+
+ probe = <<-End
+ probe #{probe_name} = process("#{ruby_path}").provider("ruby").mark("#{probe_name}")
+ {
+ #{set_argument(arg1, 1)}
+ #{set_argument(arg2, 2)}
+ #{set_argument(arg3, 3)}
+ }
+ End
+}
+
+# probename(arg1, arg2, arg3, arg4)
+text.gsub!(/ *probe (.+)\(([^,)]+),([^,)]+),([^,)]+),([^,)]+)\);/) {
+ probe_name = $1
+ arg1 = $2
+ arg2 = $3
+ arg3 = $4
+ arg4 = $5
+
+ probe = <<-End
+ probe #{probe_name} = process("#{ruby_path}").provider("ruby").mark("#{probe_name}")
+ {
+ #{set_argument(arg1, 1)}
+ #{set_argument(arg2, 2)}
+ #{set_argument(arg3, 3)}
+ #{set_argument(arg4, 4)}
+ }
+ End
+}
+
+print text
+
diff --git a/jni/ruby/tool/generic_erb.rb b/jni/ruby/tool/generic_erb.rb
new file mode 100644
index 0000000..6641b0e
--- /dev/null
+++ b/jni/ruby/tool/generic_erb.rb
@@ -0,0 +1,42 @@
+# -*- coding: us-ascii -*-
+require 'erb'
+require 'optparse'
+require 'fileutils'
+$:.unshift(File.dirname(__FILE__))
+require 'vpath'
+
+vpath = VPath.new
+timestamp = nil
+output = nil
+ifchange = nil
+source = false
+
+opt = OptionParser.new do |o|
+ o.on('-t', '--timestamp[=PATH]') {|v| timestamp = v || true}
+ o.on('-o', '--output=PATH') {|v| output = v}
+ o.on('-c', '--[no-]if-change') {|v| ifchange = v}
+ o.on('-x', '--source') {source = true}
+ vpath.def_options(o)
+ o.order!(ARGV)
+end
+template = ARGV.shift or abort opt.to_s
+erb = ERB.new(File.read(template), nil, '%-')
+erb.filename = template
+result = source ? erb.src : erb.result
+if output
+ if ifchange and (vpath.open(output, "rb") {|f| f.read} rescue nil) == result
+ puts "#{output} unchanged"
+ else
+ open(output, "wb") {|f| f.print result}
+ puts "#{output} updated"
+ end
+ if timestamp
+ if timestamp == true
+ dir, base = File.split(output)
+ timestamp = File.join(dir, ".time." + base)
+ end
+ FileUtils.touch(timestamp)
+ end
+else
+ print result
+end
diff --git a/jni/ruby/tool/id2token.rb b/jni/ruby/tool/id2token.rb
new file mode 100755
index 0000000..191b872
--- /dev/null
+++ b/jni/ruby/tool/id2token.rb
@@ -0,0 +1,24 @@
+#! /usr/bin/ruby -p
+# -*- coding: us-ascii -*-
+BEGIN {
+ require 'optparse'
+ $:.unshift(File.dirname(__FILE__))
+ require 'vpath'
+ vpath = VPath.new
+ header = nil
+
+ opt = OptionParser.new do |o|
+ vpath.def_options(o)
+ header = o.order!(ARGV).shift
+ end or abort opt.opt_s
+
+ TOKENS = {}
+ h = vpath.read(header) rescue abort("#{header} not found in #{vpath.inspect}")
+ h.scan(/^#define\s+RUBY_TOKEN_(\w+)\s+(\d+)/) do |token, id|
+ TOKENS[token] = id
+ end
+
+ TOKENS_RE = /\bRUBY_TOKEN\((#{TOKENS.keys.join('|')})\)\s*(?=\s)/
+}
+
+$_.gsub!(TOKENS_RE) {TOKENS[$1]} if /^%token/ =~ $_
diff --git a/jni/ruby/tool/ifchange b/jni/ruby/tool/ifchange
new file mode 100755
index 0000000..488e9db
--- /dev/null
+++ b/jni/ruby/tool/ifchange
@@ -0,0 +1,61 @@
+#!/bin/sh
+# usage: ifchange target temporary
+
+set -e
+timestamp=
+keepsuffix=
+empty=
+until [ $# -eq 0 ]; do
+ case "$1" in
+ --timestamp)
+ timestamp=.
+ ;;
+ --timestamp=*)
+ timestamp=`expr \( "$1" : '[^=]*=\(.*\)' \)`
+ ;;
+ --keep)
+ keepsuffix=.old
+ ;;
+ --keep=*)
+ keepsuffix=`expr \( "$1" : '[^=]*=\(.*\)' \)`
+ ;;
+ --empty)
+ empty=yes
+ ;;
+ *)
+ break
+ ;;
+ esac
+ shift
+done
+
+target="$1"
+temp="$2"
+if [ "$temp" = - ]; then
+ temp="tmpdata$$.tmp~"
+ cat > "$temp" || exit $?
+ trap 'rm -f "$temp"' 0
+fi
+
+if [ -f "$target" -a ! -${empty:+f}${empty:-s} "$temp" ] || cmp "$target" "$temp" >/dev/null 2>&1; then
+ echo "$target unchanged"
+ rm -f "$temp"
+else
+ echo "$target updated"
+ [ x"${keepsuffix}" = x ] || mv -f "$target" "${target}${keepsuffix}"
+ mv -f "$temp" "$target"
+fi
+
+if [ -n "${timestamp}" ]; then
+ if [ x"${timestamp}" = x. ]; then
+ case "$target" in
+ */*)
+ timestamp=`dirname "$target"`/.time.`basename "$target"`
+ ;;
+ *)
+ timestamp=.time."$target"
+ ;;
+ esac
+ fi
+ : > "$timestamp"
+fi
diff --git a/jni/ruby/tool/insns2vm.rb b/jni/ruby/tool/insns2vm.rb
new file mode 100755
index 0000000..f518707
--- /dev/null
+++ b/jni/ruby/tool/insns2vm.rb
@@ -0,0 +1,15 @@
+#!ruby
+
+require 'optparse'
+
+Version = %w$Revision: 11626 $[1..-1]
+
+require "#{File.join(File.dirname(__FILE__), 'instruction')}"
+
+if $0 == __FILE__
+ opts = ARGV.options
+ maker = RubyVM::SourceCodeGenerator.def_options(opts)
+ files = opts.parse!
+ generator = maker.call
+ generator.generate(files)
+end
diff --git a/jni/ruby/tool/install-sh b/jni/ruby/tool/install-sh
new file mode 100644
index 0000000..af97fa6
--- /dev/null
+++ b/jni/ruby/tool/install-sh
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+# Just only for using AC_PROG_INSTALL in configure.in.
+# See autoconf.info for more detail.
+
+cat <<EOF >&2
+Ruby uses a BSD-compatible install(1) if possible. If not, Ruby
+provides its own install(1) alternative.
+
+This script a place holder for AC_PROG_INSTALL in configure.in.
+
+Please report a bug in Ruby to http://bugs.ruby-lang.org if you see
+this message.
+
+Thank you.
+EOF
+exit 1
diff --git a/jni/ruby/tool/instruction.rb b/jni/ruby/tool/instruction.rb
new file mode 100755
index 0000000..16d97f5
--- /dev/null
+++ b/jni/ruby/tool/instruction.rb
@@ -0,0 +1,1343 @@
+#!./miniruby
+# -*- coding: us-ascii -*-
+#
+#
+
+require 'erb'
+$:.unshift(File.dirname(__FILE__))
+require 'vpath'
+
+class RubyVM
+ class Instruction
+ def initialize name, opes, pops, rets, comm, body, tvars, sp_inc,
+ orig = self, defopes = [], type = nil,
+ nsc = [], psc = [[], []]
+
+ @name = name
+ @opes = opes # [[type, name], ...]
+ @pops = pops # [[type, name], ...]
+ @rets = rets # [[type, name], ...]
+ @comm = comm # {:c => category, :e => en desc, :j => ja desc}
+ @body = body # '...'
+
+ @orig = orig
+ @defopes = defopes
+ @type = type
+ @tvars = tvars
+
+ @nextsc = nsc
+ @pushsc = psc
+ @sc = []
+ @unifs = []
+ @optimized = []
+ @is_sc = false
+ @sp_inc = sp_inc
+ end
+
+ def add_sc sci
+ @sc << sci
+ sci.set_sc
+ end
+
+ attr_reader :name, :opes, :pops, :rets
+ attr_reader :body, :comm
+ attr_reader :nextsc, :pushsc
+ attr_reader :orig, :defopes, :type
+ attr_reader :sc
+ attr_reader :unifs, :optimized
+ attr_reader :is_sc
+ attr_reader :tvars
+ attr_reader :sp_inc
+
+ def set_sc
+ @is_sc = true
+ end
+
+ def add_unif insns
+ @unifs << insns
+ end
+
+ def add_optimized insn
+ @optimized << insn
+ end
+
+ def sp_increase_c_expr
+ if(pops.any?{|t, v| v == '...'} ||
+ rets.any?{|t, v| v == '...'})
+ # user definition
+ raise "no sp increase definition" if @sp_inc.nil?
+ ret = "int inc = 0;\n"
+
+ @opes.each_with_index{|(t, v), i|
+ if (t == 'rb_num_t' && ((re = /\b#{v}\b/n) =~ @sp_inc)) ||
+ (@defopes.any?{|t, val| re =~ val})
+ ret << " int #{v} = FIX2INT(opes[#{i}]);\n"
+ elsif (t == 'CALL_INFO' && ((re = /\b#{v}\b/n) =~ @sp_inc))
+ ret << " CALL_INFO #{v} = (CALL_INFO)(opes[#{i}]);\n"
+ end
+ }
+
+ @defopes.each_with_index{|((t, var), val), i|
+ if t == 'rb_num_t' && val != '*' && /\b#{var}\b/ =~ @sp_inc
+ ret << " #{t} #{var} = #{val};\n"
+ end
+ }
+
+ ret << " #{@sp_inc};\n"
+ ret << " return depth + inc;"
+ ret
+ else
+ "return depth + #{rets.size - pops.size};"
+ end
+ end
+
+ def inspect
+ "#<Instruction:#{@name}>"
+ end
+ end
+
+ class InstructionsLoader
+ def initialize opts = {}
+ @insns = []
+ @insn_map = {}
+
+ @vpath = opts[:VPATH] || File
+ @use_const = opts[:use_const]
+ @verbose = opts[:verbose]
+ @destdir = opts[:destdir]
+
+ (@vm_opts = load_vm_opts).each {|k, v|
+ @vm_opts[k] = opts[k] if opts.key?(k)
+ }
+
+ load_insns_def opts[:"insns.def"] || 'insns.def'
+
+ load_opt_operand_def opts[:"opope.def"] || 'defs/opt_operand.def'
+ load_insn_unification_def opts[:"unif.def"] || 'defs/opt_insn_unif.def'
+ make_stackcaching_insns if vm_opt?('STACK_CACHING')
+ end
+
+ attr_reader :vpath
+ attr_reader :destdir
+
+ %w[use_const verbose].each do |attr|
+ attr_reader attr
+ alias_method "#{attr}?", attr
+ remove_method attr
+ end
+
+ def [](s)
+ @insn_map[s.to_s]
+ end
+
+ def each
+ @insns.each{|insn|
+ yield insn
+ }
+ end
+
+ def size
+ @insns.size
+ end
+
+ ###
+ private
+
+ def vm_opt? name
+ @vm_opts[name]
+ end
+
+ def load_vm_opts file = nil
+ file ||= 'vm_opts.h'
+ opts = {}
+ vpath.open(file) do |f|
+ f.grep(/^\#define\s+OPT_([A-Z_]+)\s+(\d+)/) do
+ opts[$1] = !$2.to_i.zero?
+ end
+ end
+ opts
+ end
+
+ SKIP_COMMENT_PATTERN = Regexp.compile(Regexp.escape('/** ##skip'))
+
+ include Enumerable
+
+ def add_insn insn
+ @insns << insn
+ @insn_map[insn.name] = insn
+ end
+
+ def make_insn name, opes, pops, rets, comm, body, sp_inc
+ add_insn Instruction.new(name, opes, pops, rets, comm, body, [], sp_inc)
+ end
+
+ # str -> [[type, var], ...]
+ def parse_vars line
+ raise unless /\((.*?)\)/ =~ line
+ vars = $1.split(',')
+ vars.map!{|v|
+ if /\s*(\S+)\s+(\S+)\s*/ =~ v
+ type = $1
+ var = $2
+ elsif /\s*\.\.\.\s*/ =~ v
+ type = var = '...'
+ else
+ raise
+ end
+ [type, var]
+ }
+ vars
+ end
+
+ def parse_comment comm
+ c = 'others'
+ j = ''
+ e = ''
+ comm.each_line{|line|
+ case line
+ when /@c (.+)/
+ c = $1
+ when /@e (.+)/
+ e = $1
+ when /@e\s*$/
+ e = ''
+ when /@j (.+)$/
+ j = $1
+ when /@j\s*$/
+ j = ''
+ end
+ }
+ { :c => c,
+ :e => e,
+ :j => j,
+ }
+ end
+
+ def load_insns_def file
+ body = insn = opes = pops = rets = nil
+ comment = ''
+
+ vpath.open(file) {|f|
+ f.instance_variable_set(:@line_no, 0)
+ class << f
+ def line_no
+ @line_no
+ end
+ def gets
+ @line_no += 1
+ super
+ end
+ end
+
+ while line = f.gets
+ line.chomp!
+ case line
+
+ when SKIP_COMMENT_PATTERN
+ while line = f.gets.chomp
+ if /\s+\*\/$/ =~ line
+ break
+ end
+ end
+
+ # collect instruction comment
+ when /^\/\*\*$/
+ while line = f.gets
+ if /\s+\*\/\s*$/ =~ line
+ break
+ else
+ comment << line
+ end
+ end
+
+ # start instruction body
+ when /^DEFINE_INSN$/
+ insn = f.gets.chomp
+ opes = parse_vars(f.gets.chomp)
+ pops = parse_vars(f.gets.chomp).reverse
+ rets_str = f.gets.chomp
+ rets = parse_vars(rets_str).reverse
+ comment = parse_comment(comment)
+ insn_in = true
+ body = ''
+
+ sp_inc = rets_str[%r"//\s*(.+)", 1]
+
+ raise unless /^\{$/ =~ f.gets.chomp
+ line_no = f.line_no
+
+ # end instruction body
+ when /^\}/
+ if insn_in
+ body.instance_variable_set(:@line_no, line_no)
+ body.instance_variable_set(:@file, f.path)
+ insn = make_insn(insn, opes, pops, rets, comment, body, sp_inc)
+ insn_in = false
+ comment = ''
+ end
+
+ else
+ if insn_in
+ body << line + "\n"
+ end
+ end
+ end
+ }
+ end
+
+ ## opt op
+ def load_opt_operand_def file
+ vpath.foreach(file) {|line|
+ line = line.gsub(/\#.*/, '').strip
+ next if line.length == 0
+ break if /__END__/ =~ line
+ /(\S+)\s+(.+)/ =~ line
+ insn = $1
+ opts = $2
+ add_opt_operand insn, opts.split(/,/).map{|e| e.strip}
+ } if file
+ end
+
+ def label_escape label
+ label.gsub(/\(/, '_O_').
+ gsub(/\)/, '_C_').
+ gsub(/\*/, '_WC_')
+ end
+
+ def add_opt_operand insn_name, opts
+ insn = @insn_map[insn_name]
+ opes = insn.opes
+
+ if opes.size != opts.size
+ raise "operand size mismatch for #{insn.name} (opes: #{opes.size}, opts: #{opts.size})"
+ end
+
+ ninsn = insn.name + '_OP_' + opts.map{|e| label_escape(e)}.join('_')
+ nopes = []
+ defv = []
+
+ opts.each_with_index{|e, i|
+ if e == '*'
+ nopes << opes[i]
+ end
+ defv << [opes[i], e]
+ }
+
+ make_insn_operand_optimized(insn, ninsn, nopes, defv)
+ end
+
+ def make_insn_operand_optimized orig_insn, name, opes, defopes
+ comm = orig_insn.comm.dup
+ comm[:c] = 'optimize'
+ add_insn insn = Instruction.new(
+ name, opes, orig_insn.pops, orig_insn.rets, comm,
+ orig_insn.body, orig_insn.tvars, orig_insn.sp_inc,
+ orig_insn, defopes)
+ orig_insn.add_optimized insn
+ end
+
+ ## insn unif
+ def load_insn_unification_def file
+ vpath.foreach(file) {|line|
+ line = line.gsub(/\#.*/, '').strip
+ next if line.length == 0
+ break if /__END__/ =~ line
+ make_unified_insns line.split.map{|e|
+ raise "unknown insn: #{e}" unless @insn_map[e]
+ @insn_map[e]
+ }
+ } if file
+ end
+
+ def all_combination sets
+ ret = sets.shift.map{|e| [e]}
+
+ sets.each{|set|
+ prev = ret
+ ret = []
+ prev.each{|ary|
+ set.each{|e|
+ eary = ary.dup
+ eary << e
+ ret << eary
+ }
+ }
+ }
+ ret
+ end
+
+ def make_unified_insns insns
+ if vm_opt?('UNIFY_ALL_COMBINATION')
+ insn_sets = insns.map{|insn|
+ [insn] + insn.optimized
+ }
+
+ all_combination(insn_sets).each{|insns_set|
+ make_unified_insn_each insns_set
+ }
+ else
+ make_unified_insn_each insns
+ end
+ end
+
+ def mk_private_val vals, i, redef
+ vals.dup.map{|v|
+ # v[0] : type
+ # v[1] : var name
+
+ v = v.dup
+ if v[0] != '...'
+ redef[v[1]] = v[0]
+ v[1] = "#{v[1]}_#{i}"
+ end
+ v
+ }
+ end
+
+ def mk_private_val2 vals, i, redef
+ vals.dup.map{|v|
+ # v[0][0] : type
+ # v[0][1] : var name
+ # v[1] : default val
+
+ pv = v.dup
+ v = pv[0] = pv[0].dup
+ if v[0] != '...'
+ redef[v[1]] = v[0]
+ v[1] = "#{v[1]}_#{i}"
+ end
+ pv
+ }
+ end
+
+ def make_unified_insn_each insns
+ names = []
+ opes = []
+ pops = []
+ rets = []
+ comm = {
+ :c => 'optimize',
+ :e => 'unified insn',
+ :j => 'unified insn',
+ }
+ body = ''
+ passed = []
+ tvars = []
+ defopes = []
+ sp_inc = ''
+
+ insns.each_with_index{|insn, i|
+ names << insn.name
+ redef_vars = {}
+
+ e_opes = mk_private_val(insn.opes, i, redef_vars)
+ e_pops = mk_private_val(insn.pops, i, redef_vars)
+ e_rets = mk_private_val(insn.rets, i, redef_vars)
+ # ToDo: fix it
+ e_defs = mk_private_val2(insn.defopes, i, redef_vars)
+
+ passed_vars = []
+ while pvar = e_pops.pop
+ rvar = rets.pop
+ if rvar
+ raise "unsupported unif insn: #{insns.inspect}" if rvar[0] == '...'
+ passed_vars << [pvar, rvar]
+ tvars << rvar
+ else
+ e_pops.push pvar
+ break
+ end
+ end
+
+ opes.concat e_opes
+ pops.concat e_pops
+ rets.concat e_rets
+ defopes.concat e_defs
+ sp_inc += "#{insn.sp_inc}"
+
+ body += "{ /* unif: #{i} */\n" +
+ passed_vars.map{|rpvars|
+ pv = rpvars[0]
+ rv = rpvars[1]
+ "#define #{pv[1]} #{rv[1]}"
+ }.join("\n") +
+ "\n" +
+ redef_vars.map{|v, type|
+ "#define #{v} #{v}_#{i}"
+ }.join("\n") + "\n" +
+ insn.body +
+ passed_vars.map{|rpvars|
+ "#undef #{rpvars[0][1]}"
+ }.join("\n") +
+ "\n" +
+ redef_vars.keys.map{|v|
+ "#undef #{v}"
+ }.join("\n") +
+ "\n}\n"
+ }
+
+ tvars_ary = []
+ tvars.each{|tvar|
+ unless opes.any?{|var|
+ var[1] == tvar[1]
+ } || defopes.any?{|pvar|
+ pvar[0][1] == tvar[1]
+ }
+ tvars_ary << tvar
+ end
+ }
+ add_insn insn = Instruction.new("UNIFIED_" + names.join('_'),
+ opes, pops, rets.reverse, comm, body,
+ tvars_ary, sp_inc)
+ insn.defopes.replace defopes
+ insns[0].add_unif [insn, insns]
+ end
+
+ ## sc
+ SPECIAL_INSN_FOR_SC_AFTER = {
+ /\Asend/ => [:a],
+ /\Aend/ => [:a],
+ /\Ayield/ => [:a],
+ /\Aclassdef/ => [:a],
+ /\Amoduledef/ => [:a],
+ }
+ FROM_SC = [[], [:a], [:b], [:a, :b], [:b, :a]]
+
+ def make_stackcaching_insns
+ pops = rets = nil
+
+ @insns.dup.each{|insn|
+ opops = insn.pops
+ orets = insn.rets
+ oopes = insn.opes
+ ocomm = insn.comm
+ oname = insn.name
+
+ after = SPECIAL_INSN_FOR_SC_AFTER.find {|k, v| k =~ oname}
+
+ insns = []
+ FROM_SC.each{|from|
+ name, pops, rets, pushs1, pushs2, nextsc =
+ *calc_stack(insn, from, after, opops, orets)
+
+ make_insn_sc(insn, name, oopes, pops, rets, [pushs1, pushs2], nextsc)
+ }
+ }
+ end
+
+ def make_insn_sc orig_insn, name, opes, pops, rets, pushs, nextsc
+ comm = orig_insn.comm.dup
+ comm[:c] = 'optimize(sc)'
+
+ scinsn = Instruction.new(
+ name, opes, pops, rets, comm,
+ orig_insn.body, orig_insn.tvars, orig_insn.sp_inc,
+ orig_insn, orig_insn.defopes, :sc, nextsc, pushs)
+
+ add_insn scinsn
+ orig_insn.add_sc scinsn
+ end
+
+ def self.complement_name st
+ "#{st[0] ? st[0] : 'x'}#{st[1] ? st[1] : 'x'}"
+ end
+
+ def add_stack_value st
+ len = st.length
+ if len == 0
+ st[0] = :a
+ [nil, :a]
+ elsif len == 1
+ if st[0] == :a
+ st[1] = :b
+ else
+ st[1] = :a
+ end
+ [nil, st[1]]
+ else
+ st[0], st[1] = st[1], st[0]
+ [st[1], st[1]]
+ end
+ end
+
+ def calc_stack insn, ofrom, oafter, opops, orets
+ from = ofrom.dup
+ pops = opops.dup
+ rets = orets.dup
+ rest_scr = ofrom.dup
+
+ pushs_before = []
+ pushs= []
+
+ pops.each_with_index{|e, i|
+ if e[0] == '...'
+ pushs_before = from
+ from = []
+ end
+ r = from.pop
+ break unless r
+ pops[i] = pops[i].dup << r
+ }
+
+ if oafter
+ from = oafter
+ from.each_with_index{|r, i|
+ rets[i] = rets[i].dup << r if rets[i]
+ }
+ else
+ rets = rets.reverse
+ rets.each_with_index{|e, i|
+ break if e[0] == '...'
+ pushed, r = add_stack_value from
+ rets[i] = rets[i].dup << r
+ if pushed
+ if rest_scr.pop
+ pushs << pushed
+ end
+
+ if i - 2 >= 0
+ rets[i-2].pop
+ end
+ end
+ }
+ end
+
+ if false #|| insn.name =~ /test3/
+ p ofrom
+ p pops
+ p rets
+ p pushs_before
+ p pushs
+ p from
+ exit
+ end
+
+ ret = ["#{insn.name}_SC_#{InstructionsLoader.complement_name(ofrom)}_#{complement_name(from)}",
+ pops, rets, pushs_before, pushs, from]
+ end
+ end
+
+ class SourceCodeGenerator
+ def initialize insns
+ @insns = insns
+ end
+
+ attr_reader :insns
+
+ def generate
+ raise "should not reach here"
+ end
+
+ def vpath
+ @insns.vpath
+ end
+
+ def verbose?
+ @insns.verbose?
+ end
+
+ def use_const?
+ @insns.use_const?
+ end
+
+ def build_string
+ @lines = []
+ yield
+ @lines.join("\n")
+ end
+
+ EMPTY_STRING = ''.freeze
+
+ def commit str = EMPTY_STRING
+ @lines << str
+ end
+
+ def comment str
+ @lines << str if verbose?
+ end
+
+ def output_path(fn)
+ d = @insns.destdir
+ fn = File.join(d, fn) if d
+ fn
+ end
+ end
+
+ ###################################################################
+ # vm.inc
+ class VmBodyGenerator < SourceCodeGenerator
+ # vm.inc
+ def generate
+ vm_body = ''
+ @insns.each{|insn|
+ vm_body << "\n"
+ vm_body << make_insn_def(insn)
+ }
+ src = vpath.read('template/vm.inc.tmpl')
+ ERB.new(src).result(binding)
+ end
+
+ def generate_from_insnname insnname
+ make_insn_def @insns[insnname.to_s]
+ end
+
+ #######
+ private
+
+ def make_header_prepare_stack insn
+ comment " /* prepare stack status */"
+
+ push_ba = insn.pushsc
+ raise "unsupport" if push_ba[0].size > 0 && push_ba[1].size > 0
+
+ n = 0
+ push_ba.each {|pushs| n += pushs.length}
+ commit " CHECK_VM_STACK_OVERFLOW_FOR_INSN(REG_CFP, #{n});" if n > 0
+ push_ba.each{|pushs|
+ pushs.each{|r|
+ commit " PUSH(SCREG(#{r}));"
+ }
+ }
+ end
+
+ def make_header_operands insn
+ comment " /* declare and get from iseq */"
+
+ vars = insn.opes
+ n = 0
+ ops = []
+
+ vars.each_with_index{|(type, var), i|
+ if type == '...'
+ break
+ end
+
+ # skip make operands when body has no reference to this operand
+ # TODO: really needed?
+ re = /\b#{var}\b/n
+ if re =~ insn.body or re =~ insn.sp_inc or insn.rets.any?{|t, v| re =~ v} or re =~ 'ic' or re =~ 'ci'
+ ops << " #{type} #{var} = (#{type})GET_OPERAND(#{i+1});"
+ end
+
+ n += 1
+ }
+ @opn = n
+
+ # reverse or not?
+ # ops.join
+ commit ops.reverse
+ end
+
+ def make_header_default_operands insn
+ vars = insn.defopes
+
+ vars.each{|e|
+ next if e[1] == '*'
+ if use_const?
+ commit " const #{e[0][0]} #{e[0][1]} = #{e[1]};"
+ else
+ commit " #define #{e[0][1]} #{e[1]}"
+ end
+ }
+ end
+
+ def make_footer_default_operands insn
+ comment " /* declare and initialize default opes */"
+ if use_const?
+ commit
+ else
+ vars = insn.defopes
+
+ vars.each{|e|
+ next if e[1] == '*'
+ commit "#undef #{e[0][1]}"
+ }
+ end
+ end
+
+ def make_header_stack_pops insn
+ comment " /* declare and pop from stack */"
+
+ n = 0
+ pops = []
+ vars = insn.pops
+ vars.each_with_index{|iter, i|
+ type, var, r = *iter
+ if type == '...'
+ break
+ end
+ if r
+ pops << " #{type} #{var} = SCREG(#{r});"
+ else
+ pops << " #{type} #{var} = TOPN(#{n});"
+ n += 1
+ end
+ }
+ @popn = n
+
+ # reverse or not?
+ commit pops.reverse
+ end
+
+ def make_header_temporary_vars insn
+ comment " /* declare temporary vars */"
+
+ insn.tvars.each{|var|
+ commit " #{var[0]} #{var[1]};"
+ }
+ end
+
+ def make_header_stack_val insn
+ comment "/* declare stack push val */"
+
+ vars = insn.opes + insn.pops + insn.defopes.map{|e| e[0]}
+
+ insn.rets.each{|var|
+ if vars.all?{|e| e[1] != var[1]} && var[1] != '...'
+ commit " #{var[0]} #{var[1]};"
+ end
+ }
+ end
+
+ def make_header_analysis insn
+ commit " COLLECT_USAGE_INSN(BIN(#{insn.name}));"
+ insn.opes.each_with_index{|op, i|
+ commit " COLLECT_USAGE_OPERAND(BIN(#{insn.name}), #{i}, #{op[1]});"
+ }
+ end
+
+ def make_header_pc insn
+ commit " ADD_PC(1+#{@opn});"
+ commit " PREFETCH(GET_PC());"
+ end
+
+ def make_header_popn insn
+ comment " /* management */"
+ commit " POPN(#{@popn});" if @popn > 0
+ end
+
+ def make_header_debug insn
+ comment " /* for debug */"
+ commit " DEBUG_ENTER_INSN(\"#{insn.name}\");"
+ end
+
+ def make_header_defines insn
+ commit " #define CURRENT_INSN_#{insn.name} 1"
+ commit " #define INSN_IS_SC() #{insn.sc ? 0 : 1}"
+ commit " #define INSN_LABEL(lab) LABEL_#{insn.name}_##lab"
+ commit " #define LABEL_IS_SC(lab) LABEL_##lab##_###{insn.sc.size == 0 ? 't' : 'f'}"
+ end
+
+ def each_footer_stack_val insn
+ insn.rets.reverse_each{|v|
+ break if v[1] == '...'
+ yield v
+ }
+ end
+
+ def make_footer_stack_val insn
+ comment " /* push stack val */"
+
+ n = 0
+ each_footer_stack_val(insn){|v|
+ n += 1 unless v[2]
+ }
+ commit " CHECK_VM_STACK_OVERFLOW_FOR_INSN(REG_CFP, #{n});" if n > 0
+ each_footer_stack_val(insn){|v|
+ if v[2]
+ commit " SCREG(#{v[2]}) = #{v[1]};"
+ else
+ commit " PUSH(#{v[1]});"
+ end
+ }
+ end
+
+ def make_footer_undefs insn
+ commit "#undef CURRENT_INSN_#{insn.name}"
+ commit "#undef INSN_IS_SC"
+ commit "#undef INSN_LABEL"
+ commit "#undef LABEL_IS_SC"
+ end
+
+ def make_header insn
+ commit "INSN_ENTRY(#{insn.name}){"
+ make_header_prepare_stack insn
+ commit "{"
+ make_header_stack_val insn
+ make_header_default_operands insn
+ make_header_operands insn
+ make_header_stack_pops insn
+ make_header_temporary_vars insn
+ #
+ make_header_debug insn
+ make_header_pc insn
+ make_header_popn insn
+ make_header_defines insn
+ make_header_analysis insn
+ commit "{"
+ end
+
+ def make_footer insn
+ make_footer_stack_val insn
+ make_footer_default_operands insn
+ make_footer_undefs insn
+ commit " END_INSN(#{insn.name});}}}"
+ end
+
+ def make_insn_def insn
+ build_string do
+ make_header insn
+ if line = insn.body.instance_variable_get(:@line_no)
+ file = insn.body.instance_variable_get(:@file)
+ commit "#line #{line+1} \"#{file}\""
+ commit insn.body
+ commit '#line __CURRENT_LINE__ "__CURRENT_FILE__"'
+ else
+ insn.body
+ end
+ make_footer(insn)
+ end
+ end
+ end
+
+ ###################################################################
+ # vmtc.inc
+ class VmTCIncGenerator < SourceCodeGenerator
+ def generate
+
+ insns_table = build_string do
+ @insns.each{|insn|
+ commit " LABEL_PTR(#{insn.name}),"
+ }
+ end
+
+ insn_end_table = build_string do
+ @insns.each{|insn|
+ commit " ELABEL_PTR(#{insn.name}),\n"
+ }
+ end
+
+ ERB.new(vpath.read('template/vmtc.inc.tmpl')).result(binding)
+ end
+ end
+
+ ###################################################################
+ # insns_info.inc
+ class InsnsInfoIncGenerator < SourceCodeGenerator
+ def generate
+ insns_info_inc
+ end
+
+ ###
+ private
+
+ def op2typesig op
+ case op
+ when /^OFFSET/
+ "TS_OFFSET"
+ when /^rb_num_t/
+ "TS_NUM"
+ when /^lindex_t/
+ "TS_LINDEX"
+ when /^VALUE/
+ "TS_VALUE"
+ when /^ID/
+ "TS_ID"
+ when /GENTRY/
+ "TS_GENTRY"
+ when /^IC/
+ "TS_IC"
+ when /^CALL_INFO/
+ "TS_CALLINFO"
+ when /^\.\.\./
+ "TS_VARIABLE"
+ when /^CDHASH/
+ "TS_CDHASH"
+ when /^ISEQ/
+ "TS_ISEQ"
+ when /rb_insn_func_t/
+ "TS_FUNCPTR"
+ else
+ raise "unknown op type: #{op}"
+ end
+ end
+
+ TYPE_CHARS = {
+ 'TS_OFFSET' => 'O',
+ 'TS_NUM' => 'N',
+ 'TS_LINDEX' => 'L',
+ 'TS_VALUE' => 'V',
+ 'TS_ID' => 'I',
+ 'TS_GENTRY' => 'G',
+ 'TS_IC' => 'K',
+ 'TS_CALLINFO' => 'C',
+ 'TS_CDHASH' => 'H',
+ 'TS_ISEQ' => 'S',
+ 'TS_VARIABLE' => '.',
+ 'TS_FUNCPTR' => 'F',
+ }
+
+ # insns_info.inc
+ def insns_info_inc
+ # insn_type_chars
+ insn_type_chars = TYPE_CHARS.map{|t, c|
+ "#define #{t} '#{c}'"
+ }.join("\n")
+
+ # insn_names
+ insn_names = ''
+ @insns.each{|insn|
+ insn_names << " \"#{insn.name}\",\n"
+ }
+
+ # operands info
+ operands_info = ''
+ operands_num_info = ''
+
+ @insns.each{|insn|
+ opes = insn.opes
+ operands_info << ' '
+ ot = opes.map{|type, var|
+ TYPE_CHARS.fetch(op2typesig(type))
+ }
+ operands_info << "\"#{ot.join}\"" << ",\n"
+
+ num = opes.size + 1
+ operands_num_info << " #{num},\n"
+ }
+
+ # stack num
+ stack_num_info = ''
+ @insns.each{|insn|
+ num = insn.rets.size
+ stack_num_info << " #{num},\n"
+ }
+
+ # stack increase
+ stack_increase = ''
+ @insns.each{|insn|
+ stack_increase << <<-EOS
+ case BIN(#{insn.name}):{
+ #{insn.sp_increase_c_expr}
+ }
+ EOS
+ }
+ ERB.new(vpath.read('template/insns_info.inc.tmpl')).result(binding)
+ end
+ end
+
+ ###################################################################
+ # insns.inc
+ class InsnsIncGenerator < SourceCodeGenerator
+ def generate
+ i=0
+ insns = build_string do
+ @insns.each{|insn|
+ commit " %-30s = %d," % ["BIN(#{insn.name})", i]
+ i+=1
+ }
+ end
+
+ ERB.new(vpath.read('template/insns.inc.tmpl')).result(binding)
+ end
+ end
+
+ ###################################################################
+ # minsns.inc
+ class MInsnsIncGenerator < SourceCodeGenerator
+ def generate
+ i=0
+ defs = build_string do
+ @insns.each{|insn|
+ commit " rb_define_const(mYarvInsns, %-30s, INT2FIX(%d));" %
+ ["\"I#{insn.name}\"", i]
+ i+=1
+ }
+ end
+ ERB.new(vpath.read('template/minsns.inc.tmpl')).result(binding)
+ end
+ end
+
+ ###################################################################
+ # optinsn.inc
+ class OptInsnIncGenerator < SourceCodeGenerator
+ def generate
+ optinsn_inc
+ end
+
+ ###
+ private
+
+ def val_as_type op
+ type = op[0][0]
+ val = op[1]
+
+ case type
+ when /^long/, /^rb_num_t/, /^lindex_t/
+ "INT2FIX(#{val})"
+ when /^VALUE/
+ val
+ when /^ID/
+ "INT2FIX(#{val})"
+ when /^ISEQ/, /^rb_insn_func_t/
+ val
+ when /GENTRY/
+ raise
+ when /^\.\.\./
+ raise
+ else
+ raise "type: #{type}"
+ end
+ end
+
+ # optinsn.inc
+ def optinsn_inc
+ rule = ''
+ opt_insns_map = Hash.new{|h, k| h[k] = []}
+
+ @insns.each{|insn|
+ next if insn.defopes.size == 0
+ next if insn.type == :sc
+ next if /^UNIFIED/ =~ insn.name.to_s
+
+ originsn = insn.orig
+ opt_insns_map[originsn] << insn
+ }
+
+ rule = build_string do
+ opt_insns_map.each{|originsn, optinsns|
+ commit "case BIN(#{originsn.name}):"
+
+ optinsns.sort_by{|opti|
+ opti.defopes.find_all{|e| e[1] == '*'}.size
+ }.each{|opti|
+ commit " if("
+ i = 0
+ commit " " + opti.defopes.map{|opinfo|
+ i += 1
+ next if opinfo[1] == '*'
+ "insnobj->operands[#{i-1}] == #{val_as_type(opinfo)}"
+ }.compact.join('&& ')
+ commit " ){"
+ idx = 0
+ n = 0
+ opti.defopes.each{|opinfo|
+ if opinfo[1] == '*'
+ if idx != n
+ commit " insnobj->operands[#{idx}] = insnobj->operands[#{n}];"
+ end
+ idx += 1
+ else
+ # skip
+ end
+ n += 1
+ }
+ commit " insnobj->insn_id = BIN(#{opti.name});"
+ commit " insnobj->operand_size = #{idx};"
+ commit " break;\n }\n"
+ }
+ commit " break;";
+ }
+ end
+
+ ERB.new(vpath.read('template/optinsn.inc.tmpl')).result(binding)
+ end
+ end
+
+ ###################################################################
+ # optunifs.inc
+ class OptUnifsIncGenerator < SourceCodeGenerator
+ def generate
+ unif_insns_each = ''
+ unif_insns = ''
+ unif_insns_data = []
+
+ insns = @insns.find_all{|insn| !insn.is_sc}
+ insns.each{|insn|
+ size = insn.unifs.size
+ if size > 0
+ insn.unifs.sort_by{|unif| -unif[1].size}.each_with_index{|unif, i|
+
+ uni_insn, uni_insns = *unif
+ uni_insns = uni_insns[1..-1]
+ unif_insns_each << "static const int UNIFIED_#{insn.name}_#{i}[] = {" +
+ " BIN(#{uni_insn.name}), #{uni_insns.size + 2},\n " +
+ uni_insns.map{|e| "BIN(#{e.name})"}.join(", ") + "};\n"
+ }
+ else
+
+ end
+ if size > 0
+ unif_insns << "static const int *const UNIFIED_#{insn.name}[] = {(int *)#{size+1},\n"
+ unif_insns << (0...size).map{|e| " UNIFIED_#{insn.name}_#{e}"}.join(",\n") + "};\n"
+ unif_insns_data << " UNIFIED_#{insn.name}"
+ else
+ unif_insns_data << " 0"
+ end
+ }
+ unif_insns_data = "static const int *const *const unified_insns_data[] = {\n" +
+ unif_insns_data.join(",\n") + "};\n"
+ ERB.new(vpath.read('template/optunifs.inc.tmpl')).result(binding)
+ end
+ end
+
+ ###################################################################
+ # opt_sc.inc
+ class OptSCIncGenerator < SourceCodeGenerator
+ def generate
+ sc_insn_info = []
+ @insns.each{|insn|
+ insns = insn.sc
+ if insns.size > 0
+ insns = ['SC_ERROR'] + insns.map{|e| " BIN(#{e.name})"}
+ else
+ insns = Array.new(6){'SC_ERROR'}
+ end
+ sc_insn_info << " {\n#{insns.join(",\n")}}"
+ }
+ sc_insn_info = sc_insn_info.join(",\n")
+
+ sc_insn_next = @insns.map{|insn|
+ " SCS_#{InstructionsLoader.complement_name(insn.nextsc).upcase}" +
+ (verbose? ? " /* #{insn.name} */" : '')
+ }.join(",\n")
+ ERB.new(vpath.read('template/opt_sc.inc.tmpl')).result(binding)
+ end
+ end
+
+ ###################################################################
+ # yasmdata.rb
+ class YASMDataRbGenerator < SourceCodeGenerator
+ def generate
+ insn_id2no = ''
+ @insns.each_with_index{|insn, i|
+ insn_id2no << " :#{insn.name} => #{i},\n"
+ }
+ ERB.new(vpath.read('template/yasmdata.rb.tmpl')).result(binding)
+ end
+ end
+
+ ###################################################################
+ # yarvarch.*
+ class YARVDocGenerator < SourceCodeGenerator
+ def generate
+
+ end
+
+ def desc lang
+ d = ''
+ i = 0
+ cat = nil
+ @insns.each{|insn|
+ seq = insn.opes.map{|t,v| v}.join(' ')
+ before = insn.pops.reverse.map{|t,v| v}.join(' ')
+ after = insn.rets.reverse.map{|t,v| v}.join(' ')
+
+ if cat != insn.comm[:c]
+ d << "** #{insn.comm[:c]}\n\n"
+ cat = insn.comm[:c]
+ end
+
+ d << "*** #{insn.name}\n"
+ d << "\n"
+ d << insn.comm[lang] + "\n\n"
+ d << ":instruction sequence: 0x%02x #{seq}\n" % i
+ d << ":stack: #{before} => #{after}\n\n"
+ i+=1
+ }
+ d
+ end
+
+ def desc_ja
+ d = desc :j
+ ERB.new(vpath.read('template/yarvarch.ja')).result(binding)
+ end
+
+ def desc_en
+ d = desc :e
+ ERB.new(vpath.read('template/yarvarch.en')).result(binding)
+ end
+ end
+
+ class SourceCodeGenerator
+ Files = { # codes
+ 'vm.inc' => VmBodyGenerator,
+ 'vmtc.inc' => VmTCIncGenerator,
+ 'insns.inc' => InsnsIncGenerator,
+ 'insns_info.inc' => InsnsInfoIncGenerator,
+ # 'minsns.inc' => MInsnsIncGenerator,
+ 'optinsn.inc' => OptInsnIncGenerator,
+ 'optunifs.inc' => OptUnifsIncGenerator,
+ 'opt_sc.inc' => OptSCIncGenerator,
+ 'yasmdata.rb' => YASMDataRbGenerator,
+ }
+
+ def generate args = []
+ args = Files.keys if args.empty?
+ args.each{|fn|
+ s = Files[fn].new(@insns).generate
+ open(output_path(fn), 'w') {|f| f.puts(s)}
+ }
+ end
+
+ def self.def_options(opt)
+ opts = {
+ :"insns.def" => 'insns.def',
+ :"opope.def" => 'defs/opt_operand.def',
+ :"unif.def" => 'defs/opt_insn_unif.def',
+ }
+
+ opt.on("-Dname", /\AOPT_(\w+)\z/, "enable VM option") {|s, v|
+ opts[v] = true
+ }
+ opt.on("--enable=name[,name...]", Array,
+ "enable VM options (without OPT_ prefix)") {|*a|
+ a.each {|v| opts[v] = true}
+ }
+ opt.on("-Uname", /\AOPT_(\w+)\z/, "disable VM option") {|s, v|
+ opts[v] = false
+ }
+ opt.on("--disable=name[,name...]", Array,
+ "disable VM options (without OPT_ prefix)") {|*a|
+ a.each {|v| opts[v] = false}
+ }
+ opt.on("-i", "--insnsdef=FILE", "--instructions-def",
+ "instructions definition file") {|n|
+ opts[:insns_def] = n
+ }
+ opt.on("-o", "--opt-operanddef=FILE", "--opt-operand-def",
+ "vm option: operand definition file") {|n|
+ opts[:opope_def] = n
+ }
+ opt.on("-u", "--opt-insnunifdef=FILE", "--opt-insn-unif-def",
+ "vm option: instruction unification file") {|n|
+ opts[:unif_def] = n
+ }
+ opt.on("-C", "--[no-]use-const",
+ "use consts for default operands instead of macros") {|v|
+ opts[:use_const] = v
+ }
+ opt.on("-d", "--destdir", "--output-directory=DIR",
+ "make output file underneath DIR") {|v|
+ opts[:destdir] = v
+ }
+ opt.on("-V", "--[no-]verbose") {|v|
+ opts[:verbose] = v
+ }
+
+ vpath = VPath.new
+ vpath.def_options(opt)
+
+ proc {
+ opts[:VPATH] = vpath
+ build opts
+ }
+ end
+
+ def self.build opts, vpath = ['./']
+ opts[:VPATH] ||= VPath.new(*vpath)
+ self.new InstructionsLoader.new(opts)
+ end
+ end
+end
+
diff --git a/jni/ruby/tool/jisx0208.rb b/jni/ruby/tool/jisx0208.rb
new file mode 100644
index 0000000..921f574
--- /dev/null
+++ b/jni/ruby/tool/jisx0208.rb
@@ -0,0 +1,84 @@
+module JISX0208
+ class Char
+ class << self
+ def from_sjis(sjis)
+ unless 0x8140 <= sjis && sjis <= 0xFCFC
+ raise ArgumentError, "out of the range of JIS X 0208: 0x#{sjis.to_s(16)}"
+ end
+ sjis_hi, sjis_lo = sjis >> 8, sjis & 0xFF
+ sjis_hi = (sjis_hi - ((sjis_hi <= 0x9F) ? 0x80 : 0xC0)) << 1
+ if sjis_lo <= 0x9E
+ sjis_hi -= 1
+ sjis_lo -= (sjis_lo <= 0x7E) ? 0x3F : 0x40
+ else
+ sjis_lo -= 0x9E
+ end
+ return self.new(sjis_hi, sjis_lo)
+ end
+ end
+
+ def initialize(row, cell=nil)
+ if cell
+ @code = row_cell_to_code(row, cell)
+ else
+ @code = row.to_int
+ end
+ end
+
+ def ==(other)
+ if self.class === other
+ return Integer(self) == Integer(other)
+ end
+ return super(other)
+ end
+
+ def to_int
+ return @code
+ end
+
+ def hi
+ Integer(self) >> 8
+ end
+
+ def lo
+ Integer(self) & 0xFF
+ end
+
+ def row
+ self.hi - 0x20
+ end
+
+ def cell
+ self.lo - 0x20
+ end
+
+ def succ
+ succ_hi, succ_lo = self.hi, self.lo + 1
+ if succ_lo > 0x7E
+ succ_lo = 0x21
+ succ_hi += 1
+ end
+ return self.class.new(succ_hi << 8 | succ_lo)
+ end
+
+ def to_sjis
+ h, l = self.hi, self.lo
+ h = (h + 1) / 2 + ((0x21..0x5E).include?(h) ? 0x70 : 0xB0)
+ l += self.hi.odd? ? 0x1F + ((l >= 0x60) ? 1 : 0) : 0x7E
+ return h << 8 | l
+ end
+
+ def inspect
+ "#<JISX0208::Char:#{self.object_id.to_s(16)} sjis=#{self.to_sjis.to_s(16)} jis=#{self.to_int.to_s(16)}>"
+ end
+
+ private
+
+ def row_cell_to_code(row, cell)
+ unless 0 < row && (1..94).include?(cell)
+ raise ArgumentError, "out of row-cell range: #{row}-#{cell}"
+ end
+ return (row + 0x20) << 8 | (cell + 0x20)
+ end
+ end
+end
diff --git a/jni/ruby/tool/make-snapshot b/jni/ruby/tool/make-snapshot
new file mode 100755
index 0000000..46387cf
--- /dev/null
+++ b/jni/ruby/tool/make-snapshot
@@ -0,0 +1,378 @@
+#!/usr/bin/ruby -s
+# -*- coding: us-ascii -*-
+require 'uri'
+require 'digest/md5'
+require 'digest/sha2'
+require 'fileutils'
+require 'tmpdir'
+require File.expand_path("../vcs", __FILE__)
+STDOUT.sync = true
+
+$srcdir ||= nil
+$exported = nil if ($exported ||= nil) == ""
+$archname = nil if ($archname ||= nil) == ""
+$keep_temp ||= nil
+$patch_file ||= nil
+$packages ||= nil
+$digests ||= nil
+$tooldir = File.expand_path("..", __FILE__)
+
+def usage
+ <<USAGE
+usage: #{File.basename $0} [option...] new-directory-to-save [version ...]
+options:
+ -srcdir=PATH source directory path
+ -exported=PATH make snapshot from already exported working directory
+ -archname=NAME make the basename of snapshots NAME
+ -keep_temp keep temporary working directory
+ -patch_file=PATCH apply PATCH file after export
+ -packages=PKG[,...] make PKG packages (#{PACKAGES.keys.join(", ")})
+ -digests=ALG[,...] show ALG digests (#{DIGESTS.join(", ")})
+version:
+ trunk, stable, branches/*, tags/*, X.Y, X.Y.Z, X.Y.Z-pL
+each versions may be followed by optional @revision.
+USAGE
+end
+
+DIGESTS = %w[MD5 SHA256 SHA512]
+PACKAGES = {
+ "bzip" => %w".tar.bz2 bzip2 -c",
+ "gzip" => %w".tar.gz gzip -c",
+ "xz" => %w".tar.xz xz -c",
+ "zip" => %w".zip zip -qr",
+}
+
+ENV["LC_ALL"] = ENV["LANG"] = "C"
+SVNURL = URI.parse("http://svn.ruby-lang.org/repos/ruby/")
+RUBY_VERSION_PATTERN = /^\#define\s+RUBY_VERSION\s+"([\d.]+)"/
+
+ENV["VPATH"] ||= "include/ruby"
+YACC = ENV["YACC"] ||= "bison"
+ENV["BASERUBY"] ||= "ruby"
+ENV["RUBY"] ||= "ruby"
+ENV["MV"] ||= "mv"
+ENV["RM"] ||= "rm -f"
+ENV["MINIRUBY"] ||= "ruby"
+ENV["PROGRAM"] ||= "ruby"
+ENV["AUTOCONF"] ||= "autoconf"
+ENV["BUILTIN_TRANSOBJS"] ||= "newline.o"
+
+class String
+ # for older ruby
+ alias bytesize size unless method_defined?(:bytesize)
+end
+
+class Dir
+ def self.mktmpdir(path)
+ path = File.join(tmpdir, path+"-#{$$}-#{rand(100000)}")
+ begin
+ mkdir(path)
+ rescue Errno::EEXIST
+ path.succ!
+ retry
+ end
+ path
+ end unless respond_to?(:mktmpdir)
+end
+
+$packages &&= $packages.split(/[, ]+/).tap {|pkg|
+ pkg -= PACKAGES.keys
+ pkg.empty? or abort "#{File.basename $0}: unknown packages - #{pkg.join(", ")}"
+}
+$packages ||= PACKAGES.keys
+
+$digests &&= $digests.split(/[, ]+/).tap {|dig|
+ dig -= DIGESTS
+ dig.empty? or abort "#{File.basename $0}: unknown digests - #{dig.join(", ")}"
+}
+$digests ||= DIGESTS
+
+$patch_file &&= File.expand_path($patch_file)
+path = ENV["PATH"].split(File::PATH_SEPARATOR)
+%w[YACC BASERUBY RUBY MV MINIRUBY].each do |var|
+ cmd = ENV[var]
+ unless path.any? {|dir|
+ file = File.expand_path(cmd, dir)
+ File.file?(file) and File.executable?(file)
+ }
+ abort "#{File.basename $0}: #{var} command not found - #{cmd}"
+ end
+end
+
+%w[BASERUBY RUBY MINIRUBY].each do |var|
+ `#{ENV[var]} --disable-gem -e1 2>&1`
+ if $?.success?
+ ENV[var] += ' --disable-gem'
+ end
+end
+
+if defined?($help) or defined?($_help)
+ puts usage
+ exit
+end
+unless destdir = ARGV.shift
+ abort usage
+end
+revisions = ARGV.empty? ? ["trunk"] : ARGV
+unless tmp = $exported
+ FileUtils.mkpath(destdir)
+ destdir = File.expand_path(destdir)
+ tmp = Dir.mktmpdir("ruby-snapshot")
+ FileUtils.mkpath(tmp)
+ at_exit {
+ Dir.chdir "/"
+ FileUtils.rm_rf(tmp)
+ } unless $keep_temp
+end
+
+def package(vcs, rev, destdir, tmp = nil)
+ patchlevel = false
+ prerelease = false
+ if revision = rev[/@(\d+)\z/, 1]
+ rev = $`
+ end
+ case rev
+ when /\Atrunk\z/
+ url = vcs.trunk
+ when /\Abranches\//
+ url = vcs.branch($')
+ when /\Atags\//
+ url = vcs.tag($')
+ when /\Astable\z/
+ vcs.branch_list("ruby_[0-9]*") {|n| url = n[/\Aruby_\d+_\d+\z/]}
+ url &&= vcs.branch(url)
+ when /\A(.*)\.(.*)\.(.*)-(preview|rc)(\d+)/
+ prerelease = true
+ tag = "#{$4}#{$5}"
+ url = vcs.tag("v#{$1}_#{$2}_#{$3}_#{$4}#{$5}")
+ when /\A(.*)\.(.*)\.(.*)-p(\d+)/
+ patchlevel = true
+ tag = "p#{$4}"
+ url = vcs.tag("v#{$1}_#{$2}_#{$3}_#{$4}")
+ when /\A(\d+)\.(\d+)(?:\.(\d+))?\z/
+ if $3 && ($1 > "2" || $1 == "2" && $2 >= "1")
+ patchlevel = true
+ tag = ""
+ url = vcs.tag("v#{$1}_#{$2}_#{$3}")
+ else
+ url = vcs.branch("ruby_#{rev.tr('.', '_')}")
+ end
+ else
+ warn "#{$0}: unknown version - #{rev}"
+ return
+ end
+ revision ||= vcs.get_revisions(url)[1]
+ version = nil
+ unless revision
+ url = vcs.trunk
+ vcs.grep(RUBY_VERSION_PATTERN, url, "version.h") {version = $1}
+ unless rev == version
+ warn "#{$0}: #{rev} not found"
+ return
+ end
+ revision = vcs.get_revisions(url)[1]
+ end
+ v = nil
+ if $exported
+ if String === $exported
+ v = $exported
+ end
+ else
+ v = "ruby"
+ puts "Exporting #{rev}@#{revision}"
+ exported = tmp ? File.join(tmp, v) : v
+ unless vcs.export(revision, url, exported) {|line| print line}
+ warn("Export failed")
+ return
+ end
+ if $srcdir
+ Dir.glob($srcdir + "/{tool/config.{guess,sub},gems/*.gem,.downloaded-cache/*}") do |file|
+ puts "copying #{file}"
+ dest = exported + file[$srcdir.size..-1]
+ FileUtils.mkpath(File.dirname(dest))
+ begin
+ FileUtils.ln(file, dest, force: true)
+ rescue SystemCallError
+ FileUtils.cp(file, dest, preserve: true)
+ end
+ end
+ end
+ end
+
+ Dir.chdir(tmp) if tmp
+
+ if !File.directory?(v)
+ v = Dir.glob("ruby-*").select(&File.method(:directory?))
+ v.size == 1 or abort "not exported"
+ v = v[0]
+ end
+ open("#{v}/revision.h", "wb") {|f| f.puts "#define RUBY_REVISION #{revision}"}
+ open("#{v}/.revision.time", "wb") {}
+ version ||= (versionhdr = IO.read("#{v}/version.h"))[RUBY_VERSION_PATTERN, 1]
+ version or return
+ if patchlevel
+ unless tag.empty?
+ versionhdr ||= IO.read("#{v}/version.h")
+ patchlevel = versionhdr[/^\#define\s+RUBY_PATCHLEVEL\s+(\d+)/, 1]
+ tag = (patchlevel ? "p#{patchlevel}" : "r#{revision}")
+ end
+ elsif prerelease
+ versionhdr ||= IO.read("#{v}/version.h")
+ versionhdr.sub!(/^\#define\s+RUBY_PATCHLEVEL_STR\s+"\K.+?(?=")/, tag)
+ IO.write("#{v}/version.h", versionhdr)
+ else
+ tag ||= "r#{revision}"
+ end
+ unless v == $exported
+ if $archname
+ n = $archname
+ elsif tag.empty?
+ n = "ruby-#{version}"
+ else
+ n = "ruby-#{version}-#{tag}"
+ end
+ File.directory?(n) or File.rename v, n
+ v = n
+ end
+ system(*%W"patch -d #{v} -p0 -i #{$patch_file}") if $patch_file
+ if !$exported or $patch_file
+ "take a breath, and go ahead".scan(/./) {|c|print c; sleep(c == "," ? 0.7 : 0.05)}; puts
+ end
+ def (clean = []).add(n) push(n); n end
+ Dir.chdir(v) do
+ File.open(clean.add("cross.rb"), "w") do |f|
+ f.puts "Object.__send__(:remove_const, :CROSS_COMPILING) if defined?(CROSS_COMPILING)"
+ f.puts "CROSS_COMPILING=true"
+ end
+ unless File.exist?("configure")
+ print "creating configure..."
+ unless system([ENV["AUTOCONF"]]*2)
+ puts " failed"
+ return
+ end
+ puts " done"
+ end
+ clean.add("autom4te.cache")
+ print "creating prerequisites..."
+ if File.file?("common.mk") && /^prereq/ =~ commonmk = IO.read("common.mk")
+ puts
+ extout = clean.add('tmp')
+ File.open(clean.add("config.status"), "w") {|f|
+ f.puts "s,@configure_args@,|#_!!_#|,g"
+ f.puts "s,@EXTOUT@,|#_!!_#|#{extout},g"
+ f.puts "s,@bindir@,|#_!!_#|,g"
+ f.puts "s,@ruby_install_name@,|#_!!_#|,g"
+ f.puts "s,@ARCH_FLAG@,|#_!!_#|,g"
+ f.puts "s,@CFLAGS@,|#_!!_#|,g"
+ f.puts "s,@CPPFLAGS@,|#_!!_#|,g"
+ f.puts "s,@CXXFLAGS@,|#_!!_#|,g"
+ f.puts "s,@LDFLAGS@,|#_!!_#|,g"
+ f.puts "s,@DLDFLAGS@,|#_!!_#|,g"
+ f.puts "s,@LIBEXT@,|#_!!_#|a,g"
+ f.puts "s,@OBJEXT@,|#_!!_#|o,g"
+ f.puts "s,@EXEEXT@,|#_!!_#|,g"
+ f.puts "s,@LIBRUBY@,|#_!!_#|libruby.a,g"
+ f.puts "s,@LIBRUBY_A@,|#_!!_#|libruby.a,g"
+ f.puts "s,@RM@,|#_!!_#|rm -f,g"
+ f.puts "s,@CP@,|#_!!_#|cp,g"
+ f.puts "s,@rubyarchdir@,|#_!!_#|,g"
+ }
+ FileUtils.mkpath(hdrdir = "#{extout}/include/ruby")
+ File.open("#{hdrdir}/config.h", "w") {}
+ miniruby = ENV['MINIRUBY'] + " -I. -rcross"
+ mk = IO.read("Makefile.in").gsub(/^@.*\n/, '').gsub(/@([A-Za-z_]\w*)@/) {ENV[$1]}
+ mk << commonmk.gsub(/(?<!#)\{[^{}]*\}/, "")
+ cmd = %W[make -f -
+ srcdir=. CHDIR=cd NULLCMD=:
+ PATH_SEPARATOR=#{File::PATH_SEPARATOR}
+ IFCHANGE=tool/ifchange MAKEDIRS=mkdir\ -p
+ RMALL=rm\ -fr
+ MINIRUBY=#{miniruby}
+ RUNRUBY=#{miniruby}
+ RUBY=#{ENV["RUBY"]}
+ HAVE_BASERUBY=yes
+ BASERUBY=#{ENV["BASERUBY"]}
+ PWD=#{Dir.pwd}
+ prereq]
+ IO.popen(cmd, "w") do |f|
+ f.puts mk
+ f.puts "after-update::", "clean-cache $(CLEAN_CACHE): after-update", "prereq: clean-cache $(CLEAN_CACHE)"
+ end
+ clean.push("rbconfig.rb", ".rbconfig.time", "enc.mk")
+ print "prerequisites"
+ else
+ system(*%W"#{YACC} -o parse.c parse.y")
+ end
+ FileUtils.rm_rf(clean)
+ unless $?.success?
+ puts " failed"
+ return
+ end
+ puts " done"
+ end
+
+ if v == "."
+ v = File.basename(Dir.pwd)
+ Dir.chdir ".."
+ else
+ Dir.chdir(File.dirname(v))
+ v = File.basename(v)
+ end
+
+ tarball = nil
+ return $packages.collect do |mesg|
+ (ext, *cmd) = PACKAGES[mesg]
+ File.directory?(destdir) or FileUtils.mkpath(destdir)
+ file = File.join(destdir, "#{$archname||v}#{ext}")
+ case ext
+ when /\.tar/
+ if tarball
+ next if tarball.empty?
+ else
+ tarball = "#{$archname||v}.tar"
+ print "creating tarball... #{tarball}"
+ if system("tar", "cf", tarball, v)
+ puts " done"
+ else
+ puts " failed"
+ tarball = ""
+ next
+ end
+ end
+ print "creating #{mesg} tarball... #{file}"
+ done = system(*cmd, tarball, out: file)
+ else
+ print "creating #{mesg} archive... #{file}"
+ done = system(*cmd, file, v)
+ end
+ if done
+ puts " done"
+ file
+ else
+ puts " failed"
+ nil
+ end
+ end.compact
+ensure
+ FileUtils.rm_rf(v) if v and !$exported and !$keep_temp
+end
+
+vcs = (VCS.detect($srcdir) rescue nil if $srcdir) || VCS::SVN.new(SVNURL)
+
+success = true
+revisions.collect {|rev| package(vcs, rev, destdir, tmp)}.flatten.each do |name|
+ if !name
+ success = false
+ next
+ end
+ str = open(name, "rb") {|f| f.read}
+ puts "* #{name}"
+ puts " SIZE: #{str.bytesize} bytes"
+ $digests.each do |alg|
+ printf " %-8s%s\n", "#{alg}:", Digest.const_get(alg).hexdigest(str)
+ end
+end
+
+exit false if !success
+
+# vim:fileencoding=US-ASCII sw=2 ts=4 noexpandtab ff=unix
diff --git a/jni/ruby/tool/mdoc2man.rb b/jni/ruby/tool/mdoc2man.rb
new file mode 100755
index 0000000..49058af
--- /dev/null
+++ b/jni/ruby/tool/mdoc2man.rb
@@ -0,0 +1,465 @@
+#!/usr/bin/env ruby
+###
+### mdoc2man - mdoc to man converter
+###
+### Quick usage: mdoc2man.rb < mdoc_manpage.8 > man_manpage.8
+###
+### Ported from Perl by Akinori MUSHA.
+###
+### Copyright (c) 2001 University of Illinois Board of Trustees
+### Copyright (c) 2001 Mark D. Roth
+### Copyright (c) 2002, 2003 Akinori MUSHA
+### All rights reserved.
+###
+### Redistribution and use in source and binary forms, with or without
+### modification, are permitted provided that the following conditions
+### are met:
+### 1. Redistributions of source code must retain the above copyright
+### notice, this list of conditions and the following disclaimer.
+### 2. Redistributions in binary form must reproduce the above copyright
+### notice, this list of conditions and the following disclaimer in the
+### documentation and/or other materials provided with the distribution.
+### 3. All advertising materials mentioning features or use of this software
+### must display the following acknowledgement:
+### This product includes software developed by the University of
+### Illinois at Urbana, and their contributors.
+### 4. The University nor the names of their
+### contributors may be used to endorse or promote products derived from
+### this software without specific prior written permission.
+###
+### THIS SOFTWARE IS PROVIDED BY THE TRUSTEES AND CONTRIBUTORS ``AS IS'' AND
+### ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+### IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+### ARE DISCLAIMED. IN NO EVENT SHALL THE TRUSTEES OR CONTRIBUTORS BE LIABLE
+### FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+### DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+### OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+### HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+### LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+### OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+### SUCH DAMAGE.
+###
+### $Id: mdoc2man.rb 31573 2011-05-15 11:55:52Z nobu $
+###
+
+class Mdoc2Man
+ ANGLE = 1
+ OPTION = 2
+ PAREN = 3
+
+ RE_PUNCT = /^[!"'),\.\/:;>\?\]`]$/
+
+ def initialize
+ @name = @date = @id = nil
+ @refauthors = @reftitle = @refissue = @refdate = @refopt = nil
+
+ @optlist = 0 ### 1 = bullet, 2 = enum, 3 = tag, 4 = item
+ @oldoptlist = 0
+ @nospace = 0 ### 0, 1, 2
+ @enum = 0
+ @synopsis = true
+ @reference = false
+ @ext = false
+ @extopt = false
+ @literal = false
+ end
+
+ def mdoc2man(i, o)
+ i.each { |line|
+ if /^\./ !~ line
+ o.print line
+ o.print ".br\n" if @literal
+ next
+ end
+
+ line.slice!(0, 1)
+
+ next if /\\"/ =~ line
+
+ line = parse_macro(line) and o.print line
+ }
+
+ initialize
+ end
+
+ def parse_macro(line)
+ words = line.split
+ retval = ''
+
+ quote = []
+ dl = false
+
+ while word = words.shift
+ case word
+ when RE_PUNCT
+ while q = quote.pop
+ case q
+ when OPTION
+ retval << ']'
+ when PAREN
+ retval << ')'
+ when ANGLE
+ retval << '>'
+ end
+ end
+ retval << word
+ next
+ when 'Li', 'Pf'
+ @nospace = 1
+ next
+ when 'Xo'
+ @ext = true
+ retval << ' ' unless retval.empty? || /[\n ]\z/ =~ retval
+ next
+ when 'Xc'
+ @ext = false
+ retval << "\n" unless @extopt
+ break
+ when 'Bd'
+ @literal = true if words[0] == '-literal'
+ retval << "\n"
+ break
+ when 'Ed'
+ @literal = false
+ break
+ when 'Ns'
+ @nospace = 1 if @nospace == 0
+ retval.chomp!(' ')
+ next
+ when 'No'
+ retval.chomp!(' ')
+ retval << words.shift
+ next
+ when 'Dq'
+ retval << '``'
+ begin
+ retval << words.shift << ' '
+ end until words.empty? || RE_PUNCT =~ words[0]
+ retval.chomp!(' ')
+ retval << '\'\''
+ @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]
+ next
+ when 'Sq', 'Ql'
+ retval << '`' << words.shift << '\''
+ @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]
+ next
+ # when 'Ic'
+ # retval << '\\fB' << words.shift << '\\fP'
+ # next
+ when 'Oo'
+ #retval << "[\\c\n"
+ @extopt = true
+ @nospace = 1 if @nospace == 0
+ retval << '['
+ next
+ when 'Oc'
+ @extopt = false
+ retval << ']'
+ next
+ when 'Ao'
+ @nospace = 1 if @nospace == 0
+ retval << '<'
+ next
+ when 'Ac'
+ retval << '>'
+ next
+ end
+
+ retval << ' ' if @nospace == 0 && !(retval.empty? || /[\n ]\z/ =~ retval)
+ @nospace = 0 if @nospace == 1
+
+ case word
+ when 'Dd'
+ @date = words.join(' ')
+ return nil
+ when 'Dt'
+ if words.size >= 2 && words[1] == '""' &&
+ /^(.*)\(([0-9])\)$/ =~ words[0]
+ words[0] = $1
+ words[1] = $2
+ end
+ @id = words.join(' ')
+ return nil
+ when 'Os'
+ retval << '.TH ' << @id << ' "' << @date << '" "' <<
+ words.join(' ') << '"'
+ break
+ when 'Sh'
+ retval << '.SH'
+ @synopsis = (words[0] == 'SYNOPSIS')
+ next
+ when 'Xr'
+ retval << '\\fB' << words.shift <<
+ '\\fP(' << words.shift << ')' << (words.shift||'')
+ break
+ when 'Rs'
+ @refauthors = []
+ @reftitle = ''
+ @refissue = ''
+ @refdate = ''
+ @refopt = ''
+ @reference = true
+ break
+ when 'Re'
+ retval << "\n"
+
+ # authors
+ while @refauthors.size > 1
+ retval << @refauthors.shift << ', '
+ end
+ retval << 'and ' unless retval.empty?
+ retval << @refauthors.shift
+
+ # title
+ retval << ', \\fI' << @reftitle << '\\fP'
+
+ # issue
+ retval << ', ' << @refissue unless @refissue.empty?
+
+ # date
+ retval << ', ' << @refdate unless @refdate.empty?
+
+ # optional info
+ retval << ', ' << @refopt unless @refopt.empty?
+
+ retval << ".\n"
+
+ @reference = false
+ break
+ when 'An'
+ next
+ when 'Dl'
+ retval << ".nf\n" << '\\& '
+ dl = true
+ next
+ when 'Ux'
+ retval << "UNIX"
+ next
+ end
+
+ if @reference
+ case word
+ when '%A'
+ @refauthors.unshift(words.join(' '))
+ break
+ when '%T'
+ @reftitle = words.join(' ')
+ @reftitle.sub!(/^"/, '')
+ @reftitle.sub!(/"$/, '')
+ break
+ when '%N'
+ @refissue = words.join(' ')
+ break
+ when '%D'
+ @refdate = words.join(' ')
+ break
+ when '%O'
+ @refopt = words.join(' ')
+ break
+ end
+ end
+
+ case word
+ when 'Nm'
+ name = words.empty? ? @name : words.shift
+ @name ||= name
+ retval << ".br\n" if @synopsis
+ retval << "\\fB" << name << "\\fP"
+ @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]
+ next
+ when 'Nd'
+ retval << '\\-'
+ next
+ when 'Fl'
+ retval << '\\fB\\-' << words.shift << '\\fP'
+ @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]
+ next
+ when 'Ar'
+ retval << '\\fI'
+ if words.empty?
+ retval << 'file ...\\fP'
+ else
+ retval << words.shift << '\\fP'
+ while words[0] == '|'
+ retval << ' ' << words.shift << ' \\fI' << words.shift << '\\fP'
+ end
+ @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]
+ next
+ end
+ when 'Cm'
+ retval << '\\fB' << words.shift << '\\fP'
+ while RE_PUNCT =~ words[0]
+ retval << words.shift
+ end
+ next
+ when 'Op'
+ quote << OPTION
+ @nospace = 1 if @nospace == 0
+ retval << '['
+ # words.push(words.pop + ']')
+ next
+ when 'Aq'
+ quote << ANGLE
+ @nospace = 1 if @nospace == 0
+ retval << '<'
+ # words.push(words.pop + '>')
+ next
+ when 'Pp'
+ retval << "\n"
+ next
+ when 'Ss'
+ retval << '.SS'
+ next
+ end
+
+ if word == 'Pa' && !quote.include?(OPTION)
+ retval << '\\fI'
+ retval << '\\&' if /^\./ =~ words[0]
+ retval << words.shift << '\\fP'
+ while RE_PUNCT =~ words[0]
+ retval << words.shift
+ end
+ # @nospace = 1 if @nospace == 0 && RE_PUNCT =~ words[0]
+ next
+ end
+
+ case word
+ when 'Dv'
+ retval << '.BR'
+ next
+ when 'Em', 'Ev'
+ retval << '.IR'
+ next
+ when 'Pq'
+ retval << '('
+ @nospace = 1
+ quote << PAREN
+ next
+ when 'Sx', 'Sy'
+ retval << '.B ' << words.join(' ')
+ break
+ when 'Ic'
+ retval << '\\fB'
+ until words.empty? || RE_PUNCT =~ words[0]
+ case words[0]
+ when 'Op'
+ words.shift
+ retval << '['
+ words.push(words.pop + ']')
+ next
+ when 'Aq'
+ words.shift
+ retval << '<'
+ words.push(words.pop + '>')
+ next
+ when 'Ar'
+ words.shift
+ retval << '\\fI' << words.shift << '\\fP'
+ else
+ retval << words.shift
+ end
+
+ retval << ' ' if @nospace == 0
+ end
+
+ retval.chomp!(' ')
+ retval << '\\fP'
+ retval << words.shift unless words.empty?
+ break
+ when 'Bl'
+ @oldoptlist = @optlist
+
+ case words[0]
+ when '-bullet'
+ @optlist = 1
+ when '-enum'
+ @optlist = 2
+ @enum = 0
+ when '-tag'
+ @optlist = 3
+ when '-item'
+ @optlist = 4
+ end
+
+ break
+ when 'El'
+ @optlist = @oldoptlist
+ next
+ end
+
+ if @optlist != 0 && word == 'It'
+ case @optlist
+ when 1
+ # bullets
+ retval << '.IP \\(bu'
+ when 2
+ # enum
+ @enum += 1
+ retval << '.IP ' << @enum << '.'
+ when 3
+ # tags
+ retval << ".TP\n"
+ case words[0]
+ when 'Pa', 'Ev'
+ words.shift
+ retval << '.B'
+ end
+ when 4
+ # item
+ retval << ".IP\n"
+ end
+
+ next
+ end
+
+ case word
+ when 'Sm'
+ case words[0]
+ when 'off'
+ @nospace = 2
+ when 'on'
+ # retval << "\n"
+ @nospace = 0
+ end
+ words.shift
+ next
+ end
+
+ retval << word
+ end
+
+ return nil if retval == '.'
+
+ retval.sub!(/\A\.([^a-zA-Z])/, "\\1")
+ # retval.chomp!(' ')
+
+ while q = quote.pop
+ case q
+ when OPTION
+ retval << ']'
+ when PAREN
+ retval << ')'
+ when ANGLE
+ retval << '>'
+ end
+ end
+
+ # retval << ' ' unless @nospace == 0 || retval.empty? || /\n\z/ =~ retval
+
+ retval << ' ' unless !@ext || @extopt || / $/ =~ retval
+
+ retval << "\n" unless @ext || @extopt || retval.empty? || /\n\z/ =~ retval
+
+ retval << ".fi\n" if dl
+
+ return retval
+ end
+
+ def self.mdoc2man(i, o)
+ new.mdoc2man(i, o)
+ end
+end
+
+if $0 == __FILE__
+ Mdoc2Man.mdoc2man(ARGF, STDOUT)
+end
diff --git a/jni/ruby/tool/merger.rb b/jni/ruby/tool/merger.rb
new file mode 100755
index 0000000..9449938
--- /dev/null
+++ b/jni/ruby/tool/merger.rb
@@ -0,0 +1,259 @@
+#!/bin/sh
+# -*- ruby -*-
+exec "${RUBY-ruby}" "-x" "$0" "$@" && [ ] if false
+#!ruby
+# This needs ruby 1.9 and subversion.
+# run this in a repository to commit.
+
+require 'date'
+require 'tempfile'
+
+$repos = 'svn+ssh://svn@ci.ruby-lang.org/ruby/'
+ENV['LC_ALL'] = 'C'
+
+def help
+ puts <<-end
+simple backport
+ ruby #$0 1234
+
+range backport
+ ruby #$0 1234:5678
+
+backport from other branch
+ ruby #$0 17502 mvm
+
+revision increment
+ ruby #$0 revisionup
+
+tagging major release
+ ruby #$0 tag 2.2.0
+
+tagging patch release (about 2.1.0 or later, it means X.Y.Z (Z > 0) release)
+ ruby #$0 tag
+
+tagging preview/RC
+ ruby #$0 tag 2.2.0-preview1
+
+* all operations shall be applied to the working directory.
+end
+end
+
+def version
+ v = p = nil
+ open 'version.h', 'rb' do |f|
+ f.each_line do |l|
+ case l
+ when /^#define RUBY_VERSION "(\d)\.(\d)\.(\d)"$/
+ v = $~.captures
+ when /^#define RUBY_PATCHLEVEL (-?\d+)$/
+ p = $1
+ end
+ end
+ end
+ return v, p
+end
+
+def interactive str, editfile = nil
+ loop do
+ yield
+ STDERR.puts "#{str} ([y]es|[a]bort|[r]etry#{'|[e]dit' if editfile})"
+ case STDIN.gets
+ when /\Aa/i then exit
+ when /\Ar/i then redo
+ when /\Ay/i then break
+ when /\Ae/i then system(ENV["EDITOR"], editfile)
+ else exit
+ end
+ end
+end
+
+def version_up
+ d = DateTime.now
+ d = d.new_offset(Rational(9,24)) # we need server locale (i.e. japanese) time
+ system(*%w'svn revert version.h')
+ v, p = version
+
+ teeny = v[2]
+ case v
+ when %w/1 9 2/
+ teeny = 1
+ end
+
+ p = p.to_i
+ if p != -1
+ p += 1
+ end
+
+ str = open 'version.h', 'rb' do |f| f.read end
+ [%W[RUBY_VERSION "#{v.join '.'}"],
+ %W[RUBY_VERSION_CODE #{v.join ''}],
+ %W[RUBY_VERSION_MAJOR #{v[0]}],
+ %W[RUBY_VERSION_MINOR #{v[1]}],
+ %W[RUBY_VERSION_TEENY #{teeny}],
+ %W[RUBY_RELEASE_DATE "#{d.strftime '%Y-%m-%d'}"],
+ %W[RUBY_RELEASE_CODE #{d.strftime '%Y%m%d'}],
+ %W[RUBY_PATCHLEVEL #{p}],
+ %W[RUBY_RELEASE_YEAR #{d.year}],
+ %W[RUBY_RELEASE_MONTH #{d.month}],
+ %W[RUBY_RELEASE_DAY #{d.day}],
+ ].each do |(k, i)|
+ str.sub!(/^(#define\s+#{k}\s+).*$/, "\\1#{i}")
+ end
+ str.sub!(/\s+\z/m, '')
+ fn = sprintf 'version.h.tmp.%032b', rand(1 << 31)
+ File.rename 'version.h', fn
+ open 'version.h', 'wb' do |f|
+ f.puts str
+ end
+ File.unlink fn
+end
+
+def tag intv_p = false, relname=nil
+ # relname:
+ # * 2.2.0-preview1
+ # * 2.2.0-rc1
+ # * 2.2.0
+ v, pl = version
+ x = v.join('_')
+ if relname
+ abort "patchlevel is not -1 but '#{pl}' for preview or rc" if pl != '-1' && /-(?:preview|rc)/ =~ relname
+ abort "patchlevel is not 0 but '#{pl}' for the first release" if pl != '0' && /-(?:preview|rc)/ !~ relname
+ pl = relname[/-(.*)\z/, 1]
+ curver = v.join('.') + (pl ? '-' + pl : '')
+ if relname != curver
+ abort "given relname '#{relname}' conflicts current version '#{curver}'"
+ end
+ branch_url = `svn info`[/URL: (.*)/, 1]
+ else
+ if pl == '-1'
+ abort "no relname is given and not in a release branch even if this is patch release"
+ end
+ branch_url = $repos + 'branches/ruby_'
+ if v[0] < "2" || (v[0] == "2" && v[1] < "1")
+ abort "patchlevel must be greater than 0 for patch release" if pl == "0"
+ branch_url << x
+ else
+ abort "teeny must be greater than 0 for patch release" if v[2] == "0"
+ branch_url << x.sub(/_\d+$/, '')
+ end
+ end
+ tagname = 'v' + x + (v[0] < "2" || (v[0] == "2" && v[1] < "1") || /^(?:preview|rc)/ =~ pl ? '_' + pl : '')
+ tag_url = $repos + 'tags/' + tagname
+ if intv_p
+ interactive "OK? svn cp -m \"add tag #{tagname}\" #{branch_url} #{tag_url}" do
+ end
+ end
+ system(*%w'svn cp -m', "add tag #{tagname}", branch_url, tag_url)
+end
+
+def default_merge_branch
+ %r{^URL: .*/branches/ruby_1_8_} =~ `svn info` ? 'branches/ruby_1_8' : 'trunk'
+end
+
+case ARGV[0]
+when "up", /\A(ver|version|rev|revision|lv|level|patch\s*level)\s*up/
+ version_up
+ system 'svn diff version.h'
+when "tag"
+ tag :interactive, ARGV[1]
+when nil, "-h", "--help"
+ help
+ exit
+else
+ system 'svn up'
+
+ if /--ticket=(.*)/ =~ ARGV[0]
+ tickets = $1.split(/,/).map{|num| " [Backport ##{num}]"}
+ ARGV.shift
+ else
+ tickets = []
+ end
+
+ q = $repos + (ARGV[1] || default_merge_branch)
+ revstr = ARGV[0].delete('^, :\-0-9')
+ revs = revstr.split(/[,\s]+/)
+ log = ''
+ log_svn = ''
+
+ revs.each do |rev|
+ case rev
+ when /\A\d+:\d+\z/
+ r = ['-r', rev]
+ when /\A(\d+)-(\d+)\z/
+ rev = "#{$1.to_i-1}:#$2"
+ r = ['-r', rev]
+ when /\A\d+\z/
+ r = ['-c', rev]
+ when nil then
+ puts "#$0 revision"
+ exit
+ else
+ puts "invalid revision part '#{rev}' in '#{ARGV[0]}'"
+ exit
+ end
+
+ l = IO.popen %w'svn diff' + r + %w'--diff-cmd=diff -x -pU0' + [File.join(q, 'ChangeLog')] do |f|
+ f.read
+ end
+
+ log << l
+ log_svn << l.lines.grep(/^\+\t/).join.gsub(/^\+/, '').gsub(/^\t\*/, "\n\t\*")
+
+ if log_svn.empty?
+ log_svn = IO.popen %w'svn log ' + r + [q] do |f|
+ f.read
+ end.sub(/\A-+\nr.*\n/, '').sub(/\n-+\n\z/, '').gsub(/^(?=\S)/, "\t")
+ end
+
+ a = %w'svn merge --accept=postpone' + r + [q]
+ STDERR.puts a.join(' ')
+
+ system(*a)
+ system(*%w'svn revert ChangeLog') if /^\+/ =~ l
+ end
+
+ if `svn diff --diff-cmd=diff -x -upw`.empty?
+ interactive 'Only ChangeLog is modified, right?' do
+ end
+ end
+
+ if /^\+/ =~ log
+ system(*%w'svn revert ChangeLog')
+ IO.popen %w'patch -p0', 'wb' do |f|
+ f.write log.gsub(/\+(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) [ 123][0-9] [012][0-9]:[0-5][0-9]:[0-5][0-9] \d\d\d\d/,
+ # this format-time-string was from the file local variables of ChangeLog
+ '+'+Time.now.strftime('%a %b %e %H:%M:%S %Y'))
+ end
+ system(*%w'touch ChangeLog') # needed somehow, don't know why...
+ else
+ STDERR.puts '*** You should write ChangeLog NOW!!! ***'
+ end
+
+ version_up
+ f = Tempfile.new 'merger.rb'
+ f.printf "merge revision(s) %s:%s\n", revstr, tickets.join
+ f.write log_svn
+ f.flush
+ f.close
+
+ interactive 'conflicts resolved?', f.path do
+ IO.popen(ENV["PAGER"] || "less", "w") do |g|
+ g << `svn stat`
+ g << "\n\n"
+ f.open
+ g << f.read
+ f.close
+ g << "\n\n"
+ g << `svn diff --diff-cmd=diff -x -upw`
+ end
+ end
+
+ if system(*%w'svn ci -F', f.path)
+ # tag :interactive # no longer needed.
+ system 'rm -f subversion.commitlog'
+ else
+ puts 'commit failed; try again.'
+ end
+
+ f.close(true)
+end
diff --git a/jni/ruby/tool/mkconfig.rb b/jni/ruby/tool/mkconfig.rb
new file mode 100755
index 0000000..30a259d
--- /dev/null
+++ b/jni/ruby/tool/mkconfig.rb
@@ -0,0 +1,290 @@
+#!./miniruby -s
+
+# avoid warnings with -d.
+$install_name ||= nil
+$so_name ||= nil
+
+srcdir = File.expand_path('../..', __FILE__)
+$:.replace [srcdir+"/lib"] unless defined?(CROSS_COMPILING)
+$:.unshift(".")
+
+require "fileutils"
+mkconfig = File.basename($0)
+
+rbconfig_rb = ARGV[0] || 'rbconfig.rb'
+unless File.directory?(dir = File.dirname(rbconfig_rb))
+ FileUtils.makedirs(dir, :verbose => true)
+end
+
+version = RUBY_VERSION
+config = ""
+def config.write(arg)
+ concat(arg.to_s)
+end
+$stdout = config
+
+fast = {'prefix'=>TRUE, 'ruby_install_name'=>TRUE, 'INSTALL'=>TRUE, 'EXEEXT'=>TRUE}
+print %[
+# This file was created by #{mkconfig} when ruby was built. Any
+# changes made to this file will be lost the next time ruby is built.
+
+module RbConfig
+ RUBY_VERSION.start_with?("#{version}"[/^[0-9]+[.][0-9]+[.]/]) or
+ raise "ruby lib version (#{version}) doesn't match executable version (\#{RUBY_VERSION})"
+
+]
+
+arch = RUBY_PLATFORM
+win32 = /mswin/ =~ arch
+universal = /universal.*darwin/ =~ arch
+v_fast = []
+v_others = []
+vars = {}
+continued_name = nil
+continued_line = nil
+install_name = nil
+so_name = nil
+File.foreach "config.status" do |line|
+ next if /^#/ =~ line
+ name = nil
+ case line
+ when /^s([%,])@(\w+)@\1(?:\|\#_!!_\#\|)?(.*)\1/
+ name = $2
+ val = $3.gsub(/\\(?=,)/, '')
+ when /^S\["(\w+)"\]\s*=\s*"(.*)"\s*(\\)?$/
+ name = $1
+ val = $2
+ if $3
+ continued_line = [val]
+ continued_name = name
+ next
+ end
+ when /^"(.*)"\s*(\\)?$/
+ next if !continued_line
+ continued_line << $1
+ next if $2
+ continued_line.each {|s| s.sub!(/\\n\z/, "\n")}
+ val = continued_line.join
+ name = continued_name
+ continued_line = nil
+ when /^(?:ac_given_)?INSTALL=(.*)/
+ v_fast << " CONFIG[\"INSTALL\"] = " + $1 + "\n"
+ end
+
+ if name
+ case name
+ when /^(?:ac_.*|configure_input|(?:top_)?srcdir|\w+OBJS)$/; next
+ when /^(?:X|(?:MINI|RUN|BASE)RUBY$)/; next
+ when /^(?:MAJOR|MINOR|TEENY)$/; vars[name] = val; next
+ when /^LIBRUBY_D?LD/; next
+ when /^RUBY_INSTALL_NAME$/; next vars[name] = (install_name = val).dup if $install_name
+ when /^RUBY_SO_NAME$/; next vars[name] = (so_name = val).dup if $so_name
+ when /^arch$/; if val.empty? then val = arch else arch = val end
+ when /^sitearch$/; val = '$(arch)' if val.empty?
+ end
+ case val
+ when /^\$\(ac_\w+\)$/; next
+ when /^\$\{ac_\w+\}$/; next
+ when /^\$ac_\w+$/; next
+ end
+ if /^program_transform_name$/ =~ name
+ val.sub!(/\As(\\?\W)(?:\^|\${1,2})\1\1(;|\z)/, '')
+ if val.empty?
+ $install_name ||= "ruby"
+ next
+ end
+ unless $install_name
+ $install_name = "ruby"
+ val.gsub!(/\$\$/, '$')
+ val.scan(%r[\G[\s;]*(/(?:\\.|[^/])*/)?([sy])(\\?\W)((?:(?!\3)(?:\\.|.))*)\3((?:(?!\3)(?:\\.|.))*)\3([gi]*)]) do
+ |addr, cmd, sep, pat, rep, opt|
+ if addr
+ Regexp.new(addr[/\A\/(.*)\/\z/, 1]) =~ $install_name or next
+ end
+ case cmd
+ when 's'
+ pat = Regexp.new(pat, opt.include?('i'))
+ if opt.include?('g')
+ $install_name.gsub!(pat, rep)
+ else
+ $install_name.sub!(pat, rep)
+ end
+ when 'y'
+ $install_name.tr!(Regexp.quote(pat), rep)
+ end
+ end
+ end
+ end
+ eq = win32 && vars[name] ? '<< "\n"' : '='
+ vars[name] = val
+ if name == "configure_args"
+ val.gsub!(/--with-out-ext/, "--without-ext")
+ end
+ val = val.gsub(/\$(?:\$|\{?(\w+)\}?)/) {$1 ? "$(#{$1})" : $&}.dump
+ case name
+ when /^prefix$/
+ val = "(TOPDIR || DESTDIR + #{val})"
+ when /^ARCH_FLAG$/
+ val = "arch_flag || #{val}" if universal
+ when /^UNIVERSAL_ARCHNAMES$/
+ universal, val = val, 'universal' if universal
+ when /^arch$/
+ if universal
+ val.sub!(/universal/, %q[#{arch && universal[/(?:\A|\s)#{Regexp.quote(arch)}=(\S+)/, 1] || '\&'}])
+ end
+ end
+ v = " CONFIG[\"#{name}\"] #{eq} #{val}\n"
+ if fast[name]
+ v_fast << v
+ else
+ v_others << v
+ end
+ case name
+ when "ruby_version"
+ version = val[/\A"(.*)"\z/, 1]
+ end
+ end
+# break if /^CEOF/
+end
+
+drive = File::PATH_SEPARATOR == ';'
+
+def vars.expand(val, config = self)
+ newval = val.gsub(/\$\$|\$\(([^()]+)\)|\$\{([^{}]+)\}/) {
+ var = $&
+ if !(v = $1 || $2)
+ '$'
+ elsif key = config[v = v[/\A[^:]+(?=(?::(.*?)=(.*))?\z)/]]
+ pat, sub = $1, $2
+ config[v] = false
+ config[v] = expand(key, config)
+ key = key.gsub(/#{Regexp.quote(pat)}(?=\s|\z)/n) {sub} if pat
+ key
+ else
+ var
+ end
+ }
+ val.replace(newval) unless newval == val
+ val
+end
+prefix = vars.expand(vars["prefix"] ||= "")
+rubyarchdir = vars.expand(vars["rubyarchdir"] ||= "")
+relative_archdir = rubyarchdir.rindex(prefix, 0) ? rubyarchdir[prefix.size..-1] : rubyarchdir
+print " TOPDIR = File.dirname(__FILE__).chomp!(#{relative_archdir.dump})\n"
+print " DESTDIR = ", (drive ? "TOPDIR && TOPDIR[/\\A[a-z]:/i] || " : ""), "'' unless defined? DESTDIR\n"
+print <<'ARCH' if universal
+ arch_flag = ENV['ARCHFLAGS'] || ((e = ENV['RC_ARCHS']) && e.split.uniq.map {|a| "-arch #{a}"}.join(' '))
+ arch = arch_flag && arch_flag[/\A\s*-arch\s+(\S+)\s*\z/, 1]
+ARCH
+print " universal = #{universal}\n" if universal
+print " CONFIG = {}\n"
+print " CONFIG[\"DESTDIR\"] = DESTDIR\n"
+
+versions = {}
+IO.foreach(File.join(srcdir, "version.h")) do |l|
+ m = /^\s*#\s*define\s+RUBY_(PATCHLEVEL)\s+(-?\d+)/.match(l)
+ if m
+ versions[m[1]] = m[2]
+ break
+ end
+end
+IO.foreach(File.join(srcdir, "include/ruby/version.h")) do |l|
+ m = /^\s*#\s*define\s+RUBY_API_VERSION_(MAJOR|MINOR|TEENY)\s+(-?\d+)/.match(l)
+ if m
+ versions[m[1]] = m[2]
+ break if versions.size == 4
+ end
+end
+%w[MAJOR MINOR TEENY PATCHLEVEL].each do |v|
+ print " CONFIG[#{v.dump}] = #{versions[v].dump}\n"
+end
+
+dest = drive ? %r'= "(?!\$[\(\{])(?i:[a-z]:)' : %r'= "(?!\$[\(\{])'
+v_disabled = {}
+v_others.collect! do |x|
+ if /^\s*CONFIG\["((?!abs_|old)[a-z]+(?:_prefix|dir))"\]/ === x
+ name = $1
+ if /= "no"$/ =~ x
+ v_disabled[name] = true
+ v_others.delete(name)
+ next
+ end
+ x.sub(dest, '= "$(DESTDIR)')
+ else
+ x
+ end
+end
+v_others.compact!
+
+if $install_name
+ if install_name and vars.expand("$(RUBY_INSTALL_NAME)") == $install_name
+ $install_name = install_name
+ end
+ v_fast << " CONFIG[\"ruby_install_name\"] = \"" + $install_name + "\"\n"
+ v_fast << " CONFIG[\"RUBY_INSTALL_NAME\"] = \"" + $install_name + "\"\n"
+end
+if $so_name
+ if so_name and vars.expand("$(RUBY_SO_NAME)") == $so_name
+ $so_name = so_name
+ end
+ v_fast << " CONFIG[\"RUBY_SO_NAME\"] = \"" + $so_name + "\"\n"
+end
+
+print(*v_fast)
+print(*v_others)
+print <<EOS
+ CONFIG["archdir"] = "$(rubyarchdir)"
+ CONFIG["topdir"] = File.dirname(__FILE__)
+ MAKEFILE_CONFIG = {}
+ CONFIG.each{|k,v| MAKEFILE_CONFIG[k] = v.dup}
+ def RbConfig::expand(val, config = CONFIG)
+ newval = val.gsub(/\\$\\$|\\$\\(([^()]+)\\)|\\$\\{([^{}]+)\\}/) {
+ var = $&
+ if !(v = $1 || $2)
+ '$'
+ elsif key = config[v = v[/\\A[^:]+(?=(?::(.*?)=(.*))?\\z)/]]
+ pat, sub = $1, $2
+ config[v] = false
+ config[v] = RbConfig::expand(key, config)
+ key = key.gsub(/\#{Regexp.quote(pat)}(?=\\s|\\z)/n) {sub} if pat
+ key
+ else
+ var
+ end
+ }
+ val.replace(newval) unless newval == val
+ val
+ end
+ CONFIG.each_value do |val|
+ RbConfig::expand(val)
+ end
+
+ # returns the absolute pathname of the ruby command.
+ def RbConfig.ruby
+ File.join(
+ RbConfig::CONFIG["bindir"],
+ RbConfig::CONFIG["ruby_install_name"] + RbConfig::CONFIG["EXEEXT"]
+ )
+ end
+end
+CROSS_COMPILING = nil unless defined? CROSS_COMPILING
+EOS
+
+$stdout = STDOUT
+mode = IO::RDWR|IO::CREAT
+mode |= IO::BINARY if defined?(IO::BINARY)
+open(rbconfig_rb, mode) do |f|
+ if $timestamp and f.stat.size == config.size and f.read == config
+ puts "#{rbconfig_rb} unchanged"
+ else
+ puts "#{rbconfig_rb} updated"
+ f.rewind
+ f.truncate(0)
+ f.print(config)
+ end
+end
+if String === $timestamp
+ FileUtils.touch($timestamp)
+end
+
+# vi:set sw=2:
diff --git a/jni/ruby/tool/mkrunnable.rb b/jni/ruby/tool/mkrunnable.rb
new file mode 100755
index 0000000..7d37418
--- /dev/null
+++ b/jni/ruby/tool/mkrunnable.rb
@@ -0,0 +1,122 @@
+#!./miniruby
+# -*- coding: us-ascii -*-
+
+require './rbconfig'
+require 'fileutils'
+
+case ARGV[0]
+when "-n"
+ ARGV.shift
+ include FileUtils::DryRun
+when "-v"
+ ARGV.shift
+ include FileUtils::Verbose
+else
+ include FileUtils
+end
+
+module Mswin
+ def ln_safe(src, dest, *opt)
+ cmd = ["mklink", dest.tr("/", "\\"), src.tr("/", "\\")]
+ cmd[1, 0] = opt
+ # TODO: use RUNAS or something
+ puts cmd.join(" ")
+ end
+
+ def ln_dir_safe(src, dest)
+ ln_safe(src, dest, "/d")
+ end
+end
+
+def ln_safe(src, dest)
+ link = File.readlink(dest) rescue nil
+ return if link == src
+ ln_sf(src, dest)
+end
+
+alias ln_dir_safe ln_safe
+
+if /mingw|mswin/ =~ (CROSS_COMPILING || RUBY_PLATFORM)
+ extend Mswin
+end
+
+def clean_path(path)
+ path = "#{path}/".gsub(/(\A|\/)(?:\.\/)+/, '\1').tr_s('/', '/')
+ nil while path.sub!(/[^\/]+\/\.\.\//, '')
+ path
+end
+
+def relative_path_from(path, base)
+ path = clean_path(path)
+ base = clean_path(base)
+ path, base = [path, base].map{|s|s.split("/")}
+ until path.empty? or base.empty? or path[0] != base[0]
+ path.shift
+ base.shift
+ end
+ path, base = [path, base].map{|s|s.join("/")}
+ if /(\A|\/)\.\.\// =~ base
+ File.expand_path(path)
+ else
+ base.gsub!(/[^\/]+/, '..')
+ File.join(base, path)
+ end
+end
+
+def ln_relative(src, dest)
+ parent = File.dirname(dest)
+ File.directory?(parent) or mkdir_p(parent)
+ ln_safe(relative_path_from(src, parent), dest)
+end
+
+def ln_dir_relative(src, dest)
+ parent = File.dirname(dest)
+ File.directory?(parent) or mkdir_p(parent)
+ ln_dir_safe(relative_path_from(src, parent), dest)
+end
+
+config = RbConfig::MAKEFILE_CONFIG.merge("prefix" => ".", "exec_prefix" => ".")
+config.each_value {|s| RbConfig.expand(s, config)}
+srcdir = config["srcdir"] ||= File.dirname(__FILE__)
+top_srcdir = config["top_srcdir"] ||= File.dirname(srcdir)
+extout = ARGV[0] || config["EXTOUT"]
+version = config["ruby_version"]
+arch = config["arch"]
+bindir = config["bindir"]
+libdirname = config["libdirname"]
+libdir = config[libdirname || "libdir"]
+vendordir = config["vendordir"]
+rubylibdir = config["rubylibdir"]
+rubyarchdir = config["rubyarchdir"]
+archdir = "#{extout}/#{arch}"
+rubylibs = [vendordir, rubylibdir, rubyarchdir]
+[bindir, libdir, archdir].uniq.each do |dir|
+ File.directory?(dir) or mkdir_p(dir)
+end
+
+exeext = config["EXEEXT"]
+ruby_install_name = config["ruby_install_name"]
+rubyw_install_name = config["rubyw_install_name"]
+goruby_install_name = "go" + ruby_install_name
+[ruby_install_name, rubyw_install_name, goruby_install_name].map do |ruby|
+ ruby += exeext
+ if ruby and !ruby.empty?
+ ln_relative(ruby, "#{bindir}/#{ruby}")
+ end
+end
+so = config["LIBRUBY_SO"]
+libruby = [config["LIBRUBY_A"]]
+if /\.dll\z/i =~ so
+ ln_relative(so, "#{bindir}/#{so}")
+else
+ libruby << so
+end
+libruby.concat(config["LIBRUBY_ALIASES"].split)
+libruby.each {|lib|ln_relative(lib, "#{libdir}/#{lib}")}
+ln_dir_relative("#{extout}/common", rubylibdir)
+rubyarchdir.sub!(rubylibdir, "#{extout}/common")
+vendordir.sub!(rubylibdir, "#{extout}/common")
+ln_dir_relative(archdir, rubyarchdir)
+vendordir.sub!(rubyarchdir, archdir)
+ln_dir_relative("#{top_srcdir}/lib", vendordir)
+ln_relative("rbconfig.rb", "#{archdir}/rbconfig.rb")
diff --git a/jni/ruby/tool/node_name.rb b/jni/ruby/tool/node_name.rb
new file mode 100755
index 0000000..fef7720
--- /dev/null
+++ b/jni/ruby/tool/node_name.rb
@@ -0,0 +1,6 @@
+#! ./miniruby
+while gets
+ if ~/enum node_type \{/..~/^\};/
+ ~/(NODE_.+),/ and puts(" case #{$1}:\n\treturn \"#{$1}\";")
+ end
+end
diff --git a/jni/ruby/tool/parse.rb b/jni/ruby/tool/parse.rb
new file mode 100644
index 0000000..6243d7a
--- /dev/null
+++ b/jni/ruby/tool/parse.rb
@@ -0,0 +1,13 @@
+$file = ARGV[0]
+$str = ARGF.read.sub(/^__END__.*\z/m, '')
+puts '# ' + '-' * 70
+puts "# target program: "
+puts '# ' + '-' * 70
+puts $str
+puts '# ' + '-' * 70
+
+$parsed = RubyVM::InstructionSequence.compile_file($file)
+puts "# disasm result: "
+puts '# ' + '-' * 70
+puts $parsed.disasm
+puts '# ' + '-' * 70
diff --git a/jni/ruby/tool/probes_to_wiki.rb b/jni/ruby/tool/probes_to_wiki.rb
new file mode 100644
index 0000000..ba8204c
--- /dev/null
+++ b/jni/ruby/tool/probes_to_wiki.rb
@@ -0,0 +1,16 @@
+###
+# Converts the probes.d file to redmine wiki format. Usage:
+#
+# ruby tool/probes_to_wiki.rb probes.d
+
+File.read(ARGV[0]).scan(/\/\*.*?\*\//m).grep(/ruby/) do |comment|
+ comment.gsub!(/^(\/\*|[ ]*)|\*\/$/, '').strip!
+ puts
+ comment.each_line.with_index do |line, i|
+ if i == 0
+ puts "=== #{line.chomp}"
+ else
+ puts line.gsub(/`([^`]*)`/, '(({\1}))')
+ end
+ end
+end
diff --git a/jni/ruby/tool/rbinstall.rb b/jni/ruby/tool/rbinstall.rb
new file mode 100755
index 0000000..db36a21
--- /dev/null
+++ b/jni/ruby/tool/rbinstall.rb
@@ -0,0 +1,763 @@
+#!./miniruby
+
+begin
+ load "./rbconfig.rb"
+rescue LoadError
+ CONFIG = Hash.new {""}
+else
+ include RbConfig
+ $".unshift File.expand_path("./rbconfig.rb")
+end
+
+srcdir = File.expand_path('../..', __FILE__)
+unless defined?(CROSS_COMPILING) and CROSS_COMPILING
+ $:.replace([srcdir+"/lib", Dir.pwd])
+end
+require 'fileutils'
+require 'shellwords'
+require 'optparse'
+require 'optparse/shellwords'
+require 'ostruct'
+require 'rubygems'
+
+STDOUT.sync = true
+File.umask(0)
+
+def parse_args(argv = ARGV)
+ $mantype = 'doc'
+ $destdir = nil
+ $extout = nil
+ $make = 'make'
+ $mflags = []
+ $install = []
+ $installed_list = nil
+ $dryrun = false
+ $rdocdir = nil
+ $data_mode = 0644
+ $prog_mode = 0755
+ $dir_mode = nil
+ $script_mode = nil
+ $strip = false
+ $cmdtype = (if File::ALT_SEPARATOR == '\\'
+ File.exist?("rubystub.exe") ? 'exe' : 'bat'
+ end)
+ mflags = []
+ opt = OptionParser.new
+ opt.on('-n', '--dry-run') {$dryrun = true}
+ opt.on('--dest-dir=DIR') {|dir| $destdir = dir}
+ opt.on('--extout=DIR') {|dir| $extout = (dir unless dir.empty?)}
+ opt.on('--make=COMMAND') {|make| $make = make}
+ opt.on('--mantype=MAN') {|man| $mantype = man}
+ opt.on('--make-flags=FLAGS', '--mflags', Shellwords) do |v|
+ if arg = v.first
+ arg.insert(0, '-') if /\A[^-][^=]*\Z/ =~ arg
+ end
+ $mflags.concat(v)
+ end
+ opt.on('-i', '--install=TYPE', $install_procs.keys) do |ins|
+ $install << ins
+ end
+ opt.on('--data-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|
+ $data_mode = mode
+ end
+ opt.on('--prog-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|
+ $prog_mode = mode
+ end
+ opt.on('--dir-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|
+ $dir_mode = mode
+ end
+ opt.on('--script-mode=OCTAL-MODE', OptionParser::OctalInteger) do |mode|
+ $script_mode = mode
+ end
+ opt.on('--installed-list [FILENAME]') {|name| $installed_list = name}
+ opt.on('--rdoc-output [DIR]') {|dir| $rdocdir = dir}
+ opt.on('--cmd-type=TYPE', %w[bat cmd plain]) {|cmd| $cmdtype = (cmd unless cmd == 'plain')}
+ opt.on('--[no-]strip') {|strip| $strip = strip}
+
+ opt.order!(argv) do |v|
+ case v
+ when /\AINSTALL[-_]([-\w]+)=(.*)/
+ argv.unshift("--#{$1.tr('_', '-')}=#{$2}")
+ when /\A\w[-\w+]*=\z/
+ mflags << v
+ when /\A\w[-\w+]*\z/
+ $install << v.intern
+ else
+ raise OptionParser::InvalidArgument, v
+ end
+ end rescue abort "#{$!.message}\n#{opt.help}"
+
+ unless defined?(RbConfig)
+ puts opt.help
+ exit
+ end
+
+ $make, *rest = Shellwords.shellwords($make)
+ $mflags.unshift(*rest) unless rest.empty?
+ $mflags.unshift(*mflags)
+
+ def $mflags.set?(flag)
+ grep(/\A-(?!-).*#{flag.chr}/i) { return true }
+ false
+ end
+ def $mflags.defined?(var)
+ grep(/\A#{var}=(.*)/) {return block_given? ? yield($1) : $1}
+ false
+ end
+
+ if $mflags.set?(?n)
+ $dryrun = true
+ else
+ $mflags << '-n' if $dryrun
+ end
+
+ $destdir ||= $mflags.defined?("DESTDIR")
+ if $extout ||= $mflags.defined?("EXTOUT")
+ RbConfig.expand($extout)
+ end
+
+ $continue = $mflags.set?(?k)
+
+ if $installed_list ||= $mflags.defined?('INSTALLED_LIST')
+ RbConfig.expand($installed_list, RbConfig::CONFIG)
+ $installed_list = open($installed_list, "ab")
+ $installed_list.sync = true
+ end
+
+ $rdocdir ||= $mflags.defined?('RDOCOUT')
+
+ $dir_mode ||= $prog_mode | 0700
+ $script_mode ||= $prog_mode
+end
+
+$install_procs = Hash.new {[]}
+def install?(*types, &block)
+ $install_procs[:all] <<= block
+ types.each do |type|
+ $install_procs[type] <<= block
+ end
+end
+
+def strip_file(files)
+ if !defined?($strip_command) and (cmd = CONFIG["STRIP"])
+ case cmd
+ when "", "true", ":" then return
+ else $strip_command = Shellwords.shellwords(cmd)
+ end
+ elsif !$strip_command
+ return
+ end
+ system(*($strip_command + [files].flatten))
+end
+
+def install(src, dest, options = {})
+ options = options.clone
+ strip = options.delete(:strip)
+ options[:preserve] = true
+ d = with_destdir(dest)
+ super(src, d, options)
+ srcs = Array(src)
+ if strip
+ d = srcs.map {|src| File.join(d, File.basename(src))} if $made_dirs[dest]
+ strip_file(d)
+ end
+ if $installed_list
+ dest = srcs.map {|src| File.join(dest, File.basename(src))} if $made_dirs[dest]
+ $installed_list.puts dest
+ end
+end
+
+def ln_sf(src, dest)
+ super(src, with_destdir(dest))
+ $installed_list.puts dest if $installed_list
+end
+
+$made_dirs = {}
+def makedirs(dirs)
+ dirs = fu_list(dirs)
+ dirs.collect! do |dir|
+ realdir = with_destdir(dir)
+ realdir unless $made_dirs.fetch(dir) do
+ $made_dirs[dir] = true
+ $installed_list.puts(File.join(dir, "")) if $installed_list
+ File.directory?(realdir)
+ end
+ end.compact!
+ super(dirs, :mode => $dir_mode) unless dirs.empty?
+end
+
+FalseProc = proc {false}
+def path_matcher(pat)
+ if pat and !pat.empty?
+ proc {|f| pat.any? {|n| File.fnmatch?(n, f)}}
+ else
+ FalseProc
+ end
+end
+
+def install_recursive(srcdir, dest, options = {})
+ opts = options.clone
+ noinst = opts.delete(:no_install)
+ glob = opts.delete(:glob) || "*"
+ maxdepth = opts.delete(:maxdepth)
+ subpath = (srcdir.size+1)..-1
+ prune = []
+ skip = []
+ if noinst
+ if Array === noinst
+ prune = noinst.grep(/#{File::SEPARATOR}/o).map!{|f| f.chomp(File::SEPARATOR)}
+ skip = noinst.grep(/\A[^#{File::SEPARATOR}]*\z/o)
+ else
+ if noinst.index(File::SEPARATOR)
+ prune = [noinst]
+ else
+ skip = [noinst]
+ end
+ end
+ end
+ skip |= %w"#*# *~ *.old *.bak *.orig *.rej *.diff *.patch *.core"
+ prune = path_matcher(prune)
+ skip = path_matcher(skip)
+ File.directory?(srcdir) or return rescue return
+ paths = [[srcdir, dest, 0]]
+ found = []
+ while file = paths.shift
+ found << file
+ file, d, dir = *file
+ if dir
+ depth = dir + 1
+ next if maxdepth and maxdepth < depth
+ files = []
+ Dir.foreach(file) do |f|
+ src = File.join(file, f)
+ d = File.join(dest, dir = src[subpath])
+ stat = File.lstat(src) rescue next
+ if stat.directory?
+ files << [src, d, depth] if maxdepth != depth and /\A\./ !~ f and !prune[dir]
+ elsif stat.symlink?
+ # skip
+ else
+ files << [src, d, false] if File.fnmatch?(glob, f) and !skip[f]
+ end
+ end
+ paths.insert(0, *files)
+ end
+ end
+ for src, d, dir in found
+ if dir
+ makedirs(d)
+ else
+ makedirs(d[/.*(?=\/)/m])
+ if block_given?
+ yield src, d, opts
+ else
+ install src, d, opts
+ end
+ end
+ end
+end
+
+def open_for_install(path, mode)
+ data = open(realpath = with_destdir(path), "rb") {|f| f.read} rescue nil
+ newdata = yield
+ unless $dryrun
+ unless newdata == data
+ open(realpath, "wb", mode) {|f| f.write newdata}
+ end
+ File.chmod(mode, realpath)
+ end
+ $installed_list.puts path if $installed_list
+end
+
+def with_destdir(dir)
+ return dir if !$destdir or $destdir.empty?
+ dir = dir.sub(/\A\w:/, '') if File::PATH_SEPARATOR == ';'
+ $destdir + dir
+end
+
+def prepare(mesg, basedir, subdirs=nil)
+ return unless basedir
+ case
+ when !subdirs
+ dirs = basedir
+ when subdirs.size == 0
+ subdirs = nil
+ when subdirs.size == 1
+ dirs = [basedir = File.join(basedir, subdirs)]
+ subdirs = nil
+ else
+ dirs = [basedir, *subdirs.collect {|dir| File.join(basedir, dir)}]
+ end
+ printf("installing %-18s %s%s\n", "#{mesg}:", basedir,
+ (subdirs ? " (#{subdirs.join(', ')})" : ""))
+ makedirs(dirs)
+end
+
+def CONFIG.[](name, mandatory = false)
+ value = super(name)
+ if mandatory
+ raise "CONFIG['#{name}'] must be set" if !value or value.empty?
+ end
+ value
+end
+
+exeext = CONFIG["EXEEXT"]
+
+ruby_install_name = CONFIG["ruby_install_name", true]
+rubyw_install_name = CONFIG["rubyw_install_name"]
+goruby_install_name = "go" + ruby_install_name
+
+bindir = CONFIG["bindir", true]
+libdir = CONFIG[CONFIG.fetch("libdirname", "libdir"), true]
+rubyhdrdir = CONFIG["rubyhdrdir", true]
+archhdrdir = CONFIG["rubyarchhdrdir"] || (rubyhdrdir + "/" + CONFIG['arch'])
+rubylibdir = CONFIG["rubylibdir", true]
+archlibdir = CONFIG["rubyarchdir", true]
+sitelibdir = CONFIG["sitelibdir"]
+sitearchlibdir = CONFIG["sitearchdir"]
+vendorlibdir = CONFIG["vendorlibdir"]
+vendorarchlibdir = CONFIG["vendorarchdir"]
+mandir = CONFIG["mandir", true]
+docdir = CONFIG["docdir", true]
+configure_args = Shellwords.shellwords(CONFIG["configure_args"])
+enable_shared = CONFIG["ENABLE_SHARED"] == 'yes'
+dll = CONFIG["LIBRUBY_SO", enable_shared]
+lib = CONFIG["LIBRUBY", true]
+arc = CONFIG["LIBRUBY_A", true]
+major = CONFIG["MAJOR", true]
+minor = CONFIG["MINOR", true]
+load_relative = configure_args.include?("--enable-load-relative")
+
+install?(:local, :arch, :bin, :'bin-arch') do
+ prepare "binary commands", bindir
+
+ install ruby_install_name+exeext, bindir, :mode => $prog_mode, :strip => $strip
+ if rubyw_install_name and !rubyw_install_name.empty?
+ install rubyw_install_name+exeext, bindir, :mode => $prog_mode, :strip => $strip
+ end
+ if File.exist? goruby_install_name+exeext
+ install goruby_install_name+exeext, bindir, :mode => $prog_mode, :strip => $strip
+ end
+ if enable_shared and dll != lib
+ install dll, bindir, :mode => $prog_mode, :strip => $strip
+ end
+end
+
+install?(:local, :arch, :lib) do
+ prepare "base libraries", libdir
+
+ install lib, libdir, :mode => $prog_mode, :strip => $strip unless lib == arc
+ install arc, libdir, :mode => $data_mode
+ if dll == lib and dll != arc
+ for link in CONFIG["LIBRUBY_ALIASES"].split
+ ln_sf(dll, File.join(libdir, link))
+ end
+ end
+
+ prepare "arch files", archlibdir
+ install "rbconfig.rb", archlibdir, :mode => $data_mode
+ if CONFIG["ARCHFILE"]
+ for file in CONFIG["ARCHFILE"].split
+ install file, archlibdir, :mode => $data_mode
+ end
+ end
+end
+
+install?(:local, :arch, :data) do
+ pc = CONFIG["ruby_pc"]
+ if pc and File.file?(pc) and File.size?(pc)
+ prepare "pkgconfig data", pkgconfigdir = File.join(libdir, "pkgconfig")
+ install pc, pkgconfigdir, :mode => $data_mode
+ end
+end
+
+install?(:ext, :arch, :'ext-arch') do
+ prepare "extension objects", archlibdir
+ noinst = %w[-* -*/] | (CONFIG["no_install_files"] || "").split
+ install_recursive("#{$extout}/#{CONFIG['arch']}", archlibdir, :no_install => noinst, :mode => $prog_mode, :strip => $strip)
+ prepare "extension objects", sitearchlibdir
+ prepare "extension objects", vendorarchlibdir
+end
+install?(:ext, :arch, :hdr, :'arch-hdr') do
+ prepare "extension headers", archhdrdir
+ install_recursive("#{$extout}/include/#{CONFIG['arch']}", archhdrdir, :glob => "*.h", :mode => $data_mode)
+end
+install?(:ext, :comm, :'ext-comm') do
+ prepare "extension scripts", rubylibdir
+ install_recursive("#{$extout}/common", rubylibdir, :mode => $data_mode)
+ prepare "extension scripts", sitelibdir
+ prepare "extension scripts", vendorlibdir
+end
+install?(:ext, :comm, :hdr, :'comm-hdr') do
+ hdrdir = rubyhdrdir + "/ruby"
+ prepare "extension headers", hdrdir
+ install_recursive("#{$extout}/include/ruby", hdrdir, :glob => "*.h", :mode => $data_mode)
+end
+
+install?(:doc, :rdoc) do
+ if $rdocdir
+ ridatadir = File.join(CONFIG['ridir'], CONFIG['ruby_version'], "system")
+ prepare "rdoc", ridatadir
+ install_recursive($rdocdir, ridatadir, :mode => $data_mode)
+ end
+end
+install?(:doc, :capi) do
+ prepare "capi-docs", docdir
+ install_recursive "doc/capi", docdir+"/capi", :mode => $data_mode
+end
+
+if load_relative
+ PROLOG_SCRIPT = <<EOS
+#!/bin/sh\n# -*- ruby -*-
+bindir=`#{CONFIG["CHDIR"]} "${0%/*}" 2>/dev/null; pwd`
+EOS
+ if CONFIG["LIBRUBY_RELATIVE"] != 'yes' and libpathenv = CONFIG["LIBPATHENV"]
+ pathsep = File::PATH_SEPARATOR
+ PROLOG_SCRIPT << <<EOS
+prefix="${bindir%/bin}"
+export #{libpathenv}="$prefix/lib${#{libpathenv}#{pathsep}+#{pathsep}$#{libpathenv}}"
+EOS
+ end
+ PROLOG_SCRIPT << %Q[exec "$bindir/#{ruby_install_name}" -x "$0" "$@"\n]
+else
+ PROLOG_SCRIPT = nil
+end
+
+install?(:local, :comm, :bin, :'bin-comm') do
+ prepare "command scripts", bindir
+
+ ruby_shebang = File.join(bindir, ruby_install_name)
+ if File::ALT_SEPARATOR
+ ruby_bin = ruby_shebang.tr(File::SEPARATOR, File::ALT_SEPARATOR)
+ if $cmdtype == 'exe'
+ stub = File.open("rubystub.exe", "rb") {|f| f.read} << "\n" rescue nil
+ end
+ end
+ if trans = CONFIG["program_transform_name"]
+ exp = []
+ trans.gsub!(/\$\$/, '$')
+ trans.scan(%r[\G[\s;]*(/(?:\\.|[^/])*/)?([sy])(\\?\W)((?:(?!\3)(?:\\.|.))*)\3((?:(?!\3)(?:\\.|.))*)\3([gi]*)]) do
+ |addr, cmd, sep, pat, rep, opt|
+ addr &&= Regexp.new(addr[/\A\/(.*)\/\z/, 1])
+ case cmd
+ when 's'
+ next if pat == '^' and rep.empty?
+ exp << [addr, (opt.include?('g') ? :gsub! : :sub!),
+ Regexp.new(pat, opt.include?('i')), rep.gsub(/&/){'\&'}]
+ when 'y'
+ exp << [addr, :tr!, Regexp.quote(pat), rep]
+ end
+ end
+ trans = proc do |base|
+ exp.each {|addr, opt, pat, rep| base.__send__(opt, pat, rep) if !addr or addr =~ base}
+ base
+ end
+ elsif /ruby/ =~ ruby_install_name
+ trans = proc {|base| ruby_install_name.sub(/ruby/, base)}
+ else
+ trans = proc {|base| base}
+ end
+ install_recursive(File.join(srcdir, "bin"), bindir, :maxdepth => 1) do |src, cmd|
+ cmd = cmd.sub(/[^\/]*\z/m) {|n| RbConfig.expand(trans[n])}
+
+ shebang = ''
+ body = ''
+ open(src, "rb") do |f|
+ shebang = f.gets
+ body = f.read
+ end
+ shebang or raise "empty file - #{src}"
+ if PROLOG_SCRIPT
+ shebang.sub!(/\A(\#!.*?ruby\b)?/) {PROLOG_SCRIPT + ($1 || "#!ruby\n")}
+ else
+ shebang.sub!(/\A\#!.*?ruby\b/) {"#!" + ruby_shebang}
+ end
+ shebang.sub!(/\r$/, '')
+ body.gsub!(/\r$/, '')
+
+ cmd << ".#{$cmdtype}" if $cmdtype
+ open_for_install(cmd, $script_mode) do
+ case $cmdtype
+ when "exe"
+ stub + shebang + body
+ when "bat"
+ [<<-"EOH".gsub(/^\s+/, ''), shebang, body, "__END__\n:endofruby\n"].join.gsub(/$/, "\r")
+ @echo off
+ @if not "%~d0" == "~d0" goto WinNT
+ #{ruby_bin} -x "#{cmd}" %1 %2 %3 %4 %5 %6 %7 %8 %9
+ @goto endofruby
+ :WinNT
+ "%~dp0#{ruby_install_name}" -x "%~f0" %*
+ @goto endofruby
+ EOH
+ when "cmd"
+ <<"/EOH" << shebang << body
+@"%~dp0#{ruby_install_name}" -x "%~f0" %*
+@exit /b %ERRORLEVEL%
+/EOH
+ else
+ shebang + body
+ end
+ end
+ end
+end
+
+install?(:local, :comm, :lib) do
+ prepare "library scripts", rubylibdir
+ noinst = %w[README* *.txt *.rdoc *.gemspec]
+ install_recursive(File.join(srcdir, "lib"), rubylibdir, :no_install => noinst, :mode => $data_mode)
+end
+
+install?(:local, :comm, :hdr, :'comm-hdr') do
+ prepare "common headers", rubyhdrdir
+
+ noinst = []
+ unless RUBY_PLATFORM =~ /mswin|mingw|bccwin/
+ noinst << "win32.h"
+ end
+ noinst = nil if noinst.empty?
+ install_recursive(File.join(srcdir, "include"), rubyhdrdir, :no_install => noinst, :glob => "*.h", :mode => $data_mode)
+end
+
+install?(:local, :comm, :man) do
+ mdocs = Dir["#{srcdir}/man/*.[1-9]"]
+ prepare "manpages", mandir, ([] | mdocs.collect {|mdoc| mdoc[/\d+$/]}).sort.collect {|sec| "man#{sec}"}
+
+ mandir = File.join(mandir, "man")
+ has_goruby = File.exist?(goruby_install_name+exeext)
+ require File.join(srcdir, "tool/mdoc2man.rb") if $mantype != "doc"
+ mdocs.each do |mdoc|
+ next unless File.file?(mdoc) and open(mdoc){|fh| fh.read(1) == '.'}
+ base = File.basename(mdoc)
+ if base == "goruby.1"
+ next unless has_goruby
+ end
+
+ destdir = mandir + (section = mdoc[/\d+$/])
+ destname = ruby_install_name.sub(/ruby/, base.chomp(".#{section}"))
+ destfile = File.join(destdir, "#{destname}.#{section}")
+
+ if $mantype == "doc"
+ install mdoc, destfile, :mode => $data_mode
+ else
+ class << (w = [])
+ alias print push
+ end
+ open(mdoc) {|r| Mdoc2Man.mdoc2man(r, w)}
+ open_for_install(destfile, $data_mode) {w.join("")}
+ end
+ end
+end
+
+module RbInstall
+ module Specs
+ class FileCollector
+ def initialize(base_dir)
+ @base_dir = base_dir
+ end
+
+ def collect
+ (ruby_libraries + built_libraries).sort
+ end
+
+ private
+ def type
+ /\/(ext|lib)?\/.*?\z/ =~ @base_dir
+ $1
+ end
+
+ def ruby_libraries
+ case type
+ when "ext"
+ prefix = "#{$extout}/common/"
+ base = "#{prefix}#{relative_base}"
+ when "lib"
+ base = @base_dir
+ prefix = base.sub(/lib\/.*?\z/, "") + "lib/"
+ end
+
+ Dir.glob("#{base}{.rb,/**/*.rb}").collect do |ruby_source|
+ remove_prefix(prefix, ruby_source)
+ end
+ end
+
+ def built_libraries
+ case type
+ when "ext"
+ prefix = "#{$extout}/#{CONFIG['arch']}/"
+ base = "#{prefix}#{relative_base}"
+ Dir.glob("#{base}{.so,/**/*.so}").collect do |built_library|
+ remove_prefix(prefix, built_library)
+ end
+ when "lib"
+ []
+ end
+ end
+
+ def relative_base
+ /\/#{Regexp.escape(type)}\/(.*?)\z/ =~ @base_dir
+ $1
+ end
+
+ def remove_prefix(prefix, string)
+ string.sub(/\A#{Regexp.escape(prefix)}/, "")
+ end
+ end
+
+ class Reader < Struct.new(:src)
+ def gemspec
+ @gemspec ||= begin
+ spec = Gem::Specification.load(src) || raise("invalid spec in #{src}")
+ file_collector = FileCollector.new(File.dirname(src))
+ spec.files = file_collector.collect
+ spec
+ end
+ end
+
+ def spec_source
+ @gemspec.to_ruby
+ end
+ end
+
+ class Generator < Struct.new(:name, :base_dir, :src, :execs)
+ def gemspec
+ @gemspec ||= eval spec_source
+ end
+
+ def spec_source
+ <<-GEMSPEC
+Gem::Specification.new do |s|
+ s.name = #{name.dump}
+ s.version = #{version.dump}
+ s.summary = "This #{name} is bundled with Ruby"
+ s.executables = #{execs.inspect}
+ s.files = #{files.inspect}
+end
+ GEMSPEC
+ end
+
+ private
+ def version
+ version = open(src) { |f|
+ f.find { |s| /^\s*\w*VERSION\s*=(?!=)/ =~ s }
+ } or return
+ version.split(%r"=\s*", 2)[1].strip[/\A([\'\"])(.*?)\1/, 2]
+ end
+
+ def files
+ file_collector = FileCollector.new(base_dir)
+ file_collector.collect
+ end
+ end
+ end
+end
+# :startdoc:
+
+install?(:ext, :comm, :gem) do
+ $:.unshift(File.join(srcdir, "lib"))
+ require("rubygems.rb")
+ gem_dir = Gem.default_dir
+ directories = Gem.ensure_gem_subdirectories(gem_dir, :mode => $dir_mode)
+ prepare "default gems", gem_dir, directories
+
+ spec_dir = File.join(gem_dir, directories.grep(/^spec/)[0])
+ default_spec_dir = "#{spec_dir}/default"
+ makedirs(default_spec_dir)
+
+ gems = {}
+ File.foreach(File.join(srcdir, "defs/default_gems")) do |line|
+ line.chomp!
+ line.sub!(/\s*#.*/, '')
+ next if line.empty?
+ words = []
+ line.scan(/\G\s*([^\[\]\s]+|\[([^\[\]]*)\])/) do
+ words << ($2 ? $2.split : $1)
+ end
+ name, base_dir, src, execs = *words
+ next unless name and base_dir and src
+
+ src = File.join(srcdir, src)
+ base_dir = File.join(srcdir, base_dir)
+ specgen = RbInstall::Specs::Generator.new(name, base_dir, src, execs || [])
+ gems[name] ||= specgen
+ end
+
+ Dir.glob(srcdir+"/{lib,ext}/**/*.gemspec").each do |src|
+ specgen = RbInstall::Specs::Reader.new(src)
+ gems[specgen.gemspec.name] ||= specgen
+ end
+
+ gems.sort.each do |name, specgen|
+ gemspec = specgen.gemspec
+ base_dir = specgen.src.sub(/\A#{Regexp.escape(srcdir)}\//, "")
+ full_name = "#{gemspec.name}-#{gemspec.version}"
+
+ puts "#{" "*30}#{gemspec.name} #{gemspec.version}"
+ gemspec_path = File.join(default_spec_dir, "#{full_name}.gemspec")
+ open_for_install(gemspec_path, $data_mode) do
+ specgen.spec_source
+ end
+
+ unless gemspec.executables.empty? then
+ bin_dir = File.join(gem_dir, 'gems', full_name, 'bin')
+ makedirs(bin_dir)
+
+ execs = gemspec.executables.map {|exec| File.join(srcdir, 'bin', exec)}
+ install(execs, bin_dir, :mode => $prog_mode)
+ end
+ end
+end
+
+install?(:ext, :comm, :gem) do
+ begin
+ require "zlib"
+ rescue LoadError
+ end
+ if defined?(Zlib)
+ require 'pathname'
+ gem_dir = Gem.default_dir
+ directories = Gem.ensure_gem_subdirectories(gem_dir, :mode => $dir_mode)
+ prepare "bundle gems", gem_dir, directories
+ Dir.glob(srcdir+'/gems/*.gem').each do |gem|
+ Gem.install gem, Gem::Requirement.default, :install_dir => with_destdir(Gem.dir), :domain => :local, :ignore_dependencies => true
+ gemname = Pathname(gem).basename
+ puts "#{" "*30}#{gemname}"
+ end
+ # fix directory permissions
+ # TODO: Gem.install should accept :dir_mode option or something
+ File.chmod($dir_mode, *Dir.glob(with_destdir(Gem.dir)+"/**/"))
+ # fix .gemspec permissions
+ File.chmod($data_mode, *Dir.glob(with_destdir(Gem.dir)+"/specifications/*.gemspec"))
+ else
+ puts "skip installing bundle gems because of lacking zlib"
+ end
+end
+
+parse_args()
+
+include FileUtils
+include FileUtils::NoWrite if $dryrun
+@fileutils_output = STDOUT
+@fileutils_label = ''
+
+all = $install.delete(:all)
+$install << :local << :ext if $install.empty?
+installs = $install.map do |inst|
+ if !(procs = $install_procs[inst]) || procs.empty?
+ next warn("unknown install target - #{inst}")
+ end
+ procs
+end
+installs.flatten!
+installs.uniq!
+installs |= $install_procs[:all] if all
+installs.each do |block|
+ dir = Dir.pwd
+ begin
+ block.call
+ ensure
+ Dir.chdir(dir)
+ end
+end
+
+# vi:set sw=2:
diff --git a/jni/ruby/tool/rbuninstall.rb b/jni/ruby/tool/rbuninstall.rb
new file mode 100755
index 0000000..1a11766
--- /dev/null
+++ b/jni/ruby/tool/rbuninstall.rb
@@ -0,0 +1,67 @@
+#! /usr/bin/ruby -nl
+BEGIN {
+ $dryrun = false
+ $tty = STDOUT.tty?
+ until ARGV.empty?
+ case ARGV[0]
+ when /\A--destdir=(.*)/
+ $destdir = $1
+ when /\A-n\z/
+ $dryrun = true
+ when /\A--(?:no-)?tty\z/
+ $tty = !$1
+ else
+ break
+ end
+ ARGV.shift
+ end
+ $dirs = []
+ $files = []
+}
+list = ($_.chomp!('/') ? $dirs : $files)
+$_ = File.join($destdir, $_) if $destdir
+list << $_
+END {
+ status = true
+ $\ = ors = (!$dryrun and $tty) ? "\e[K\r" : "\n"
+ $files.each do |file|
+ print "rm #{file}"
+ unless $dryrun
+ begin
+ File.unlink(file)
+ rescue Errno::ENOENT
+ rescue
+ status = false
+ puts $!
+ end
+ end
+ end
+ unlink = {}
+ $dirs.each do |dir|
+ unlink[dir] = true
+ end
+ while dir = $dirs.pop
+ print "rmdir #{dir}"
+ unless $dryrun
+ begin
+ begin
+ unlink.delete(dir)
+ Dir.rmdir(dir)
+ rescue Errno::ENOTDIR
+ raise unless File.symlink?(dir)
+ File.unlink(dir)
+ end
+ rescue Errno::ENOENT, Errno::ENOTEMPTY
+ rescue
+ status = false
+ puts $!
+ else
+ parent = File.dirname(dir)
+ $dirs.push(parent) unless parent == dir or unlink[parent]
+ end
+ end
+ end
+ $\ = nil
+ print ors.chomp
+ exit(status)
+}
diff --git a/jni/ruby/tool/redmine-backporter.rb b/jni/ruby/tool/redmine-backporter.rb
new file mode 100755
index 0000000..121aa3e
--- /dev/null
+++ b/jni/ruby/tool/redmine-backporter.rb
@@ -0,0 +1,416 @@
+#!/usr/bin/env ruby
+require 'open-uri'
+require 'openssl'
+require 'net/http'
+require 'json'
+require 'io/console'
+require 'stringio'
+require 'strscan'
+require 'optparse'
+require 'pp'
+
+VERSION = '0.0.1'
+
+opts = OptionParser.new
+target_version = nil
+repo_path = nil
+api_key = nil
+ssl_verify = true
+opts.on('-k REDMINE_API_KEY', '--key=REDMINE_API_KEY', 'specify your REDMINE_API_KEY') {|v| api_key = v}
+opts.on('-t TARGET_VERSION', '--target=TARGET_VARSION', /\A\d(?:\.\d)+\z/, 'specify target version (ex: 2.1)') {|v| target_version = v}
+opts.on('-r RUBY_REPO_PATH', '--repository=RUBY_REPO_PATH', 'specify repository path') {|v| repo_path = v}
+opts.on('--[no-]ssl-verify', TrueClass, 'use / not use SSL verify') {|v| ssl_verify = v}
+opts.version = VERSION
+opts.parse!(ARGV)
+
+http_options = {use_ssl: true}
+http_options[:verify_mode] = OpenSSL::SSL::VERIFY_NONE unless ssl_verify
+openuri_options = {}
+openuri_options[:ssl_verify_mode] = OpenSSL::SSL::VERIFY_NONE unless ssl_verify
+
+TARGET_VERSION = target_version || ENV['TARGET_VERSION'] || (raise 'need to specify TARGET_VERSION')
+RUBY_REPO_PATH = repo_path || ENV['RUBY_REPO_PATH']
+BACKPORT_CF_KEY = 'cf_5'
+STATUS_CLOSE = 5
+REDMINE_API_KEY = api_key || ENV['REDMINE_API_KEY'] || (raise 'need to specify REDMINE_API_KEY')
+REDMINE_BASE = 'https://bugs.ruby-lang.org'
+
+@query = {
+ 'f[]' => BACKPORT_CF_KEY,
+ "op[#{BACKPORT_CF_KEY}]" => '~',
+ "v[#{BACKPORT_CF_KEY}][]" => "#{TARGET_VERSION}: REQUIRED",
+ 'limit' => 40,
+ 'status_id' => STATUS_CLOSE,
+ 'sort' => 'updated_on'
+}
+
+PRIORITIES = {
+ 'Low' => [:white, :blue],
+ 'Normal' => [],
+ 'High' => [:red],
+ 'Urgent' => [:red, :white],
+ 'Immediate' => [:red, :white, {underscore: true}],
+}
+COLORS = {
+ black: 30,
+ red: 31,
+ green: 32,
+ yellow: 33,
+ blue: 34,
+ magenta: 35,
+ cyan: 36,
+ white: 37,
+}
+
+class String
+ def color(fore=nil, back=nil, bold: false, underscore: false)
+ seq = ""
+ if bold
+ seq << "\e[1m"
+ end
+ if underscore
+ seq << "\e[2m"
+ end
+ if fore
+ c = COLORS[fore]
+ raise "unknown foreground color #{fore}" unless c
+ seq << "\e[#{c}m"
+ end
+ if back
+ c = COLORS[back]
+ raise "unknown background color #{back}" unless c
+ seq << "\e[#{c + 10}m"
+ end
+ if seq.empty?
+ self
+ else
+ seq << self << "\e[0m"
+ end
+ end
+end
+
+def wcwidth(wc)
+ return 8 if wc == "\t"
+ n = wc.ord
+ if n < 0x20
+ 0
+ elsif n < 0x80
+ 1
+ else
+ 2
+ end
+end
+
+def fold(str, col)
+ i = 0
+ size = str.size
+ len = 0
+ while i < size
+ case c = str[i]
+ when "\r", "\n"
+ len = 0
+ else
+ d = wcwidth(c)
+ len += d
+ if len == col
+ str.insert(i+1, "\n")
+ len = 0
+ i += 2
+ next
+ elsif len > col
+ str.insert(i, "\n")
+ len = d
+ i += 2
+ next
+ end
+ end
+ i += 1
+ end
+ str
+end
+
+class StringScanner
+ # lx: limit of x (colmns of screen)
+ # ly: limit of y (rows of screen)
+ def getrows(lx, ly)
+ cp1 = charpos
+ x = 0
+ y = 0
+ until eos?
+ case c = getch
+ when "\r"
+ x = 0
+ when "\n"
+ x = 0
+ y += 1
+ when "\t"
+ x += 8
+ when /[\x00-\x7f]/
+ # halfwidth
+ x += 1
+ else
+ # fullwidth
+ x += 2
+ end
+
+ if x > lx
+ x = 0
+ y += 1
+ unscan
+ end
+ if y >= ly
+ return string[cp1...charpos]
+ end
+ end
+ string[cp1..-1]
+ end
+end
+
+def more(sio)
+ console = IO.console
+ ly, lx = console.winsize
+ ly -= 1
+ str = sio.string
+ cls = "\r" + (" " * lx) + "\r"
+
+ ss = StringScanner.new(str)
+
+ rows = ss.getrows(lx, ly)
+ puts rows
+ until ss.eos?
+ print ":"
+ case c = console.getch
+ when ' '
+ rows = ss.getrows(lx, ly)
+ puts cls + rows
+ when 'j', "\r"
+ rows = ss.getrows(lx, 1)
+ puts cls + rows
+ when "q"
+ print cls
+ break
+ else
+ print "\b"
+ end
+ end
+end
+
+def mergeinfo
+ `svn propget svn:mergeinfo #{RUBY_REPO_PATH}`
+end
+
+def find_svn_log(pattern)
+ `svn log --xml --stop-on-copy --search='#{pattern}' #{RUBY_REPO_PATH}`
+end
+
+def show_last_journal(http, uri)
+ res = http.get("#{uri.path}?include=journals")
+ res.value
+ h = JSON(res.body)
+ x = h["issue"]
+ raise "no issue" unless x
+ x = x["journals"]
+ raise "no journals" unless x
+ x = x.last
+ puts "== #{x["user"]["name"]} (#{x["created_on"]})"
+ x["details"].each do |y|
+ puts JSON(y)
+ end
+ puts x["notes"]
+end
+
+def backport_command_string
+ " backport --ticket=#{@issue} #{@changesets.join(',')}"
+end
+
+console = IO.console
+row, col = console.winsize
+@query['limit'] = row - 2
+puts "Backporter #{VERSION}".color(bold: true) + " for #{TARGET_VERSION}"
+
+@issues = nil
+@issue = nil
+@changesets = nil
+while true
+ print '> '
+ begin
+ l = gets
+ rescue Interrupt
+ break
+ end
+ l.strip! if l
+ case l
+ when 'ls'
+ uri = URI(REDMINE_BASE+'/projects/ruby-trunk/issues.json?'+URI.encode_www_form(@query))
+ # puts uri
+ res = JSON(uri.read(openuri_options))
+ @issues = issues = res["issues"]
+ from = res["offset"] + 1
+ total = res["total_count"]
+ to = from + issues.size - 1
+ puts "#{from}-#{to} / #{total}"
+ issues.each_with_index do |x, i|
+ id = "##{x["id"]}".color(*PRIORITIES[x["priority"]["name"]])
+ puts "#{'%2d' % i} #{id} #{x["priority"]["name"][0]} #{x["status"]["name"][0]} #{x["subject"][0,80]}"
+ end
+ when /\A(?:show +)?(\d+)\z/
+ id = $1.to_i
+ id = @issues[id]["id"] if @issues && id < @issues.size
+ @issue = id
+ uri = "#{REDMINE_BASE}/issues/#{id}"
+ uri = URI(uri+".json?include=children,attachments,relations,changesets,journals")
+ res = JSON(uri.read(openuri_options))
+ i = res["issue"]
+ unless i["changesets"]
+ abort "You don't have view_changesets permission"
+ end
+ id = "##{i["id"]}".color(*PRIORITIES[i["priority"]["name"]])
+ sio = StringIO.new
+ sio.puts <<eom
+#{i["subject"]}
+#{i["project"]["name"]} [#{i["tracker"]["name"]} #{id}] #{i["status"]["name"]} (#{i["created_on"]})
+author: #{i["author"]["name"]}
+assigned: #{i["assigned_to"].to_h["name"]}
+eom
+ i["custom_fields"].each do |x|
+ sio.puts "%-10s: %s" % [x["name"], x["value"]]
+ end
+ #res["attachements"].each do |x|
+ #end
+ sio.puts i["description"]
+ sio.puts
+ sio.puts "= changesets"
+ @changesets = []
+ i["changesets"].each do |x|
+ @changesets << x["revision"]
+ sio.puts "== #{x["revision"]} #{x["committed_on"]} #{x["user"]["name"] rescue nil}"
+ sio.puts x["comments"]
+ end
+ if i["journals"] && !i["journals"].empty?
+ sio.puts "= journals"
+ i["journals"].each do |x|
+ sio.puts "== #{x["user"]["name"]} (#{x["created_on"]})"
+ x["details"].each do |y|
+ sio.puts JSON(y)
+ end
+ sio.puts x["notes"]
+ end
+ end
+ more(sio)
+
+ when 's'
+ unless @issue
+ puts "ticket not selected"
+ next
+ end
+ puts backport_command_string
+
+ when /\Adone(?: +(\d+))?(?: -- +(.*))?\z/
+ notes = $2
+ notes.strip! if notes
+ if $1
+ i = $1.to_i
+ i = @issues[i]["id"] if @issues && i < @issues.size
+ @issue = i
+ end
+ unless @issue
+ puts "ticket not selected"
+ next
+ end
+
+ log = find_svn_log("##@issue]")
+ if log && /revision="(?<rev>\d+)/ =~ log
+ str = log[/merge revision\(s\) ([^:]+)(?=:)/]
+ str.insert(5, "d")
+ str = "ruby_#{TARGET_VERSION.tr('.','_')} r#{rev} #{str}."
+ if notes
+ str << "\n"
+ str << notes
+ end
+ notes = str
+ else
+ puts "no commit is found whose log include ##@issue"
+ next
+ end
+ puts notes
+
+ uri = URI("#{REDMINE_BASE}/issues/#{@issue}.json")
+ Net::HTTP.start(uri.host, uri.port, http_options) do |http|
+ res = http.get(uri.path)
+ data = JSON(res.body)
+ h = data["issue"]["custom_fields"].find{|x|x["id"]==5}
+ if h and val = h["value"]
+ case val[/(?:\A|, )#{Regexp.quote TARGET_VERSION}: ([^,]+)/, 1]
+ when 'REQUIRED', 'UNKNOWN', 'DONTNEED', 'WONTFIX'
+ val[*$~.offset(1)] = 'DONE'
+ when 'DONE' # , /\A\d+\z/
+ puts 'already backport is done'
+ next # already done
+ when nil
+ val << ", #{TARGET_VERSION}: DONE"
+ else
+ raise "unknown status '#$1'"
+ end
+ else
+ val = '#{TARGET_VERSION}: DONE'
+ end
+
+ data = { "issue" => { "custom_fields" => [ {"id"=>5, "value" => val} ] } }
+ data['issue']['notes'] = notes if notes
+ res = http.put(uri.path, JSON(data),
+ 'X-Redmine-API-Key' => REDMINE_API_KEY,
+ 'Content-Type' => 'application/json')
+ res.value
+
+ show_last_journal(http, uri)
+ end
+ when /\Aclose(?: +(\d+))?\z/
+ if $1
+ i = $1.to_i
+ i = @issues[i]["id"] if @issues && i < @issues.size
+ @issue = i
+ end
+ unless @issue
+ puts "ticket not selected"
+ next
+ end
+
+ uri = URI("#{REDMINE_BASE}/issues/#{@issue}.json")
+ Net::HTTP.start(uri.host, uri.port, http_options) do |http|
+ data = { "issue" => { "status_id" => STATUS_CLOSE } }
+ res = http.put(uri.path, JSON(data),
+ 'X-Redmine-API-Key' => REDMINE_API_KEY,
+ 'Content-Type' => 'application/json')
+ res.value
+
+ show_last_journal(http, uri)
+ end
+ when /\last(?: +(\d+))?\z/
+ if $1
+ i = $1.to_i
+ i = @issues[i]["id"] if @issues && i < @issues.size
+ @issue = i
+ end
+ unless @issue
+ puts "ticket not selected"
+ next
+ end
+
+ uri = URI("#{REDMINE_BASE}/issues/#{@issue}.json")
+ Net::HTTP.start(uri.host, uri.port, http_options) do |http|
+ show_last_journal(http, uri)
+ end
+ when ''
+ when nil, 'quit', 'exit'
+ exit
+ when 'help'
+ puts 'ls '.color(bold: true) + ' show all required tickets'
+ puts 'show TICKET '.color(bold: true) + ' show the detail of the TICKET, and select it'
+ puts 'TICKET '.color(bold: true) + ' show the backport option of the selected ticket for merger.rb'
+ puts 'done [TICKET] [-- NOTE]'.color(bold: true) + ' set Backport field of the TICKET to DONE'
+ puts 'close [TICKET] '.color(bold: true) + ' close the TICKET'
+ puts 'last [TICKET] '.color(bold: true) + ' show the last journal of the TICKET'
+ else
+ puts "error #{l.inspect}"
+ end
+end
diff --git a/jni/ruby/tool/release.sh b/jni/ruby/tool/release.sh
new file mode 100755
index 0000000..4c1d7cc
--- /dev/null
+++ b/jni/ruby/tool/release.sh
@@ -0,0 +1,38 @@
+#!/bin/sh
+
+RUBYDIR=/home/ftp/pub/ruby
+EXTS='.tar.gz .tar.bz2 .tar.xz .zip'
+
+releases=`ls ruby-*|grep -o 'ruby-[0-9]\.[0-9]\.[0-9]\(-\(preview\|rc\|p\)[0-9]\{1,4\}\)\?'|uniq`
+
+# check files
+for r in $releases
+do
+ echo "checking files for $r..."
+ for ext in $EXTS
+ do
+ if ! [ -f $r$ext ];then
+ echo "ERROR: $r$ext not found"
+ exit 1
+ fi
+ done
+ echo "files are ok"
+done
+
+# version directory
+for r in $releases
+do
+ xy=`echo $r|grep -o '[0-9]\.[0-9]'`
+ preview=`echo $r|grep -o -- '-\(preview\|rc\)'`
+ dir="${RUBYDIR}/$xy"
+ echo "$dir"
+ mkdir -p $dir
+ for ext in $EXTS
+ do
+ cp $r$ext $dir/$r$ext
+ ln -sf $xy/$r$ext ${RUBYDIR}/$r$ext
+ if [ x$preview = x ];then
+ ln -sf $xy/$r$ext ${RUBYDIR}/ruby-$xy-stable$ext
+ fi
+ done
+done
diff --git a/jni/ruby/tool/rmdirs b/jni/ruby/tool/rmdirs
new file mode 100755
index 0000000..6dcf984
--- /dev/null
+++ b/jni/ruby/tool/rmdirs
@@ -0,0 +1,11 @@
+#!/bin/sh
+for dir do
+ while rmdir "$dir" >/dev/null 2>&1 &&
+ parent=`expr "$dir" : '\(.*\)/[^/][^/]*'`; do
+ case "$parent" in
+ . | .. | "$dir") break;;
+ *) dir="$parent";;
+ esac
+ done
+done
+true
diff --git a/jni/ruby/tool/rubytest.rb b/jni/ruby/tool/rubytest.rb
new file mode 100755
index 0000000..a06c400
--- /dev/null
+++ b/jni/ruby/tool/rubytest.rb
@@ -0,0 +1,30 @@
+#! ./miniruby
+
+exit if defined?(CROSS_COMPILING) and CROSS_COMPILING
+ruby = ENV["RUBY"]
+unless ruby
+ load './rbconfig.rb'
+ ruby = "./#{RbConfig::CONFIG['ruby_install_name']}#{RbConfig::CONFIG['EXEEXT']}"
+end
+unless File.exist? ruby
+ print "#{ruby} is not found.\n"
+ print "Try `make' first, then `make test', please.\n"
+ exit false
+end
+ARGV[0] and opt = ARGV[0][/\A--run-opt=(.*)/, 1] and ARGV.shift
+
+$stderr.reopen($stdout)
+error = ''
+
+srcdir = File.expand_path('..', File.dirname(__FILE__))
+`#{ruby} #{opt} #{srcdir}/sample/test.rb #{ARGV.join(' ')}`.each_line do |line|
+ if line =~ /^end of test/
+ print "\ntest succeeded\n"
+ exit true
+ end
+ error << line if %r:^(sample/test.rb|not): =~ line
+end
+puts
+print error
+print "test failed\n"
+exit false
diff --git a/jni/ruby/tool/runruby.rb b/jni/ruby/tool/runruby.rb
new file mode 100755
index 0000000..86b9327
--- /dev/null
+++ b/jni/ruby/tool/runruby.rb
@@ -0,0 +1,99 @@
+#!./miniruby
+
+show = false
+precommand = []
+while arg = ARGV[0]
+ break ARGV.shift if arg == '--'
+ /\A--([-\w]+)(?:=(.*))?\z/ =~ arg or break
+ arg, value = $1, $2
+ re = Regexp.new('\A'+arg.gsub(/\w+\b/, '\&\\w*')+'\z', "i")
+ case
+ when re =~ "srcdir"
+ srcdir = value
+ when re =~ "archdir"
+ archdir = value
+ when re =~ "cpu"
+ precommand << "arch" << "-arch" << value
+ when re =~ "extout"
+ extout = value
+ when re =~ "pure"
+ # obsolete switch do nothing
+ when re =~ "debugger"
+ require 'shellwords'
+ precommand.concat(value ? (Shellwords.shellwords(value) unless value == "no") : %w"gdb --args")
+ when re =~ "precommand"
+ require 'shellwords'
+ precommand.concat(Shellwords.shellwords(value))
+ when re =~ "show"
+ show = true
+ else
+ break
+ end
+ ARGV.shift
+end
+
+unless defined?(File.realpath)
+ def File.realpath(*args)
+ Dir.chdir(expand_path(*args)) do
+ Dir.pwd
+ end
+ end
+end
+
+srcdir ||= File.realpath('..', File.dirname(__FILE__))
+archdir ||= '.'
+
+abs_archdir = File.expand_path(archdir)
+$:.unshift(abs_archdir)
+
+config = File.read(conffile = File.join(abs_archdir, 'rbconfig.rb'))
+config.sub!(/^(\s*)RUBY_VERSION\s*==.*(\sor\s*)$/, '\1true\2')
+config = Module.new {module_eval(config, conffile)}::RbConfig::CONFIG
+
+ruby = File.join(archdir, config["RUBY_INSTALL_NAME"]+config['EXEEXT'])
+unless File.exist?(ruby)
+ abort "#{ruby} is not found.\nTry `make' first, then `make test', please.\n"
+end
+
+libs = [abs_archdir]
+extout ||= config["EXTOUT"]
+if extout
+ abs_extout = File.expand_path(extout, abs_archdir)
+ libs << File.expand_path("common", abs_extout) << File.expand_path(config['arch'], abs_extout)
+end
+libs << File.expand_path("lib", srcdir)
+config["bindir"] = abs_archdir
+
+env = {}
+
+env["RUBY"] = File.expand_path(ruby)
+env["PATH"] = [abs_archdir, ENV["PATH"]].compact.join(File::PATH_SEPARATOR)
+
+if e = ENV["RUBYLIB"]
+ libs |= e.split(File::PATH_SEPARATOR)
+end
+env["RUBYLIB"] = $:.replace(libs).join(File::PATH_SEPARATOR)
+
+libruby_so = File.join(abs_archdir, config['LIBRUBY_SO'])
+if File.file?(libruby_so)
+ if e = config['LIBPATHENV'] and !e.empty?
+ env[e] = [abs_archdir, ENV[e]].compact.join(File::PATH_SEPARATOR)
+ end
+ if /linux/ =~ RUBY_PLATFORM
+ env["LD_PRELOAD"] = [libruby_so, ENV["LD_PRELOAD"]].compact.join(' ')
+ end
+end
+
+ENV.update env
+
+cmd = [ruby]
+cmd.concat(ARGV)
+cmd.unshift(*precommand) unless precommand.empty?
+
+if show
+ require 'shellwords'
+ env.each {|k,v| puts "#{k}=#{v}"}
+ puts Shellwords.join(cmd)
+end
+
+exec(*cmd)
diff --git a/jni/ruby/tool/strip-rdoc.rb b/jni/ruby/tool/strip-rdoc.rb
new file mode 100755
index 0000000..1902cb5
--- /dev/null
+++ b/jni/ruby/tool/strip-rdoc.rb
@@ -0,0 +1,23 @@
+#!ruby
+
+ARGF.binmode
+source = ARGF.read
+source = source.gsub(%r{/\*([!*])((?!\*/).+?)\*/}m) do |comment|
+ marker, comment = $1, $2
+ next "/**#{comment}*/" unless /^\s*\*\s?\-\-\s*$/ =~ comment
+ doxybody = nil
+ comment.each_line do |line|
+ if doxybody
+ if /^\s*\*\s?\+\+\s*$/ =~ line
+ break
+ end
+ doxybody << line
+ else
+ if /^\s*\*\s?--\s*$/ =~ line
+ doxybody = "\n"
+ end
+ end
+ end
+ "/*#{marker}#{doxybody}*/"
+end
+print source
diff --git a/jni/ruby/tool/test/test_jisx0208.rb b/jni/ruby/tool/test/test_jisx0208.rb
new file mode 100644
index 0000000..d323c84
--- /dev/null
+++ b/jni/ruby/tool/test/test_jisx0208.rb
@@ -0,0 +1,40 @@
+require 'test/unit'
+
+require '../tool/jisx0208'
+
+class Test_JISX0208_Char < Test::Unit::TestCase
+ def test_create_with_row_cell
+ assert_equal JISX0208::Char.new(0x2121), JISX0208::Char.new(1, 1)
+ end
+
+ def test_succ
+ assert_equal JISX0208::Char.new(0x2221), JISX0208::Char.new(0x217e).succ
+ assert_equal JISX0208::Char.new(2, 1), JISX0208::Char.new(1, 94).succ
+ assert_equal JISX0208::Char.new(0x7f21), JISX0208::Char.new(0x7e7e).succ
+ end
+
+ def test_to_shift_jis
+ assert_equal 0x895C, JISX0208::Char.new(0x313D).to_sjis
+ assert_equal 0x895C, JISX0208::Char.from_sjis(0x895C).to_sjis
+ assert_equal 0xF3DE, JISX0208::Char.from_sjis(0xF3DE).to_sjis
+ assert_equal 0xFC40, JISX0208::Char.from_sjis(0xFC40).to_sjis
+ end
+
+ def test_from_sjis
+ assert_raise(ArgumentError) { JISX0208::Char.from_sjis(-1) }
+ assert_raise(ArgumentError) { JISX0208::Char.from_sjis(0x10000) }
+ assert_nothing_raised { JISX0208::Char.from_sjis(0x8140) }
+ assert_nothing_raised { JISX0208::Char.from_sjis(0xFCFC) }
+ assert_equal JISX0208::Char.new(0x313D), JISX0208::Char.from_sjis(0x895C)
+ end
+
+ def test_row
+ assert_equal 1, JISX0208::Char.new(0x2121).row
+ assert_equal 94, JISX0208::Char.new(0x7E7E).row
+ end
+
+ def test_cell
+ assert_equal 1, JISX0208::Char.new(0x2121).cell
+ assert_equal 94, JISX0208::Char.new(0x7E7E).cell
+ end
+end
diff --git a/jni/ruby/tool/transcode-tblgen.rb b/jni/ruby/tool/transcode-tblgen.rb
new file mode 100644
index 0000000..832d9a4
--- /dev/null
+++ b/jni/ruby/tool/transcode-tblgen.rb
@@ -0,0 +1,1074 @@
+require 'optparse'
+require 'erb'
+require 'fileutils'
+require 'pp'
+
+class Array
+ unless [].respond_to? :product
+ def product(*args)
+ if args.empty?
+ self.map {|e| [e] }
+ else
+ result = []
+ self.each {|e0|
+ result.concat args.first.product(*args[1..-1]).map {|es| [e0, *es] }
+ }
+ result
+ end
+ end
+ end
+end
+
+class String
+ unless "".respond_to? :start_with?
+ def start_with?(*prefixes)
+ prefixes.each {|prefix|
+ return true if prefix.length <= self.length && prefix == self[0, prefix.length]
+ }
+ false
+ end
+ end
+end
+
+NUM_ELEM_BYTELOOKUP = 2
+
+C_ESC = {
+ "\\" => "\\\\",
+ '"' => '\"',
+ "\n" => '\n',
+}
+
+0x00.upto(0x1f) {|ch| C_ESC[[ch].pack("C")] ||= "\\%03o" % ch }
+0x7f.upto(0xff) {|ch| C_ESC[[ch].pack("C")] = "\\%03o" % ch }
+C_ESC_PAT = Regexp.union(*C_ESC.keys)
+
+def c_esc(str)
+ '"' + str.gsub(C_ESC_PAT) { C_ESC[$&] } + '"'
+end
+
+HEX2 = /(?:[0-9A-Fa-f]{2})/
+
+class ArrayCode
+ def initialize(type, name)
+ @type = type
+ @name = name
+ @len = 0;
+ @content = ''
+ end
+
+ def length
+ @len
+ end
+
+ def insert_at_last(num, str)
+ newnum = self.length + num
+ @content << str
+ @len += num
+ end
+
+ def to_s
+ <<"End"
+static const #{@type}
+#{@name}[#{@len}] = {
+#{@content}};
+End
+ end
+end
+
+class Action
+ def initialize(value)
+ @value = value
+ end
+ attr_reader :value
+
+ def hash
+ @value.hash
+ end
+
+ def eql?(other)
+ self.class == other.class &&
+ @value == other.value
+ end
+ alias == eql?
+end
+
+class Branch
+ def initialize(byte_min, byte_max, child_tree)
+ @byte_min = byte_min
+ @byte_max = byte_max
+ @child_tree = child_tree
+ @hash = byte_min.hash ^ byte_max.hash ^ child_tree.hash
+ end
+ attr_reader :byte_min, :byte_max, :child_tree, :hash
+
+ def eql?(other)
+ self.class == other.class &&
+ @hash == other.hash &&
+ @byte_min == other.byte_min &&
+ @byte_max == other.byte_max &&
+ @child_tree == other.child_tree
+ end
+ alias == eql?
+end
+
+class ActionMap
+ def self.parse_to_rects(mapping)
+ rects = []
+ n = 0
+ mapping.each {|pat, action|
+ pat = pat.to_s
+ if /\A\s*\(empset\)\s*\z/ =~ pat
+ next
+ elsif /\A\s*\(empstr\)\s*\z/ =~ pat
+ rects << ['', '', action]
+ n += 1
+ elsif /\A\s*(#{HEX2}+)\s*\z/o =~ pat
+ hex = $1.upcase
+ rects << [hex, hex, action]
+ elsif /\A\s*((#{HEX2}|\{#{HEX2}(?:-#{HEX2})?(,#{HEX2}(?:-#{HEX2})?)*\})+(\s+|\z))*\z/o =~ pat
+ pat = pat.upcase
+ pat.scan(/\S+/) {
+ pat1 = $&
+ ranges_list = []
+ pat1.scan(/#{HEX2}|\{([^\}]*)\}/o) {
+ ranges_list << []
+ if !$1
+ ranges_list.last << [$&,$&]
+ else
+ set = {}
+ $1.scan(/(#{HEX2})(?:-(#{HEX2}))?/o) {
+ if !$2
+ c = $1.to_i(16)
+ set[c] = true
+ else
+ b = $1.to_i(16)
+ e = $2.to_i(16)
+ b.upto(e) {|c| set[c] = true }
+ end
+ }
+ i = nil
+ 0.upto(256) {|j|
+ if set[j]
+ if !i
+ i = j
+ end
+ if !set[j+1]
+ ranges_list.last << ["%02X" % i, "%02X" % j]
+ i = nil
+ end
+ end
+ }
+ end
+ }
+ first_ranges = ranges_list.shift
+ first_ranges.product(*ranges_list).each {|range_list|
+ min = range_list.map {|x, y| x }.join
+ max = range_list.map {|x, y| y }.join
+ rects << [min, max, action]
+ }
+ }
+ else
+ raise ArgumentError, "invalid pattern: #{pat.inspect}"
+ end
+ }
+ rects
+ end
+
+ def self.unambiguous_action(actions0)
+ actions = actions0.uniq
+ if actions.length == 1
+ actions[0]
+ else
+ actions.delete(:nomap0)
+ if actions.length == 1
+ actions[0]
+ else
+ raise ArgumentError, "ambiguous actions: #{actions0.inspect}"
+ end
+ end
+ end
+
+ def self.build_tree(rects)
+ expand(rects) {|prefix, actions|
+ unambiguous_action(actions)
+ }
+ end
+
+ def self.parse(mapping)
+ rects = parse_to_rects(mapping)
+ tree = build_tree(rects)
+ self.new(tree)
+ end
+
+ def self.merge_rects(*rects_list)
+ if rects_list.length < 2
+ raise ArgumentError, "not enough arguments"
+ end
+
+ all_rects = []
+ rects_list.each_with_index {|rects, i|
+ all_rects.concat rects.map {|min, max, action| [min, max, [i, action]] }
+ }
+
+ tree = expand(all_rects) {|prefix, actions|
+ args = Array.new(rects_list.length) { [] }
+ actions.each {|i, action|
+ args[i] << action
+ }
+ yield(prefix, *args)
+ }
+
+ self.new(tree)
+ end
+
+ def self.merge(*mappings, &block)
+ merge_rects(*mappings.map {|m| parse_to_rects(m) }, &block)
+ end
+
+ def self.merge2(map1, map2, &block)
+ rects1 = parse_to_rects(map1)
+ rects2 = parse_to_rects(map2)
+
+ actions = []
+ all_rects = []
+
+ rects1.each {|rect|
+ min, max, action = rect
+ rect[2] = actions.length
+ actions << action
+ all_rects << rect
+ }
+
+ boundary = actions.length
+
+ rects2.each {|rect|
+ min, max, action = rect
+ rect[2] = actions.length
+ actions << action
+ all_rects << rect
+ }
+
+ tree = expand(all_rects) {|prefix, as0|
+ as1 = []
+ as2 = []
+ as0.each {|i|
+ if i < boundary
+ as1 << actions[i]
+ else
+ as2 << actions[i]
+ end
+ }
+ yield(prefix, as1, as2)
+ }
+
+ self.new(tree)
+ end
+
+ def self.expand(rects, &block)
+ #numsing = numreg = 0
+ #rects.each {|min, max, action| if min == max then numsing += 1 else numreg += 1 end }
+ #puts "#{numsing} singleton mappings and #{numreg} region mappings."
+ singleton_rects = []
+ region_rects = []
+ rects.each {|rect|
+ min, max, action = rect
+ if min == max
+ singleton_rects << rect
+ else
+ region_rects << rect
+ end
+ }
+ @singleton_rects = singleton_rects.sort_by {|min, max, action| min }
+ @singleton_rects.reverse!
+ ret = expand_rec("", region_rects, &block)
+ @singleton_rects = nil
+ ret
+ end
+
+ TMPHASH = {}
+ def self.expand_rec(prefix, region_rects, &block)
+ return region_rects if region_rects.empty? && !((s_rect = @singleton_rects.last) && s_rect[0].start_with?(prefix))
+ if region_rects.empty? ? s_rect[0].length == prefix.length : region_rects[0][0].empty?
+ h = TMPHASH
+ while (s_rect = @singleton_rects.last) && s_rect[0].start_with?(prefix)
+ min, max, action = @singleton_rects.pop
+ raise ArgumentError, "ambiguous pattern: #{prefix}" if min.length != prefix.length
+ h[action] = true
+ end
+ region_rects.each {|min, max, action|
+ raise ArgumentError, "ambiguous pattern: #{prefix}" if !min.empty?
+ h[action] = true
+ }
+ tree = Action.new(block.call(prefix, h.keys))
+ h.clear
+ else
+ tree = []
+ each_firstbyte_range(prefix, region_rects) {|byte_min, byte_max, r_rects2|
+ if byte_min == byte_max
+ prefix2 = prefix + "%02X" % byte_min
+ else
+ prefix2 = prefix + "{%02X-%02X}" % [byte_min, byte_max]
+ end
+ child_tree = expand_rec(prefix2, r_rects2, &block)
+ tree << Branch.new(byte_min, byte_max, child_tree)
+ }
+ end
+ return tree
+ end
+
+ def self.each_firstbyte_range(prefix, region_rects)
+ index_from = TMPHASH
+
+ region_ary = []
+ region_rects.each {|min, max, action|
+ raise ArgumentError, "ambiguous pattern: #{prefix}" if min.empty?
+ min_firstbyte = min[0,2].to_i(16)
+ min_rest = min[2..-1]
+ max_firstbyte = max[0,2].to_i(16)
+ max_rest = max[2..-1]
+ region_ary << [min_firstbyte, max_firstbyte, [min_rest, max_rest, action]]
+ index_from[min_firstbyte] = true
+ index_from[max_firstbyte+1] = true
+ }
+
+ byte_from = Array.new(index_from.size)
+ bytes = index_from.keys
+ bytes.sort!
+ bytes.reverse!
+ bytes.each_with_index {|byte, i|
+ index_from[byte] = i
+ byte_from[i] = byte
+ }
+
+ region_rects_ary = Array.new(index_from.size) { [] }
+ region_ary.each {|min_firstbyte, max_firstbyte, rest_elt|
+ index_from[min_firstbyte].downto(index_from[max_firstbyte+1]+1) {|i|
+ region_rects_ary[i] << rest_elt
+ }
+ }
+
+ index_from.clear
+
+ r_rects = region_rects_ary.pop
+ region_byte = byte_from.pop
+ prev_r_start = region_byte
+ prev_r_rects = []
+ while r_rects && (s_rect = @singleton_rects.last) && (seq = s_rect[0]).start_with?(prefix)
+ singleton_byte = seq[prefix.length, 2].to_i(16)
+ min_byte = singleton_byte < region_byte ? singleton_byte : region_byte
+ if prev_r_start < min_byte && !prev_r_rects.empty?
+ yield prev_r_start, min_byte-1, prev_r_rects
+ end
+ if region_byte < singleton_byte
+ prev_r_start = region_byte
+ prev_r_rects = r_rects
+ r_rects = region_rects_ary.pop
+ region_byte = byte_from.pop
+ elsif region_byte > singleton_byte
+ yield singleton_byte, singleton_byte, prev_r_rects
+ prev_r_start = singleton_byte+1
+ else # region_byte == singleton_byte
+ prev_r_start = region_byte+1
+ prev_r_rects = r_rects
+ r_rects = region_rects_ary.pop
+ region_byte = byte_from.pop
+ yield singleton_byte, singleton_byte, prev_r_rects
+ end
+ end
+
+ while r_rects
+ if prev_r_start < region_byte && !prev_r_rects.empty?
+ yield prev_r_start, region_byte-1, prev_r_rects
+ end
+ prev_r_start = region_byte
+ prev_r_rects = r_rects
+ r_rects = region_rects_ary.pop
+ region_byte = byte_from.pop
+ end
+
+ while (s_rect = @singleton_rects.last) && (seq = s_rect[0]).start_with?(prefix)
+ singleton_byte = seq[prefix.length, 2].to_i(16)
+ yield singleton_byte, singleton_byte, []
+ end
+ end
+
+ def initialize(tree)
+ @tree = tree
+ end
+
+ def inspect
+ "\#<#{self.class}:" +
+ @tree.inspect +
+ ">"
+ end
+
+ def max_input_length_rec(tree)
+ case tree
+ when Action
+ 0
+ else
+ tree.map {|branch|
+ max_input_length_rec(branch.child_tree)
+ }.max + 1
+ end
+ end
+
+ def max_input_length
+ max_input_length_rec(@tree)
+ end
+
+ def empty_action
+ if @tree.kind_of? Action
+ @tree.value
+ else
+ nil
+ end
+ end
+
+ OffsetsMemo = {}
+ InfosMemo = {}
+
+ def format_offsets(min, max, offsets)
+ offsets = offsets[min..max]
+ code = "%d, %d,\n" % [min, max]
+ 0.step(offsets.length-1,16) {|i|
+ code << " "
+ code << offsets[i,8].map {|off| "%3d," % off.to_s }.join('')
+ if i+8 < offsets.length
+ code << " "
+ code << offsets[i+8,8].map {|off| "%3d," % off.to_s }.join('')
+ end
+ code << "\n"
+ }
+ code
+ end
+
+ UsedName = {}
+
+ StrMemo = {}
+
+ def str_name(bytes)
+ size = @bytes_code.length
+ rawbytes = [bytes].pack("H*")
+
+ n = nil
+ if !n && !(suf = rawbytes.gsub(/[^A-Za-z0-9_]/, '')).empty? && !UsedName[nn = "str1_" + suf] then n = nn end
+ if !n && !UsedName[nn = "str1_" + bytes] then n = nn end
+ n ||= "str1s_#{size}"
+
+ StrMemo[bytes] = n
+ UsedName[n] = true
+ n
+ end
+
+ def gen_str(bytes)
+ if n = StrMemo[bytes]
+ n
+ else
+ len = bytes.length/2
+ size = @bytes_code.length
+ n = str_name(bytes)
+ @bytes_code.insert_at_last(1 + len,
+ "\#define #{n} makeSTR1(#{size})\n" +
+ " makeSTR1LEN(#{len})," + bytes.gsub(/../, ' 0x\&,') + "\n\n")
+ n
+ end
+ end
+
+ def generate_info(info)
+ case info
+ when :nomap, :nomap0
+ # :nomap0 is low priority. it never collides.
+ "NOMAP"
+ when :undef
+ "UNDEF"
+ when :invalid
+ "INVALID"
+ when :func_ii
+ "FUNii"
+ when :func_si
+ "FUNsi"
+ when :func_io
+ "FUNio"
+ when :func_so
+ "FUNso"
+ when /\A(#{HEX2})\z/o
+ "o1(0x#$1)"
+ when /\A(#{HEX2})(#{HEX2})\z/o
+ "o2(0x#$1,0x#$2)"
+ when /\A(#{HEX2})(#{HEX2})(#{HEX2})\z/o
+ "o3(0x#$1,0x#$2,0x#$3)"
+ when /funsio\((\d+)\)/
+ "funsio(#{$1})"
+ when /\A(#{HEX2})(3[0-9])(#{HEX2})(3[0-9])\z/o
+ "g4(0x#$1,0x#$2,0x#$3,0x#$4)"
+ when /\A(f[0-7])(#{HEX2})(#{HEX2})(#{HEX2})\z/o
+ "o4(0x#$1,0x#$2,0x#$3,0x#$4)"
+ when /\A(#{HEX2}){4,259}\z/o
+ gen_str(info.upcase)
+ when /\A\/\*BYTE_LOOKUP\*\// # pointer to BYTE_LOOKUP structure
+ $'.to_s
+ else
+ raise "unexpected action: #{info.inspect}"
+ end
+ end
+
+ def format_infos(infos)
+ infos = infos.map {|info| generate_info(info) }
+ maxlen = infos.map {|info| info.length }.max
+ columns = maxlen <= 16 ? 4 : 2
+ code = ""
+ 0.step(infos.length-1, columns) {|i|
+ code << " "
+ is = infos[i,columns]
+ is.each {|info|
+ code << sprintf(" %#{maxlen}s,", info)
+ }
+ code << "\n"
+ }
+ code
+ end
+
+ def generate_lookup_node(name, table)
+ bytes_code = @bytes_code
+ words_code = @words_code
+ offsets = []
+ infos = []
+ infomap = {}
+ min = max = nil
+ table.each_with_index {|action, byte|
+ action ||= :invalid
+ if action != :invalid
+ min = byte if !min
+ max = byte
+ end
+ unless o = infomap[action]
+ infomap[action] = o = infos.length
+ infos[o] = action
+ end
+ offsets[byte] = o
+ }
+ infomap.clear
+ if !min
+ min = max = 0
+ end
+
+ offsets_key = [min, max, offsets[min..max]]
+ if n = OffsetsMemo[offsets_key]
+ offsets_name = n
+ else
+ offsets_name = "#{name}_offsets"
+ OffsetsMemo[offsets_key] = offsets_name
+ size = bytes_code.length
+ bytes_code.insert_at_last(2+max-min+1,
+ "\#define #{offsets_name} #{size}\n" +
+ format_offsets(min,max,offsets) + "\n")
+ end
+
+ if n = InfosMemo[infos]
+ infos_name = n
+ else
+ infos_name = "#{name}_infos"
+ InfosMemo[infos] = infos_name
+
+ size = words_code.length
+ words_code.insert_at_last(infos.length,
+ "\#define #{infos_name} WORDINDEX2INFO(#{size})\n" +
+ format_infos(infos) + "\n")
+ end
+
+ size = words_code.length
+ words_code.insert_at_last(NUM_ELEM_BYTELOOKUP,
+ "\#define #{name} WORDINDEX2INFO(#{size})\n" +
+ <<"End" + "\n")
+ #{offsets_name},
+ #{infos_name},
+End
+ end
+
+ PreMemo = {}
+ NextName = "a"
+
+ def generate_node(name_hint=nil)
+ if n = PreMemo[@tree]
+ return n
+ end
+
+ table = Array.new(0x100, :invalid)
+ @tree.each {|branch|
+ byte_min, byte_max, child_tree = branch.byte_min, branch.byte_max, branch.child_tree
+ rest = ActionMap.new(child_tree)
+ if a = rest.empty_action
+ table.fill(a, byte_min..byte_max)
+ else
+ name_hint2 = nil
+ if name_hint
+ name_hint2 = "#{name_hint}_#{byte_min == byte_max ? '%02X' % byte_min : '%02Xto%02X' % [byte_min, byte_max]}"
+ end
+ v = "/*BYTE_LOOKUP*/" + rest.gennode(@bytes_code, @words_code, name_hint2)
+ table.fill(v, byte_min..byte_max)
+ end
+ }
+
+ if !name_hint
+ name_hint = "fun_" + NextName
+ NextName.succ!
+ end
+
+ PreMemo[@tree] = name_hint
+
+ generate_lookup_node(name_hint, table)
+ name_hint
+ end
+
+ def gennode(bytes_code, words_code, name_hint=nil)
+ @bytes_code = bytes_code
+ @words_code = words_code
+ name = generate_node(name_hint)
+ @bytes_code = nil
+ @words_code = nil
+ return name
+ end
+end
+
+def citrus_mskanji_cstomb(csid, index)
+ case csid
+ when 0
+ index
+ when 1
+ index + 0x80
+ when 2, 3
+ row = index >> 8
+ raise "invalid byte sequence" if row < 0x21
+ if csid == 3
+ if row <= 0x2F
+ offset = (row == 0x22 || row >= 0x26) ? 0xED : 0xF0
+ elsif row >= 0x4D && row <= 0x7E
+ offset = 0xCE
+ else
+ raise "invalid byte sequence"
+ end
+ else
+ raise "invalid byte sequence" if row > 0x97
+ offset = (row < 0x5F) ? 0x81 : 0xC1
+ end
+ col = index & 0xFF
+ raise "invalid byte sequence" if (col < 0x21 || col > 0x7E)
+
+ row -= 0x21
+ col -= 0x21
+ if (row & 1) == 0
+ col += 0x40
+ col += 1 if (col >= 0x7F)
+ else
+ col += 0x9F;
+ end
+ row = row / 2 + offset
+ (row << 8) | col
+ end.to_s(16)
+end
+
+def citrus_euc_cstomb(csid, index)
+ case csid
+ when 0x0000
+ index
+ when 0x8080
+ index | 0x8080
+ when 0x0080
+ index | 0x8E80
+ when 0x8000
+ index | 0x8F8080
+ end.to_s(16)
+end
+
+def citrus_stateless_iso_cstomb(csid, index)
+ (index | 0x8080 | (csid << 16)).to_s(16)
+end
+
+def citrus_cstomb(ces, csid, index)
+ case ces
+ when 'mskanji'
+ citrus_mskanji_cstomb(csid, index)
+ when 'euc'
+ citrus_euc_cstomb(csid, index)
+ when 'stateless_iso'
+ citrus_stateless_iso_cstomb(csid, index)
+ end
+end
+
+SUBDIR = %w/APPLE AST BIG5 CNS CP EBCDIC EMOJI GB GEORGIAN ISO646 ISO-8859 JIS KAZAKH KOI KS MISC TCVN/
+
+
+def citrus_decode_mapsrc(ces, csid, mapsrcs)
+ table = []
+ mapsrcs.split(',').each do |mapsrc|
+ path = [$srcdir]
+ mode = nil
+ if mapsrc.rindex(/UCS(?:@[A-Z]+)?/, 0)
+ mode = :from_ucs
+ from = mapsrc[$&.size+1..-1]
+ path << SUBDIR.find{|x| from.rindex(x, 0) }
+ else
+ mode = :to_ucs
+ path << SUBDIR.find{|x| mapsrc.rindex(x, 0) }
+ end
+ if /\bUCS@(BMP|SMP|SIP|TIP|SSP)\b/ =~ mapsrc
+ plane = {"BMP"=>0, "SMP"=>1, "SIP"=>2, "TIP"=>3, "SSP"=>14}[$1]
+ else
+ plane = 0
+ end
+ plane <<= 16
+ path << mapsrc.gsub(':', '@')
+ path = File.join(*path)
+ path << ".src"
+ path[path.rindex('/')] = '%'
+ STDERR.puts 'load mapsrc %s' % path if VERBOSE_MODE
+ open(path) do |f|
+ f.each_line do |l|
+ break if /^BEGIN_MAP/ =~ l
+ end
+ f.each_line do |l|
+ next if /^\s*(?:#|$)/ =~ l
+ break if /^END_MAP/ =~ l
+ case mode
+ when :from_ucs
+ case l
+ when /0x(\w+)\s*-\s*0x(\w+)\s*=\s*INVALID/
+ # Citrus OOB_MODE
+ when /(0x\w+)\s*=\s*(0x\w+)/
+ table.push << [plane | $1.hex, citrus_cstomb(ces, csid, $2.hex)]
+ else
+ raise "unknown notation '%s'"% l
+ end
+ when :to_ucs
+ case l
+ when /(0x\w+)\s*=\s*(0x\w+)/
+ table.push << [citrus_cstomb(ces, csid, $1.hex), plane | $2.hex]
+ else
+ raise "unknown notation '%s'"% l
+ end
+ end
+ end
+ end
+ end
+ return table
+end
+
+def import_ucm(path)
+ to_ucs = []
+ from_ucs = []
+ File.foreach(File.join($srcdir, "ucm", path)) do |line|
+ uc, bs, fb = nil
+ if /^<U([0-9a-fA-F]+)>\s*([\+0-9a-fA-Fx\\]+)\s*\|(\d)/ =~ line
+ uc = $1.hex
+ bs = $2.delete('x\\')
+ fb = $3.to_i
+ next if uc < 128 && uc == bs.hex
+ elsif /^([<U0-9a-fA-F>+]+)\s*([\+0-9a-fA-Fx\\]+)\s*\|(\d)/ =~ line
+ uc = $1.scan(/[0-9a-fA-F]+>/).map(&:hex).pack("U*").unpack("H*")[0]
+ bs = $2.delete('x\\')
+ fb = $3.to_i
+ end
+ to_ucs << [bs, uc] if fb == 0 || fb == 3
+ from_ucs << [uc, bs] if fb == 0 || fb == 1
+ end
+ [to_ucs, from_ucs]
+end
+
+def encode_utf8(map)
+ r = []
+ map.each {|k, v|
+ # integer means UTF-8 encoded sequence.
+ k = [k].pack("U").unpack("H*")[0].upcase if Integer === k
+ v = [v].pack("U").unpack("H*")[0].upcase if Integer === v
+ r << [k,v]
+ }
+ r
+end
+
+UnspecifiedValidEncoding = Object.new
+
+def transcode_compile_tree(name, from, map, valid_encoding)
+ map = encode_utf8(map)
+ h = {}
+ map.each {|k, v|
+ h[k] = v unless h[k] # use first mapping
+ }
+ if valid_encoding.equal? UnspecifiedValidEncoding
+ valid_encoding = ValidEncoding.fetch(from)
+ end
+ if valid_encoding
+ am = ActionMap.merge2(h, {valid_encoding => :undef}) {|prefix, as1, as2|
+ a1 = as1.empty? ? nil : ActionMap.unambiguous_action(as1)
+ a2 = as2.empty? ? nil : ActionMap.unambiguous_action(as2)
+ if !a2
+ raise "invalid mapping: #{prefix}"
+ end
+ a1 || a2
+ }
+ else
+ am = ActionMap.parse(h)
+ end
+ h.clear
+
+ max_input = am.max_input_length
+ defined_name = am.gennode(TRANSCODE_GENERATED_BYTES_CODE, TRANSCODE_GENERATED_WORDS_CODE, name)
+ return defined_name, max_input
+end
+
+TRANSCODERS = []
+TRANSCODE_GENERATED_TRANSCODER_CODE = ''
+
+def transcode_tbl_only(from, to, map, valid_encoding=UnspecifiedValidEncoding)
+ if VERBOSE_MODE
+ if from.empty? || to.empty?
+ STDERR.puts "converter for #{from.empty? ? to : from}"
+ else
+ STDERR.puts "converter from #{from} to #{to}"
+ end
+ end
+ id_from = from.tr('^0-9A-Za-z', '_')
+ id_to = to.tr('^0-9A-Za-z', '_')
+ if from == "UTF-8"
+ tree_name = "to_#{id_to}"
+ elsif to == "UTF-8"
+ tree_name = "from_#{id_from}"
+ else
+ tree_name = "from_#{id_from}_to_#{id_to}"
+ end
+ real_tree_name, max_input = transcode_compile_tree(tree_name, from, map, valid_encoding)
+ return map, tree_name, real_tree_name, max_input
+end
+
+def transcode_tblgen(from, to, map, valid_encoding=UnspecifiedValidEncoding)
+ map, tree_name, real_tree_name, max_input = transcode_tbl_only(from, to, map, valid_encoding)
+ transcoder_name = "rb_#{tree_name}"
+ TRANSCODERS << transcoder_name
+ input_unit_length = UnitLength[from]
+ max_output = map.map {|k,v| String === v ? v.length/2 : 1 }.max
+ transcoder_code = <<"End"
+static const rb_transcoder
+#{transcoder_name} = {
+ #{c_esc from}, #{c_esc to}, #{real_tree_name},
+ TRANSCODE_TABLE_INFO,
+ #{input_unit_length}, /* input_unit_length */
+ #{max_input}, /* max_input */
+ #{max_output}, /* max_output */
+ asciicompat_converter, /* asciicompat_type */
+ 0, NULL, NULL, /* state_size, state_init, state_fini */
+ NULL, NULL, NULL, NULL,
+ NULL, NULL, NULL
+};
+End
+ TRANSCODE_GENERATED_TRANSCODER_CODE << transcoder_code
+ ''
+end
+
+def transcode_generate_node(am, name_hint=nil)
+ STDERR.puts "converter for #{name_hint}" if VERBOSE_MODE
+ name = am.gennode(TRANSCODE_GENERATED_BYTES_CODE, TRANSCODE_GENERATED_WORDS_CODE, name_hint)
+ ''
+end
+
+def transcode_generated_code
+ TRANSCODE_GENERATED_BYTES_CODE.to_s +
+ TRANSCODE_GENERATED_WORDS_CODE.to_s +
+ "\#define TRANSCODE_TABLE_INFO " +
+ "#{OUTPUT_PREFIX}byte_array, #{TRANSCODE_GENERATED_BYTES_CODE.length}, " +
+ "#{OUTPUT_PREFIX}word_array, #{TRANSCODE_GENERATED_WORDS_CODE.length}, " +
+ "((int)sizeof(unsigned int))\n" +
+ TRANSCODE_GENERATED_TRANSCODER_CODE
+end
+
+def transcode_register_code
+ code = ''
+ TRANSCODERS.each {|transcoder_name|
+ code << " rb_register_transcoder(&#{transcoder_name});\n"
+ }
+ code
+end
+
+UnitLength = {
+ 'UTF-16BE' => 2,
+ 'UTF-16LE' => 2,
+ 'UTF-32BE' => 4,
+ 'UTF-32LE' => 4,
+}
+UnitLength.default = 1
+
+ValidEncoding = {
+ '1byte' => '{00-ff}',
+ '2byte' => '{00-ff}{00-ff}',
+ '4byte' => '{00-ff}{00-ff}{00-ff}{00-ff}',
+ 'US-ASCII' => '{00-7f}',
+ 'UTF-8' => '{00-7f}
+ {c2-df}{80-bf}
+ e0{a0-bf}{80-bf}
+ {e1-ec}{80-bf}{80-bf}
+ ed{80-9f}{80-bf}
+ {ee-ef}{80-bf}{80-bf}
+ f0{90-bf}{80-bf}{80-bf}
+ {f1-f3}{80-bf}{80-bf}{80-bf}
+ f4{80-8f}{80-bf}{80-bf}',
+ 'UTF-16BE' => '{00-d7,e0-ff}{00-ff}
+ {d8-db}{00-ff}{dc-df}{00-ff}',
+ 'UTF-16LE' => '{00-ff}{00-d7,e0-ff}
+ {00-ff}{d8-db}{00-ff}{dc-df}',
+ 'UTF-32BE' => '0000{00-d7,e0-ff}{00-ff}
+ 00{01-10}{00-ff}{00-ff}',
+ 'UTF-32LE' => '{00-ff}{00-d7,e0-ff}0000
+ {00-ff}{00-ff}{01-10}00',
+ 'EUC-JP' => '{00-7f}
+ {a1-fe}{a1-fe}
+ 8e{a1-fe}
+ 8f{a1-fe}{a1-fe}',
+ 'CP51932' => '{00-7f}
+ {a1-fe}{a1-fe}
+ 8e{a1-fe}',
+ 'EUC-JIS-2004' => '{00-7f}
+ {a1-fe}{a1-fe}
+ 8e{a1-fe}
+ 8f{a1-fe}{a1-fe}',
+ 'Shift_JIS' => '{00-7f}
+ {81-9f,e0-fc}{40-7e,80-fc}
+ {a1-df}',
+ 'EUC-KR' => '{00-7f}
+ {a1-fe}{a1-fe}',
+ 'CP949' => '{00-7f}
+ {81-fe}{41-5a,61-7a,81-fe}',
+ 'Big5' => '{00-7f}
+ {81-fe}{40-7e,a1-fe}',
+ 'EUC-TW' => '{00-7f}
+ {a1-fe}{a1-fe}
+ 8e{a1-b0}{a1-fe}{a1-fe}',
+ 'GBK' => '{00-80}
+ {81-fe}{40-7e,80-fe}',
+ 'GB18030' => '{00-7f}
+ {81-fe}{40-7e,80-fe}
+ {81-fe}{30-39}{81-fe}{30-39}',
+}
+
+def ValidEncoding(enc)
+ ValidEncoding.fetch(enc)
+end
+
+def set_valid_byte_pattern(encoding, pattern_or_label)
+ pattern =
+ if ValidEncoding[pattern_or_label]
+ ValidEncoding[pattern_or_label]
+ else
+ pattern_or_label
+ end
+ if ValidEncoding[encoding] and ValidEncoding[encoding]!=pattern
+ raise ArgumentError, "trying to change valid byte pattern for encoding #{encoding} from #{ValidEncoding[encoding]} to #{pattern}"
+ end
+ ValidEncoding[encoding] = pattern
+end
+
+# the following may be used in different places, so keep them here for the moment
+set_valid_byte_pattern 'ASCII-8BIT', '1byte'
+set_valid_byte_pattern 'Windows-31J', 'Shift_JIS'
+set_valid_byte_pattern 'eucJP-ms', 'EUC-JP'
+
+def make_signature(filename, src)
+ "src=#{filename.dump}, len=#{src.length}, checksum=#{src.sum}"
+end
+
+if __FILE__ == $0
+ start_time = Time.now
+
+ output_filename = nil
+ verbose_mode = false
+ force_mode = false
+
+ op = OptionParser.new
+ op.def_option("--help", "show help message") { puts op; exit 0 }
+ op.def_option("--verbose", "verbose mode") { verbose_mode = true }
+ op.def_option("--force", "force table generation") { force_mode = true }
+ op.def_option("--output=FILE", "specify output file") {|arg| output_filename = arg }
+ op.parse!
+
+ VERBOSE_MODE = verbose_mode
+
+ OUTPUT_FILENAME = output_filename
+ OUTPUT_PREFIX = output_filename ? File.basename(output_filename)[/\A[A-Za-z0-9_]*/] : ""
+ OUTPUT_PREFIX.sub!(/\A_+/, '')
+ OUTPUT_PREFIX.sub!(/_*\z/, '_')
+
+ TRANSCODE_GENERATED_BYTES_CODE = ArrayCode.new("unsigned char", "#{OUTPUT_PREFIX}byte_array")
+ TRANSCODE_GENERATED_WORDS_CODE = ArrayCode.new("unsigned int", "#{OUTPUT_PREFIX}word_array")
+
+ arg = ARGV.shift
+ $srcdir = File.dirname(arg)
+ $:.unshift $srcdir unless $:.include? $srcdir
+ src = File.read(arg)
+ src.force_encoding("ascii-8bit") if src.respond_to? :force_encoding
+ this_script = File.read(__FILE__)
+ this_script.force_encoding("ascii-8bit") if this_script.respond_to? :force_encoding
+
+ base_signature = "/* autogenerated. */\n"
+ base_signature << "/* #{make_signature(File.basename(__FILE__), this_script)} */\n"
+ base_signature << "/* #{make_signature(File.basename(arg), src)} */\n"
+
+ if !force_mode && output_filename && File.readable?(output_filename)
+ old_signature = File.open(output_filename) {|f| f.gets("").chomp }
+ chk_signature = base_signature.dup
+ old_signature.each_line {|line|
+ if %r{/\* src="([0-9a-z_.-]+)",} =~ line
+ name = $1
+ next if name == File.basename(arg) || name == File.basename(__FILE__)
+ path = File.join($srcdir, name)
+ if File.readable? path
+ chk_signature << "/* #{make_signature(name, File.read(path))} */\n"
+ end
+ end
+ }
+ if old_signature == chk_signature
+ now = Time.now
+ File.utime(now, now, output_filename)
+ STDERR.puts "already up-to-date: #{output_filename}" if VERBOSE_MODE
+ exit
+ end
+ end
+
+ if VERBOSE_MODE
+ if output_filename
+ STDERR.puts "generating #{output_filename} ..."
+ end
+ end
+
+ libs1 = $".dup
+ erb = ERB.new(src, nil, '%')
+ erb.filename = arg
+ erb_result = erb.result(binding)
+ libs2 = $".dup
+
+ libs = libs2 - libs1
+ lib_sigs = ''
+ libs.each {|lib|
+ lib = File.basename(lib)
+ path = File.join($srcdir, lib)
+ if File.readable? path
+ lib_sigs << "/* #{make_signature(lib, File.read(path))} */\n"
+ end
+ }
+
+ result = ''
+ result << base_signature
+ result << lib_sigs
+ result << "\n"
+ result << erb_result
+ result << "\n"
+
+ if output_filename
+ new_filename = output_filename + ".new"
+ FileUtils.mkdir_p(File.dirname(output_filename))
+ File.open(new_filename, "wb") {|f| f << result }
+ File.rename(new_filename, output_filename)
+ tms = Process.times
+ elapsed = Time.now - start_time
+ STDERR.puts "done. (#{'%.2f' % tms.utime}user #{'%.2f' % tms.stime}system #{'%.2f' % elapsed}elapsed)" if VERBOSE_MODE
+ else
+ print result
+ end
+end
diff --git a/jni/ruby/tool/update-deps b/jni/ruby/tool/update-deps
new file mode 100755
index 0000000..2e7a7e7
--- /dev/null
+++ b/jni/ruby/tool/update-deps
@@ -0,0 +1,615 @@
+#!/usr/bin/ruby
+
+# tool/update-deps verify makefile dependencies.
+
+# Requirements:
+# gcc 4.5 (for -save-temps=obj option)
+# GNU make (for -p option)
+#
+# Warning: ccache (and similar tools) must be disabled for
+# -save-temps=obj to work properly.
+#
+# Usage:
+# 1. Compile ruby with -save-temps=obj option.
+# Ex. ./configure debugflags='-save-temps=obj -g' && make all golf
+# 2. Run tool/update-deps to show dependency problems.
+# Ex. ruby tool/update-deps
+# 3. Use --fix to fix makefiles.
+# Ex. ruby tool/update-deps --fix
+#
+# Other usages:
+# * Fix makefiles using previously detected dependency problems
+# Ex. ruby tool/update-deps --actual-fix [file]
+# "ruby tool/update-deps --fix" is same as "ruby tool/update-deps | ruby tool/update-deps --actual-fix".
+
+require 'optparse'
+require 'stringio'
+require 'pathname'
+require 'open3'
+require 'pp'
+
+# When out-of-place bulid, files may be built in source directory or
+# build directory.
+# Some files are always built in the source directory.
+# Some files are always built in the build directory.
+# Some files are built in the source directory for tarball but build directory for repository (svn).
+
+=begin
+How to build test directories.
+
+VER=2.2.0
+REV=48577
+tar xf ruby-$VER-r$REV.tar.xz
+cp -a ruby-$VER-r$REV tarball_source_dir_original
+mv ruby-$VER-r$REV tarball_source_dir_after_build
+svn co -q -r$REV http://svn.ruby-lang.org/repos/ruby/trunk ruby
+(cd ruby; autoconf)
+cp -a ruby repo_source_dir_original
+mv ruby repo_source_dir_after_build
+mkdir tarball_build_dir repo_build_dir tarball_install_dir repo_install_dir
+(cd tarball_build_dir; ../tarball_source_dir_after_build/configure --prefix=$(cd ../tarball_install_dir; pwd) && make all golf install) > tarball.log 2>&1
+(cd repo_build_dir; ../repo_source_dir_after_build/configure --prefix=$(cd ../repo_install_dir; pwd) && make all golf install) > repo.log 2>&1
+ruby -rpp -rfind -e '
+ds = %w[
+ repo_source_dir_original
+ repo_source_dir_after_build
+ repo_build_dir
+ tarball_source_dir_original
+ tarball_source_dir_after_build
+ tarball_build_dir
+]
+files = {}
+ds.each {|d|
+ files[d] = {}
+ Dir.chdir(d) { Find.find(".") {|f| files[d][f] = true if %r{\.(c|h|inc|dmyh)\z} =~ f } }
+}
+result = {}
+files_union = files.values.map {|h| h.keys }.flatten.uniq.sort
+files_union.each {|f|
+ k = files.map {|d,h| h[f] ? d : nil }.compact.sort
+ next if k == %w[repo_source_dir_after_build repo_source_dir_original tarball_source_dir_after_build tarball_source_dir_original]
+ next if k == %w[repo_build_dir tarball_build_dir] && File.basename(f) == "extconf.h"
+ result[k] ||= []
+ result[k] << f
+}
+result.each {|k,v|
+ k.each {|d|
+ puts d
+ }
+ v.each {|f|
+ puts " " + f.sub(%r{\A\./}, "")
+ }
+ puts
+}
+' | tee compare.log
+=end
+
+# Files built in the source directory.
+# They can be referenced as $(top_srcdir)/filename.
+# % ruby -e 'def g(d) Dir.chdir(d) { Dir["**/*.{c,h,inc,dmyh}"] } end; puts((g("repo_source_dir_after_build") - g("repo_source_dir_original")).sort)'
+FILES_IN_SOURCE_DIRECTORY = %w[
+ revision.h
+]
+
+# Files built in the build directory (except extconf.h).
+# They can be referenced as $(topdir)/filename.
+# % ruby -e 'def g(d) Dir.chdir(d) { Dir["**/*.{c,h,inc,dmyh}"] } end; puts(g("tarball_build_dir").reject {|f| %r{/extconf.h\z} =~ f }.sort)'
+FILES_IN_BUILD_DIRECTORY = %w[
+ encdb.h
+ ext/etc/constdefs.h
+ ext/socket/constdefs.c
+ ext/socket/constdefs.h
+ probes.h
+ transdb.h
+ verconf.h
+]
+
+# They are built in the build directory if the source is obtained from the repository.
+# However they are pre-built for tarball and they exist in the source directory extracted from the tarball.
+# % ruby -e 'def g(d) Dir.chdir(d) { Dir["**/*.{c,h,inc,dmyh}"] } end; puts((g("repo_build_dir") & g("tarball_source_dir_original")).sort)'
+FILES_NEED_VPATH = %w[
+ ext/rbconfig/sizeof/sizes.c
+ ext/ripper/eventids1.c
+ ext/ripper/eventids2table.c
+ ext/ripper/ripper.c
+ golf_prelude.c
+ id.c
+ id.h
+ insns.inc
+ insns_info.inc
+ known_errors.inc
+ lex.c
+ miniprelude.c
+ newline.c
+ node_name.inc
+ opt_sc.inc
+ optinsn.inc
+ optunifs.inc
+ parse.c
+ parse.h
+ prelude.c
+ probes.dmyh
+ vm.inc
+ vmtc.inc
+
+ enc/trans/big5.c
+ enc/trans/chinese.c
+ enc/trans/emoji.c
+ enc/trans/emoji_iso2022_kddi.c
+ enc/trans/emoji_sjis_docomo.c
+ enc/trans/emoji_sjis_kddi.c
+ enc/trans/emoji_sjis_softbank.c
+ enc/trans/escape.c
+ enc/trans/gb18030.c
+ enc/trans/gbk.c
+ enc/trans/iso2022.c
+ enc/trans/japanese.c
+ enc/trans/japanese_euc.c
+ enc/trans/japanese_sjis.c
+ enc/trans/korean.c
+ enc/trans/single_byte.c
+ enc/trans/utf8_mac.c
+ enc/trans/utf_16_32.c
+]
+
+# Multiple files with same filename.
+# It is not good idea to refer them using VPATH.
+# Files in FILES_SAME_NAME_INC is referenced using $(hdrdir).
+# Files in FILES_SAME_NAME_TOP is referenced using $(top_srcdir).
+# include/ruby.h is referenced using $(top_srcdir) because mkmf.rb replaces
+# $(hdrdir)/ruby.h to $(hdrdir)/ruby/ruby.h
+
+FILES_SAME_NAME_INC = %w[
+ include/ruby/ruby.h
+ include/ruby/version.h
+]
+
+FILES_SAME_NAME_TOP = %w[
+ include/ruby.h
+ version.h
+]
+
+# Other source files exist in the source directory.
+
+def in_makefile(target, source)
+ target = target.to_s
+ source = source.to_s
+ case target
+ when %r{\A[^/]*\z}
+ target2 = "#{target.sub(/\.o\z/, '.$(OBJEXT)')}"
+ case source
+ when *FILES_IN_SOURCE_DIRECTORY then source2 = "$(top_srcdir)/#{source}"
+ when *FILES_IN_BUILD_DIRECTORY then source2 = "{$(VPATH)}#{source}" # VPATH is not used now but it may changed in future.
+ when *FILES_NEED_VPATH then source2 = "{$(VPATH)}#{source}"
+ when *FILES_SAME_NAME_INC then source2 = "$(hdrdir)/#{source.sub(%r{\Ainclude/},'')}"
+ when *FILES_SAME_NAME_TOP then source2 = "$(top_srcdir)/#{source}"
+ when 'thread_pthread.c' then source2 = '{$(VPATH)}thread_$(THREAD_MODEL).c'
+ when 'thread_pthread.h' then source2 = '{$(VPATH)}thread_$(THREAD_MODEL).h'
+ when %r{\A[^/]*\z} then source2 = "{$(VPATH)}#{File.basename source}"
+ when %r{\A\.ext/include/[^/]+/ruby/} then source2 = "{$(VPATH)}#{$'}"
+ when %r{\Ainclude/ruby/} then source2 = "{$(VPATH)}#{$'}"
+ when %r{\Aenc/} then source2 = "{$(VPATH)}#{$'}"
+ when %r{\Amissing/} then source2 = "{$(VPATH)}#{$'}"
+ when %r{\Accan/} then source2 = "$(CCAN_DIR)/#{$'}"
+ when %r{\Adefs/} then source2 = "{$(VPATH)}#{source}"
+ else source2 = "$(top_srcdir)/#{source}"
+ end
+ ["common.mk", target2, source2]
+ when %r{\Aenc/}
+ target2 = "#{target.sub(/\.o\z/, '.$(OBJEXT)')}"
+ case source
+ when *FILES_IN_SOURCE_DIRECTORY then source2 = "$(top_srcdir)/#{source}"
+ when *FILES_IN_BUILD_DIRECTORY then source2 = source
+ when *FILES_NEED_VPATH then source2 = source
+ when *FILES_SAME_NAME_INC then source2 = "$(hdrdir)/#{source.sub(%r{\Ainclude/},'')}"
+ when *FILES_SAME_NAME_TOP then source2 = "$(top_srcdir)/#{source}"
+ when %r{\A\.ext/include/[^/]+/ruby/} then source2 = $'
+ when %r{\Ainclude/ruby/} then source2 = $'
+ when %r{\Aenc/} then source2 = source
+ else source2 = "$(top_srcdir)/#{source}"
+ end
+ ["enc/depend", target2, source2]
+ when %r{\Aext/}
+ unless File.exist?("#{File.dirname(target)}/extconf.rb")
+ warn "warning: not found: #{File.dirname(target)}/extconf.rb"
+ end
+ target2 = File.basename(target)
+ relpath = Pathname(source).relative_path_from(Pathname(target).dirname).to_s
+ case source
+ when *FILES_IN_SOURCE_DIRECTORY then source2 = "$(top_srcdir)/#{source}"
+ when *FILES_IN_BUILD_DIRECTORY then source2 = relpath
+ when *FILES_NEED_VPATH then source2 = "{$(VPATH)}#{File.basename source}"
+ when *FILES_SAME_NAME_INC then source2 = "$(hdrdir)/#{source.sub(%r{\Ainclude/},'')}"
+ when *FILES_SAME_NAME_TOP then source2 = "$(top_srcdir)/#{source}"
+ when %r{\A\.ext/include/[^/]+/ruby/} then source2 = "$(arch_hdrdir)/ruby/#{$'}"
+ when %r{\Ainclude/} then source2 = "$(hdrdir)/#{$'}"
+ when %r{\A#{Regexp.escape File.dirname(target)}/extconf\.h\z} then source2 = "$(RUBY_EXTCONF_H)"
+ when %r{\A#{Regexp.escape File.dirname(target)}/} then source2 = $'
+ else source2 = "$(top_srcdir)/#{source}"
+ end
+ ["#{File.dirname(target)}/depend", target2, source2]
+ else
+ raise "unexpected target: #{target}"
+ end
+end
+
+DEPENDENCIES_SECTION_START_MARK = "\# AUTOGENERATED DEPENDENCIES START\n"
+DEPENDENCIES_SECTION_END_MARK = "\# AUTOGENERATED DEPENDENCIES END\n"
+
+def init_global
+ ENV['LC_ALL'] = 'C'
+
+ $opt_fix = false
+ $opt_a = false
+ $opt_actual_fix = false
+ $i_not_found = false
+end
+
+def optionparser
+ op = OptionParser.new
+ op.banner = 'Usage: ruby tool/update-deps'
+ op.def_option('-a', 'show valid dependencies') { $opt_a = true }
+ op.def_option('--fix') { $opt_fix = true }
+ op.def_option('--actual-fix') { $opt_actual_fix = true }
+ op
+end
+
+def read_make_deps(cwd)
+ dependencies = {}
+ make_p, make_p_stderr, make_p_status = Open3.capture3("make -p all miniruby ruby golf")
+ File.open('update-deps.make.out.log', 'w') {|f| f.print make_p }
+ File.open('update-deps.make.err.log', 'w') {|f| f.print make_p_stderr }
+ if !make_p_status.success?
+ puts make_p_stderr
+ raise "make failed"
+ end
+ dirstack = [cwd]
+ curdir = nil
+ make_p.scan(%r{Entering\ directory\ ['`](.*)'|
+ ^\#\ (GNU\ Make)\ |
+ ^CURDIR\ :=\ (.*)|
+ ^([/0-9a-zA-Z._-]+):(.*)\n((?:\#.*\n)*)|
+ ^\#\ (Finished\ Make\ data\ base\ on)\ |
+ Leaving\ directory\ ['`](.*)'}x) {
+ directory_enter = $1
+ data_base_start = $2
+ data_base_curdir = $3
+ rule_target = $4
+ rule_sources = $5
+ rule_desc = $6
+ data_base_end = $7
+ directory_leave = $8
+ #p $~
+ if directory_enter
+ enter_dir = Pathname(directory_enter)
+ #p [:enter, enter_dir]
+ dirstack.push enter_dir
+ elsif data_base_start
+ curdir = nil
+ elsif data_base_curdir
+ curdir = Pathname(data_base_curdir)
+ elsif rule_target && rule_sources && rule_desc &&
+ /Modification time never checked/ !~ rule_desc # This pattern match eliminates rules which VPATH is not expanded.
+ target = rule_target
+ deps = rule_sources
+ deps = deps.scan(%r{[/0-9a-zA-Z._-]+})
+ next if /\.o\z/ !~ target.to_s
+ next if /\A\./ =~ target.to_s # skip rules such as ".c.o"
+ #p [curdir, target, deps]
+ dir = curdir || dirstack.last
+ dependencies[dir + target] ||= []
+ dependencies[dir + target] |= deps.map {|dep| dir + dep }
+ elsif data_base_end
+ curdir = nil
+ elsif directory_leave
+ leave_dir = Pathname(directory_leave)
+ #p [:leave, leave_dir]
+ if leave_dir != dirstack.last
+ warn "unexpected leave_dir : #{dirstack.last.inspect} != #{leave_dir.inspect}"
+ end
+ dirstack.pop
+ end
+ }
+ dependencies
+end
+
+#def guess_compiler_wd(filename, hint0)
+# hint = hint0
+# begin
+# guess = hint + filename
+# if guess.file?
+# return hint
+# end
+# hint = hint.parent
+# end while hint.to_s != '.'
+# raise ArgumentError, "can not find #{filename} (hint: #{hint0})"
+#end
+
+def read_single_cc_deps(path_i, cwd)
+ files = {}
+ path_i.each_line.with_index {|line, lineindex|
+ next if /\A\# \d+ "(.*)"/ !~ line
+ files[$1] = lineindex
+ }
+ # gcc emits {# 1 "/absolute/directory/of/the/source/file//"} at 2nd line.
+ compiler_wd = files.keys.find {|f| %r{\A/.*//\z} =~ f }
+ if compiler_wd
+ files.delete compiler_wd
+ compiler_wd = Pathname(compiler_wd.sub(%r{//\z}, ''))
+ else
+ raise "compiler working directory not found"
+ end
+ deps = []
+ files.each_key {|dep|
+ next if %r{\A<.*>\z} =~ dep # omit <command-line>, etc.
+ dep = Pathname(dep)
+ if dep.relative?
+ dep = compiler_wd + dep
+ end
+ if !dep.file?
+ warn "warning: file not found: #{dep}"
+ next
+ end
+ next if !dep.to_s.start_with?(cwd.to_s) # omit system headers.
+ deps << dep
+ }
+ deps
+end
+
+def read_cc_deps(cwd)
+ deps = {}
+ Pathname.glob('**/*.o').sort.each {|fn_o|
+ fn_i = fn_o.sub_ext('.i')
+ if !fn_i.exist?
+ warn "warning: not found: #{fn_i}"
+ $i_not_found = true
+ next
+ end
+ path_o = cwd + fn_o
+ path_i = cwd + fn_i
+ deps[path_o] = read_single_cc_deps(path_i, cwd)
+ }
+ deps
+end
+
+def concentrate(dependencies, cwd)
+ deps = {}
+ dependencies.keys.sort.each {|target|
+ sources = dependencies[target]
+ target = target.relative_path_from(cwd)
+ sources = sources.map {|s|
+ rel = s.relative_path_from(cwd)
+ rel
+ }
+ if %r{\A\.\.(/|\z)} =~ target.to_s
+ warn "warning: out of tree target: #{target}"
+ next
+ end
+ sources = sources.reject {|s|
+ if %r{\A\.\.(/|\z)} =~ s.to_s
+ warn "warning: out of tree source: #{s}"
+ true
+ else
+ false
+ end
+ }
+ deps[target] = sources
+ }
+ deps
+end
+
+def sort_paths(paths)
+ paths.sort_by {|t|
+ ary = t.to_s.split(%r{/})
+ ary.map.with_index {|e, i| i == ary.length-1 ? [0, e] : [1, e] } # regular file first, directories last.
+ }
+end
+
+def show_deps(tag, deps)
+ targets = sort_paths(deps.keys)
+ targets.each {|t|
+ sources = sort_paths(deps[t])
+ sources.each {|s|
+ puts "#{tag} #{t}: #{s}"
+ }
+ }
+end
+
+def detect_dependencies(out=$stdout)
+ cwd = Pathname.pwd
+ make_deps = read_make_deps(cwd)
+ #pp make_deps
+ make_deps = concentrate(make_deps, cwd)
+ #pp make_deps
+ cc_deps = read_cc_deps(cwd)
+ #pp cc_deps
+ cc_deps = concentrate(cc_deps, cwd)
+ #pp cc_deps
+ return make_deps, cc_deps
+end
+
+def compare_deps(make_deps, cc_deps, out=$stdout)
+ targets = make_deps.keys | cc_deps.keys
+
+ makefiles = {}
+
+ make_lines_hash = {}
+ make_deps.each {|t, sources|
+ sources.each {|s|
+ makefile, t2, s2 = in_makefile(t, s)
+ makefiles[makefile] = true
+ make_lines_hash[makefile] ||= Hash.new(false)
+ make_lines_hash[makefile]["#{t2}: #{s2}"] = true
+ }
+ }
+
+ cc_lines_hash = {}
+ cc_deps.each {|t, sources|
+ sources.each {|s|
+ makefile, t2, s2 = in_makefile(t, s)
+ makefiles[makefile] = true
+ cc_lines_hash[makefile] ||= Hash.new(false)
+ cc_lines_hash[makefile]["#{t2}: #{s2}"] = true
+ }
+ }
+
+ makefiles.keys.sort.each {|makefile|
+ cc_lines = cc_lines_hash[makefile] || Hash.new(false)
+ make_lines = make_lines_hash[makefile] || Hash.new(false)
+ content = begin
+ File.read(makefile)
+ rescue Errno::ENOENT
+ ''
+ end
+ if /^#{Regexp.escape DEPENDENCIES_SECTION_START_MARK}
+ ((?:.*\n)*)
+ #{Regexp.escape DEPENDENCIES_SECTION_END_MARK}/x =~ content
+ pre_post_part = [$`, $']
+ current_lines = Hash.new(false)
+ $1.each_line {|line| current_lines[line.chomp] = true }
+ (cc_lines.keys | current_lines.keys | make_lines.keys).sort.each {|line|
+ status = [cc_lines[line], current_lines[line], make_lines[line]]
+ case status
+ when [true, true, true]
+ # no problem
+ when [true, true, false]
+ out.puts "warning #{makefile} : #{line} (make doesn't detect written dependency)"
+ when [true, false, true]
+ out.puts "add_auto #{makefile} : #{line} (harmless)" # This is automatically updatable.
+ when [true, false, false]
+ out.puts "add_auto #{makefile} : #{line} (harmful)" # This is automatically updatable.
+ when [false, true, true]
+ out.puts "del_cc #{makefile} : #{line}" # Not automatically updatable because build on other OS may need the dependency.
+ when [false, true, false]
+ out.puts "del_cc #{makefile} : #{line} (Curious. make doesn't detect this dependency.)" # Not automatically updatable because build on other OS may need the dependency.
+ when [false, false, true]
+ out.puts "del_make #{makefile} : #{line}" # Not automatically updatable because the dependency is written manually.
+ else
+ raise "unexpected status: #{status.inspect}"
+ end
+ }
+ else
+ (cc_lines.keys | make_lines.keys).sort.each {|line|
+ status = [cc_lines[line], make_lines[line]]
+ case status
+ when [true, true]
+ # no problem
+ when [true, false]
+ out.puts "add_manual #{makefile} : #{line}" # Not automatically updatable because makefile has no section to update automatically.
+ when [false, true]
+ out.puts "del_manual #{makefile} : #{line}" # Not automatically updatable because makefile has no section to update automatically.
+ else
+ raise "unexpected status: #{status.inspect}"
+ end
+ }
+ end
+ }
+end
+
+def main_show(out=$stdout)
+ make_deps, cc_deps = detect_dependencies(out)
+ compare_deps(make_deps, cc_deps, out)
+end
+
+def extract_deplines(problems)
+ adds = {}
+ others = {}
+ problems.each_line {|line|
+ case line
+ when /\Aadd_auto (\S+) : ((\S+): (\S+))/
+ (adds[$1] ||= []) << [line, "#{$2}\n"]
+ when /\A(?:del_cc|del_make|add_manual|del_manual|warning) (\S+) : /
+ (others[$1] ||= []) << line
+ else
+ raise "unexpected line: #{line.inspect}"
+ end
+ }
+ return adds, others
+end
+
+def main_actual_fix(problems)
+ adds, others = extract_deplines(problems)
+ (adds.keys | others.keys).sort.each {|makefile|
+ content = begin
+ File.read(makefile)
+ rescue Errno::ENOENT
+ nil
+ end
+
+ if content &&
+ /^#{Regexp.escape DEPENDENCIES_SECTION_START_MARK}
+ ((?:.*\n)*)
+ #{Regexp.escape DEPENDENCIES_SECTION_END_MARK}/x =~ content
+ pre_dep_post = [$`, $1, $']
+ else
+ pre_dep_post = nil
+ end
+
+ if pre_dep_post && adds[makefile]
+ pre_lines, dep_lines, post_lines = pre_dep_post
+ dep_lines = dep_lines.lines.to_a
+ add_lines = adds[makefile].map(&:last)
+ new_lines = (dep_lines | add_lines).sort.uniq
+ new_content = [
+ pre_lines,
+ DEPENDENCIES_SECTION_START_MARK,
+ *new_lines,
+ DEPENDENCIES_SECTION_END_MARK,
+ post_lines
+ ].join
+ if content != new_content
+ puts "modified: #{makefile}"
+ tmp_makefile = "#{makefile}.new.#{$$}"
+ File.write(tmp_makefile, new_content)
+ File.rename tmp_makefile, makefile
+ (add_lines - dep_lines).each {|line| puts " added #{line}" }
+ else
+ puts "not modified: #{makefile}"
+ end
+ if others[makefile]
+ others[makefile].each {|line| puts " #{line}" }
+ end
+ else
+ if pre_dep_post
+ puts "no addtional lines: #{makefile}"
+ elsif content
+ puts "no dependencies section: #{makefile}"
+ else
+ puts "no makefile: #{makefile}"
+ end
+ if adds[makefile]
+ puts " warning: dependencies section was exist at previous phase."
+ end
+ if adds[makefile]
+ adds[makefile].map(&:first).each {|line| puts " #{line}" }
+ end
+ if others[makefile]
+ others[makefile].each {|line| puts " #{line}" }
+ end
+ end
+ }
+end
+
+def main_fix
+ problems = StringIO.new
+ main_show(problems)
+ main_actual_fix(problems.string)
+end
+
+def run
+ op = optionparser
+ op.parse!(ARGV)
+ if $opt_actual_fix
+ main_actual_fix(ARGF.read)
+ elsif $opt_fix
+ main_fix
+ else
+ main_show
+ end
+end
+
+init_global
+run
+if $i_not_found
+ warn "warning: missing *.i files, see help in #$0 and ensure ccache is disabled"
+end
diff --git a/jni/ruby/tool/vcs.rb b/jni/ruby/tool/vcs.rb
new file mode 100644
index 0000000..66d2764
--- /dev/null
+++ b/jni/ruby/tool/vcs.rb
@@ -0,0 +1,256 @@
+# vcs
+
+ENV.delete('PWD')
+
+unless File.respond_to? :realpath
+ require 'pathname'
+ def File.realpath(arg)
+ Pathname(arg).realpath.to_s
+ end
+end
+
+def IO.pread(*args)
+ STDERR.puts(*args.inspect) if $DEBUG
+ popen(*args) {|f|f.read}
+end
+
+if RUBY_VERSION < "1.9"
+ class IO
+ @orig_popen = method(:popen)
+
+ if defined?(fork)
+ def self.popen(command, *rest, &block)
+ if !(Array === command)
+ @orig_popen.call(command, *rest, &block)
+ elsif block
+ @orig_popen.call("-", *rest) {|f| f ? yield(f) : exec(*command)}
+ else
+ @orig_popen.call("-", *rest) or exec(*command)
+ end
+ end
+ else
+ require 'shellwords'
+ def self.popen(command, *rest, &block)
+ command = command.shelljoin if Array === command
+ @orig_popen.call(command, *rest, &block)
+ end
+ end
+ end
+end
+
+class VCS
+ class NotFoundError < RuntimeError; end
+
+ @@dirs = []
+ def self.register(dir)
+ @@dirs << [dir, self]
+ end
+
+ def self.detect(path)
+ @@dirs.each do |dir, klass|
+ return klass.new(path) if File.directory?(File.join(path, dir))
+ prev = path
+ loop {
+ curr = File.realpath(File.join(prev, '..'))
+ break if curr == prev # stop at the root directory
+ return klass.new(path) if File.directory?(File.join(curr, dir))
+ prev = curr
+ }
+ end
+ raise VCS::NotFoundError, "does not seem to be under a vcs: #{path}"
+ end
+
+ def initialize(path)
+ @srcdir = path
+ super()
+ end
+
+ NullDevice = defined?(IO::NULL) ? IO::NULL :
+ %w[/dev/null NUL NIL: NL:].find {|dev| File.exist?(dev)}
+
+ # return a pair of strings, the last revision and the last revision in which
+ # +path+ was modified.
+ def get_revisions(path)
+ if String === path or path.respond_to?(:to_path)
+ path = relative_to(path)
+ end
+ last, changed, modified, *rest = (
+ begin
+ if NullDevice
+ save_stderr = STDERR.dup
+ STDERR.reopen NullDevice, 'w'
+ end
+ self.class.get_revisions(path, @srcdir)
+ ensure
+ if save_stderr
+ STDERR.reopen save_stderr
+ save_stderr.close
+ end
+ end
+ )
+ last or raise VCS::NotFoundError, "last revision not found"
+ changed or raise VCS::NotFoundError, "changed revision not found"
+ if modified
+ /\A(\d+)-(\d+)-(\d+)\D(\d+):(\d+):(\d+(?:\.\d+)?)\s*(?:Z|([-+]\d\d)(\d\d))\z/ =~ modified or
+ raise "unknown time format - #{modified}"
+ match = $~[1..6].map { |x| x.to_i }
+ off = $7 ? "#{$7}:#{$8}" : "+00:00"
+ match << off
+ begin
+ modified = Time.new(*match)
+ rescue ArgumentError
+ modified = Time.utc(*$~[1..6]) + $7.to_i * 3600 + $8.to_i * 60
+ end
+ end
+ return last, changed, modified, *rest
+ end
+
+ def relative_to(path)
+ if path
+ srcdir = File.realpath(@srcdir)
+ path = File.realdirpath(path)
+ list1 = srcdir.split(%r{/})
+ list2 = path.split(%r{/})
+ while !list1.empty? && !list2.empty? && list1.first == list2.first
+ list1.shift
+ list2.shift
+ end
+ if list1.empty? && list2.empty?
+ "."
+ else
+ ([".."] * list1.length + list2).join("/")
+ end
+ else
+ '.'
+ end
+ end
+
+ class SVN < self
+ register(".svn")
+
+ def self.get_revisions(path, srcdir = nil)
+ if srcdir and (String === path or path.respond_to?(:to_path))
+ path = File.join(srcdir, path)
+ end
+ info_xml = IO.pread(%W"svn info --xml #{path}")
+ _, last, _, changed, _ = info_xml.split(/revision="(\d+)"/)
+ modified = info_xml[/<date>([^<>]*)/, 1]
+ [last, changed, modified]
+ end
+
+ def url
+ unless defined?(@url)
+ url = IO.pread(%W"svn info --xml #{@srcdir}")[/<root>(.*)<\/root>/, 1]
+ @url = URI.parse(url+"/") if url
+ end
+ @url
+ end
+
+ def branch(name)
+ url + "branches/#{name}"
+ end
+
+ def tag(name)
+ url + "tags/#{name}"
+ end
+
+ def trunk
+ url + "trunk"
+ end
+
+ def branch_list(pat)
+ IO.popen(%W"svn ls #{branch('')}") do |f|
+ f.each do |line|
+ line.chomp!
+ line.chomp!('/')
+ yield(line) if File.fnmatch?(pat, line)
+ end
+ end
+ end
+
+ def grep(pat, tag, *files, &block)
+ cmd = %W"svn cat"
+ files.map! {|n| File.join(tag, n)} if tag
+ set = block.binding.eval("proc {|match| $~ = match}")
+ IO.popen([cmd, *files]) do |f|
+ f.grep(pat) do |s|
+ set[$~]
+ yield s
+ end
+ end
+ end
+
+ def export(revision, url, dir)
+ IO.popen(%W"svn export -r #{revision} #{url} #{dir}") do |pipe|
+ pipe.each {|line| /^A/ =~ line or yield line}
+ end
+ $?.success?
+ end
+ end
+
+ class GIT < self
+ register(".git")
+
+ def self.get_revisions(path, srcdir = nil)
+ logcmd = %W[git log -n1 --date=iso]
+ logcmd[1, 0] = ["-C", srcdir] if srcdir
+ logcmd << "--grep=^ *git-svn-id: .*@[0-9][0-9]*"
+ idpat = /git-svn-id: .*?@(\d+) \S+\Z/
+ log = IO.pread(logcmd)
+ last = log[idpat, 1]
+ if path
+ log = IO.pread(logcmd + [path])
+ changed = log[idpat, 1]
+ else
+ changed = last
+ end
+ modified = log[/^Date:\s+(.*)/, 1]
+ [last, changed, modified]
+ end
+
+ def branch(name)
+ name
+ end
+
+ alias tag branch
+
+ def trunk
+ branch("trunk")
+ end
+
+ def stable
+ cmd = %W"git for-each-ref --format=\%(refname:short) refs/heads/ruby_[0-9]*"
+ cmd[1, 0] = ["-C", @srcdir] if @srcdir
+ branch(IO.pread(cmd)[/.*^(ruby_\d+_\d+)$/m, 1])
+ end
+
+ def branch_list(pat)
+ cmd = %W"git for-each-ref --format=\%(refname:short) refs/heads/#{pat}"
+ cmd[1, 0] = ["-C", @srcdir] if @srcdir
+ IO.popen(cmd) {|f|
+ f.each {|line|
+ line.chomp!
+ yield line
+ }
+ }
+ end
+
+ def grep(pat, tag, *files, &block)
+ cmd = %W[git grep -h --perl-regexp #{tag} --]
+ cmd[1, 0] = ["-C", @srcdir] if @srcdir
+ set = block.binding.eval("proc {|match| $~ = match}")
+ IO.popen([cmd, *files]) do |f|
+ f.grep(pat) do |s|
+ set[$~]
+ yield s
+ end
+ end
+ end
+
+ def export(revision, url, dir)
+ ret = system("git", "clone", "-s", (@srcdir || '.'), "-b", url, dir)
+ FileUtils.rm_rf("#{dir}/.git") if ret
+ ret
+ end
+ end
+end
diff --git a/jni/ruby/tool/vpath.rb b/jni/ruby/tool/vpath.rb
new file mode 100644
index 0000000..48ab148
--- /dev/null
+++ b/jni/ruby/tool/vpath.rb
@@ -0,0 +1,87 @@
+# -*- coding: us-ascii -*-
+
+class VPath
+ attr_accessor :separator
+
+ def initialize(*list)
+ @list = list
+ @additional = []
+ @separator = nil
+ end
+
+ def inspect
+ list.inspect
+ end
+
+ def search(meth, base, *rest)
+ begin
+ meth.call(base, *rest)
+ rescue Errno::ENOENT => error
+ list.each do |dir|
+ return meth.call(File.join(dir, base), *rest) rescue nil
+ end
+ raise error
+ end
+ end
+
+ def process(*args, &block)
+ search(File.method(__callee__), *args, &block)
+ end
+
+ alias stat process
+ alias lstat process
+
+ def open(*args)
+ f = search(File.method(:open), *args)
+ if block_given?
+ begin
+ yield f
+ ensure
+ f.close unless f.closed?
+ end
+ else
+ f
+ end
+ end
+
+ def read(*args)
+ open(*args) {|f| f.read}
+ end
+
+ def foreach(file, *args, &block)
+ open(file) {|f| f.each(*args, &block)}
+ end
+
+ def def_options(opt)
+ opt.on("-I", "--srcdir=DIR", "add a directory to search path") {|dir|
+ @additional << dir
+ }
+ opt.on("-L", "--vpath=PATH LIST", "add directories to search path") {|dirs|
+ @additional << [dirs]
+ }
+ opt.on("--path-separator=SEP", /\A(?:\W\z|\.(\W).+)/, "separator for vpath") {|sep, vsep|
+ # hack for msys make.
+ @separator = vsep || sep
+ }
+ end
+
+ def list
+ @additional.reject! do |dirs|
+ case dirs
+ when String
+ @list << dirs
+ when Array
+ raise "--path-separator option is needed for vpath list" unless @separator
+ # @separator ||= (require 'rbconfig'; RbConfig::CONFIG["PATH_SEPARATOR"])
+ @list.concat(dirs[0].split(@separator))
+ end
+ true
+ end
+ @list
+ end
+
+ def strip(path)
+ prefix = list.map {|dir| Regexp.quote(dir)}
+ path.sub(/\A#{prefix.join('|')}(?:\/|\z)/, '')
+ end
+end
diff --git a/jni/ruby/tool/vtlh.rb b/jni/ruby/tool/vtlh.rb
new file mode 100644
index 0000000..fcd3630
--- /dev/null
+++ b/jni/ruby/tool/vtlh.rb
@@ -0,0 +1,15 @@
+# ARGF = open('ha')
+cd = `pwd`.chomp + '/'
+ARGF.each{|line|
+ if /^0x([a-z0-9]+),/ =~ line
+ stat = line.split(',')
+ addr = stat[0].hex + 0x00400000
+ retired = stat[2].to_i
+ ticks = stat[3].to_i
+
+ src = `addr2line -e miniruby.exe #{addr.to_s(16)}`.chomp
+ src.sub!(cd, '')
+ puts '%-40s 0x%08x %8d %8d' % [src, addr, retired, ticks]
+ end
+}
+
diff --git a/jni/ruby/tool/ytab.sed b/jni/ruby/tool/ytab.sed
new file mode 100755
index 0000000..46317db
--- /dev/null
+++ b/jni/ruby/tool/ytab.sed
@@ -0,0 +1,37 @@
+#!/bin/sed -f
+/^int yydebug;/{
+i\
+#ifndef yydebug
+a\
+#endif
+}
+/^extern int yydebug;/{
+i\
+#ifndef yydebug
+a\
+#endif
+}
+/^yydestruct.*yymsg/,/#endif/{
+ /^yydestruct/{
+ /parser/!{
+ h
+ s/^/ruby_parser_&/
+ s/)$/, parser)/
+ /\*/s/parser)$/struct parser_params *&/
+ }
+ }
+ /^#endif/{
+ x
+ /^./{
+ i\
+ struct parser_params *parser;
+ a\
+#define yydestruct(m, t, v) ruby_parser_yydestruct(m, t, v, parser)
+ }
+ x
+ }
+}
+s/^\([ ]*\)\(yyerror[ ]*([ ]*parser,\)/\1parser_\2/
+s!^ *extern char \*getenv();!/* & */!
+s/^\(#.*\)".*\.tab\.c"/\1"parse.c"/
+/^\(#.*\)".*\.y"/s:\\\\:/:g