summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-02-24 04:31:29 +0000
committermatz <matz@b2dd03c8-39d4-4d8f-98ff-823fe69b080e>1999-02-24 04:31:29 +0000
commit3976feed73bf4ec27183824870ee077c2b5b00b1 (patch)
treecb461ab9246a2c8e13d373a8c2d2e6378e4db9cc
parent51fa86ece2d2b0f72c86c70fe1314e412c7a9e68 (diff)
990224
git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_1_3@405 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
-rw-r--r--ChangeLog133
-rw-r--r--MANIFEST8
-rw-r--r--Makefile.in6
-rw-r--r--README6
-rw-r--r--README.EXT.jp8
-rw-r--r--README.jp13
-rw-r--r--ToDo8
-rw-r--r--array.c20
-rw-r--r--bignum.c7
-rw-r--r--class.c10
-rw-r--r--config.sub4
-rw-r--r--configure170
-rw-r--r--configure.in22
-rw-r--r--dln.c4
-rw-r--r--error.c1
-rw-r--r--eval.c100
-rw-r--r--ext/curses/curses.c4
-rw-r--r--ext/curses/extconf.rb2
-rw-r--r--ext/extmk.rb.in21
-rw-r--r--ext/nkf/MANIFEST7
-rw-r--r--ext/nkf/extconf.rb2
-rw-r--r--ext/nkf/lib/kconv.rb58
-rw-r--r--ext/nkf/nkf.c207
-rw-r--r--ext/nkf/orig/nkf.c1897
-rw-r--r--ext/nkf/test.rb318
-rw-r--r--ext/tk/lib/tk.rb1
-rw-r--r--file.c3
-rw-r--r--fnmatch.c243
-rw-r--r--fnmatch.h36
-rw-r--r--hash.c68
-rw-r--r--intern.h3
-rw-r--r--io.c142
-rw-r--r--lib/e2mmap.rb269
-rw-r--r--lib/matrix.rb67
-rw-r--r--lib/tempfile.rb3
-rw-r--r--marshal.c10
-rw-r--r--misc/ruby-mode.el14
-rw-r--r--missing/fnmatch.c192
-rw-r--r--missing/fnmatch.h57
-rw-r--r--missing/strftime.c28
-rw-r--r--numeric.c29
-rw-r--r--parse.c12
-rw-r--r--parse.y12
-rw-r--r--process.c8
-rw-r--r--re.c9
-rw-r--r--regex.c321
-rw-r--r--regex.h18
-rw-r--r--ruby.h10
-rw-r--r--string.c69
-rw-r--r--struct.c72
-rw-r--r--time.c324
-rw-r--r--util.c1
-rw-r--r--util.h4
-rw-r--r--variable.c2
-rw-r--r--version.h2
-rw-r--r--win32/ruby.def3
56 files changed, 4017 insertions, 1051 deletions
diff --git a/ChangeLog b/ChangeLog
index 555553c55f..31c0ea31cc 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,127 @@
+Tue Feb 23 14:21:41 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * parse.y (yylex): warn if identifier! immediately followed by `='.
+
+Tue Feb 23 12:32:41 1999 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
+
+ * eval.c (rb_load): tilde expandion moved to find_file.
+
+ * eval.c (find_file): tilde expandion added.
+
+Tue Feb 23 10:50:20 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * eval.c (require_method): require can handle multiple fnames.
+
+ * hash.c (rb_hash_foreach_iter): hash key may be nil.
+
+Mon Feb 22 17:44:02 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * regex.c (re_match): should not pop failure point on success for
+ non-greedy matches.
+
+ * io.c (Init_IO): remove global_functions getc, readchar, ungetc,
+ seek, tell, rewind.
+
+Sat Feb 20 22:54:26 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * numeric.c (rb_num2long): no implicit conversion from boolean.
+
+Sat Feb 20 09:58:42 1999 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
+
+ * numeric.c (flo_to_s): portable Infinity and NaN support.
+
+Sat Feb 20 07:13:31 1999 WATANABE Tetsuya <tetsu@jpn.hp.com>
+
+ * io.c (rb_file_sysopen): forgot to initialize a local variable.
+
+Fri Feb 19 23:05:07 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * string.c (rb_str_subseq): range check changed.
+
+ * marshal.c: increment MARSHAL_MINOR for Time format change.
+
+ * time.c (time_old_load): support old marshal format.
+
+ * time.c (time_load): changed for new format Y/M/D/h/m/s/usec.
+
+ * time.c (time_dump): marshal dump format has changed.
+
+Fri Feb 19 00:25:57 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * time.c (time_arg): should reject "sep\0" and such.
+
+ * time.c (time_plus): Time#+ should not receive Time object
+ operand.
+
+ * string.c (rb_str_substr): nagative length raises exception now.
+
+ * array.c (beg_len): if end == -1, it points end of the array.
+
+ * array.c (rb_ary_subseq): nagative length raises exception now.
+
+Thu Feb 18 20:57:04 1999 Tadayoshi Funaba <tadf@kt.rim.or.jp>
+
+ * time.c (rb_strftime): strftime() may return 0 on success too.
+
+ * time.c (time_strftime): `\0' within format string shoule not be
+ ommited in the result.
+
+ * time.c (rb_strftime): zero length format.
+
+ * time.c (time_to_a): yday start with 1 now.
+
+ * time.c (time_zone): support for long timezone name.
+
+ * time.c (time_yday): yday start with 1 now.
+
+ * time.c (time_minus): minus calculation was wrong.
+
+ * time.c (time_minus): sec, usec should be at least `long', maybe
+ they should be `time_t'.
+
+ * time.c (time_plus): addition with float was wrong.
+
+ * time.c (time_to_s): support for long timezone name.
+
+ * time.c (time_gm_or_local): too far future check moved.
+
+ * time.c (time_arg): treat 2 digit year as 69-99 => 1969-1999,
+ 00-68 => 2000-2068
+
+Thu Feb 18 03:56:47 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * missing/fnmatch.c: moved to missing directory.
+
+Wed Feb 17 16:22:26 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * struct.c (rb_struct_alloc): actual initialization now be done in
+ `initialize'.
+
+Wed Feb 17 09:47:15 1999 okabe katsuyuki <hgc02147@nifty.ne.jp>
+
+ * regex.c (re_search): use mbclen() instead of ismbchar().
+
+ * re.c (rb_reg_s_quote): should handle mbchars properly.
+
+Wed Feb 17 01:25:26 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * parse.y (yylex): stop comment concatenation by backslash follows
+ after >= 0x80 char. may cause problem with Latin chars.
+
+ * eval.c (error_print): exception in rb_obj_as_string() caused
+ SEGV. protect it by PUSH_TAG/POP_TAG.
+
+ * error.c (exc_exception): `Exception#exception' should return self.
+
+Wed Feb 17 01:12:22 1999 Hirotaka Ichikawa <hirotaka.ichikawa@tosmec.toshiba.co.jp>
+
+ * configure.in: BeOS patch.
+
+Tue Feb 16 14:25:00 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
+
+ * regex.c (re_compile_pattern): should reallocate mbc space for
+ character class unless current_mbctype is ASCII.
+
Mon Feb 15 15:48:30 1999 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
* configure.in: specify `-Wl,-E' only for GNU ld.
@@ -10,6 +134,15 @@ Sun Feb 14 22:36:40 1999 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
* sprintf.c (rb_f_sprintf): `%G' was ommited.
+Sun Feb 14 12:47:48 1999 EGUCHI Osamu <eguchi@shizuokanet.ne.jp>
+
+ * numeric.c (Init_Numeric): allow divide by zero on FreeBSD.
+
+ * numeric.c (Init_Numeric): FloatDomainError added.
+
+ * configure.in (AC_REPLACE_FUNCS): add checks for functions
+ insinf, isnan, and finite.
+
Sat Feb 13 01:24:16 1999 Yukihiro Matsumoto <matz@netlab.co.jp>
* eval.c (rb_thread_create_0): should protect th->thread.
diff --git a/MANIFEST b/MANIFEST
index 78f23bf786..e32c4fc309 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -1,4 +1,5 @@
COPYING
+COPYING.LIB
ChangeLog
MANIFEST
Makefile.in
@@ -28,8 +29,6 @@ env.h
error.c
eval.c
file.c
-fnmatch.c
-fnmatch.h
gc.c
glob.c
hash.c
@@ -143,7 +142,12 @@ missing/crypt.c
missing/dir.h
missing/dup2.c
missing/file.h
+missing/finite.c
missing/flock.c
+missing/fnmatch.c
+missing/fnmatch.h
+missing/isinf.c
+missing/isnan.c
missing/memcmp.c
missing/memmove.c
missing/mkdir.c
diff --git a/Makefile.in b/Makefile.in
index 937e97205a..f399fca6b1 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -51,7 +51,6 @@ OBJS = array.o \
error.o \
eval.o \
file.o \
- fnmatch.o \
gc.o \
glob.o \
hash.o \
@@ -152,6 +151,9 @@ dup2.o: @srcdir@/missing/dup2.c
flock.o: @srcdir@/missing/flock.c
$(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/flock.c
+fnmatch.o: @srcdir@/missing/fnmatch.c
+ $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/fnmatch.c
+
memcmp.o: @srcdir@/missing/memcmp.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/memcmp.c
@@ -216,7 +218,7 @@ file.o: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
fnmatch.o: fnmatch.c config.h fnmatch.h
gc.o: gc.c ruby.h config.h defines.h intern.h rubysig.h st.h node.h env.h re.h regex.h
glob.o: config.h glob.c fnmatch.h
-hash.o: hash.c ruby.h config.h defines.h intern.h st.h rubysig.h
+hash.o: hash.c ruby.h config.h defines.h intern.h st.h rubysig.h util.h
inits.o: inits.c ruby.h config.h defines.h intern.h
io.o: io.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
main.o: main.c ruby.h config.h defines.h intern.h
diff --git a/README b/README
index dd93c592be..b4b429f45d 100644
--- a/README
+++ b/README
@@ -98,9 +98,9 @@ You can redistribute it and/or modify it under either the terms of the GPL
4. You may modify and include the part of the software into any other
software (possibly commercial). But some files in the distribution
are not written by the author, so that they are not under this terms.
- They are gc.c(partly), utils.c(partly), regex.[ch], fnmatch.[ch],
- glob.c, st.[ch] and some files under the ./missing directory. See
- each file for the copying condition.
+ They are gc.c(partly), utils.c(partly), regex.[ch], glob.c, st.[ch]
+ and some files under the ./missing directory. See each file for the
+ copying condition.
5. The scripts and library files supplied as input to or produced as
output from the software do not automatically fall under the
diff --git a/README.EXT.jp b/README.EXT.jp
index f838b02b40..1d56f25501 100644
--- a/README.EXT.jp
+++ b/README.EXT.jp
@@ -265,10 +265,10 @@ Rubyで提供されている関数を使えばRubyインタプリタに新しい機能
ます.
これらの関数の argcという引数はCの関数へ渡される引数の数(と
-形式)を決めます.argcが正の時は関数に引き渡す引数の数を意味
-します.16個以上の引数は使えません(が,要りませんよね,そん
-なに).実際の関数には先頭の引数としてselfが与えられますので,
-指定した数より1多い引数を持つことになります.
+形式)を決めます.argcが0以上の時は関数に引き渡す引数の数を意
+味します.16個以上の引数は使えません(が,要りませんよね,そ
+んなに).実際の関数には先頭の引数としてselfが与えられますの
+で,指定した数より1多い引数を持つことになります.
argcが負の時は引数の数ではなく,形式を指定したことになります.
argcが-1の時は引数を配列に入れて渡されます.argcが-2の時は引
diff --git a/README.jp b/README.jp
index d137a435d8..5e3b2301b0 100644
--- a/README.jp
+++ b/README.jp
@@ -142,22 +142,21 @@ Licence)または以下に示す条件でRubyを再配布できます.GPLにつ
(b) 機械可読なソースコードを添付する.
- (c) 変更を行ったバイナリは名前を変更したうえ,ソースの
- 入手法を明示する.
+ (c) 変更を行ったバイナリは名前を変更したうえ,オリジナ
+ ルのソースコードの入手法を明示する.
(d) その他の配布条件を作者と合意する.
4. 他のプログラムへの引用はいかなる目的であれ自由です.た
だし,Rubyに含まれる他の作者によるコードは,それぞれの
作者の意向による制限が加えられます.具体的にはgc.c(一部),
- util.c(一部),st.[ch],regex.[ch], fnmatch.[ch], glob.c
- および./missingディレクトリ下のファイル群が該当します.
- それぞれの配布条件などに付いては各ファイルを参照してく
- ださい.
+ util.c(一部),st.[ch],regex.[ch], glob.c および.
+ /missingディレクトリ下のファイル群が該当します.それぞ
+ れの配布条件などに付いては各ファイルを参照してください.
5. Rubyへの入力となるスクリプトおよび,Rubyからの出力の権
利はRubyの作者ではなく,それぞれの入出力を生成した人に
- 属します.また,Rubyに組み込むための拡張モジュールにつ
+ 属します.また,Rubyに組み込むための拡張ライブラリにつ
いても同様です.
6. Rubyは無保証です.作者はRubyをサポートする意志はありま
diff --git a/ToDo b/ToDo
index 7f20c28ed3..8f46ad630b 100644
--- a/ToDo
+++ b/ToDo
@@ -5,6 +5,7 @@ Language Spec.
* method to retrieve argument information (need new C API)
* multiple return values, yield values. maybe imcompatible
* cascading method invocation.
+* def Class#method .. end
Hacking Interpreter
@@ -15,6 +16,13 @@ Hacking Interpreter
* syntax tree -> bytecode ???
* scrambled script, or script filter
+Standard Libraries
+
+* String#scanf(?)
+* Object#fmt(?)
+* Integer[num], Float[num] (String[str]??)
+* Stream or Port, abstract superclass of IO.
+
Extension Libraries
* mod_ruby, FastCGI ruby
diff --git a/array.c b/array.c
index 8b0d379999..8b25b9c1b3 100644
--- a/array.c
+++ b/array.c
@@ -355,8 +355,9 @@ rb_ary_subseq(ary, beg, len)
{
VALUE ary2;
- if (len <= 0) {
- return rb_ary_new2(0);
+ if (len == 0) return rb_ary_new2(0);
+ if (len < 0) {
+ rb_raise(rb_eIndexError, "negative length %d", len);
}
if (beg < 0) {
len += beg;
@@ -393,17 +394,20 @@ beg_len(range, begp, lenp, len)
if (end < 0) {
end = len + end;
}
+ *begp = beg;
if (beg > end) {
+ if (e == -1) {
+ *lenp = 0;
+ return Qtrue;
+ }
rb_raise(rb_eIndexError, "end smaller than beg [%d..%d]", b, e);
}
- *begp = beg;
if (beg > len) {
*lenp = 0;
}
else {
- len = end - beg +1;
- *lenp = len;
+ *lenp = end - beg + 1;
}
return Qtrue;
}
@@ -555,6 +559,9 @@ rb_ary_aset(argc, argv, ary)
if (beg < 0) {
beg = RARRAY(ary)->len + beg;
}
+#ifdef INABA
+ if (len < 0) return Qnil;
+#endif
rb_ary_replace(ary, beg, len, arg3);
return arg3;
}
@@ -564,6 +571,9 @@ rb_ary_aset(argc, argv, ary)
}
else if (beg_len(arg1, &beg, &len, RARRAY(ary)->len)) {
/* check if idx is Range */
+#ifdef INABA
+ if (len < 0) return Qnil;
+#endif
rb_ary_replace(ary, beg, len, arg2);
return arg2;
}
diff --git a/bignum.c b/bignum.c
index 4986890932..8ba36bb2a9 100644
--- a/bignum.c
+++ b/bignum.c
@@ -403,6 +403,13 @@ rb_dbl2big(d)
VALUE z;
double u = (d < 0)?-d:d;
+ if (isinf(d)) {
+ rb_raise(rb_eFloatDomainError, d < 0 ? "-Inifinity" : "Inifinity");
+ }
+ if (isnan(d)) {
+ rb_raise(rb_eFloatDomainError, "NaN");
+ }
+
while (!POSFIXABLE(u) || 0 != (long)u) {
u /= (double)(BIGRAD);
i++;
diff --git a/class.c b/class.c
index dad3a46858..93f8226045 100644
--- a/class.c
+++ b/class.c
@@ -603,7 +603,7 @@ rb_scan_args(argc, argv, fmt, va_alist)
rb_raise(rb_eArgError, "wrong # of arguments (%d for %d)", argc, n);
for (i=0; i<n; i++) {
var = va_arg(vargs, VALUE*);
- *var = argv[i];
+ if (var) *var = argv[i];
}
p++;
}
@@ -616,10 +616,10 @@ rb_scan_args(argc, argv, fmt, va_alist)
for (; i<n; i++) {
var = va_arg(vargs, VALUE*);
if (argc > i) {
- *var = argv[i];
+ if (var) *var = argv[i];
}
else {
- *var = Qnil;
+ if (var) *var = Qnil;
}
}
p++;
@@ -628,10 +628,10 @@ rb_scan_args(argc, argv, fmt, va_alist)
if(*p == '*') {
var = va_arg(vargs, VALUE*);
if (argc > i) {
- *var = rb_ary_new4(argc-i, argv+i);
+ if (var) *var = rb_ary_new4(argc-i, argv+i);
}
else {
- *var = rb_ary_new();
+ if (var) *var = rb_ary_new();
}
}
else if (*p == '\0') {
diff --git a/config.sub b/config.sub
index 858aba7aa5..48d744cd57 100644
--- a/config.sub
+++ b/config.sub
@@ -151,7 +151,7 @@ case $basic_machine in
# Some are omitted here because they have special meanings below.
tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
| arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
- | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 \
+ | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 | hppa2.0w \
| alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
| i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
| mips64 | mipsel | mips64el | mips64orion | mips64orionel \
@@ -178,7 +178,7 @@ case $basic_machine in
| m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
- | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* \
+ | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* | hppa2.0w-* \
| alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
| ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
| sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
diff --git a/configure b/configure
index 103020a187..21308470a3 100644
--- a/configure
+++ b/configure
@@ -2961,15 +2961,16 @@ echo "$ac_t""$ac_cv_func_memcmp_clean" 1>&6
test $ac_cv_func_memcmp_clean = no && LIBOBJS="$LIBOBJS memcmp.${ac_objext}"
for ac_func in dup2 memmove mkdir strcasecmp strerror strftime\
- strchr strstr strtoul strdup crypt flock vsnprintf
+ strchr strstr strtoul strdup crypt flock vsnprintf\
+ fnmatch isinf isnan finite
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:2968: checking for $ac_func" >&5
+echo "configure:2969: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 2973 "configure"
+#line 2974 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -2992,7 +2993,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:2996: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:2997: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -3021,16 +3022,16 @@ done
for ac_func in fmod killpg drand48 random wait4 waitpid syscall getcwd\
truncate chsize times utimes fcntl lockf setitimer\
setruid seteuid setreuid setrgid setegid setregid\
- setpgrp2 getpgid setpgid getgroups getpriority\
- dlopen sigprocmask sigaction _setjmp setpgrp setsid
+ getpgrp setpgrp getpgid setpgid getgroups getpriority\
+ dlopen sigprocmask sigaction _setjmp setsid
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:3029: checking for $ac_func" >&5
+echo "configure:3030: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3034 "configure"
+#line 3035 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -3053,7 +3054,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:3057: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -3079,12 +3080,12 @@ done
if test "$ac_cv_func_strftime" = no; then
echo $ac_n "checking whether struct tm is in sys/time.h or time.h""... $ac_c" 1>&6
-echo "configure:3083: checking whether struct tm is in sys/time.h or time.h" >&5
+echo "configure:3084: checking whether struct tm is in sys/time.h or time.h" >&5
if eval "test \"`echo '$''{'ac_cv_struct_tm'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3088 "configure"
+#line 3089 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <time.h>
@@ -3092,7 +3093,7 @@ int main() {
struct tm *tp; tp->tm_sec;
; return 0; }
EOF
-if { (eval echo configure:3096: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3097: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_tm=time.h
else
@@ -3113,12 +3114,12 @@ EOF
fi
echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6
-echo "configure:3117: checking for tm_zone in struct tm" >&5
+echo "configure:3118: checking for tm_zone in struct tm" >&5
if eval "test \"`echo '$''{'ac_cv_struct_tm_zone'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3122 "configure"
+#line 3123 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <$ac_cv_struct_tm>
@@ -3126,7 +3127,7 @@ int main() {
struct tm tm; tm.tm_zone;
; return 0; }
EOF
-if { (eval echo configure:3130: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3131: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_struct_tm_zone=yes
else
@@ -3146,12 +3147,12 @@ EOF
else
echo $ac_n "checking for tzname""... $ac_c" 1>&6
-echo "configure:3150: checking for tzname" >&5
+echo "configure:3151: checking for tzname" >&5
if eval "test \"`echo '$''{'ac_cv_var_tzname'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3155 "configure"
+#line 3156 "configure"
#include "confdefs.h"
#include <time.h>
#ifndef tzname /* For SGI. */
@@ -3161,7 +3162,7 @@ int main() {
atoi(*tzname);
; return 0; }
EOF
-if { (eval echo configure:3165: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3166: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
ac_cv_var_tzname=yes
else
@@ -3183,14 +3184,14 @@ EOF
fi
cat > conftest.$ac_ext <<EOF
-#line 3187 "configure"
+#line 3188 "configure"
#include "confdefs.h"
int main() {
extern int daylight; int i = daylight;
; return 0; }
EOF
-if { (eval echo configure:3194: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:3195: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
cat >> confdefs.h <<\EOF
#define HAVE_DAYLIGHT 1
@@ -3210,7 +3211,7 @@ EOF
else
echo $ac_n "checking for BSD signal semantics""... $ac_c" 1>&6
-echo "configure:3214: checking for BSD signal semantics" >&5
+echo "configure:3215: checking for BSD signal semantics" >&5
if eval "test \"`echo '$''{'rb_cv_bsd_signal'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3218,7 +3219,7 @@ else
rb_cv_bsd_signal=no
else
cat > conftest.$ac_ext <<EOF
-#line 3222 "configure"
+#line 3223 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -3240,7 +3241,7 @@ main()
}
EOF
-if { (eval echo configure:3244: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3245: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
rb_cv_bsd_signal=yes
else
@@ -3264,7 +3265,7 @@ EOF
fi
echo $ac_n "checking whether getpgrp takes no argument""... $ac_c" 1>&6
-echo "configure:3268: checking whether getpgrp takes no argument" >&5
+echo "configure:3269: checking whether getpgrp takes no argument" >&5
if eval "test \"`echo '$''{'ac_cv_func_getpgrp_void'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3272,7 +3273,7 @@ else
{ echo "configure: error: cannot check getpgrp if cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 3276 "configure"
+#line 3277 "configure"
#include "confdefs.h"
/*
@@ -3327,7 +3328,7 @@ main()
}
EOF
-if { (eval echo configure:3331: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3332: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_getpgrp_void=yes
else
@@ -3351,7 +3352,7 @@ EOF
fi
echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6
-echo "configure:3355: checking whether setpgrp takes no argument" >&5
+echo "configure:3356: checking whether setpgrp takes no argument" >&5
if eval "test \"`echo '$''{'ac_cv_func_setpgrp_void'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3359,7 +3360,7 @@ else
{ echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 3363 "configure"
+#line 3364 "configure"
#include "confdefs.h"
#ifdef HAVE_UNISTD_H
@@ -3379,7 +3380,7 @@ main()
}
EOF
-if { (eval echo configure:3383: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_func_setpgrp_void=no
else
@@ -3404,7 +3405,7 @@ fi
echo $ac_n "checking for working strtod""... $ac_c" 1>&6
-echo "configure:3408: checking for working strtod" >&5
+echo "configure:3409: checking for working strtod" >&5
if eval "test \"`echo '$''{'rb_cv_func_strtod'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3412,7 +3413,7 @@ else
rb_cv_func_strtod=no
else
cat > conftest.$ac_ext <<EOF
-#line 3416 "configure"
+#line 3417 "configure"
#include "confdefs.h"
double strtod ();
@@ -3442,7 +3443,7 @@ main()
}
EOF
-if { (eval echo configure:3446: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3447: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
rb_cv_func_strtod=yes
else
@@ -3460,14 +3461,14 @@ echo "$ac_t""$rb_cv_func_strtod" 1>&6
test $rb_cv_func_strtod = no && LIBOBJS="$LIBOBJS strtod.o"
echo $ac_n "checking whether byte ordering is bigendian""... $ac_c" 1>&6
-echo "configure:3464: checking whether byte ordering is bigendian" >&5
+echo "configure:3465: checking whether byte ordering is bigendian" >&5
if eval "test \"`echo '$''{'ac_cv_c_bigendian'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
ac_cv_c_bigendian=unknown
# See if sys/param.h defines the BYTE_ORDER macro.
cat > conftest.$ac_ext <<EOF
-#line 3471 "configure"
+#line 3472 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
@@ -3478,11 +3479,11 @@ int main() {
#endif
; return 0; }
EOF
-if { (eval echo configure:3482: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3483: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
# It does; now see whether it defined to BIG_ENDIAN or not.
cat > conftest.$ac_ext <<EOF
-#line 3486 "configure"
+#line 3487 "configure"
#include "confdefs.h"
#include <sys/types.h>
#include <sys/param.h>
@@ -3493,7 +3494,7 @@ int main() {
#endif
; return 0; }
EOF
-if { (eval echo configure:3497: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3498: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
ac_cv_c_bigendian=yes
else
@@ -3513,7 +3514,7 @@ if test "$cross_compiling" = yes; then
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 3517 "configure"
+#line 3518 "configure"
#include "confdefs.h"
main () {
/* Are we little or big endian? From Harbison&Steele. */
@@ -3526,7 +3527,7 @@ main () {
exit (u.c[sizeof (long) - 1] == 1);
}
EOF
-if { (eval echo configure:3530: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3531: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_c_bigendian=no
else
@@ -3550,14 +3551,14 @@ EOF
fi
echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6
-echo "configure:3554: checking whether char is unsigned" >&5
+echo "configure:3555: checking whether char is unsigned" >&5
if eval "test \"`echo '$''{'ac_cv_c_char_unsigned'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
if test "$GCC" = yes; then
# GCC predefines this symbol on systems where it applies.
cat > conftest.$ac_ext <<EOF
-#line 3561 "configure"
+#line 3562 "configure"
#include "confdefs.h"
#ifdef __CHAR_UNSIGNED__
yes
@@ -3579,7 +3580,7 @@ if test "$cross_compiling" = yes; then
{ echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; }
else
cat > conftest.$ac_ext <<EOF
-#line 3583 "configure"
+#line 3584 "configure"
#include "confdefs.h"
/* volatile prevents gcc2 from optimizing the test away on sparcs. */
#if !defined(__STDC__) || __STDC__ != 1
@@ -3589,7 +3590,7 @@ main() {
volatile char c = 255; exit(c < 0);
}
EOF
-if { (eval echo configure:3593: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3594: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
ac_cv_c_char_unsigned=yes
else
@@ -3614,7 +3615,7 @@ fi
echo $ac_n "checking whether right shift preserve sign bit""... $ac_c" 1>&6
-echo "configure:3618: checking whether right shift preserve sign bit" >&5
+echo "configure:3619: checking whether right shift preserve sign bit" >&5
if eval "test \"`echo '$''{'rb_cv_rshift_sign'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3622,7 +3623,7 @@ else
rb_cv_rshift_sign=yes
else
cat > conftest.$ac_ext <<EOF
-#line 3626 "configure"
+#line 3627 "configure"
#include "confdefs.h"
int
@@ -3634,7 +3635,7 @@ main()
}
EOF
-if { (eval echo configure:3638: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3639: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
rb_cv_rshift_sign=yes
else
@@ -3662,19 +3663,19 @@ EOF
fi
echo $ac_n "checking count field in FILE structures""... $ac_c" 1>&6
-echo "configure:3666: checking count field in FILE structures" >&5
+echo "configure:3667: checking count field in FILE structures" >&5
if eval "test \"`echo '$''{'rb_cv_fcnt'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3671 "configure"
+#line 3672 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
FILE *f = stdin; f->_cnt = 0;
; return 0; }
EOF
-if { (eval echo configure:3678: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3679: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
rb_cv_fcnt="_cnt"
else
@@ -3684,14 +3685,14 @@ fi
rm -f conftest*
if test "$rb_cv_fcnt" = ""; then
cat > conftest.$ac_ext <<EOF
-#line 3688 "configure"
+#line 3689 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
FILE *f = stdin; f->__cnt = 0;
; return 0; }
EOF
-if { (eval echo configure:3695: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3696: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
rb_cv_fcnt="__cnt"
else
@@ -3702,14 +3703,14 @@ rm -f conftest*
fi
if test "$rb_cv_fcnt" = ""; then
cat > conftest.$ac_ext <<EOF
-#line 3706 "configure"
+#line 3707 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
FILE *f = stdin; f->_r = 0;
; return 0; }
EOF
-if { (eval echo configure:3713: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3714: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
rb_cv_fcnt="_r"
else
@@ -3720,14 +3721,14 @@ rm -f conftest*
fi
if test "$rb_cv_fcnt" = ""; then
cat > conftest.$ac_ext <<EOF
-#line 3724 "configure"
+#line 3725 "configure"
#include "confdefs.h"
#include <stdio.h>
int main() {
FILE *f = stdin; f->readCount = 0;
; return 0; }
EOF
-if { (eval echo configure:3731: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3732: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
rb_cv_fcnt="readCount"
else
@@ -3766,7 +3767,7 @@ fi
case "$host_os" in
linux*)
echo $ac_n "checking whether ELF binaries are produced""... $ac_c" 1>&6
-echo "configure:3770: checking whether ELF binaries are produced" >&5
+echo "configure:3771: checking whether ELF binaries are produced" >&5
if eval "test \"`echo '$''{'rb_cv_binary_elf'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -3774,7 +3775,7 @@ else
rb_cv_binary_elf=yes
else
cat > conftest.$ac_ext <<EOF
-#line 3778 "configure"
+#line 3779 "configure"
#include "confdefs.h"
/* Test for whether ELF binaries are produced */
@@ -3794,7 +3795,7 @@ main() {
}
EOF
-if { (eval echo configure:3798: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:3799: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
rb_cv_binary_elf=yes
else
@@ -3824,7 +3825,7 @@ STATIC=
if test "$with_dln_a_out" != yes; then
rb_cv_dlopen=unknown
echo $ac_n "checking whether OS depend dynamic link works""... $ac_c" 1>&6
-echo "configure:3828: checking whether OS depend dynamic link works" >&5
+echo "configure:3829: checking whether OS depend dynamic link works" >&5
if test "$GCC" = yes; then
case "$host_os" in
nextstep*) ;;
@@ -3868,6 +3869,8 @@ echo "configure:3828: checking whether OS depend dynamic link works" >&5
LDFLAGS="-rdynamic"
DLDFLAGS='-Wl,-soname,$(.TARGET)'
rb_cv_freebsd_elf=yes
+ else
+ test "$GCC" = yes && `$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null || LDSHARED="ld -Bshareable"
fi
rb_cv_dlopen=yes ;;
netbsd*) LDSHARED="ld -Bshareable"
@@ -3897,11 +3900,15 @@ echo "configure:3828: checking whether OS depend dynamic link works" >&5
human*) DLDFLAGS=''
LDSHARED=''
LDFLAGS='' ;;
- beos*) LDSHARED="ld -xms"
- case "$host_cpu" in
+ beos*) case "$host_cpu" in
powerpc*)
+ LDSHARED="ld -xms"
DLDFLAGS="-f ruby.exp -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
;;
+ i586*)
+ LDSHARED="ld -shared"
+ DLDFLAGS="-L/boot/develop/lib/x86 -lbe -lroot"
+ ;;
*)
DLDFLAGS="ruby.def -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
;;
@@ -3918,12 +3925,12 @@ if test "$ac_cv_header_a_out_h" = yes; then
if test "$with_dln_a_out" = yes || test "$rb_cv_dlopen" = unknown; then
cat confdefs.h > config.h
echo $ac_n "checking whether matz's dln works""... $ac_c" 1>&6
-echo "configure:3922: checking whether matz's dln works" >&5
+echo "configure:3929: checking whether matz's dln works" >&5
if eval "test \"`echo '$''{'rb_cv_dln_a_out'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 3927 "configure"
+#line 3934 "configure"
#include "confdefs.h"
#define USE_DLN_A_OUT
@@ -3933,7 +3940,7 @@ int main() {
; return 0; }
EOF
-if { (eval echo configure:3937: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
+if { (eval echo configure:3944: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then
rm -rf conftest*
rb_cv_dln_a_out=yes
else
@@ -4035,7 +4042,7 @@ fi
case "$host_os" in
human*)
echo $ac_n "checking for _harderr in -lsignal""... $ac_c" 1>&6
-echo "configure:4039: checking for _harderr in -lsignal" >&5
+echo "configure:4046: checking for _harderr in -lsignal" >&5
ac_lib_var=`echo signal'_'_harderr | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -4043,7 +4050,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lsignal $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4047 "configure"
+#line 4054 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4054,7 +4061,7 @@ int main() {
_harderr()
; return 0; }
EOF
-if { (eval echo configure:4058: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4065: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -4082,7 +4089,7 @@ else
fi
echo $ac_n "checking for hmemset in -lhmem""... $ac_c" 1>&6
-echo "configure:4086: checking for hmemset in -lhmem" >&5
+echo "configure:4093: checking for hmemset in -lhmem" >&5
ac_lib_var=`echo hmem'_'hmemset | sed 'y%./+-%__p_%'`
if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
@@ -4090,7 +4097,7 @@ else
ac_save_LIBS="$LIBS"
LIBS="-lhmem $LIBS"
cat > conftest.$ac_ext <<EOF
-#line 4094 "configure"
+#line 4101 "configure"
#include "confdefs.h"
/* Override any gcc2 internal prototype to avoid an error. */
/* We use char because int might match the return type of a gcc2
@@ -4101,7 +4108,7 @@ int main() {
hmemset()
; return 0; }
EOF
-if { (eval echo configure:4105: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4112: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_lib_$ac_lib_var=yes"
else
@@ -4131,12 +4138,12 @@ fi
for ac_func in select
do
echo $ac_n "checking for $ac_func""... $ac_c" 1>&6
-echo "configure:4135: checking for $ac_func" >&5
+echo "configure:4142: checking for $ac_func" >&5
if eval "test \"`echo '$''{'ac_cv_func_$ac_func'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
cat > conftest.$ac_ext <<EOF
-#line 4140 "configure"
+#line 4147 "configure"
#include "confdefs.h"
/* System header to define __stub macros and hopefully few prototypes,
which can conflict with char $ac_func(); below. */
@@ -4159,7 +4166,7 @@ $ac_func();
; return 0; }
EOF
-if { (eval echo configure:4163: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
+if { (eval echo configure:4170: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then
rm -rf conftest*
eval "ac_cv_func_$ac_func=yes"
else
@@ -4184,7 +4191,7 @@ fi
done
echo $ac_n "checking whether PD libc _dtos18 fail to convert big number""... $ac_c" 1>&6
-echo "configure:4188: checking whether PD libc _dtos18 fail to convert big number" >&5
+echo "configure:4195: checking whether PD libc _dtos18 fail to convert big number" >&5
if eval "test \"`echo '$''{'rb_cv_missing__dtos18'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4192,7 +4199,7 @@ else
rb_cv_missing__dtos18=no
else
cat > conftest.$ac_ext <<EOF
-#line 4196 "configure"
+#line 4203 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -4204,7 +4211,7 @@ main ()
}
EOF
-if { (eval echo configure:4208: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4215: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
rb_cv_missing__dtos18=yes
else
@@ -4226,7 +4233,7 @@ EOF
fi
echo $ac_n "checking whether PD libc fconvert fail to round""... $ac_c" 1>&6
-echo "configure:4230: checking whether PD libc fconvert fail to round" >&5
+echo "configure:4237: checking whether PD libc fconvert fail to round" >&5
if eval "test \"`echo '$''{'rb_cv_missing_fconvert'+set}'`\" = set"; then
echo $ac_n "(cached) $ac_c" 1>&6
else
@@ -4234,7 +4241,7 @@ else
rb_cv_missing_fconvert=no
else
cat > conftest.$ac_ext <<EOF
-#line 4238 "configure"
+#line 4245 "configure"
#include "confdefs.h"
#include <stdio.h>
@@ -4247,7 +4254,7 @@ main ()
}
EOF
-if { (eval echo configure:4251: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
+if { (eval echo configure:4258: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null
then
rb_cv_missing_fconvert=yes
else
@@ -4301,7 +4308,6 @@ LIBRUBY='$(LIBRUBY_A)'
LIBRUBYARG='$(LIBRUBY_A)'
SOLIBS=
if test "$host_os" = "beos"; then
- CFLAGS="$CFLAGS -relax_pointers"
LIBRUBY='$(LIBRUBY_SO)'
LIBRUBYARG='-l$(RUBY_INSTALL_NAME)'
SOLIBS='-lnet'
@@ -4309,6 +4315,10 @@ if test "$host_os" = "beos"; then
case "$host_cpu" in
powerpc*)
cp beos/ruby.def.in ruby.exp
+ CFLAGS="$CFLAGS -relax_pointers"
+ ;;
+ i586*)
+ LDFLAGS="$LDFLAGS -L."
;;
*)
echo EXPORTS > ruby.def
diff --git a/configure.in b/configure.in
index 26945dd0d9..8894cd612c 100644
--- a/configure.in
+++ b/configure.in
@@ -187,12 +187,13 @@ AC_FUNC_ALLOCA
AC_FUNC_VFORK
AC_FUNC_MEMCMP
AC_REPLACE_FUNCS(dup2 memmove mkdir strcasecmp strerror strftime\
- strchr strstr strtoul strdup crypt flock vsnprintf)
+ strchr strstr strtoul strdup crypt flock vsnprintf\
+ fnmatch isinf isnan finite)
AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall getcwd\
truncate chsize times utimes fcntl lockf setitimer\
setruid seteuid setreuid setrgid setegid setregid\
- setpgrp2 getpgid setpgid getgroups getpriority\
- dlopen sigprocmask sigaction _setjmp setpgrp setsid)
+ getpgrp setpgrp getpgid setpgid getgroups getpriority\
+ dlopen sigprocmask sigaction _setjmp setsid)
if test "$ac_cv_func_strftime" = no; then
AC_STRUCT_TIMEZONE
AC_TRY_LINK([],
@@ -402,6 +403,8 @@ if test "$with_dln_a_out" != yes; then
LDFLAGS="-rdynamic"
DLDFLAGS='-Wl,-soname,$(.TARGET)'
rb_cv_freebsd_elf=yes
+ else
+ test "$GCC" = yes && `$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null || LDSHARED="ld -Bshareable"
fi
rb_cv_dlopen=yes ;;
netbsd*) LDSHARED="ld -Bshareable"
@@ -431,11 +434,15 @@ if test "$with_dln_a_out" != yes; then
human*) DLDFLAGS=''
LDSHARED=''
LDFLAGS='' ;;
- beos*) LDSHARED="ld -xms"
- case "$host_cpu" in
+ beos*) case "$host_cpu" in
powerpc*)
+ LDSHARED="ld -xms"
DLDFLAGS="-f ruby.exp -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
;;
+ i586*)
+ LDSHARED="ld -shared"
+ DLDFLAGS="-L/boot/develop/lib/x86 -lbe -lroot"
+ ;;
*)
DLDFLAGS="ruby.def -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
;;
@@ -595,7 +602,6 @@ LIBRUBY='$(LIBRUBY_A)'
LIBRUBYARG='$(LIBRUBY_A)'
SOLIBS=
if test "$host_os" = "beos"; then
- CFLAGS="$CFLAGS -relax_pointers"
LIBRUBY='$(LIBRUBY_SO)'
LIBRUBYARG='-l$(RUBY_INSTALL_NAME)'
SOLIBS='-lnet'
@@ -603,6 +609,10 @@ if test "$host_os" = "beos"; then
case "$host_cpu" in
powerpc*)
cp beos/ruby.def.in ruby.exp
+ CFLAGS="$CFLAGS -relax_pointers"
+ ;;
+ i586*)
+ LDFLAGS="$LDFLAGS -L."
;;
*)
echo EXPORTS > ruby.def
diff --git a/dln.c b/dln.c
index 023a7e735a..d8f6ec6995 100644
--- a/dln.c
+++ b/dln.c
@@ -1407,14 +1407,14 @@ dln_load(file)
/* strcat(init_fct_symname, "__Fv"); */ /* parameter nothing. */
/* "__Fv" dont need! The Be Book Bug ? */
err_stat = get_image_symbol(img_id, buf,
- B_SYMBOL_TYPE_TEXT, &init_fct);
+ B_SYMBOL_TYPE_TEXT, (void **)&init_fct);
if (err_stat != B_NO_ERROR) {
char real_name[1024];
strcpy(real_name, buf);
strcat(real_name, "__Fv");
err_stat = get_image_symbol(img_id, real_name,
- B_SYMBOL_TYPE_TEXT, &init_fct);
+ B_SYMBOL_TYPE_TEXT, (void **)&init_fct);
}
if ((B_BAD_IMAGE_ID == err_stat) || (B_BAD_INDEX == err_stat)) {
diff --git a/error.c b/error.c
index 64e5183cca..98a77ce68e 100644
--- a/error.c
+++ b/error.c
@@ -290,6 +290,7 @@ exc_exception(argc, argv, self)
{
VALUE etype, exc;
+ if (argc == 0) return self;
if (argc == 1 && self == argv[0]) return self;
etype = CLASS_OF(self);
while (FL_TEST(etype, FL_SINGLETON)) {
diff --git a/eval.c b/eval.c
index 7e1e6c74e1..d7a23149a9 100644
--- a/eval.c
+++ b/eval.c
@@ -786,12 +786,19 @@ error_print()
{
VALUE errat;
VALUE eclass;
- VALUE einfo;
- volatile int safe = safe_level;
+ char *einfo;
+ int elen;
if (NIL_P(ruby_errinfo)) return;
- errat = get_backtrace(ruby_errinfo);
+ PUSH_TAG(PROT_NONE);
+ if (EXEC_TAG() == 0) {
+ errat = get_backtrace(ruby_errinfo);
+ }
+ else {
+ errat = Qnil;
+ }
+ POP_TAG();
if (!NIL_P(errat)) {
VALUE mesg = RARRAY(errat)->ptr[0];
@@ -802,37 +809,45 @@ error_print()
}
eclass = CLASS_OF(ruby_errinfo);
- einfo = rb_obj_as_string(ruby_errinfo);
- if (eclass == rb_eRuntimeError && RSTRING(einfo)->len == 0) {
+ PUSH_TAG(PROT_NONE);
+ if (EXEC_TAG() == 0) {
+ einfo = str2cstr(rb_obj_as_string(ruby_errinfo), &elen);
+ }
+ else {
+ einfo = "";
+ elen = 0;
+ }
+ POP_TAG();
+ if (eclass == rb_eRuntimeError && elen == 0) {
fprintf(stderr, ": unhandled exception\n");
}
else {
VALUE epath;
epath = rb_class_path(eclass);
- if (RSTRING(einfo)->len == 0) {
+ if (elen == 0) {
fprintf(stderr, ": ");
fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr);
putc('\n', stderr);
}
else {
char *tail = 0;
- int len = RSTRING(einfo)->len;
+ int len = elen;
if (RSTRING(epath)->ptr[0] == '#') epath = 0;
- if (tail = strchr(RSTRING(einfo)->ptr, '\n')) {
- len = tail - RSTRING(einfo)->ptr;
+ if (tail = strchr(einfo, '\n')) {
+ len = tail - einfo;
tail++; /* skip newline */
}
fprintf(stderr, ": ");
- fwrite(RSTRING(einfo)->ptr, 1, len, stderr);
+ fwrite(einfo, 1, elen, stderr);
if (epath) {
fprintf(stderr, " (");
fwrite(RSTRING(epath)->ptr, 1, RSTRING(epath)->len, stderr);
fprintf(stderr, ")\n");
}
if (tail) {
- fwrite(tail, 1, RSTRING(einfo)->len-len-1, stderr);
+ fwrite(tail, 1, elen-len-1, stderr);
putc('\n', stderr);
}
}
@@ -858,7 +873,6 @@ error_print()
}
}
}
- safe_level = safe;
}
#if !defined(NT) && !defined(__MACOS__)
@@ -895,7 +909,7 @@ ruby_init()
/* default visibility is private at toplevel */
SCOPE_SET(SCOPE_PRIVATE);
- PUSH_TAG(PROT_NONE)
+ PUSH_TAG(PROT_NONE);
if ((state = EXEC_TAG()) == 0) {
rb_call_inits();
ruby_class = rb_cObject;
@@ -3479,8 +3493,9 @@ rb_f_missing(argc, argv, obj)
VALUE obj;
{
ID id;
- VALUE desc = 0;
+ volatile VALUE d = 0;
char *format = 0;
+ char *desc = "";
char *file = ruby_sourcefile;
int line = ruby_sourceline;
@@ -3492,19 +3507,19 @@ rb_f_missing(argc, argv, obj)
format = "undefined method `%s' for nil";
break;
case T_TRUE:
- format = "undefined method `%s' for Qtrue";
+ format = "undefined method `%s' for true";
break;
case T_FALSE:
- format = "undefined method `%s' for Qfalse";
+ format = "undefined method `%s' for false";
break;
case T_OBJECT:
- desc = rb_any_to_s(obj);
+ d = rb_any_to_s(obj);
break;
default:
- desc = rb_inspect(obj);
+ d = rb_inspect(obj);
break;
}
- if (desc) {
+ if (d) {
if (last_call_status & CSTAT_PRIV) {
format = "private method `%s' called for %s";
}
@@ -3524,9 +3539,10 @@ rb_f_missing(argc, argv, obj)
if (!format) {
format = "undefined method `%s' for %s";
}
- if (RSTRING(desc)->len > 65) {
- desc = rb_any_to_s(obj);
+ if (RSTRING(d)->len > 65) {
+ d = rb_any_to_s(obj);
}
+ desc = RSTRING(d)->ptr;
}
ruby_sourcefile = file;
@@ -3534,9 +3550,7 @@ rb_f_missing(argc, argv, obj)
PUSH_FRAME(); /* fake frame */
*ruby_frame = *_frame.prev->prev;
- rb_raise(rb_eNameError, format,
- rb_id2name(id),
- desc?(char*)RSTRING(desc)->ptr:"");
+ rb_raise(rb_eNameError, format, rb_id2name(id), desc);
POP_FRAME();
return Qnil; /* not reached */
@@ -4456,6 +4470,12 @@ find_file(file)
return file;
}
+ if (file[0] == '~') {
+ VALUE argv[1];
+ argv[0] = rb_str_new2(file);
+ file = STR2CSTR(rb_file_s_expand_path(1, argv));
+ }
+
if (rb_load_path) {
int i;
@@ -4493,9 +4513,6 @@ rb_load(fname, wrap)
else {
Check_SafeStr(fname);
}
- if (RSTRING(fname)->ptr[0] == '~') {
- fname = rb_file_s_expand_path(1, &fname);
- }
file = find_file(RSTRING(fname)->ptr);
if (!file) {
rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr);
@@ -4733,6 +4750,20 @@ rb_f_require(obj, fname)
return Qtrue;
}
+static VALUE
+require_method(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
+{
+ int i;
+
+ for (i=0; i<argc; i++) {
+ rb_f_require(self, argv[i]);
+ }
+ return Qnil;
+}
+
static void
set_method_visibility(self, argc, argv, ex)
VALUE self;
@@ -4898,6 +4929,17 @@ rb_obj_call_init(obj)
POP_ITER();
}
+void
+rb_obj_call_init2(obj, argc, argv)
+ VALUE obj;
+ int argc;
+ VALUE *argv;
+{
+ PUSH_ITER(rb_iterator_p()?ITER_PRE:ITER_NOT);
+ rb_funcall2(obj, init, argc, argv);
+ POP_ITER();
+}
+
VALUE
rb_class_new_instance(argc, argv, klass)
int argc;
@@ -4963,7 +5005,7 @@ errinfo_setter(val, id, var)
ID id;
VALUE *var;
{
- if (!rb_obj_is_kind_of(val, rb_eException)) {
+ if (!NIL_P(val) && !rb_obj_is_kind_of(val, rb_eException)) {
rb_raise(rb_eTypeError, "assigning non-exception to $!");
}
*var = val;
@@ -5175,7 +5217,7 @@ Init_load()
rb_define_readonly_variable("$\"", &rb_features);
rb_define_global_function("load", rb_f_load, -1);
- rb_define_global_function("require", rb_f_require, 1);
+ rb_define_global_function("require", require_method, -1);
rb_define_global_function("autoload", rb_f_autoload, 2);
rb_global_variable(&ruby_wrapper);
}
diff --git a/ext/curses/curses.c b/ext/curses/curses.c
index f3d1bc0970..89396a805f 100644
--- a/ext/curses/curses.c
+++ b/ext/curses/curses.c
@@ -11,6 +11,9 @@
# ifdef HAVE_NCURSES_CURSES_H
# include <ncurses/curses.h>
# else
+#ifdef __hpux
+#include <curses_colr/curses.h>
+#else
# include <curses.h>
# if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_maxx)
# define _maxx maxx
@@ -26,6 +29,7 @@
# endif
# endif
#endif
+#endif
#include "ruby.h"
diff --git a/ext/curses/extconf.rb b/ext/curses/extconf.rb
index 442a9424a2..8356241f95 100644
--- a/ext/curses/extconf.rb
+++ b/ext/curses/extconf.rb
@@ -8,6 +8,8 @@ if have_header("ncurses.h") and have_library("ncurses", "initscr")
make=TRUE
elsif have_header("ncurses/curses.h") and have_library("ncurses", "initscr")
make=TRUE
+elsif have_header("curses_colr/curses.h") and have_library("cur_colr", "initscr")
+ make=TRUE
else
$CFLAGS=nil
have_library("termcap", "tgetent")
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index d422b32322..ceadc4dd77 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -294,8 +294,7 @@ LDSHARED = @LDSHARED@
mfile.printf "\
-#program_transform_name = -e @program_transform_name@
-#RUBY_INSTALL_NAME = `t='$(program_transform_name)'; echo @RUBY_INSTALL_NAME@ | sed $$t`
+RUBY_INSTALL_NAME = @RUBY_INSTALL_NAME@
prefix = @prefix@
exec_prefix = @exec_prefix@
@@ -449,7 +448,7 @@ def extmake(target)
elsif $clean
system "make clean"
else
- system "make all"
+ system "make all" or exit
end
end
if $static
@@ -514,6 +513,10 @@ end
exit if $install or $clean
$extinit = "" unless $extinit
+
+ruby = "@RUBY_INSTALL_NAME@@binsuffix@"
+miniruby = "miniruby@binsuffix@"
+
if $extlist.size > 0
for s,t in $extlist
f = format("%s/%s.a", s, t)
@@ -546,8 +549,8 @@ if $extlist.size > 0
Dir.chdir ".."
- if older("ruby@binsuffix@", "#{$top_srcdir}/ext/@setup@") or older("ruby@binsuffix@", "miniruby@binsuffix@")
- `rm -f ruby@binsuffix@`
+ if older(ruby, "#{$top_srcdir}/ext/@setup@") or older(ruby, miniruby)
+ system("rm -f #{ruby}")
end
if $extobjs
@@ -558,12 +561,12 @@ if $extlist.size > 0
if PLATFORM =~ /m68k-human|beos/
$extlibs.gsub!("-L/usr/local/lib", "") if $extlibs
end
- system format('make ruby@binsuffix@ EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs)
+ system format('make #{ruby} EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs)
else
Dir.chdir ".."
- if older("@RUBY_INSTALL_NAME@@binsuffix@", "miniruby@binsuffix@")
- `rm -f @RUBY_INSTALL_NAME@@binsuffix@`
- system("make @RUBY_INSTALL_NAME@@binsuffix@")
+ if older(ruby, miniruby)
+ system("rm -f #{ruby}")
+ system("make #{ruby}")
end
end
diff --git a/ext/nkf/MANIFEST b/ext/nkf/MANIFEST
new file mode 100644
index 0000000000..7e3345a6b7
--- /dev/null
+++ b/ext/nkf/MANIFEST
@@ -0,0 +1,7 @@
+MANIFEST
+depend
+extconf.rb
+lib/kconv.rb
+nkf.c
+orig/nkf.c
+test.rb
diff --git a/ext/nkf/extconf.rb b/ext/nkf/extconf.rb
new file mode 100644
index 0000000000..710662f19c
--- /dev/null
+++ b/ext/nkf/extconf.rb
@@ -0,0 +1,2 @@
+require 'mkmf'
+create_makefile('nkf')
diff --git a/ext/nkf/lib/kconv.rb b/ext/nkf/lib/kconv.rb
new file mode 100644
index 0000000000..bfd276330d
--- /dev/null
+++ b/ext/nkf/lib/kconv.rb
@@ -0,0 +1,58 @@
+require 'nkf'
+
+module Kconv
+ AUTO = NKF::AUTO
+ JIS = NKF::JIS
+ EUC = NKF::EUC
+ SJIS = NKF::SJIS
+ BINARY = NKF::BINARY
+ NOCONV = NKF::NOCONV
+ UNKNOWN = NKF::UNKNOWN
+ def kconv(str, out_code, in_code = AUTO)
+ opt = '-'
+ case in_code
+ when NKF::JIS
+ opt << 'J'
+ when NKF::EUC
+ opt << 'E'
+ when NKF::SJIS
+ opt << 'S'
+ end
+
+ case out_code
+ when NKF::JIS
+ opt << 'j'
+ when NKF::EUC
+ opt << 'e'
+ when NKF::SJIS
+ opt << 's'
+ when NKF::NOCONV
+ return str
+ end
+
+ opt = '' if opt == '-'
+
+ NKF::nkf(opt, str)
+ end
+ module_function :kconv
+
+ def tojis(str)
+ NKF::nkf('-j', str)
+ end
+ module_function :tojis
+
+ def toeuc(str)
+ NKF::nkf('-e', str)
+ end
+ module_function :toeuc
+
+ def tosjis(str)
+ NKF::nkf('-s', str)
+ end
+ module_function :tosjis
+
+ def guess(str)
+ NKF::guess(str)
+ end
+ module_function :guess
+end
diff --git a/ext/nkf/nkf.c b/ext/nkf/nkf.c
new file mode 100644
index 0000000000..6b5db0fe70
--- /dev/null
+++ b/ext/nkf/nkf.c
@@ -0,0 +1,207 @@
+#include "ruby.h"
+
+#define _AUTO 0
+#define _JIS 1
+#define _EUC 2
+#define _SJIS 3
+#define _BINARY 4
+#define _NOCONV 4
+#define _UNKNOWN _AUTO
+
+#undef getc
+#undef ungetc
+#define getc(f) (input_ctr>i_len?-1:input[input_ctr++])
+#define ungetc(c,f) input_ctr--
+
+#undef putchar
+#define putchar(c) rb_nkf_putchar(c)
+
+#define INCSIZE 32
+static int incsize;
+
+static unsigned char *input, *output;
+static int input_ctr, i_len;
+static int output_ctr, o_len;
+
+static VALUE dst;
+
+static int
+rb_nkf_putchar(c)
+ unsigned int c;
+{
+ if (output_ctr >= o_len) {
+ o_len += incsize;
+ rb_str_cat(dst, "", incsize);
+ incsize *= 2;
+ }
+
+ output[output_ctr++] = c;
+/*
+printf("[[%c][%c][%d]]\n", c, output[output_ctr - 1], output_ctr);
+*/
+ return c;
+}
+
+#define PERL_XS 1
+#include "orig/nkf.c"
+
+static VALUE
+rb_nkf_kconv(obj, opt, src)
+ VALUE obj, opt, src;
+{
+ int i;
+ char *opt_ptr, *opt_end;
+
+ reinit();
+ opt_ptr = str2cstr(opt, &i);
+ opt_end = opt_ptr + i;
+ for (; opt_ptr < opt_end; opt_ptr++) {
+ if (*opt_ptr != '-') {
+ continue;
+ }
+ arguments(opt_ptr);
+ }
+ dst = rb_str_new(0, RSTRING(src)->len*3 + 10); /* large enough? */
+
+ incsize = INCSIZE;
+
+ input_ctr = 0;
+ input = str2cstr(src, &i_len);
+
+ output_ctr = 0;
+ output = RSTRING(dst)->ptr;
+ o_len = RSTRING(dst)->len;
+ *output = '\0';
+
+ if(iso8859_f && (oconv != j_oconv || !x0201_f )) {
+ iso8859_f = FALSE;
+ }
+
+ kanji_convert(NULL);
+ output_ctr--;
+ if (output[output_ctr] == '\0') {
+/*
+printf("([%c][%d])\n", output[output_ctr], output_ctr);
+*/
+ RSTRING(dst)->len = output_ctr;
+ } else {
+/*
+printf("<[%c][%d]>\n", output[output_ctr], output_ctr);
+*/
+ RSTRING(dst)->len = output_ctr + 1;
+ }
+
+ return dst;
+}
+
+/*
+ * Character code detection - Algorithm described in:
+ * Ken Lunde. `Understanding Japanese Information Processing'
+ * Sebastopol, CA: O'Reilly & Associates.
+ */
+
+static VALUE
+rb_nkf_guess(obj, src)
+ VALUE obj, src;
+{
+ unsigned char *p;
+ unsigned char *pend;
+ int sequence_counter = 0;
+
+ Check_Type(src, T_STRING);
+
+ p = RSTRING(src)->ptr;
+ pend = p + RSTRING(src)->len;
+
+#define INCR do {\
+ p++;\
+ if (p==pend) return INT2FIX(_UNKNOWN);\
+ sequence_counter++;\
+ if (sequence_counter % 2 == 1 && *p != 0xa4)\
+ sequence_counter = 0;\
+ if (6 <= sequence_counter) {\
+ sequence_counter = 0;\
+ return INT2FIX(_EUC);\
+ }\
+} while (0)
+
+ if (*p == 0xa4)
+ sequence_counter = 1;
+
+ while (p<pend) {
+ if (*p == '\033') {
+ return INT2FIX(_JIS);
+ }
+ if ('\000' < *p && *p < '\006'
+ || *p == 0x7f
+ || *p == 0xdf) {
+ return INT2FIX(_BINARY);
+ }
+ if (0x81 <= *p && *p <= 0x8d) {
+ return INT2FIX(_SJIS);
+ }
+ if (0x8f <= *p && *p <= 0x9f) {
+ return INT2FIX(_SJIS);
+ }
+ if (*p == 0x8e) { /* SS2 */
+ INCR;
+ if ((0x40 <= *p && *p <= 0x7e) ||
+ (0x80 <= *p && *p <= 0xa0) ||
+ (0xe0 <= *p && *p <= 0xfc))
+ return INT2FIX(_SJIS);
+ }
+ else if (0xa1 <= *p && *p <= 0xdf) {
+ INCR;
+ if (0xf0 <= *p && *p <= 0xfe)
+ return INT2FIX(_EUC);
+ if (0xe0 <= *p && *p <= 0xef) {
+ while (p < pend && *p >= 0x40) {
+ if (*p >= 0x81) {
+ if (*p <= 0x8d || (0x8f <= *p && *p <= 0x9f)) {
+ return INT2FIX(_SJIS);
+ }
+ else if (0xfd <= *p && *p <= 0xfe) {
+ return INT2FIX(_EUC);
+ }
+ }
+ INCR;
+ }
+ }
+ else if (*p <= 0x9f) {
+ return INT2FIX(_SJIS);
+ }
+ }
+ else if (0xf0 <= *p && *p <= 0xfe) {
+ return INT2FIX(_EUC);
+ }
+ else if (0xe0 <= *p && *p <= 0xef) {
+ INCR;
+ if ((0x40 <= *p && *p <= 0x7e) ||
+ (0x80 <= *p && *p <= 0xa0)) {
+ return INT2FIX(_SJIS);
+ }
+ if (0xfd <= *p && *p <= 0xfe) {
+ return INT2FIX(_EUC);
+ }
+ }
+ INCR;
+ }
+ return INT2FIX(_UNKNOWN);
+}
+
+void
+Init_nkf()
+{
+ VALUE mKconv = rb_define_module("NKF");
+
+ rb_define_module_function(mKconv, "nkf", rb_nkf_kconv, 2);
+ rb_define_module_function(mKconv, "guess", rb_nkf_guess, 1);
+
+ rb_define_const(mKconv, "AUTO", INT2FIX(_AUTO));
+ rb_define_const(mKconv, "JIS", INT2FIX(_JIS));
+ rb_define_const(mKconv, "EUC", INT2FIX(_EUC));
+ rb_define_const(mKconv, "SJIS", INT2FIX(_SJIS));
+ rb_define_const(mKconv, "BINARY", INT2FIX(_BINARY));
+ rb_define_const(mKconv, "NOCONV", INT2FIX(_NOCONV));
+ rb_define_const(mKconv, "UNKNOWN", INT2FIX(_UNKNOWN));
+}
diff --git a/ext/nkf/orig/nkf.c b/ext/nkf/orig/nkf.c
new file mode 100644
index 0000000000..8de08a8b36
--- /dev/null
+++ b/ext/nkf/orig/nkf.c
@@ -0,0 +1,1897 @@
+/** Network Kanji Filter. (PDS Version)
+************************************************************************
+** Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)
+** $BO"Mm@h!'(B $B!J3t!KIY;NDL8&5f=j!!%=%U%H#38&!!;T@n!!;j(B
+** $B!J(BE-Mail Address: ichikawa@flab.fujitsu.co.jp$B!K(B
+** Copyright (C) 1996,1998
+** $BO"Mm@h!'(B $BN05eBg3X>pJs9)3X2J(B $B2OLn(B $B??<#(B mine/X0208 support
+** $B!J(BE-Mail Address: kono@ie.u-ryukyu.ac.jp$B!K(B
+** $BO"Mm@h!'(B COW for DOS & Win16 & Win32 & OS/2
+** $B!J(BE-Mail Address: GHG00637@niftyserve.or.p$B!K(B
+** $B$3$N%=!<%9$N$$$+$J$kJ#<L!$2~JQ!$=$@5$b5vBz$7$^$9!#$?$@$7!"(B
+** $B$=$N:]$K$O!"C/$,9W8%$7$?$r<($9$3$NItJ,$r;D$9$3$H!#(B
+** $B:FG[I[$d;(;o$NIUO?$J$I$NLd$$9g$o$;$bI,MW$"$j$^$;$s!#(B
+** $B$3$N%W%m%0%i%`$K$D$$$F$OFC$K2?$NJ]>Z$b$7$J$$!"0-$7$+$i$:!#(B
+** Everyone is permitted to do anything on this program
+** including copying, modifying, improving.
+** as long as you don't try to pretend that you wrote it.
+** i.e., the above copyright notice has to appear in all copies.
+** You don't have to ask before copying or publishing.
+** THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+***********************************************************************/
+
+static char *CopyRight =
+ "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),1998 S. Kono, COW";
+static char *Version =
+ "1.7";
+static char *Patchlevel =
+ "0/9711/Shinji Kono";
+
+/*
+**
+**
+**
+** USAGE: nkf [flags] [file]
+**
+** Flags:
+** b Output is bufferred (DEFAULT)
+** u Output is unbufferred
+**
+** t no operation
+**
+** j Outout code is JIS 7 bit (DEFAULT SELECT)
+** s Output code is MS Kanji (DEFAULT SELECT)
+** e Output code is AT&T JIS (DEFAULT SELECT)
+** l Output code is JIS 7bit and ISO8859-1 Latin-1
+**
+** m MIME conversion for ISO-2022-JP
+** i_ Output sequence to designate JIS-kanji (DEFAULT_J)
+** o_ Output sequence to designate single-byte roman characters (DEFAULT_R)
+**
+** r {de/en}crypt ROT13/47
+**
+** v display Version
+**
+** T Text mode output (for MS-DOS)
+**
+** x Do not convert X0201 kana into X0208
+** Z Convert X0208 alphabet to ASCII
+**
+** f60 fold option
+**
+** m MIME decode
+** B try to fix broken JIS, missing Escape
+** B[1-9] broken level
+**
+** O Output to 'nkf.out' file
+** d Delete \r in line feed
+** c Add \r in line feed
+**/
+/******************************/
+/* $B%G%U%)%k%H$N=PNO%3!<%IA*Br(B */
+/* Select DEFAULT_CODE */
+#define DEFAULT_CODE_JIS
+/* #define DEFAULT_CODE_SJIS */
+/* #define DEFAULT_CODE_EUC */
+/******************************/
+
+#if (defined(__TURBOC__) || defined(LSI_C)) && !defined(MSDOS)
+#define MSDOS
+#endif
+
+#ifndef PERL_XS
+#include <stdio.h>
+#endif
+
+#if defined(MSDOS) || defined(__OS2__)
+#include <stdlib.h>
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+#ifdef MSDOS
+#ifdef LSI_C
+#define setbinmode(fp) fsetbin(fp)
+#else /* Microsoft C, Turbo C */
+#define setbinmode(fp) setmode(fileno(fp), O_BINARY)
+#endif
+#else /* UNIX,OS/2 */
+#define setbinmode(fp)
+#endif
+
+#ifdef _IOFBF /* SysV and MSDOS */
+#define setvbuffer(fp, buf, size) setvbuf(fp, buf, _IOFBF, size)
+#else /* BSD */
+#define setvbuffer(fp, buf, size) setbuffer(fp, buf, size)
+#endif
+
+/*Borland C++ 4.5 EasyWin*/
+#if defined(__TURBOC__) && defined(_Windows) && !defined(__WIN32__) /*Easy Win */
+#define EASYWIN
+#include <windows.h>
+#endif
+
+#define FALSE 0
+#define TRUE 1
+
+/* state of output_mode and input_mode */
+
+#define ASCII 0
+#define X0208 1
+#define X0201 2
+#define NO_X0201 3
+#define JIS_INPUT 4
+#define SJIS_INPUT 5
+#define LATIN1_INPUT 6
+#define FIXED_MIME 7
+#define DOUBLE_SPACE -2
+
+#define NL 0x0a
+#define ESC 0x1b
+#define SPACE 0x20
+#define AT 0x40
+#define SSP 0xa0
+#define DEL 0x7f
+#define SI 0x0f
+#define SO 0x0e
+#define SSO 0x8e
+
+#define HOLD_SIZE 32
+#define IOBUF_SIZE 16384
+
+#define DEFAULT_J 'B'
+#define DEFAULT_R 'B'
+
+#define SJ0162 0x00e1 /* 01 - 62 ku offset */
+#define SJ6394 0x0161 /* 63 - 94 ku offset */
+
+
+/* MIME preprocessor */
+
+#undef STRICT_MIME /* do stupid strict mime integrity check */
+#define GETC(p) ((!mime_mode)?getc(p):mime_getc(p))
+#define UNGETC(c,p) ((!mime_mode)?ungetc(c,p):mime_ungetc(c))
+
+
+#ifdef EASYWIN /*Easy Win */
+extern POINT _BufferSize;
+#endif
+
+/* function prototype */
+
+#ifndef _
+# ifdef __STDC__
+# define _(args) args
+# else
+# define _(args) ()
+# endif
+#endif
+
+#ifndef PERL_XS
+static void noconvert _((FILE *f));
+static int mime_integrity _((FILE *f,unsigned char *p));
+static int usage _((void));
+static char stdibuf[IOBUF_SIZE];
+static char stdobuf[IOBUF_SIZE];
+static unsigned int mime_input = 0; /* undecoded */
+static int end_check;
+#endif
+
+static void kanji_convert _((FILE *f));
+static void h_conv _((FILE *f,int c2,int c1));
+static int push_hold_buf _((int c2,int c1));
+static void s_iconv _((int c2,int c1));
+static void e_oconv _((int c2,int c1));
+static void s_oconv _((int c2,int c1));
+static void j_oconv _((int c2,int c1));
+static int line_fold _((int c2,int c1));
+static int pre_convert _((int c1,int c2));
+static int mime_begin _((FILE *f));
+static int mime_getc _((FILE *f));
+static int mime_ungetc _((unsigned int c));
+static int base64decode _((int c));
+static void arguments _((char *c));
+static void reinit _((void));
+
+/* buffers */
+
+static unsigned char hold_buf[HOLD_SIZE*2];
+static int hold_count;
+
+/* MIME preprocessor fifo */
+
+#define MIME_BUF_SIZE (1024) /* 2^n ring buffer */
+#define MIME_BUF_MASK (MIME_BUF_SIZE-1)
+#define Fifo(n) mime_buf[(n)&MIME_BUF_MASK]
+static unsigned char mime_buf[MIME_BUF_SIZE];
+static unsigned int mime_top = 0;
+static unsigned int mime_last = 0; /* decoded */
+
+/* flags */
+static int unbuf_f = FALSE;
+static int estab_f = FALSE;
+static int nop_f = FALSE;
+static int binmode_f = TRUE; /* binary mode */
+static int rot_f = FALSE; /* rot14/43 mode */
+static int input_f = FALSE; /* non fixed input code */
+static int alpha_f = FALSE; /* convert JIx0208 alphbet to ASCII */
+static int mime_f = TRUE; /* convert MIME B base64 or Q */
+static int mimebuf_f = FALSE; /* MIME buffered input */
+static int broken_f = FALSE; /* convert ESC-less broken JIS */
+static int iso8859_f = FALSE; /* ISO8859 through */
+#if defined(MSDOS) || defined(__OS2__)
+static int x0201_f = TRUE; /* Assume JISX0201 kana */
+#else
+static int x0201_f = NO_X0201; /* Assume NO JISX0201 */
+#endif
+
+/* X0208 -> ASCII converter */
+
+static int c1_return;
+
+/* fold parameter */
+static int line = 0; /* chars in line */
+static int prev = 0;
+static int fold_f = FALSE;
+static int fold_len = 0;
+
+/* options */
+static char kanji_intro = DEFAULT_J,
+ ascii_intro = DEFAULT_R;
+
+/* Folding */
+
+int line_fold();
+#define FOLD_MARGIN 10
+#define DEFAULT_FOLD 60
+
+/* converters */
+
+#ifdef DEFAULT_CODE_JIS
+# define DEFAULT_CONV j_oconv
+#endif
+#ifdef DEFAULT_CODE_SJIS
+# define DEFAULT_CONV s_oconv
+#endif
+#ifdef DEFAULT_CODE_EUC
+# define DEFAULT_CONV e_oconv
+#endif
+
+static void (*iconv)(int c2,int c1);
+ /* s_iconv or oconv */
+static void (*oconv)(int c2,int c1) = DEFAULT_CONV;
+ /* [ejs]_oconv */
+
+/* Global states */
+static int output_mode = ASCII, /* output kanji mode */
+ input_mode = ASCII, /* input kanji mode */
+ shift_mode = FALSE; /* TRUE shift out, or X0201 */
+static int mime_mode = FALSE; /* MIME mode B base64, Q hex */
+
+/* X0201 / X0208 conversion tables */
+
+/* X0201 kana conversion table */
+/* 90-9F A0-DF */
+unsigned char cv[]= {
+0x21,0x21,0x21,0x23,0x21,0x56,0x21,0x57,
+0x21,0x22,0x21,0x26,0x25,0x72,0x25,0x21,
+0x25,0x23,0x25,0x25,0x25,0x27,0x25,0x29,
+0x25,0x63,0x25,0x65,0x25,0x67,0x25,0x43,
+0x21,0x3c,0x25,0x22,0x25,0x24,0x25,0x26,
+0x25,0x28,0x25,0x2a,0x25,0x2b,0x25,0x2d,
+0x25,0x2f,0x25,0x31,0x25,0x33,0x25,0x35,
+0x25,0x37,0x25,0x39,0x25,0x3b,0x25,0x3d,
+0x25,0x3f,0x25,0x41,0x25,0x44,0x25,0x46,
+0x25,0x48,0x25,0x4a,0x25,0x4b,0x25,0x4c,
+0x25,0x4d,0x25,0x4e,0x25,0x4f,0x25,0x52,
+0x25,0x55,0x25,0x58,0x25,0x5b,0x25,0x5e,
+0x25,0x5f,0x25,0x60,0x25,0x61,0x25,0x62,
+0x25,0x64,0x25,0x66,0x25,0x68,0x25,0x69,
+0x25,0x6a,0x25,0x6b,0x25,0x6c,0x25,0x6d,
+0x25,0x6f,0x25,0x73,0x21,0x2b,0x21,0x2c,
+0x00,0x00};
+
+
+/* X0201 kana conversion table for daguten */
+/* 90-9F A0-DF */
+unsigned char dv[]= {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x25,0x2c,0x25,0x2e,
+0x25,0x30,0x25,0x32,0x25,0x34,0x25,0x36,
+0x25,0x38,0x25,0x3a,0x25,0x3c,0x25,0x3e,
+0x25,0x40,0x25,0x42,0x25,0x45,0x25,0x47,
+0x25,0x49,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x25,0x50,0x25,0x53,
+0x25,0x56,0x25,0x59,0x25,0x5c,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00};
+
+/* X0201 kana conversion table for han-daguten */
+/* 90-9F A0-DF */
+unsigned char ev[]= {
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x25,0x51,0x25,0x54,
+0x25,0x57,0x25,0x5a,0x25,0x5d,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00};
+
+
+/* X0208 kigou conversion table */
+/* 0x8140 - 0x819e */
+unsigned char fv[] = {
+
+0x00,0x00,0x00,0x00,0x2c,0x2e,0x00,0x3a,
+0x3b,0x3f,0x21,0x00,0x00,0x27,0x60,0x00,
+0x5e,0x00,0x5f,0x00,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x2d,0x00,0x2f,
+0x5c,0x00,0x00,0x7c,0x00,0x00,0x60,0x27,
+0x22,0x22,0x28,0x29,0x00,0x00,0x5b,0x5d,
+0x7b,0x7d,0x3c,0x3e,0x00,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x2b,0x2d,0x00,0x00,
+0x00,0x3d,0x00,0x3c,0x3e,0x00,0x00,0x00,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+0x24,0x00,0x00,0x25,0x23,0x26,0x2a,0x40,
+0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+} ;
+
+
+static int file_out = FALSE;
+static int add_cr = FALSE;
+static int del_cr = FALSE;
+
+#ifndef PERL_XS
+int
+main(argc, argv)
+ int argc;
+ char **argv;
+{
+ FILE *fin;
+ char *cp;
+
+#ifdef EASYWIN /*Easy Win */
+ _BufferSize.y = 400;/*Set Scroll Buffer Size*/
+#endif
+
+ for (argc--,argv++; (argc > 0) && **argv == '-'; argc--, argv++) {
+ cp = *argv;
+ arguments(cp);
+ }
+
+ if(iso8859_f && (oconv != j_oconv || !x0201_f )) {
+ fprintf(stderr,"Mixed ISO8859/JISX0201/SJIS/EUC output is not allowed.\n");
+ exit(1);
+ }
+
+ if(binmode_f == TRUE)
+#ifdef __OS2__
+ if(freopen("","wb",stdout) == NULL)
+ return (-1);
+#else
+ setbinmode(stdout);
+#endif
+
+ if(unbuf_f)
+ setbuf(stdout, (char *) NULL);
+ else
+ setvbuffer(stdout, stdobuf, IOBUF_SIZE);
+
+ if(argc == 0) {
+ if(binmode_f == TRUE)
+#ifdef __OS2__
+ if(freopen("","rb",stdin) == NULL) return (-1);
+#else
+ setbinmode(stdin);
+#endif
+ setvbuffer(stdin, stdibuf, IOBUF_SIZE);
+ if(nop_f)
+ noconvert(stdin);
+ else
+ kanji_convert(stdin);
+ } else {
+ while (argc--) {
+ if((fin = fopen(*argv++, "r")) == NULL) {
+ perror(*--argv);
+ return(-1);
+ } else {
+/* reopen file for stdout */
+ if(file_out == TRUE){
+ if(argc == 1 ) {
+ if(freopen(*argv++, "w", stdout) == NULL) {
+ perror(*--argv);
+ return (-1);
+ }
+ argc--;
+ } else {
+ if(freopen("nkf.out", "w", stdout) == NULL) {
+ perror(*--argv);
+ return (-1);
+ }
+ }
+ if(binmode_f == TRUE) {
+#ifdef __OS2__
+ if(freopen("","wb",stdout) == NULL)
+ return (-1);
+#else
+ setbinmode(stdout);
+#endif
+ }
+ }
+ if(binmode_f == TRUE)
+#ifdef __OS2__
+ if(freopen("","rb",fin) == NULL)
+ return (-1);
+#else
+ setbinmode(fin);
+#endif
+ setvbuffer(fin, stdibuf, IOBUF_SIZE);
+ if(nop_f)
+ noconvert(fin);
+ else
+ kanji_convert(fin);
+ fclose(fin);
+ }
+ }
+ }
+#ifdef EASYWIN /*Easy Win */
+ if(file_out == FALSE)
+ scanf("%d",&end_check);
+ else
+ fclose(stdout);
+#else /* for Other OS */
+ if(file_out == TRUE)
+ fclose(stdout);
+#endif
+ return (0);
+}
+#endif
+
+void
+arguments(cp)
+ char *cp;
+{
+ while (*cp) {
+ switch (*cp++) {
+ case 'b': /* buffered mode */
+ unbuf_f = FALSE;
+ continue;
+ case 'u': /* non bufferd mode */
+ unbuf_f = TRUE;
+ continue;
+ case 't': /* transparent mode */
+ nop_f = TRUE;
+ continue;
+ case 'j': /* JIS output */
+ case 'n':
+ oconv = j_oconv;
+ continue;
+ case 'e': /* AT&T EUC output */
+ oconv = e_oconv;
+ continue;
+ case 's': /* SJIS output */
+ oconv = s_oconv;
+ continue;
+ case 'l': /* ISO8859 Latin-1 support, no conversion */
+ iso8859_f = TRUE; /* Only compatible with ISO-2022-JP */
+ input_f = LATIN1_INPUT;
+ continue;
+ case 'i': /* Kanji IN ESC-$-@/B */
+ if(*cp=='@'||*cp=='B')
+ kanji_intro = *cp++;
+ continue;
+ case 'o': /* ASCII IN ESC-(-J/B */
+ if(*cp=='J'||*cp=='B'||*cp=='H')
+ ascii_intro = *cp++;
+ continue;
+ case 'r':
+ rot_f = TRUE;
+ continue;
+#if defined(MSDOS) || defined(__OS2__)
+ case 'T':
+ binmode_f = FALSE;
+ continue;
+#endif
+#ifndef PERL_XS
+ case 'v':
+ usage();
+ exit(1);
+ break;
+#endif
+ /* Input code assumption */
+ case 'J': /* JIS input */
+ case 'E': /* AT&T EUC input */
+ input_f = JIS_INPUT;
+ continue;
+ case 'S': /* MS Kanji input */
+ input_f = SJIS_INPUT;
+ if(x0201_f==NO_X0201) x0201_f=TRUE;
+ continue;
+ case 'Z': /* Convert X0208 alphabet to asii */
+ /* bit:0 Convert X0208
+ bit:1 Convert Kankaku to one space
+ bit:2 Convert Kankaku to two spaces
+ */
+ if('9'>= *cp && *cp>='0')
+ alpha_f |= 1<<(*cp++ -'0');
+ else
+ alpha_f |= TRUE;
+ continue;
+ case 'x': /* Convert X0201 kana to X0208 or X0201 Conversion */
+ x0201_f = FALSE; /* No X0201->X0208 conversion */
+ /* accept X0201
+ ESC-(-I in JIS, EUC, MS Kanji
+ SI/SO in JIS, EUC, MS Kanji
+ SSO in EUC, JIS, not in MS Kanji
+ MS Kanji (0xa0-0xdf)
+ output X0201
+ ESC-(-I in JIS (0x20-0x5f)
+ SSO in EUC (0xa0-0xdf)
+ 0xa0-0xd in MS Kanji (0xa0-0xdf)
+ */
+ continue;
+ case 'X': /* Assume X0201 kana */
+ /* Default value is NO_X0201 for EUC/MS-Kanji mix */
+ x0201_f = TRUE;
+ continue;
+ case 'f': /* folding -f60 or -f */
+ fold_f = TRUE;
+ fold_len = atoi(cp);
+ if(!(0<fold_len && fold_len<BUFSIZ))
+ fold_len = DEFAULT_FOLD;
+ while('0'<= *cp && *cp <='9') cp++;
+ continue;
+ case 'm': /* MIME support */
+ mime_f = TRUE;
+ if(*cp=='B'||*cp=='Q') {
+ mime_mode = *cp++;
+ mimebuf_f = FIXED_MIME;
+ } else if (*cp=='0') {
+ mime_f = FALSE;
+ }
+ continue;
+ case 'M': /* MIME output */
+ oconv = j_oconv; /* sorry... not yet done.. */
+ continue;
+ case 'B': /* Broken JIS support */
+ /* bit:0 no ESC JIS
+ bit:1 allow any x on ESC-(-x or ESC-$-x
+ bit:2 reset to ascii on NL
+ */
+ if('9'>= *cp && *cp>='0')
+ broken_f |= 1<<(*cp++ -'0');
+ else
+ broken_f |= TRUE;
+ continue;
+#ifndef PERL_XS
+ case 'O':/* for Output file */
+ file_out = TRUE;
+ continue;
+#endif
+ case 'c':/* add cr code */
+ add_cr = TRUE;
+ continue;
+ case 'd':/* delete cr code */
+ del_cr = TRUE;
+ continue;
+ default:
+ /* bogus option but ignored */
+ continue;
+ }
+ }
+}
+
+#ifndef PERL_XS
+static void
+noconvert(f)
+ FILE *f;
+{
+ int c;
+
+ while ((c = getc(f)) != EOF)
+ putchar(c);
+}
+#endif
+
+
+static void
+kanji_convert(f)
+ FILE *f;
+{
+ int c1, c2;
+
+ c2 = 0;
+
+ if(input_f == JIS_INPUT || input_f == LATIN1_INPUT) {
+ estab_f = TRUE; iconv = oconv;
+ } else if(input_f == SJIS_INPUT) {
+ estab_f = TRUE; iconv = s_iconv;
+ } else {
+ estab_f = FALSE; iconv = oconv;
+ }
+ input_mode = ASCII;
+ output_mode = ASCII;
+ shift_mode = FALSE;
+
+#define NEXT continue /* no output, get next */
+#define SEND ; /* output c1 and c2, get next */
+#define LAST break /* end of loop, go closing */
+
+ while ((c1 = GETC(f)) != EOF) {
+ if(c2) {
+ /* second byte */
+ if(c2 > DEL) {
+ /* in case of 8th bit is on */
+ if(!estab_f) {
+ /* in case of not established yet */
+ if(c1 > SSP) {
+ /* It is still ambiguious */
+ h_conv(f, c2, c1);
+ c2 = 0;
+ NEXT;
+ } else if(c1 < AT) {
+ /* ignore bogus code */
+ c2 = 0;
+ NEXT;
+ } else {
+ /* established */
+ /* it seems to be MS Kanji */
+ estab_f = TRUE;
+ iconv = s_iconv;
+ SEND;
+ }
+ } else
+ /* in case of already established */
+ if(c1 < AT) {
+ /* ignore bogus code */
+ c2 = 0;
+ NEXT;
+ } else
+ SEND;
+ } else
+ /* 7 bit code */
+ /* it might be kanji shitfted */
+ if((c1 == DEL) || (c1 <= SPACE)) {
+ /* ignore bogus first code */
+ c2 = 0;
+ NEXT;
+ } else
+ SEND;
+ } else {
+ /* first byte */
+ if(c1 > DEL) {
+ /* 8 bit code */
+ if(!estab_f && !iso8859_f) {
+ /* not established yet */
+ if(c1 < SSP) {
+ /* it seems to be MS Kanji */
+ estab_f = TRUE;
+ iconv = s_iconv;
+ } else if(c1 < 0xe0) {
+ /* it seems to be EUC */
+ estab_f = TRUE;
+ iconv = oconv;
+ } else {
+ /* still ambiguious */
+ }
+ c2 = c1;
+ NEXT;
+ } else { /* estab_f==TRUE */
+ if(iso8859_f) {
+ SEND;
+ } else if(SSP<=c1 && c1<0xe0 && iconv == s_iconv) {
+ /* SJIS X0201 Case... */
+ /* This is too arrogant, but ... */
+ if(x0201_f==NO_X0201) {
+ iconv = oconv;
+ c2 = c1;
+ NEXT;
+ } else
+ if(x0201_f) {
+ if(dv[(c1-SSP)*2]||ev[(c1-SSP)*2]) {
+ /* look ahead for X0201/X0208conversion */
+ if((c2 = GETC(f)) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ LAST;
+ } else if(c2==(0xde)) { /* $BByE@(B */
+ (*oconv)(dv[(c1-SSP)*2],dv[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else if(c2==(0xdf)&&ev[(c1-SSP)*2]) {
+ /* $BH>ByE@(B */
+ (*oconv)(ev[(c1-SSP)*2],ev[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ }
+ UNGETC(c2,f); c2 = 0;
+ }
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ NEXT;
+ } else
+ SEND;
+ } else if(c1==SSO && iconv != s_iconv) {
+ /* EUC X0201 Case */
+ /* This is too arrogant
+ if(x0201_f == NO_X0201) {
+ estab_f = FALSE;
+ c2 = 0;
+ NEXT;
+ } */
+ c1 = GETC(f); /* skip SSO */
+ euc_1byte_check:
+ if(x0201_f && SSP<=c1 && c1<0xe0) {
+ if(dv[(c1-SSP)*2]||ev[(c1-SSP)*2]) {
+ if((c2 = GETC(f)) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ LAST;
+ }
+ /* forward lookup $BByE@(B/$BH>ByE@(B */
+ if(c2 != SSO) {
+ UNGETC(c2,f); c2 = 0;
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ NEXT;
+ } else if((c2 = GETC(f)) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ (*oconv)(0,SSO);
+ LAST;
+ } else if(c2==(0xde)) { /* $BByE@(B */
+ (*oconv)(dv[(c1-SSP)*2],dv[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else if(c2==(0xdf)&&ev[(c1-SSP)*2]) {
+ /* $BH>ByE@(B */
+ (*oconv)(ev[(c1-SSP)*2],ev[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ /* we have to check this c2 */
+ /* and no way to push back SSO */
+ c1 = c2; c2 = 0;
+ goto euc_1byte_check;
+ }
+ }
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ NEXT;
+ } else
+ SEND;
+ } else if(c1 < SSP && iconv != s_iconv) {
+ /* strange code in EUC */
+ iconv = s_iconv; /* try SJIS */
+ c2 = c1;
+ NEXT;
+ } else {
+ /* already established */
+ c2 = c1;
+ NEXT;
+ }
+ }
+ } else if((c1 > SPACE) && (c1 != DEL)) {
+ /* in case of Roman characters */
+ if(shift_mode) {
+ c1 |= 0x80;
+ /* output 1 shifted byte */
+ if(x0201_f && (!iso8859_f||input_mode==X0201) &&
+ SSP<=c1 && c1<0xe0 ) {
+ if(dv[(c1-SSP)*2]||ev[(c1-SSP)*2]) {
+ if((c2 = GETC(f)) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ LAST;
+ } else if(c2==(0xde&0x7f)) { /* $BByE@(B */
+ (*oconv)(dv[(c1-SSP)*2],dv[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else if(c2==(0xdf&0x7f)&&ev[(c1-SSP)*2]) {
+ /* $BH>ByE@(B */
+ (*oconv)(ev[(c1-SSP)*2],ev[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ }
+ UNGETC(c2,f); c2 = 0;
+ }
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ NEXT;
+ } else
+ SEND;
+ } else if(c1 == '(' && broken_f && input_mode == X0208
+ && !mime_mode ) {
+ /* Try to recover missing escape */
+ if((c1 = GETC(f)) == EOF) {
+ (*oconv)(0, '(');
+ LAST;
+ } else {
+ if(c1 == 'B' || c1 == 'J' || c1 == 'H') {
+ input_mode = ASCII; shift_mode = FALSE;
+ NEXT;
+ } else {
+ (*oconv)(0, '(');
+ /* do not modify various input_mode */
+ /* It can be vt100 sequence */
+ SEND;
+ }
+ }
+ } else if(input_mode == X0208) {
+ /* in case of Kanji shifted */
+ c2 = c1;
+ NEXT;
+ /* goto next_byte */
+ } else if(c1 == '=' && mime_f && !mime_mode ) {
+ if((c1 = getc(f)) == EOF) {
+ (*oconv)(0, '=');
+ LAST;
+ } else if(c1 == '?') {
+ /* =? is mime conversiooon start sequence */
+ if(mime_begin(f) == EOF) /* check in detail */
+ LAST;
+ else
+ NEXT;
+ } else {
+ (*oconv)(0, '=');
+ ungetc(c1,f);
+ NEXT;
+ }
+ } else if(c1 == '$' && broken_f && !mime_mode) {
+ /* try to recover missing escape */
+ if((c1 = GETC(f)) == EOF) {
+ (*oconv)(0, '$');
+ LAST;
+ } else if(c1 == '@'|| c1 == 'B') {
+ /* in case of Kanji in ESC sequence */
+ input_mode = X0208;
+ shift_mode = FALSE;
+ NEXT;
+ } else {
+ /* sorry */
+ (*oconv)(0, '$');
+ (*oconv)(0, c1);
+ NEXT;
+ }
+ } else
+ SEND;
+ } else if(c1 == SI) {
+ shift_mode = FALSE;
+ NEXT;
+ } else if(c1 == SO) {
+ shift_mode = TRUE;
+ NEXT;
+ } else if(c1 == ESC ) {
+ if((c1 = GETC(f)) == EOF) {
+ (*oconv)(0, ESC);
+ LAST;
+ } else if(c1 == '$') {
+ if((c1 = GETC(f)) == EOF) {
+ (*oconv)(0, ESC);
+ (*oconv)(0, '$');
+ LAST;
+ } else if(c1 == '@'|| c1 == 'B') {
+ /* This is kanji introduction */
+ input_mode = X0208;
+ shift_mode = FALSE;
+ NEXT;
+ } else if(c1 == '(') {
+ if((c1 = GETC(f)) == EOF) {
+ (*oconv)(0, ESC);
+ (*oconv)(0, '$');
+ (*oconv)(0, '(');
+ LAST;
+ } else if(c1 == '@'|| c1 == 'B') {
+ /* This is kanji introduction */
+ input_mode = X0208;
+ shift_mode = FALSE;
+ NEXT;
+ } else {
+ (*oconv)(0, ESC);
+ (*oconv)(0, '$');
+ (*oconv)(0, '(');
+ (*oconv)(0, c1);
+ NEXT;
+ }
+ } else if(broken_f&0x2) {
+ input_mode = X0208;
+ shift_mode = FALSE;
+ NEXT;
+ } else {
+ (*oconv)(0, ESC);
+ (*oconv)(0, '$');
+ (*oconv)(0, c1);
+ NEXT;
+ }
+ } else if(c1 == '(') {
+ if((c1 = GETC(f)) == EOF) {
+ (*oconv)(0, ESC);
+ (*oconv)(0, '(');
+ LAST;
+ } else {
+ if(c1 == 'I') {
+ /* This is X0201 kana introduction */
+ input_mode = X0201; shift_mode = X0201;
+ NEXT;
+ } else if(c1 == 'B' || c1 == 'J' || c1 == 'H') {
+ /* This is X0208 kanji introduction */
+ input_mode = ASCII; shift_mode = FALSE;
+ NEXT;
+ } else if(broken_f&0x2) {
+ input_mode = ASCII; shift_mode = FALSE;
+ NEXT;
+ } else {
+ (*oconv)(0, ESC);
+ (*oconv)(0, '(');
+ /* maintain various input_mode here */
+ SEND;
+ }
+ }
+ } else {
+ /* lonely ESC */
+ (*oconv)(0, ESC);
+ SEND;
+ }
+ } else if(c1 == NL && broken_f&4) {
+ input_mode = ASCII;
+ SEND;
+ } else
+ SEND;
+ }
+ /* send: */
+ if(input_mode == X0208)
+ (*oconv)(c2, c1); /* this is JIS, not SJIS/EUC case */
+ else
+ (*iconv)(c2, c1); /* can be EUC/SJIS */
+ c2 = 0;
+ continue;
+ /* goto next_word */
+ }
+
+ /* epilogue */
+ (*iconv)(EOF, 0);
+}
+
+
+
+
+static void
+h_conv(f, c2, c1)
+ FILE *f;
+ int c1, c2;
+{
+ int wc;
+
+
+ /** it must NOT be in the kanji shifte sequence */
+ /** it must NOT be written in JIS7 */
+ /** and it must be after 2 byte 8bit code */
+
+ hold_count = 0;
+ push_hold_buf(c2, c1);
+ c2 = 0;
+
+ while ((c1 = GETC(f)) != EOF) {
+ if(c2) {
+ /* second byte */
+ if(!estab_f) {
+ /* not established */
+ if(c1 > SSP) {
+ /* it is still ambiguious yet */
+ SEND;
+ } else if(c1 < AT) {
+ /* ignore bogus first byte */
+ c2 = 0;
+ SEND;
+ } else {
+ /* now established */
+ /* it seems to be MS Kanji */
+ estab_f = TRUE;
+ iconv = s_iconv;
+ SEND;
+ }
+ } else
+ SEND;
+ } else {
+ /* First byte */
+ if(c1 > DEL) {
+ /* 8th bit is on */
+ if(c1 < SSP) {
+ /* it seems to be MS Kanji */
+ estab_f = TRUE;
+ iconv = s_iconv;
+ } else if(c1 < 0xe0) {
+ /* it seems to be EUC */
+ estab_f = TRUE;
+ iconv = oconv;
+ } else {
+ /* still ambiguious */
+ }
+ c2 = c1;
+ NEXT;
+ } else
+ /* 7 bit code , then send without any process */
+ SEND;
+ }
+ /* send: */
+ if((push_hold_buf(c2, c1) == EOF) || estab_f)
+ break;
+ c2 = 0;
+ continue;
+ }
+
+ /** now,
+ ** 1) EOF is detected, or
+ ** 2) Code is established, or
+ ** 3) Buffer is FULL (but last word is pushed)
+ **
+ ** in 1) and 3) cases, we continue to use
+ ** Kanji codes by oconv and leave estab_f unchanged.
+ **/
+
+ for (wc = 0; wc < hold_count; wc += 2) {
+ c2 = hold_buf[wc];
+ c1 = hold_buf[wc+1];
+ (*iconv)(c2, c1);
+ }
+ return;
+}
+
+
+
+int
+push_hold_buf(c2, c1)
+ int c2, c1;
+{
+ if(hold_count >= HOLD_SIZE*2)
+ return (EOF);
+ hold_buf[hold_count++] = c2;
+ hold_buf[hold_count++] = c1;
+ return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count);
+}
+
+
+static void
+s_iconv(c2, c1)
+ int c2,
+ c1;
+{
+ if((c2 == EOF) || (c2 == 0)) {
+ /* NOP */
+ } else {
+ c2 = c2 + c2 - ((c2 <= 0x9f) ? SJ0162 : SJ6394);
+ if(c1 < 0x9f)
+ c1 = c1 - ((c1 > DEL) ? SPACE : 0x1f);
+ else {
+ c1 = c1 - 0x7e;
+ c2++;
+ }
+ }
+ (*oconv)(c2, c1);
+}
+
+
+static void
+e_oconv(c2, c1)
+ int c2, c1;
+{
+ c2 = pre_convert(c1,c2); c1 = c1_return;
+ if(fold_f) {
+ switch(line_fold(c2,c1)) {
+ case '\n':
+ if(add_cr == TRUE) {
+ putchar('\r');
+ c1 = '\n';
+ }
+ putchar('\n');
+ break;
+ case 0: return;
+ case '\r':
+ c1 = '\n'; c2 = 0;
+ break;
+ case '\t':
+ case ' ':
+ c1 = ' '; c2 = 0;
+ break;
+ }
+ }
+ if(c2==DOUBLE_SPACE) {
+ putchar(' '); putchar(' ');
+ return;
+ }
+ if(c2 == EOF)
+ return;
+ else if(c2 == 0 && (c1&0x80)) {
+ putchar(SSO); putchar(c1);
+ } else if(c2 == 0) {
+ if(c1 == '\n' && add_cr == TRUE)
+ putchar('\r');
+ if(c1 != '\r')
+ putchar(c1);
+ else if(del_cr == FALSE)
+ putchar(c1);
+ } else {
+ if((c1<0x20 || 0x7e<c1) ||
+ (c2<0x20 || 0x7e<c2)) {
+ estab_f = FALSE;
+ return; /* too late to rescue this char */
+ }
+ putchar(c2 | 0x080);
+ putchar(c1 | 0x080);
+ }
+ return;
+}
+
+
+static void
+s_oconv(c2, c1)
+ int c2, c1;
+{
+ c2 = pre_convert(c1,c2); c1 = c1_return;
+ if(fold_f) {
+ switch(line_fold(c2,c1)) {
+ case '\n':
+ if(add_cr == TRUE) {
+ putchar('\r');
+ c1 = '\n';
+ }
+ putchar('\n');
+ break;
+ case '\r':
+ c1 = '\n'; c2 = 0;
+ break;
+ case 0: return;
+ case '\t':
+ case ' ':
+ c1 = ' '; c2 = 0;
+ break;
+ }
+ }
+ if(c2==DOUBLE_SPACE) {
+ putchar(' '); putchar(' ');
+ return;
+ }
+ if(c2 == EOF)
+ return;
+ else if(c2 == 0) {
+ if(c1 == '\n' && add_cr == TRUE)
+ putchar('\r');
+ if(c1 != '\r')
+ putchar(c1);
+ else if(del_cr == FALSE)
+ putchar(c1);
+ } else {
+ if((c1<0x20 || 0x7e<c1) ||
+ (c2<0x20 || 0x7e<c2)) {
+ estab_f = FALSE;
+ return; /* too late to rescue this char */
+ }
+ putchar((((c2 - 1) >> 1) + ((c2 <= 0x5e) ? 0x71 : 0xb1)));
+ putchar((c1 + ((c2 & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e)));
+ }
+ return;
+}
+
+
+static void
+j_oconv(c2, c1)
+ int c2, c1;
+{
+ c2 = pre_convert(c1,c2); c1 = c1_return;
+ if(fold_f) {
+ switch(line_fold(c2,c1)) {
+ case '\n':
+ if(output_mode) {
+ putchar(ESC);
+ putchar('(');
+ putchar(ascii_intro);
+ }
+ if(add_cr == TRUE) {
+ putchar('\r');
+ c1 = '\n';
+ }
+ putchar('\n');
+ output_mode = ASCII;
+ break;
+ case '\r':
+ c1 = '\n'; c2 = 0;
+ break;
+ case '\t':
+ case ' ':
+ c1 = ' '; c2 = 0;
+ break;
+ case 0: return;
+ }
+ }
+ if(c2 == EOF) {
+ if(output_mode) {
+ putchar(ESC);
+ putchar('(');
+ putchar(ascii_intro);
+ }
+ } else if(c2 == 0 && (c1 & 0x80)) {
+ if(input_mode==X0201 || !iso8859_f) {
+ if(output_mode!=X0201) {
+ putchar(ESC);
+ putchar('(');
+ putchar('I');
+ output_mode = X0201;
+ }
+ c1 &= 0x7f;
+ } else {
+ /* iso8859 introduction, or 8th bit on */
+ /* Can we convert in 7bit form using ESC-'-'-A ?
+ Is this popular? */
+ }
+ putchar(c1);
+ } else if(c2 == 0) {
+ if(output_mode) {
+ putchar(ESC);
+ putchar('(');
+ putchar(ascii_intro);
+ output_mode = ASCII;
+ }
+ if(c1 == '\n' && add_cr == TRUE)
+ putchar('\r');
+ if(c1 != '\r')
+ putchar(c1);
+ else if(del_cr == FALSE)
+ putchar(c1);
+ } else if(c2 == DOUBLE_SPACE) {
+ if(output_mode) {
+ putchar(ESC);
+ putchar('(');
+ putchar(ascii_intro);
+ output_mode = ASCII;
+ }
+ putchar(' ');
+ if(c1 == '\n' && add_cr == TRUE)
+ putchar('\r');
+ if(c1 != '\r')
+ putchar(c1);
+ else if(del_cr == FALSE)
+ putchar(c1);
+ } else {
+ if(output_mode != X0208) {
+ putchar(ESC);
+ putchar('$');
+ putchar(kanji_intro);
+ output_mode = X0208;
+ }
+ if(c1<0x20 || 0x7e<c1)
+ return;
+ if(c2<0x20 || 0x7e<c2)
+ return;
+ putchar(c2);
+ if(c1 == '\n' && add_cr == TRUE)
+ putchar('\r');
+ if(c1 != '\r')
+ putchar(c1);
+ else if(del_cr == FALSE)
+ putchar(c1);
+ }
+ return;
+}
+
+
+
+#define rot13(c) ( \
+ ( c < 'A' ) ? c: \
+ (c <= 'M') ? (c + 13): \
+ (c <= 'Z') ? (c - 13): \
+ (c < 'a') ? (c): \
+ (c <= 'm') ? (c + 13): \
+ (c <= 'z') ? (c - 13): \
+ (c) \
+)
+
+#define rot47(c) ( \
+ ( c < '!' ) ? c: \
+ ( c <= 'O' ) ? (c + 47) : \
+ ( c <= '~' ) ? (c - 47) : \
+ c \
+)
+
+
+/*
+ Return value of line_fold()
+
+ \n add newline and output char
+ \r add newline and output nothing
+ ' ' space
+ 0 skip
+ 1 (or else) normal output
+
+ fold state in prev (previous character)
+
+ >0x80 Japanese (X0208/X0201)
+ <0x80 ASCII
+ \n new line
+ ' ' space
+
+ This fold algorthm does not preserve heading space in a line.
+ This is the main difference from fmt.
+*/
+
+int
+line_fold(c2,c1)
+int c2,c1;
+{
+ int prev0;
+ if(c1=='\r')
+ return 0; /* ignore cr */
+ if(c1== 8) {
+ if(line>0) line--;
+ return 1;
+ }
+ if(c2==EOF && line != 0) /* close open last line */
+ return '\n';
+ /* new line */
+ if(c1=='\n') {
+ if(prev == c1) { /* duplicate newline */
+ if(line) {
+ line = 0;
+ return '\n'; /* output two newline */
+ } else {
+ line = 0;
+ return 1;
+ }
+ } else {
+ if(prev&0x80) { /* Japanese? */
+ prev = c1;
+ return 0; /* ignore given single newline */
+ } else if(prev==' ') {
+ return 0;
+ } else {
+ prev = c1;
+ if(++line<=fold_len)
+ return ' ';
+ else {
+ line = 0;
+ return '\r'; /* fold and output nothing */
+ }
+ }
+ }
+ }
+ if(c1=='\f') {
+ prev = '\n';
+ if(line==0)
+ return 1;
+ line = 0;
+ return '\n'; /* output newline and clear */
+ }
+ /* X0208 kankaku or ascii space */
+ if( (c2==0&&c1==' ')||
+ (c2==0&&c1=='\t')||
+ (c2==DOUBLE_SPACE)||
+ (c2=='!'&& c1=='!')) {
+ if(prev == ' ') {
+ return 0; /* remove duplicate spaces */
+ }
+ prev = ' ';
+ if(++line<=fold_len)
+ return ' '; /* output ASCII space only */
+ else {
+ prev = ' '; line = 0;
+ return '\r'; /* fold and output nothing */
+ }
+ }
+ prev0 = prev; /* we still need this one... , but almost done */
+ prev = c1;
+ if(c2 || (SSP<=c1 && c1<=0xdf))
+ prev |= 0x80; /* this is Japanese */
+ line += (c2==0)?1:2;
+ if(line<=fold_len) { /* normal case */
+ return 1;
+ }
+ if(line>=fold_len+FOLD_MARGIN) { /* too many kinsou suspension */
+ line = (c2==0)?1:2;
+ return '\n'; /* We can't wait, do fold now */
+ }
+ /* simple kinsoku rules return 1 means no folding */
+ if(c2==0) {
+ if(c1==0xde) return 1; /* $B!+(B*/
+ if(c1==0xdf) return 1; /* $B!,(B*/
+ if(c1==0xa4) return 1; /* $B!#(B*/
+ if(c1==0xa3) return 1; /* $B!$(B*/
+ if(c1==0xa1) return 1; /* $B!W(B*/
+ if(c1==0xb0) return 1; /* - */
+ if(SSP<=c1 && c1<=0xdf) { /* X0201 */
+ line = 1;
+ return '\n';/* add one new line before this character */
+ }
+ /* fold point in ASCII { [ ( */
+ if(( c1!=')'&&
+ c1!=']'&&
+ c1!='}'&&
+ c1!='.'&&
+ c1!=','&&
+ c1!='!'&&
+ c1!='?'&&
+ c1!='/'&&
+ c1!=':'&&
+ c1!=';')&&
+ ((prev0=='\n')|| (prev0==' ')|| /* ignored new line */
+ (prev0&0x80)) /* X0208 - ASCII */
+ ) {
+ line = 1;
+ return '\n';/* add one new line before this character */
+ }
+ return 1; /* default no fold in ASCII */
+ } else {
+ if(c2=='!') {
+ if(c1=='"') return 1; /* $B!"(B */
+ if(c1=='#') return 1; /* $B!#(B */
+ if(c1=='$') return 1; /* $B!$(B */
+ if(c1=='%') return 1; /* $B!%(B */
+ if(c1=='\'') return 1; /* $B!\(B */
+ if(c1=='(') return 1; /* $B!((B */
+ if(c1==')') return 1; /* $B!)(B */
+ if(c1=='*') return 1; /* $B!*(B */
+ if(c1=='+') return 1; /* $B!+(B */
+ if(c1==',') return 1; /* $B!,(B */
+ }
+ line = 2;
+ return '\n'; /* add one new line before this character */
+ }
+}
+
+int
+pre_convert(c1,c2)
+ int c1,c2;
+{
+ if(c2) c1 &= 0x7f;
+ c1_return = c1;
+ if(c2==EOF) return c2;
+ c2 &= 0x7f;
+ if(rot_f) {
+ if(c2) {
+ c1 = rot47(c1);
+ c2 = rot47(c2);
+ } else {
+ if(!(c1 & 0x80))
+ c1 = rot13(c1);
+ }
+ c1_return = c1;
+ }
+ /* JISX0208 Alphabet */
+ if(alpha_f && c2 == 0x23 ) return 0;
+ /* JISX0208 Kigou */
+ if(alpha_f && c2 == 0x21 ) {
+ if(0x21==c1) {
+ if(alpha_f&0x2) {
+ c1_return = ' ';
+ return 0;
+ } else if(alpha_f&0x4) {
+ c1_return = ' ';
+ return DOUBLE_SPACE;
+ } else {
+ return c2;
+ }
+ } else if(0x20<c1 && c1<0x7f && fv[c1-0x20]) {
+ c1_return = fv[c1-0x20];
+ return 0;
+ }
+ }
+ return c2;
+}
+
+
+#ifdef STRICT_MIME
+/* This converts */
+
+unsigned char *mime_pattern[] = {
+ (unsigned char *)"\075?ISO-8859-1?Q?",
+ (unsigned char *)"\075?ISO-2022-JP?B?",
+ (unsigned char *)"\075?ISO-2022-JP?Q?",
+ (unsigned char *)"\075?JAPANESE_EUC?B?",
+ (unsigned char *)"\075?SHIFT_JIS?B?",
+ NULL
+};
+
+int mime_encode[] = {
+ 'Q', 'B', 'Q',
+ 0
+};
+#endif
+
+#define MAXRECOVER 20
+int iso8859_f_save;
+
+#ifdef STRICT_MIME
+
+#define nkf_toupper(c) (('a'<=c && c<='z')?(c-('a'-'A')):c)
+/* I don't trust portablity of toupper */
+
+int
+mime_begin(f)
+ FILE *f;
+{
+ int c1;
+ int i,j,k;
+ unsigned char *p,*q;
+ int r[MAXRECOVER]; /* recovery buffer, max mime pattern lenght */
+
+ mime_mode = FALSE;
+ /* =? has been checked */
+ j = 0;
+ p = mime_pattern[j];
+ r[0]='='; r[1]='?';
+
+ for(i=2;p[i]>' ';i++) { /* start at =? */
+ if( ((((r[i] = c1 = getc(f))==EOF) || nkf_toupper(c1) != p[i] ) {
+ /* pattern fails, try next one */
+ q = p;
+ while (p = mime_pattern[++j]) {
+ for(k=2;k<i;k++) /* assume length(p) > i */
+ if(p[k]!=q[k]) break;
+ if(k==i && nkf_toupper(c1)==p[k]) break;
+ }
+ if(p) continue; /* found next one, continue */
+ /* all fails, output from recovery buffer */
+ ungetc(c1,f);
+ for(j=0;j<i;j++) {
+ (*oconv)(0,r[j]);
+ }
+ return c1;
+ }
+ }
+ mime_mode = mime_encode[j];
+ iso8859_f_save = iso8859_f;
+ if(j==0) {
+ iso8859_f = TRUE;
+ }
+ if(mime_mode=='B') {
+ mimebuf_f = unbuf_f;
+ if(!unbuf_f) {
+ /* do MIME integrity check */
+ return mime_integrity(f,mime_pattern[j]);
+ }
+ }
+ mimebuf_f = TRUE;
+ return c1;
+}
+
+#define mime_getc0(f) (mimebuf_f?getc(f):Fifo(mime_input++))
+#define mime_ungetc0(c,f) (mimebuf_f?ungetc(c,f):mime_input--)
+
+#else
+int
+mime_begin(f)
+FILE *f;
+{
+ int c1;
+ int i,j,k;
+ int r[MAXRECOVER]; /* recovery buffer, max mime pattern lenght */
+
+ mime_mode = FALSE;
+ /* =? has been checked */
+ j = 0;
+ r[0]='='; r[1]='?';
+ for(i=2;i<MAXRECOVER;i++) { /* start at =? */
+ /* We accept any charcter type even if it is breaked by new lines */
+ if( (r[i] = c1 = getc(f))==EOF) break;
+ if(c1=='=') break;
+ if(c1<' '&& c1!='\r' && c1!='\n') break;
+ if(c1=='?') {
+ i++;
+ if(!(i<MAXRECOVER) || (r[i] = c1 = getc(f))==EOF) break;
+ if(c1=='b'||c1=='B') {
+ mime_mode = 'B';
+ } else if(c1=='q'||c1=='Q') {
+ mime_mode = 'Q';
+ } else {
+ break;
+ }
+ i++;
+ if(!(i<MAXRECOVER) || (r[i] = c1 = getc(f))==EOF) break;
+ if(c1=='?') {
+ break;
+ } else {
+ mime_mode = FALSE;
+ }
+ break;
+ }
+ }
+ if(!mime_mode || c1==EOF || i==MAXRECOVER) {
+ ungetc(c1,f);
+ for(j=0;j<i;j++) {
+ (*oconv)(0,r[j]);
+ }
+ return c1;
+ }
+ iso8859_f_save = iso8859_f;
+ /* do no MIME integrity check */
+ return c1; /* used only for checking EOF */
+}
+
+#define mime_getc0(f) getc(f)
+#define mime_ungetc0(c,f) ungetc(c,f)
+
+#endif
+
+int
+mime_getc(f)
+ FILE *f;
+{
+ int c1, c2, c3, c4, cc;
+ int t1, t2, t3, t4, mode, exit_mode;
+
+ if(mime_top != mime_last) { /* Something is in FIFO */
+ return Fifo(mime_top++);
+ }
+
+ if(mimebuf_f == FIXED_MIME)
+ exit_mode = mime_mode;
+ else
+ exit_mode = FALSE;
+ if(mime_mode == 'Q') {
+ if((c1 = mime_getc0(f)) == EOF) return (EOF);
+ if(c1=='_') return ' ';
+ if(c1!='=' && c1!='?')
+ return c1;
+ mime_mode = exit_mode; /* prepare for quit */
+ if(c1<=' ') return c1;
+ if((c2 = mime_getc0(f)) == EOF) return (EOF);
+ if(c2<=' ') return c2;
+ if(c1=='?'&&c2=='=') {
+ /* end Q encoding */
+ input_mode = exit_mode;
+ iso8859_f = iso8859_f_save;
+ return getc(f);
+ }
+ if(c1=='?') {
+ mime_mode = 'Q'; /* still in MIME */
+ mime_ungetc0(c2,f);
+ return c1;
+ }
+ if((c3 = mime_getc0(f)) == EOF) return (EOF);
+ if(c2<=' ') return c2;
+ mime_mode = 'Q'; /* still in MIME */
+#define hex(c) (('0'<=c&&c<='9')?(c-'0'):\
+ ('A'<=c&&c<='F')?(c-'A'+10):('a'<=c&&c<='f')?(c-'a'+10):0)
+ return ((hex(c2)<<4) + hex(c3));
+ }
+
+ if(mime_mode != 'B') {
+ mime_mode = FALSE;
+ return getc(f);
+ }
+
+
+ /* Base64 encoding */
+ /*
+ MIME allows line break in the middle of
+ Base64, but we are very pessimistic in decoding
+ in unbuf mode because MIME encoded code may broken by
+ less or editor's control sequence (such as ESC-[-K in unbuffered
+ mode. ignore incomplete MIME.
+ */
+ mode = mime_mode;
+ mime_mode = exit_mode; /* prepare for quit */
+
+ while ((c1 = mime_getc0(f))<=' ') {
+ if(c1==EOF)
+ return (EOF);
+ }
+ if((c2 = mime_getc0(f))<=' ') {
+ if(c2==EOF)
+ return (EOF);
+ if(mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c2;
+ }
+ if((c1 == '?') && (c2 == '=')) {
+ input_mode = ASCII;
+ while((c1 = getc(f))==' ' /* || c1=='\n' || c1=='\r' */);
+ return c1;
+ }
+ if((c3 = mime_getc0(f))<=' ') {
+ if(c3==EOF)
+ return (EOF);
+ if(mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c3;
+ }
+ if((c4 = mime_getc0(f))<=' ') {
+ if(c4==EOF)
+ return (EOF);
+ if(mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c4;
+ }
+
+ mime_mode = mode; /* still in MIME sigh... */
+
+ /* BASE 64 decoding */
+
+ t1 = 0x3f & base64decode(c1);
+ t2 = 0x3f & base64decode(c2);
+ t3 = 0x3f & base64decode(c3);
+ t4 = 0x3f & base64decode(c4);
+ cc = ((t1 << 2) & 0x0fc) | ((t2 >> 4) & 0x03);
+ if(c2 != '=') {
+ Fifo(mime_last++) = cc;
+ cc = ((t2 << 4) & 0x0f0) | ((t3 >> 2) & 0x0f);
+ if(c3 != '=') {
+ Fifo(mime_last++) = cc;
+ cc = ((t3 << 6) & 0x0c0) | (t4 & 0x3f);
+ if(c4 != '=')
+ Fifo(mime_last++) = cc;
+ }
+ } else {
+ return c1;
+ }
+ return Fifo(mime_top++);
+}
+
+int
+mime_ungetc(c)
+ unsigned int c;
+{
+ Fifo(mime_last++) = c;
+ return c;
+}
+
+#ifdef STRICT_MIME
+int
+mime_integrity(f,p)
+ FILE *f;
+ unsigned char *p;
+{
+ int c,d;
+ unsigned int q;
+ /* In buffered mode, read until =? or NL or buffer fffull
+ */
+ mime_input = mime_top;
+ mime_last = mime_top;
+ while(*p) Fifo(mime_input++) = *p++;
+ d = 0;
+ q = mime_input;
+ while((c=getc(f))!=EOF) {
+ if(((mime_input-mime_top)&MIME_BUF_MASK)==0) break;
+ if(c=='=' && d=='?') {
+ /* checked. skip header, start decode */
+ Fifo(mime_input++) = c;
+ mime_input = q;
+ return 1;
+ }
+ if(!( (c=='+'||c=='/'|| c=='=' || c=='?' ||
+ ('a'<=c && c<='z')||('A'<= c && c<='Z')||('0'<=c && c<='9'))))
+ break;
+ /* Should we check length mod 4? */
+ Fifo(mime_input++) = c;
+ d=c;
+ }
+ /* In case of Incomplete MIME, no MIME decode */
+ Fifo(mime_input++) = c;
+ mime_last = mime_input; /* point undecoded buffer */
+ mime_mode = 1; /* no decode on Fifo last in mime_getc */
+ return 1;
+}
+#endif
+
+int
+base64decode(c)
+ int c;
+{
+ int i;
+ if(c > '@')
+ if(c < '[')
+ i = c - 'A'; /* A..Z 0-25 */
+ else
+ i = c - 'G' /* - 'a' + 26 */ ; /* a..z 26-51 */
+ else if(c > '/')
+ i = c - '0' + '4' /* - '0' + 52 */ ; /* 0..9 52-61 */
+ else if(c == '+')
+ i = '>' /* 62 */ ; /* + 62 */
+ else
+ i = '?' /* 63 */ ; /* / 63 */
+ return (i);
+}
+
+void
+reinit()
+{
+ unbuf_f = FALSE;
+ estab_f = FALSE;
+ nop_f = FALSE;
+ binmode_f = TRUE;
+ rot_f = FALSE;
+ input_f = FALSE;
+ alpha_f = FALSE;
+ mime_f = TRUE;
+ mimebuf_f = FALSE;
+ broken_f = FALSE;
+ iso8859_f = FALSE;
+ x0201_f = TRUE;
+ x0201_f = NO_X0201;
+ fold_f = FALSE;
+ kanji_intro = DEFAULT_J;
+ ascii_intro = DEFAULT_R;
+ oconv = DEFAULT_CONV;
+ output_mode = ASCII;
+ input_mode = ASCII;
+ shift_mode = FALSE;
+ mime_mode = FALSE;
+ file_out = FALSE;
+ add_cr = FALSE;
+ del_cr = FALSE;
+}
+
+#ifndef PERL_XS
+int
+usage()
+{
+ fprintf(stderr,"USAGE: nkf(nkf32,wnkf,nkf2) -[flags] [in file] .. [out file for -O flag]\n");
+ fprintf(stderr,"Flags:\n");
+ fprintf(stderr,"b,u Output is bufferred (DEFAULT),Output is unbufferred\n");
+#ifdef DEFAULT_CODE_SJIS
+ fprintf(stderr,"j,s,e Outout code is JIS 7 bit, Shift JIS (DEFAULT), AT&T JIS (EUC)\n");
+#endif
+#ifdef DEFAULT_CODE_JIS
+ fprintf(stderr,"j,s,e Outout code is JIS 7 bit (DEFAULT), Shift JIS, AT&T JIS (EUC)\n");
+#endif
+#ifdef DEFAULT_CODE_EUC
+ fprintf(stderr,"j,s,e Outout code is JIS 7 bit, Shift JIS, AT&T JIS (EUC) (DEFAULT)\n");
+#endif
+ fprintf(stderr,"J,S,E Input assumption is JIS 7 bit , Shift JIS, AT&T JIS (EUC)\n");
+ fprintf(stderr,"t no conversion\n");
+ fprintf(stderr,"i_ Output sequence to designate JIS-kanji (DEFAULT B)\n");
+ fprintf(stderr,"o_ Output sequence to designate ASCII (DEFAULT B)\n");
+ fprintf(stderr,"r {de/en}crypt ROT13/47\n");
+ fprintf(stderr,"v Show this usage\n");
+ fprintf(stderr,"m[BQ0] MIME decode [B:base64,Q:quoted,0:no decode]\n");
+ fprintf(stderr,"l ISO8859-1 (Latin-1) support\n");
+ fprintf(stderr,"f Folding: -f60 or -f\n");
+ fprintf(stderr,"Z[0-2] Convert X0208 alphabet to ASCII 1: Kankaku to space,2: 2 spaces\n");
+ fprintf(stderr,"X,x Assume X0201 kana in MS-Kanji, -x preserves X0201\n");
+ fprintf(stderr,"B[0-2] Broken input 0: missing ESC,1: any X on ESC-[($]-X,2: ASCII on NL\n");
+#ifdef MSDOS
+ fprintf(stderr,"T Text mode output\n");
+#endif
+ fprintf(stderr,"O Output to File (DEFAULT 'nkf.out')\n");
+ fprintf(stderr,"d,c Delete \\r in line feed, Add \\r in line feed\n");
+ fprintf(stderr,"Network Kanji Filter Version %s (%s) "
+#if defined(MSDOS) && !defined(_Windows)
+ "for DOS"
+#endif
+#if !defined(__WIN32__) && defined(_Windows)
+ "for Win16"
+#endif
+#if defined(__WIN32__) && defined(_Windows)
+ "for Win32"
+#endif
+#ifdef __OS2__
+ "for OS/2"
+#endif
+ ,Version,Patchlevel);
+ fprintf(stderr,"\n%s\n",CopyRight);
+ return 0;
+}
+#endif
+
+/**
+ ** $B%Q%C%A@):n<T(B
+ ** void@merope.pleiades.or.jp (Kusakabe Youichi)
+ ** NIDE Naoyuki <nide@ics.nara-wu.ac.jp>
+ ** ohta@src.ricoh.co.jp (Junn Ohta)
+ ** inouet@strl.nhk.or.jp (Tomoyuki Inoue)
+ ** kiri@pulser.win.or.jp (Tetsuaki Kiriyama)
+ ** Kimihiko Sato <sato@sail.t.u-tokyo.ac.jp>
+ ** a_kuroe@kuroe.aoba.yokohama.jp (Akihiko Kuroe)
+ ** kono@ie.u-ryukyu.ac.jp (Shinji Kono)
+ ** GHG00637@nifty-serve.or.jp (COW)
+ **
+ ** $B:G=*99?7F|(B
+ ** 1998.11.7
+ **/
+
+/* end */
diff --git a/ext/nkf/test.rb b/ext/nkf/test.rb
new file mode 100644
index 0000000000..4519f8ba7e
--- /dev/null
+++ b/ext/nkf/test.rb
@@ -0,0 +1,318 @@
+$counter = 0
+def result(result, message = nil)
+ $counter += 1
+ printf("%s %d%s\n",
+ result ? 'ok' : 'no',
+ $counter,
+ message ? ' ... ' + message : '')
+end
+
+begin
+ require 'nkf'
+ include NKF
+rescue LoadError
+ result(false)
+end
+result(true)
+
+if nkf('-me', '1')
+ result(true);
+else
+ result(false);
+end
+
+output = nkf('-e', "\033\$@#1#3#2%B")
+if output
+ # print output, "\n"
+ result(true, output)
+else
+ result(false)
+end
+
+output = nkf('-Zj', "\033\$@#1#3#2%B")
+if output
+ # print output, "\n"
+ result(true, output)
+else
+ result(false)
+end
+
+output = "\244\306 " * 1024
+old = output.length
+output = nkf("-j", output)
+if output
+ # print output, "\n"
+ result(true, "#{old} #{output.length}")
+else
+ result(false)
+end
+
+
+$detail = false
+def test(opt, input, expect)
+ print "\nINPUT:\n", input if $detail
+ print "\nEXPECT:\n", expect if $detail
+ result = nkf(opt, input)
+ print "\nGOT:\n", result if $detail
+
+ print result == expect ? "Ok\n" : "Fail\n"
+ return result
+end
+
+# Basic Conversion
+print "\nBasic Conversion test\n\n"
+
+example = {}
+example['jis'] = <<'eofeof'.unpack('u')[0]
+M1FER<W0@4W1A9V4@&R1"(3DQ(3%^2R%+?D]3&RA"(%-E8V]N9"!3=&%G92`;
+M)$)0)TU:&RA"($AI<F%G86YA(!LD0B0B)"0D)B0H)"HD;R1R)',;*$(*2V%T
+M86MA;F$@&R1")2(E)"4F)2@E*B5O)7(E<QLH0B!+:6=O=2`;)$(A)B%G(S`C
+/029!)E@G(B=!*$`;*$(*
+eofeof
+#'
+
+example['sjis'] = <<'eofeof'.unpack('u')[0]
+M1FER<W0@4W1A9V4@@5B)0(F>ED"6GIAR(%-E8V]N9"!3=&%G92"8I9=Y($AI
+M<F%G86YA((*@@J*"I(*F@JB"[8+P@O$*2V%T86MA;F$@@T&#0X-%@T>#28./
+>@Y*#DR!+:6=O=2"!18&'@D^"8(._@]:$081@A+X*
+eofeof
+#'
+
+example['euc'] = <<'eofeof'.unpack('u')[0]
+M1FER<W0@4W1A9V4@H;FQH;'^RZ'+_L_3(%-E8V]N9"!3=&%G92#0I\W:($AI
+M<F%G86YA(*2BI*2DIJ2HI*JD[Z3RI/,*2V%T86MA;F$@I:*EI*6FI:BEJJ7O
+>I?*E\R!+:6=O=2"AIJ'GH["CP:;!IMBGHJ?!J,`*
+eofeof
+#'
+
+example['amb'] = <<'eofeof'.unpack('u')[0]
+MI<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"QI<*PL:7"L+&E
+MPK"QI<*PL:7"L+&EPK"QI<(*I<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"QI<*P
+ML:7"L+&EPK"QI<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"QI<(*I<*PL:7"L+&E
+MPK"QI<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"QI<*PL:7"
+ML+&EPK"QI<(*I<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"Q
+MI<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"QI<(*I<*PL:7"L+&EPK"QI<*PL:7"
+ML+&EPK"QI<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"QI<*PL:7"L+&EPK"QI<(*
+eofeof
+
+example['amb.euc'] = <<'eofeof'.unpack('u')[0]
+M&R1")4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25"
+M,#$E0C`Q)4(P,25",#$E0C`Q)4(;*$(*&R1")4(P,25",#$E0C`Q)4(P,25"
+M,#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(;
+M*$(*&R1")4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P
+M,25",#$E0C`Q)4(P,25",#$E0C`Q)4(;*$(*&R1")4(P,25",#$E0C`Q)4(P
+M,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q
+M)4(;*$(*&R1")4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q
+>)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(;*$(*
+eofeof
+
+example['amb.sjis'] = <<'eofeof'.unpack('u')[0]
+M&RA))4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25"
+M,#$E0C`Q)4(P,25",#$E0C`Q)4(;*$(*&RA))4(P,25",#$E0C`Q)4(P,25"
+M,#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(;
+M*$(*&RA))4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P
+M,25",#$E0C`Q)4(P,25",#$E0C`Q)4(;*$(*&RA))4(P,25",#$E0C`Q)4(P
+M,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q
+M)4(;*$(*&RA))4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q
+>)4(P,25",#$E0C`Q)4(P,25",#$E0C`Q)4(;*$(*
+eofeof
+
+example['x0201.sjis'] = <<'eofeof'.unpack('u')[0]
+MD5.*<(-*@TR#3H-0@U*#2X--@T^#48-3"I%3B7""8()A@F*"8X)D@F6"9H*!
+M@H*"@X*$@H6"AH*'"I%3BTR-AH%)@9>!E(&0@9.!3X&5@9:!:8%J@7R!>X&!
+M@6V!;H%O@7"!CPJ4O(IPMK>X/;FZMMZWWKC>N=ZZWH+&"I2\BG#*W\O?S-_-
+MW\[?M]^QW@K*W\O?S`IH86YK86MU(,K?R]_,I`K*W\O?S-VA"I2\BG""S(SC
+!"@!"
+eofeof
+#'
+
+example['x0201.euc'] = <<'eofeof'.unpack('u')[0]
+MP;2ST:6KI:VEKZ6QI;.EK*6NI;"ELJ6T"L&TL=&CP:/"H\.CQ*/%H\:CQZ/A
+MH^*CXZ/DH^6CYJ/G"L&TM:VYYJ&JH?>A]*'PH?.AL*'UH?:ARJ'+H=VAW*'A
+MH<ZASZ'0H=&A[PK(OK/1CK:.MXZX/8ZYCKJ.MH[>CK>.WHZXCMZ.N8[>CKJ.
+MWJ3("LB^L]&.RH[?CLN.WX[,CM^.S8[?CLZ.WXZWCM^.L8[>"H[*CM^.RX[?
+MCLP*:&%N:V%K=2".RH[?CLN.WX[,CJ0*CLJ.WX[+CM^.S([=CJ$*R+ZST:3.
+#N.4*
+eofeof
+#'
+
+example['x0201.jis'] = <<'eofeof'.unpack('u')[0]
+M&R1"030S424K)2TE+R4Q)3,E+"4N)3`E,B4T&RA""ALD0D$T,5$C02-"(T,C
+M1"-%(T8C1R-A(V(C8R-D(V4C9B-G&RA""ALD0D$T-2TY9B$J(7<A="%P(7,A
+M,"%U(78A2B%+(5TA7"%A(4XA3R%0(5$A;QLH0@H;)$)(/C-1&RA)-C<X&RA"
+M/1LH23DZ-EXW7CA>.5XZ7ALD0B1(&RA""ALD0D@^,U$;*$E*7TM?3%]-7TY?
+M-U\Q7ALH0@H;*$E*7TM?3!LH0@IH86YK86MU(!LH24I?2U],)!LH0@H;*$E*
+97TM?3%TA&RA""ALD0D@^,U$D3CAE&RA""@``
+eofeof
+#`
+
+example['x0201.sosi'] = <<'eofeof'.unpack('u')[0]
+M&R1"030S424K)2TE+R4Q)3,E+"4N)3`E,B4T&RA*"ALD0D$T,5$C02-"(T,C
+M1"-%(T8C1R-A(V(C8R-D(V4C9B-G&RA*"ALD0D$T-2TY9B$J(7<A="%P(7,A
+M,"%U(78A2B%+(5TA7"%A(4XA3R%0(5$A;QLH2@H;)$)(/C-1&RA*#C8W.`\;
+M*$H]#CDZ-EXW7CA>.5XZ7@\;)$(D2!LH2@H;)$)(/C-1&RA*#DI?2U],7TU?
+M3E\W7S%>#PH.2E]+7TP/&RA*"FAA;FMA:W4@#DI?2U],)`\;*$H*#DI?2U],
+672$/&RA*"ALD0D@^,U$D3CAE&RA""@``
+eofeof
+#"
+
+example['x0201.x0208'] = <<'eofeof'.unpack('u')[0]
+M&R1"030S424K)2TE+R4Q)3,E+"4N)3`E,B4T&RA""ALD0D$T,5$;*$)!0D-$
+M149'86)C9&5F9PH;)$)!-#4M.68;*$(A0",D)5XF*B@I+2L]6UU[?1LD0B%O
+M&RA""ALD0D@^,U$E*R4M)2\;*$(]&R1")3$E,R4L)2XE,"4R)30D2!LH0@H;
+M)$)(/C-1)5$E5"57)5HE724M(2PE(B$K&RA""ALD0B51)50E51LH0@IH86YK
+M86MU(!LD0B51)50E52$B&RA""ALD0B51)50E525S(2,;*$(*&R1"2#XS421.
+&.&4;*$(*
+eofeof
+#`
+
+example['mime.iso2022'] = <<'eofeof'.unpack('u')[0]
+M/3])4T\M,C`R,BU*4#]"/T=Y4D%.144W96E23TI566Q/4U9)1WEH2S\]"CT_
+M:7-O+3(P,C(M2E`_0C]'>5)!3D5%-V5I4D]*55EL3U-624=Y:$L_/0H]/VES
+M;RTR,#(R+4I0/U$_/3%")$(D1B11/3%"*$)?96YD/ST*&R1`)#TD)B0K)$H;
+M*$H@/3])4T\M,C`R,BU*4#]"/T=Y4D%.144W96E23U!Y:S=D:'-O4V<]/3\]
+M(&5N9"!O9B!L:6YE"CT_25-/+3(P,C(M2E`_0C]'>5)!3D5%-V5I4D]0>6LW
+M9&AS;U-G/3T_/2`]/TE33RTR,#(R+4I0/T(_1WE204Y%13=E:5)/4'EK-V1H
+M<V]39ST]/ST*0G)O:V5N(&-A<V4*/3])4T\M,C`R,BU*4#]"/T=Y4D%.144W
+M96E23U!Y:S=D"FAS;U-G/3T_/2`]/TE33RTR,`HR,BU*4#]"/T=Y4D%.144W
+M96E23U!Y:S=D:'-O4V<]/3\]"CT_25-/+3(P,C(M2E`_0C]'>5)!3D5%-V5I
+44D]*55EL3QM;2U-624=Y:$L_/0H_
+eofeof
+#'
+
+example['mime.ans.strict'] = <<'eofeof'.unpack('u')[0]
+M&R1"-$$[>B1.)48E.25(&RA""ALD0C1!.WHD3B5&)3DE2!LH0@H;)$(D1B11
+M&RA"(&5N9`H;)$(D/20F)"LD2ALH0B`;)$(T03MZ)$X_*3MV&RA"96YD(&]F
+M(&QI;F4*&R1"-$$[>B1./RD[=C1!.WHD3C\I.W8;*$(*0G)O:V5N(&-A<V4*
+M/3])4T\M,C`R,BU*4#]"/T=Y4D%.144W96E23U!Y:S=D"FAS;U-G/3T_/2`]
+M/TE33RTR,`HR,BU*4#]"/T=Y4D%.144W96E23U!Y:S=D:'-O4V<]/3\]"CT_
+L25-/+3(P,C(M2E`_0C]'>5)!3D5%-V5I4D]*55EL3QM;2U-624=Y:$L_/0H_
+eofeof
+#'
+
+example['mime.unbuf.strict'] = <<'eofeof'.unpack('u')[0]
+M&R1"-$$[>B1.)48E.25(&RA""ALD0C1!.WHD3B5&)3DE2!LH0@H;)$(D1B11
+M&RA"(&5N9`H;)$(D/20F)"LD2ALH0B`;)$(T03MZ)$X_*3MV&RA"96YD(&]F
+M(&QI;F4*&R1"-$$[>B1./RD[=C1!.WHD3C\I.W8;*$(*0G)O:V5N(&-A<V4*
+M&R1"-$$[>B1./RD;*$)H<V]39ST]/ST@/3])4T\M,C`*,C(M2E`_0C]'>5)!
+M3D5%-V5I4D]0>6LW9&AS;U-G/3T_/0H;)$(T03MZ)$XE1ALH0EM+4U9)1WEH
+$2S\]"F5I
+eofeof
+
+example['mime.ans'] = <<'eofeof'.unpack('u')[0]
+M&R1"-$$[>B1.)48E.25(&RA""ALD0C1!.WHD3B5&)3DE2!LH0@H;)$(D1B11
+M&RA"(&5N9`H;)$(D/20F)"LD2ALH0B`;)$(T03MZ)$X_*3MV&RA"96YD(&]F
+M(&QI;F4*&R1"-$$[>B1./RD[=C1!.WHD3C\I.W8;*$(*0G)O:V5N(&-A<V4*
+M&R1"-$$[>B1./RD;*$)H<V]39ST]/ST@&R1"-$$[>B1./RD[=ALH0@H;)$(T
+603MZ)$XE1ALH0EM+4U9)1WEH2S\]"@`*
+eofeof
+#"
+
+example['mime.unbuf'] = <<'eofeof'.unpack('u')[0]
+M&R1"-$$[>B1.)48E.25(&RA""ALD0C1!.WHD3B5&)3DE2!LH0@H;)$(D1B11
+M&RA"(&5N9`H;)$(D/20F)"LD2ALH0B`;)$(T03MZ)$X_*3MV&RA"96YD(&]F
+M(&QI;F4*&R1"-$$[>B1./RD[=C1!.WHD3C\I.W8;*$(*0G)O:V5N(&-A<V4*
+M&R1"-$$[>B1./RD;*$)H<V]39ST]/ST@&R1"-$$[>B1./RD[=ALH0@H;)$(T
+603MZ)$XE1ALH0EM+4U9)1WEH2S\]"@`*
+eofeof
+#"
+
+example['mime.base64'] = <<'eofeof'.unpack('u')[0]
+M9W-M5"])3&YG<FU#>$I+-&=Q=4,S24LS9W%Q0E%:3TUI-39,,S0Q-&=S5T)1
+M43!+9VUA1%9O3T@*9S)+1%1O3'=K8C)1;$E+;V=Q2T-X24MG9W5M0W%*3EEG
+<<T=#>$E+9V=U;4,X64Q&9W)70S592VMG<6U""F=Q
+eofeof
+#"
+
+example['mime.base64.ans'] = <<'eofeof'.unpack('u')[0]
+M&R1")$M&?B1I)#LD1D0Z)"TD7B0Y)"PA(D5L-7XV83E9)$<A(ALH0@T*&R1"
+M(T<E-R5G)4,E+R1R0C\_="0J)"0D1B0B)&LD*D4Y)$,D1B0B)&LD<R1')#<D
+(9R0F)"L;*$(E
+eofeof
+#'
+
+example['mime.is8859'] = <<'eofeof'.unpack('u')[0]
+M/3])4T\M.#@U.2TQ/U$_*CU#-V%V83\_/2`*4&5E<B!4]G)N9W)E;@I,87-S
+M92!(:6QL97+X92!0971E<G-E;B`@7"`B36EN(&MA97!H97-T(&AA<B!F86%E
+M="!E="!F;V5L(2(*06%R:'5S(%5N:79E<G-I='DL($1%3DU!4DL@(%P@(DUI
+<;B!KYG!H97-T(&AA<B!FY65T(&5T(&;X;"$B"@!K
+eofeof
+
+example['mime.is8859.ans'] = <<'eofeof'.unpack('u')[0]
+M*L=A=F$_(`I0965R(%3V<FYG<F5N"DQA<W-E($AI;&QE<OAE(%!E=&5R<V5N
+M("!<(")-:6X@:V%E<&AE<W0@:&%R(&9A865T(&5T(&9O96PA(@I!87)H=7,@
+M56YI=F5R<VET>2P@1$5.34%22R`@7"`B36EN(&OF<&AE<W0@:&%R(&;E970@
+)970@9OAL(2(*
+eofeof
+#"
+
+print 'JIS to JIS ... '; test(' ', example['jis'], example['jis'])
+print 'JIS to SJIS... '; test('-s', example['jis'], example['sjis'])
+print 'JIS to EUC ... '; test('-e', example['jis'], example['euc'])
+
+print 'SJIS to JIS ... '; test('-j', example['sjis'], example['jis'])
+print 'SJIS to SJIS... '; test('-s', example['sjis'], example['sjis'])
+print 'SJIS to EUC ... '; test('-e', example['sjis'], example['euc'])
+
+print 'EUC to JIS ... '; test(' ', example['euc'], example['jis'])
+print 'EUC to SJIS... '; test('-s', example['euc'], example['sjis'])
+print 'EUC to EUC ... '; test('-e', example['euc'], example['euc'])
+
+
+# Ambigous Case
+print 'Ambiguous Case. '; test('' , example['amb'], example['amb.euc'])
+
+# Input assumption
+print 'SJIS Input assumption '
+test('-Sx', example['amb'], example['amb.sjis'])
+
+# X0201 仮名
+# X0201->X0208 conversion
+# X0208 aphabet -> ASCII
+# X0201 相互変換
+
+print "\nX0201 test\n\n"
+
+# -X is necessary to allow X0201 in SJIS
+# -Z convert X0208 alphabet to ASCII
+print 'X0201 conversion: SJIS '
+test('-XZ', example['x0201.sjis'], example['x0201.x0208'])
+print 'X0201 conversion: JIS '
+test('-Z', example['x0201.jis'], example['x0201.x0208'])
+print 'X0201 conversion:SI/SO '
+test('-Z', example['x0201.sosi'], example['x0201.x0208'])
+print 'X0201 conversion: EUC '
+test('-Z', example['x0201.euc'], example['x0201.x0208'])
+# -x means X0201 output
+print 'X0201 output: SJIS '
+test('-xs', example['x0201.euc'], example['x0201.sjis'])
+print 'X0201 output: JIS '
+test('-xj', example['x0201.sjis'], example['x0201.jis'])
+print 'X0201 output: EUC '
+test('-xe', example['x0201.jis'], example['x0201.euc'])
+
+# MIME decode
+
+print "\nMIME test\n\n"
+
+# MIME ISO-2022-JP
+
+print "Next test is expeced to Fail.\n"
+
+print 'MIME decode (strict) '
+tmp = test('-m', example['mime.iso2022'], example['mime.ans.strict'])
+print 'MIME decode (nonstrict)'
+tmp = test('-m', example['mime.iso2022'], example['mime.ans'])
+# open(OUT,'>tmp1');print OUT pack('u',$tmp);close(OUT);
+# unbuf mode implies more pessimistic decode
+print 'MIME decode (unbuf) '
+test('-mu', example['mime.iso2022'], example['mime.unbuf'])
+print 'MIME decode (base64) '
+t = test('-mB', example['mime.base64'], example['mime.base64.ans'])
+
+# MIME ISO-8859-1
+
+# Without -l, ISO-8859-1 was handled as X0201.
+
+print 'MIME ISO-8859-1 (Q) '
+test('-ml', example['mime.is8859'], example['mime.is8859.ans'])
diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb
index bd896639fc..8fc57f307e 100644
--- a/ext/tk/lib/tk.rb
+++ b/ext/tk/lib/tk.rb
@@ -579,6 +579,7 @@ module Tk
end
module Wm
+ include TkComm
def aspect(*args)
w = window(tk_call('wm', 'grid', path, *args))
w.split.collect{|s|s.to_i} if args.length == 0
diff --git a/file.c b/file.c
index 92d9c76158..8591023d08 100644
--- a/file.c
+++ b/file.c
@@ -28,6 +28,7 @@
# define MAXPATHLEN 1024
#endif
+#include <time.h>
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#else
@@ -39,6 +40,8 @@ struct timeval {
#endif /* NT */
#endif
+VALUE rb_time_new _((time_t, time_t));
+
#ifdef HAVE_UTIME_H
#include <utime.h>
#endif
diff --git a/fnmatch.c b/fnmatch.c
deleted file mode 100644
index f031749c3d..0000000000
--- a/fnmatch.c
+++ /dev/null
@@ -1,243 +0,0 @@
-/* Copyright (C) 1991 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#include "config.h"
-#include <errno.h>
-#include "fnmatch.h"
-
-#ifdef USE_CWGUSI
-#include <sys/errno.h>
-#endif
-
-#if !defined (__GNU_LIBRARY__) && !defined (STDC_HEADERS)
-# if !defined (errno)
-extern int errno;
-# endif /* !errno */
-#endif
-
-/* Match STRING against the filename pattern PATTERN, returning zero if
- it matches, FNM_NOMATCH if not. */
-int
-fnmatch (pattern, string, flags)
- char *pattern;
- char *string;
- int flags;
-{
- register char *p = pattern, *n = string;
- register char c;
-
- if ((flags & ~__FNM_FLAGS) != 0)
- {
- errno = EINVAL;
- return (-1);
- }
-
- while ((c = *p++) != '\0')
- {
- switch (c)
- {
- case '?':
- if (*n == '\0')
- return (FNM_NOMATCH);
- else if ((flags & FNM_PATHNAME) && *n == '/')
- /* If we are matching a pathname, `?' can never match a `/'. */
- return (FNM_NOMATCH);
- else if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
- /* `?' cannot match a `.' if it is the first character of the
- string or if it is the first character following a slash and
- we are matching a pathname. */
- return (FNM_NOMATCH);
- break;
-
- case '\\':
- if (!(flags & FNM_NOESCAPE))
- {
- c = *p++;
- if (c == '\0')
- return (FNM_NOMATCH);
- }
- if (*n != c)
- return (FNM_NOMATCH);
- break;
-
- case '*':
- if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
- /* `*' cannot match a `.' if it is the first character of the
- string or if it is the first character following a slash and
- we are matching a pathname. */
- return (FNM_NOMATCH);
-
- /* Collapse multiple consecutive, `*' and `?', but make sure that
- one character of the string is consumed for each `?'. */
- for (c = *p++; c == '?' || c == '*'; c = *p++)
- {
- if ((flags & FNM_PATHNAME) && *n == '/')
- /* A slash does not match a wildcard under FNM_PATHNAME. */
- return (FNM_NOMATCH);
- else if (c == '?')
- {
- if (*n == '\0')
- return (FNM_NOMATCH);
- /* One character of the string is consumed in matching
- this ? wildcard, so *??? won't match if there are
- fewer than three characters. */
- n++;
- }
- }
-
- if (c == '\0')
- return (0);
-
- /* General case, use recursion. */
- {
- char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
- for (--p; *n != '\0'; ++n)
- /* Only call fnmatch if the first character indicates a
- possible match. */
- if ((c == '[' || *n == c1) &&
- fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
- return (0);
- return (FNM_NOMATCH);
- }
-
- case '[':
- {
- /* Nonzero if the sense of the character class is inverted. */
- register int not;
-
- if (*n == '\0')
- return (FNM_NOMATCH);
-
- /* A character class cannot match a `.' if it is the first
- character of the string or if it is the first character
- following a slash and we are matching a pathname. */
- if ((flags & FNM_PERIOD) && *n == '.' &&
- (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
- return (FNM_NOMATCH);
-
- /* POSIX.2 2.8.3.1.2 says: `An expression containing a `[' that
- is not preceded by a backslash and is not part of a bracket
- expression produces undefined results.' This implementation
- treats the `[' as just a character to be matched if there is
- not a closing `]'. This code will have to be changed when
- POSIX.2 character classes are implemented. */
- {
- register char *np;
-
- for (np = p; np && *np && *np != ']'; np++)
- ;
-
- if (np && !*np)
- {
- if (*n != '[')
- return (FNM_NOMATCH);
- break;
- }
- }
-
- not = (*p == '!' || *p == '^');
- if (not)
- ++p;
-
- c = *p++;
- for (;;)
- {
- register char cstart, cend;
-
- /* Initialize cstart and cend in case `-' is the last
- character of the pattern. */
- cstart = cend = c;
-
- if (!(flags & FNM_NOESCAPE) && c == '\\')
- {
- if (*p == '\0')
- return FNM_NOMATCH;
- cstart = cend = *p++;
- }
-
- if (c == '\0')
- /* [ (unterminated) loses. */
- return (FNM_NOMATCH);
-
- c = *p++;
-
- if ((flags & FNM_PATHNAME) && c == '/')
- /* [/] can never match. */
- return (FNM_NOMATCH);
-
- /* This introduces a range, unless the `-' is the last
- character of the class. Find the end of the range
- and move past it. */
- if (c == '-' && *p != ']')
- {
- cend = *p++;
- if (!(flags & FNM_NOESCAPE) && cend == '\\')
- cend = *p++;
- if (cend == '\0')
- return (FNM_NOMATCH);
-
- c = *p++;
- }
-
- if (*n >= cstart && *n <= cend)
- goto matched;
-
- if (c == ']')
- break;
- }
- if (!not)
- return (FNM_NOMATCH);
- break;
-
- matched:
- /* Skip the rest of the [...] that already matched. */
- while (c != ']')
- {
- if (c == '\0')
- /* [... (unterminated) loses. */
- return (FNM_NOMATCH);
-
- c = *p++;
- if (!(flags & FNM_NOESCAPE) && c == '\\')
- {
- if (*p == '\0')
- return FNM_NOMATCH;
- /* XXX 1003.2d11 is unclear if this is right. */
- ++p;
- }
- }
- if (not)
- return (FNM_NOMATCH);
- }
- break;
-
- default:
- if (c != *n)
- return (FNM_NOMATCH);
- }
-
- ++n;
- }
-
- if (*n == '\0')
- return (0);
-
- return (FNM_NOMATCH);
-}
diff --git a/fnmatch.h b/fnmatch.h
deleted file mode 100644
index 62c8c8fa02..0000000000
--- a/fnmatch.h
+++ /dev/null
@@ -1,36 +0,0 @@
-/* Copyright (C) 1991 Free Software Foundation, Inc.
-This file is part of the GNU C Library.
-
-The GNU C Library is free software; you can redistribute it and/or
-modify it under the terms of the GNU Library General Public License as
-published by the Free Software Foundation; either version 2 of the
-License, or (at your option) any later version.
-
-The GNU C Library 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
-Library General Public License for more details.
-
-You should have received a copy of the GNU Library General Public
-License along with the GNU C Library; see the file COPYING.LIB. If
-not, write to the Free Software Foundation, Inc., 675 Mass Ave,
-Cambridge, MA 02139, USA. */
-
-#ifndef _FNMATCH_H
-
-#define _FNMATCH_H 1
-
-/* Bits set in the FLAGS argument to `fnmatch'. */
-#define FNM_PATHNAME (1 << 0)/* No wildcard can ever match `/'. */
-#define FNM_NOESCAPE (1 << 1)/* Backslashes don't quote special chars. */
-#define FNM_PERIOD (1 << 2)/* Leading `.' is matched only explicitly. */
-#define __FNM_FLAGS (FNM_PATHNAME|FNM_NOESCAPE|FNM_PERIOD)
-
-/* Value returned by `fnmatch' if STRING does not match PATTERN. */
-#define FNM_NOMATCH 1
-
-/* Match STRING against the filename pattern PATTERN,
- returning zero if it matches, FNM_NOMATCH if not. */
-extern int fnmatch();
-
-#endif /* fnmatch.h */
diff --git a/hash.c b/hash.c
index 5cd7af2551..66bf6e7308 100644
--- a/hash.c
+++ b/hash.c
@@ -12,6 +12,7 @@
#include "ruby.h"
#include "st.h"
+#include "util.h"
#include "rubysig.h"
#include <sys/types.h>
@@ -131,7 +132,7 @@ rb_hash_foreach_iter(key, value, arg)
st_table *tbl = RHASH(arg->hash)->tbl;
struct st_table_entry **bins = tbl->bins;
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
status = (*arg->func)(key, value, arg->arg);
if (RHASH(arg->hash)->tbl != tbl || RHASH(arg->hash)->tbl->bins != bins){
rb_raise(rb_eIndexError, "rehash occurred during iteration");
@@ -432,7 +433,7 @@ shift_i(key, value, var)
VALUE key, value;
struct shift_var *var;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
if (var->stop) return ST_STOP;
var->stop = 1;
var->key = key;
@@ -458,7 +459,7 @@ static int
delete_if_i(key, value)
VALUE key, value;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
if (RTEST(rb_yield(rb_assoc_new(key, value))))
return ST_DELETE;
return ST_CONTINUE;
@@ -548,7 +549,7 @@ static int
each_value_i(key, value)
VALUE key, value;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_yield(value);
return ST_CONTINUE;
}
@@ -565,7 +566,7 @@ static int
each_key_i(key, value)
VALUE key, value;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_yield(key);
return ST_CONTINUE;
}
@@ -582,7 +583,7 @@ static int
each_pair_i(key, value)
VALUE key, value;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_yield(rb_assoc_new(key, value));
return ST_CONTINUE;
}
@@ -599,7 +600,7 @@ static int
to_a_i(key, value, ary)
VALUE key, value, ary;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_ary_push(ary, rb_assoc_new(key, value));
return ST_CONTINUE;
}
@@ -629,7 +630,7 @@ inspect_i(key, value, str)
{
VALUE str2;
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
if (RSTRING(str)->len > 1) {
rb_str_cat(str, ", ", 2);
}
@@ -691,7 +692,7 @@ static int
keys_i(key, value, ary)
VALUE key, value, ary;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_ary_push(ary, key);
return ST_CONTINUE;
}
@@ -712,7 +713,7 @@ static int
values_i(key, value, ary)
VALUE key, value, ary;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_ary_push(ary, value);
return ST_CONTINUE;
}
@@ -744,7 +745,7 @@ static int
rb_hash_search_value(key, value, data)
VALUE key, value, *data;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
if (rb_equal(value, data[1])) {
data[0] = Qtrue;
return ST_STOP;
@@ -777,7 +778,7 @@ equal_i(key, val1, data)
{
VALUE val2;
- if (key == Qnil) return ST_CONTINUE;
+ if (val1 == Qnil) return ST_CONTINUE;
if (!st_lookup(data->tbl, key, &val2)) {
data->result = Qfalse;
return ST_STOP;
@@ -811,7 +812,7 @@ rb_hash_invert_i(key, value, hash)
VALUE key, value;
VALUE hash;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_hash_aset(hash, value, key);
return ST_CONTINUE;
}
@@ -831,7 +832,7 @@ rb_hash_update_i(key, value, hash)
VALUE key, value;
VALUE hash;
{
- if (key == Qnil) return ST_CONTINUE;
+ if (value == Qnil) return ST_CONTINUE;
rb_hash_aset(hash, key, value);
return ST_CONTINUE;
}
@@ -852,6 +853,24 @@ extern char **environ;
#endif
static char **origenviron;
+void
+ruby_unsetenv(name)
+ char *name;
+{
+ int i, len;
+
+ len = strlen(name);
+ for(i=0; environ[i]; i++) {
+ if (strncmp(environ[i], name, len) == 0 && environ[i][len] == '=') {
+ break;
+ }
+ }
+ while (environ[i]) {
+ environ[i] = environ[i+1];
+ i++;
+ }
+}
+
static VALUE
env_delete(obj, name)
VALUE obj, name;
@@ -861,7 +880,9 @@ env_delete(obj, name)
rb_secure(4);
nam = STR2CSTR(name);
- if (strcmp(nam, "PATH") == 0) path_tainted = 0;
+ if (strcmp(nam, "PATH") == 0 && !OBJ_TAINTED(name)) {
+ path_tainted = 0;
+ }
len = strlen(nam);
for(i=0; environ[i]; i++) {
if (strncmp(environ[i], nam, len) == 0 && environ[i][len] == '=') {
@@ -991,8 +1012,8 @@ char *nam;
return i;
}
-static void
-my_setenv(name, value)
+void
+ruby_setenv(name, value)
char *name;
char *value;
{
@@ -1098,6 +1119,17 @@ my_setenv(name, value)
#endif /* WIN32 */
}
+void
+ruby_setenv2(name, value)
+ char *name;
+ char *value;
+{
+ if (value == NULL) {
+ ruby_unsetenv(name);
+ }
+ ruby_setenv(name, value);
+}
+
static VALUE
rb_f_setenv(obj, nm, val)
VALUE obj, nm, val;
@@ -1121,7 +1153,7 @@ rb_f_setenv(obj, nm, val)
if (strlen(value) != vlen)
rb_raise(rb_eArgError, "Bad environment value");
- my_setenv(name, value);
+ ruby_setenv(name, value);
if (strcmp(name, "PATH") == 0) {
if (OBJ_TAINTED(val)) {
/* already tainted, no check */
diff --git a/intern.h b/intern.h
index 8967cfe763..3a524c1c2e 100644
--- a/intern.h
+++ b/intern.h
@@ -118,6 +118,7 @@ void rb_jump_tag _((int)) NORETURN;
void rb_provide _((char*));
VALUE rb_f_require _((VALUE, VALUE));
void rb_obj_call_init _((VALUE));
+void rb_obj_call_init2 _((VALUE, int, VALUE*));
VALUE rb_class_new_instance _((int, VALUE*, VALUE));
VALUE rb_f_lambda _((void));
VALUE rb_protect _((VALUE (*)(), VALUE, int*));
@@ -286,8 +287,6 @@ VALUE rb_struct_alloc _((VALUE, VALUE));
VALUE rb_struct_aref _((VALUE, VALUE));
VALUE rb_struct_aset _((VALUE, VALUE, VALUE));
VALUE rb_struct_getmember _((VALUE, ID));
-/* time.c */
-VALUE rb_time_new _((int, int));
/* variable.c */
VALUE rb_mod_name _((VALUE));
VALUE rb_class_path _((VALUE));
diff --git a/io.c b/io.c
index 24122f9e13..9eba04ad7e 100644
--- a/io.c
+++ b/io.c
@@ -59,6 +59,9 @@ struct timeval {
extern void Init_File _((void));
#ifdef __BEOS__
+# ifdef _X86_
+# define NOFILE (OPEN_MAX)
+# endif
#include <net/socket.h>
#endif
@@ -1229,6 +1232,7 @@ rb_file_sysopen(fname, flags, mode)
MakeOpenFile(port, fptr);
fd = rb_open(fname, flags, mode);
+ m = rb_io_flags_mode(flags);
fptr->mode = rb_io_mode_flags2(flags);
fptr->f = rb_fdopen(fd, m);
fptr->path = strdup(fname);
@@ -2208,76 +2212,13 @@ rb_f_readline(argc, argv)
}
static VALUE
-rb_f_tell()
-{
- return rb_io_tell(file);
-}
-
-static VALUE
-rb_f_seek(self, offset, ptrname)
- VALUE self, offset, ptrname;
-{
- if (!next_argv()) {
- rb_raise(rb_eArgError, "no stream to seek");
- }
-
- return rb_io_seek(file, offset, ptrname);
-}
-
-static VALUE
-rb_f_set_pos(self, offset)
- VALUE self, offset;
-{
- if (!next_argv()) {
- rb_raise(rb_eArgError, "no stream to pos");
- }
-
- return rb_io_set_pos(file, offset);
-}
-
-static VALUE
-rb_f_rewind()
-{
- return rb_io_rewind(file);
-}
-
-static VALUE
-rb_f_eof()
-{
- if (init_p == 0 && !next_argv())
- return Qtrue;
- if (rb_io_eof(file)) {
- next_p = 1;
- return Qtrue;
- }
- return Qfalse;
-}
-
-static VALUE
rb_f_getc()
{
+ rb_warn("getc is obsolete; use STDIN.getc instead");
return rb_io_getc(rb_stdin);
}
static VALUE
-rb_f_ungetc(self, c)
- VALUE self, c;
-{
- return rb_io_ungetc(rb_stdin, c);
-}
-
-static VALUE
-rb_f_readchar()
-{
- VALUE c = rb_f_getc();
-
- if (NIL_P(c)) {
- rb_eof_error();
- }
- return c;
-}
-
-static VALUE
rb_f_readlines(argc, argv)
int argc;
VALUE *argv;
@@ -2781,6 +2722,40 @@ rb_io_s_readlines(argc, argv, io)
}
static VALUE
+arg_tell()
+{
+ return rb_io_tell(file);
+}
+
+static VALUE
+arg_seek(self, offset, ptrname)
+ VALUE self, offset, ptrname;
+{
+ if (!next_argv()) {
+ rb_raise(rb_eArgError, "no stream to seek");
+ }
+
+ return rb_io_seek(file, offset, ptrname);
+}
+
+static VALUE
+arg_set_pos(self, offset)
+ VALUE self, offset;
+{
+ if (!next_argv()) {
+ rb_raise(rb_eArgError, "no stream to pos");
+ }
+
+ return rb_io_set_pos(file, offset);
+}
+
+static VALUE
+arg_rewind()
+{
+ return rb_io_rewind(file);
+}
+
+static VALUE
arg_fileno()
{
return rb_io_fileno(file);
@@ -2855,6 +2830,25 @@ arg_readchar()
}
static VALUE
+arg_eof()
+{
+ if (init_p == 0 && !next_argv())
+ return Qtrue;
+ if (rb_io_eof(file)) {
+ next_p = 1;
+ return Qtrue;
+ }
+ return Qfalse;
+}
+
+static VALUE
+rb_f_eof()
+{
+ rb_warn("eof? is obsolete; use ARGF.eof? instead");
+ return arg_eof();
+}
+
+static VALUE
arg_each_line(argc, argv)
int argc;
VALUE *argv;
@@ -2952,15 +2946,10 @@ Init_IO()
rb_define_global_function("puts", rb_f_puts, -1);
rb_define_global_function("gets", rb_f_gets, -1);
rb_define_global_function("readline", rb_f_readline, -1);
- rb_define_global_function("tell", rb_f_tell, 0);
- rb_define_global_function("seek", rb_f_seek, 2);
- rb_define_global_function("rewind", rb_f_rewind, 0);
rb_define_global_function("eof", rb_f_eof, 0);
rb_define_global_function("eof?", rb_f_eof, 0);
rb_define_global_function("getc", rb_f_getc, 0);
- rb_define_global_function("readchar", rb_f_readchar, 0);
rb_define_global_function("select", rb_f_select, -1);
- rb_define_global_function("ungetc", rb_f_ungetc, 1);
rb_define_global_function("readlines", rb_f_readlines, -1);
@@ -3086,14 +3075,13 @@ Init_IO()
rb_define_singleton_method(argf, "readline", rb_f_readline, -1);
rb_define_singleton_method(argf, "getc", arg_getc, 0);
rb_define_singleton_method(argf, "readchar", arg_readchar, 0);
- rb_define_singleton_method(argf, "tell", rb_f_tell, 0);
- rb_define_singleton_method(argf, "seek", rb_f_seek, 2);
- rb_define_singleton_method(argf, "rewind", rb_f_rewind, 0);
- rb_define_singleton_method(argf, "pos", rb_f_tell, 0);
- rb_define_singleton_method(argf, "pos=", rb_f_set_pos, 1);
- rb_define_singleton_method(argf, "eof", rb_f_eof, 0);
- rb_define_singleton_method(argf, "eof?", rb_f_eof, 0);
- rb_define_singleton_method(argf, "ungetc", rb_f_ungetc, 1);
+ rb_define_singleton_method(argf, "tell", arg_tell, 0);
+ rb_define_singleton_method(argf, "seek", arg_seek, 2);
+ rb_define_singleton_method(argf, "rewind", arg_rewind, 0);
+ rb_define_singleton_method(argf, "pos", arg_tell, 0);
+ rb_define_singleton_method(argf, "pos=", arg_set_pos, 1);
+ rb_define_singleton_method(argf, "eof", arg_eof, 0);
+ rb_define_singleton_method(argf, "eof?", arg_eof, 0);
rb_define_singleton_method(argf, "to_s", arg_filename, 0);
rb_define_singleton_method(argf, "filename", arg_filename, 0);
diff --git a/lib/e2mmap.rb b/lib/e2mmap.rb
index 3d72aaf7f4..e04ed4a5b4 100644
--- a/lib/e2mmap.rb
+++ b/lib/e2mmap.rb
@@ -1,17 +1,46 @@
#
# e2mmap.rb - for ruby 1.1
-# $Release Version: 1.2$
-# $Revision: 1.8 $
-# $Date: 1998/08/19 15:22:22 $
+# $Release Version: 2.0$
+# $Revision: 1.10 $
+# $Date: 1999/02/17 12:33:17 $
# by Keiju ISHITSUKA
#
# --
# Usage:
#
+# U1)
# class Foo
# extend Exception2MassageMapper
+# def_e2message ExistingExceptionClass, "message..."
# def_exception :NewExceptionClass, "message..."[, superclass]
+# ...
+# end
+#
+# U2)
+# module Error
+# extend Exception2MassageMapper
# def_e2meggage ExistingExceptionClass, "message..."
+# def_exception :NewExceptionClass, "message..."[, superclass]
+# ...
+# end
+# class Foo
+# include Exp
+# ...
+# end
+#
+# foo = Foo.new
+# foo.Fail ....
+#
+# U3)
+# module Error
+# extend Exception2MassageMapper
+# def_e2message ExistingExceptionClass, "message..."
+# def_exception :NewExceptionClass, "message..."[, superclass]
+# ...
+# end
+# class Foo
+# extend Exception2MessageMapper
+# include Error
# ...
# end
#
@@ -19,113 +48,149 @@
# Foo.Fail ExistingExceptionClass, arg...
#
#
-if VERSION < "1.1"
- require "e2mmap1_0.rb"
-else
+fail "Use Ruby 1.1" if VERSION < "1.1"
+
+module Exception2MessageMapper
+ @RCS_ID='-$Id: e2mmap.rb,v 1.10 1999/02/17 12:33:17 keiju Exp keiju $-'
+
+ E2MM = Exception2MessageMapper
+
+ def E2MM.extend_object(cl)
+ super
+ cl.bind(self) unless cl == E2MM
+ end
- module Exception2MessageMapper
- @RCS_ID='-$Id: e2mmap.rb,v 1.8 1998/08/19 15:22:22 keiju Exp keiju $-'
-
- E2MM = Exception2MessageMapper
+ # 以前との互換性のために残してある.
+ def E2MM.extend_to(b)
+ c = eval("self", b)
+ c.extend(self)
+ end
- def E2MM.extend_object(cl)
+ def bind(cl)
+ self.module_eval %[
+ def Raise(err = nil, *rest)
+ Exception2MessageMapper.Raise(self.type, err, *rest)
+ end
+ alias Fail Raise
+
+ def self.append_features(mod)
+ super
+ mod.extend Exception2MessageMapper
+ end
+ ]
+ end
+
+ # Fail(err, *rest)
+ # err: 例外
+ # rest: メッセージに渡すパラメータ
+ #
+ def Raise(err = nil, *rest)
+ E2MM.Raise(self, err, *rest)
+ end
+ alias Fail Raise
+
+ # 過去の互換性のため
+ alias fail! fail
+ def fail(err = nil, *rest)
+ begin
+ E2MM.Fail(self, err, *rest)
+ rescue E2MM::ErrNotRegisteredException
super
- cl.bind(self)
end
-
- # backward compatibility
- def E2MM.extend_to(b)
- c = eval("self", b)
- c.extend(self)
- end
-
- # public :fail
- alias fail! fail
+ end
+ class << self
+ public :fail
+ end
- #def fail(err = nil, *rest)
- # super
- #end
+
+ # def_e2message(c, m)
+ # c: exception
+ # m: message_form
+ # 例外cのメッセージをmとする.
+ #
+ def def_e2message(c, m)
+ E2MM.def_e2message(self, c, m)
+ end
+
+ # def_exception(c, m)
+ # n: exception_name
+ # m: message_form
+ # s: 例外スーパークラス(デフォルト: StandardError)
+ # 例外名``c''をもつ例外を定義し, そのメッセージをmとする.
+ #
+ def def_exception(n, m, s = StandardError)
+ E2MM.def_exception(self, n, m, s)
+ end
- def Fail(err = nil, *rest)
- Exception2MessageMapper.Fail Exception2MessageMapper::ErrNotRegisteredException, err.inspect
- end
-
- def bind(cl)
- self.module_eval %q^
- E2MM_ErrorMSG = {} unless self.const_defined?(:E2MM_ErrorMSG)
- # fail(err, *rest)
- # err: Exception
- # rest: Parameter accompanied with the exception
- #
- def self.Fail(err = nil, *rest)
- if form = E2MM_ErrorMSG[err]
- $! = err.new(sprintf(form, *rest))
- $@ = caller(0) if $@.nil?
- $@.shift
- # e2mm_fail()
- raise()
-# elsif self == Exception2MessageMapper
-# fail Exception2MessageMapper::ErrNotRegisteredException, err.to_s
- else
-# print "super\n"
- super
- end
- end
+ #
+ # Private definitions.
+ #
+ # {[class, exp] => message, ...}
+ @MessageMap = {}
+
+ # E2MM.def_exception(k, e, m)
+ # k: 例外を定義するクラス
+ # e: exception
+ # m: message_form
+ # 例外cのメッセージをmとする.
+ #
+ def E2MM.def_e2message(k, c, m)
+ E2MM.instance_eval{@MessageMap[[k, c]] = m}
+ c
+ end
+
+ # E2MM.def_exception(k, c, m)
+ # k: 例外を定義するクラス
+ # n: exception_name
+ # m: message_form
+ # s: 例外スーパークラス(デフォルト: StandardError)
+ # 例外名``c''をもつ例外を定義し, そのメッセージをmとする.
+ #
+ def E2MM.def_exception(k, n, m, s = StandardError)
+ n = n.id2name if n.kind_of?(Fixnum)
+ e = Class.new(s)
+ E2MM.instance_eval{@MessageMap[[k, e]] = m}
+ k.const_set(n, e)
+ end
- # backward compatibility
- def self.fail(err = nil, *rest)
- if form = E2MM_ErrorMSG[err]
- $! = err.new(sprintf(form, *rest))
- $@ = caller(0) if $@.nil?
- $@.shift
- # e2mm_fail()
- raise()
-# elsif self == Exception2MessageMapper
-# fail Exception2MessageMapper::ErrNotRegisteredException, err.to_s
- else
-# print "super\n"
- super
- end
- end
- class << self
- public :fail
- end
-
- # def_exception(c, m)
- # c: exception
- # m: message_form
- #
- def self.def_e2message(c, m)
- E2MM_ErrorMSG[c] = m
- end
-
- # def_exception(c, m)
- # n: exception_name
- # m: message_form
- # s: superclass_of_exception (default: Exception)
- # defines excaption named ``c'', whose message is ``m''.
- #
- #def def_exception(n, m)
- def self.def_exception(n, m, s = nil)
- n = n.id2name if n.kind_of?(Fixnum)
- unless s
- if defined?(StandardError)
- s = StandardError
- else
- s = Exception
- end
- end
- e = Class.new(s)
+ # Fail(klass, err, *rest)
+ # klass: 例外の定義されているクラス
+ # err: 例外
+ # rest: メッセージに渡すパラメータ
+ #
+ def E2MM.Raise(klass = E2MM, err = nil, *rest)
+ if form = e2mm_message(klass, err)
+ $! = err.new(sprintf(form, *rest))
+ $@ = caller(1) if $@.nil?
+ #p $@
+ #p __FILE__
+ $@.shift if $@[0] =~ /^#{Regexp.quote(__FILE__)}:/
+ raise
+ else
+ E2MM.Fail E2MM, ErrNotRegisteredException, err.inspect
+ end
+ end
+ class <<E2MM
+ alias Fail Raise
+ end
- const_set(n, e)
- E2MM_ErrorMSG[e] = m
- # const_get(:E2MM_ErrorMSG)[e] = m
- end
- ^
+ def E2MM.e2mm_message(klass, exp)
+ for c in klass.ancestors
+ if mes = @MessageMap[[c,exp]]
+ p mes
+ m = klass.instance_eval('"' + mes + '"')
+ return m
end
-
- extend E2MM
- def_exception(:ErrNotClassOrModule, "Not Class or Module")
- def_exception(:ErrNotRegisteredException, "not registerd exception(%s)")
end
+ nil
+ end
+ class <<self
+ alias message e2mm_message
+ end
+
+ E2MM.def_exception(E2MM,
+ :ErrNotRegisteredException,
+ "not registerd exception(%s)")
end
+
+
diff --git a/lib/matrix.rb b/lib/matrix.rb
index 64b0738e1b..4767b4b545 100644
--- a/lib/matrix.rb
+++ b/lib/matrix.rb
@@ -1,8 +1,9 @@
+#!/usr/local/bin/ruby
#
# matrix.rb -
# $Release Version: 1.0$
-# $Revision: 1.6 $
-# $Date: 1998/07/31 03:39:49 $
+# $Revision: 1.8 $
+# $Date: 1999/02/17 12:34:19 $
# Original Version from Smalltalk-80 version
# on July 23, 1985 at 8:37:17 am
# by Keiju ISHITSUKA
@@ -17,6 +18,8 @@
# :
# rown]
#
+# column: 列
+# row: 行
#
# module ExceptionForMatrix::
# Exceptions:
@@ -173,19 +176,19 @@
require "e2mmap.rb"
module ExceptionForMatrix
- Exception2MessageMapper.extend_to(binding)
-
+ extend Exception2MessageMapper
def_e2message(TypeError, "wrong argument type %s (expected %s)")
def_e2message(ArgumentError, "Wrong # of arguments(%d for %d)")
- def_exception("ErrDimensionMismatch", "\#{self.type} dimemsion mismatch")
+ def_exception("ErrDimensionMismatch", "\#{self.name} dimension mismatch")
def_exception("ErrNotRegular", "Not Regular Matrix")
def_exception("ErrOperationNotDefined", "This operation(%s) can\\'t defined")
end
class Matrix
- @RCS_ID='-$Id: matrix.rb,v 1.6 1998/07/31 03:39:49 keiju Exp keiju $-'
-
+ @RCS_ID='-$Id: matrix.rb,v 1.8 1999/02/17 12:34:19 keiju Exp keiju $-'
+
+# extend Exception2MessageMapper
include ExceptionForMatrix
# instance creations
@@ -337,7 +340,7 @@ class Matrix
from_col = param[2]
size_col = param[3]
else
- Matrix.fail ArgumentError, param.inspect
+ Matrix.Raise ArgumentError, param.inspect
end
rows = @rows[from_row, size_row].collect{
@@ -410,7 +413,7 @@ class Matrix
r = self * m
return r.column(0)
when Matrix
- Matrix.fail ErrDimensionMismatch if column_size != m.row_size
+ Matrix.Raise ErrDimensionMismatch if column_size != m.row_size
rows = (0 .. row_size - 1).collect {
|i|
@@ -434,7 +437,7 @@ class Matrix
def +(m)
case m
when Numeric
- Matrix.fail ErrOperationNotDefined, "+"
+ Matrix.Raise ErrOperationNotDefined, "+"
when Vector
m = Matrix.column_vector(m)
when Matrix
@@ -443,7 +446,7 @@ class Matrix
return x + y
end
- Matrix.fail ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
+ Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
rows = (0 .. row_size - 1).collect {
|i|
@@ -458,7 +461,7 @@ class Matrix
def -(m)
case m
when Numeric
- Matrix.fail ErrOperationNotDefined, "-"
+ Matrix.Raise ErrOperationNotDefined, "-"
when Vector
m = Matrix.column_vector(m)
when Matrix
@@ -467,7 +470,7 @@ class Matrix
return x - y
end
- Matrix.fail ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
+ Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
rows = (0 .. row_size - 1).collect {
|i|
@@ -499,7 +502,7 @@ class Matrix
end
def inverse
- Matrix.fail ErrDimensionMismatch unless square?
+ Matrix.Raise ErrDimensionMismatch unless square?
Matrix.I(row_size).inverse_from(self)
end
alias inv inverse
@@ -512,7 +515,7 @@ class Matrix
if (akk = a[k][k]) == 0
i = k
begin
- fail ErrNotRegular if (i += 1) > size
+ Matrix.Raise ErrNotRegular if (i += 1) > size
end while a[i][k] == 0
a[i], a[k] = a[k], a[i]
@rows[i], @rows[k] = @rows[k], @rows[i]
@@ -568,9 +571,9 @@ class Matrix
end
z
elsif other.kind_of?(Float) || defined?(Rational) && other.kind_of?(Rational)
- fail ErrOperationNotDefined, "**"
+ Matrix.Raise ErrOperationNotDefined, "**"
else
- fail ErrOperationNotDefined, "**"
+ Matrix.Raise ErrOperationNotDefined, "**"
end
end
@@ -663,6 +666,8 @@ class Matrix
case other
when Numeric
return Scalar.new(other), self
+ else
+ raise TypeError, "#{type} can't be coerced into #{other.type}"
end
end
@@ -725,7 +730,7 @@ class Matrix
when Numeric
Scalar.new(@value + other)
when Vector, Matrix
- Scalar.fail WrongArgType, other.type, "Numeric or Scalar"
+ Scalar.Raise WrongArgType, other.type, "Numeric or Scalar"
when Scalar
Scalar.new(@value + other.value)
else
@@ -739,7 +744,7 @@ class Matrix
when Numeric
Scalar.new(@value - other)
when Vector, Matrix
- Scalar.fail WrongArgType, other.type, "Numeric or Scalar"
+ Scalar.Raise WrongArgType, other.type, "Numeric or Scalar"
when Scalar
Scalar.new(@value - other.value)
else
@@ -765,7 +770,7 @@ class Matrix
when Numeric
Scalar.new(@value / other)
when Vector
- Scalar.fail WrongArgType, other.type, "Numeric or Scalar or Matrix"
+ Scalar.Raise WrongArgType, other.type, "Numeric or Scalar or Matrix"
when Matrix
self * _M.inverse
else
@@ -779,7 +784,7 @@ class Matrix
when Numeric
Scalar.new(@value ** other)
when Vector
- Scalar.fail WrongArgType, other.type, "Numeric or Scalar or Matrix"
+ Scalar.Raise WrongArgType, other.type, "Numeric or Scalar or Matrix"
when Matrix
other.powered_by(self)
else
@@ -802,7 +807,7 @@ class Vector
private_class_method :new
def Vector.[](*array)
- new(:init_elements, array, FALSE)
+ new(:init_elements, array, copy = FALSE)
end
def Vector.elements(array, copy = TRUE)
@@ -833,7 +838,7 @@ class Vector
# ENUMRATIONS
def each2(v)
- Vector.fail ErrDimensionMismatch if size != v.size
+ Vector.Raise ErrDimensionMismatch if size != v.size
0.upto(size - 1) do
|i|
yield @elements[i], v[i]
@@ -841,7 +846,7 @@ class Vector
end
def collect2(v)
- Vector.fail ErrDimensionMismatch if size != v.size
+ Vector.Raise ErrDimensionMismatch if size != v.size
(0 .. size - 1).collect do
|i|
yield @elements[i], v[i]
@@ -878,7 +883,7 @@ class Vector
when Matrix
self.covector * x
else
- s, x = X.corece(self)
+ s, x = X.coerce(self)
s * x
end
end
@@ -886,7 +891,7 @@ class Vector
def +(v)
case v
when Vector
- Vector.fail ErrDimensionMismatch if size != v.size
+ Vector.Raise ErrDimensionMismatch if size != v.size
els = collect2(v) {
|v1, v2|
v1 + v2
@@ -895,7 +900,7 @@ class Vector
when Matrix
Matrix.column_vector(self) + v
else
- s, x = v.corece(self)
+ s, x = v.coerce(self)
s + x
end
end
@@ -903,7 +908,7 @@ class Vector
def -(v)
case v
when Vector
- Vector.fail ErrDimensionMismatch if size != v.size
+ Vector.Raise ErrDimensionMismatch if size != v.size
els = collect2(v) {
|v1, v2|
v1 - v2
@@ -912,7 +917,7 @@ class Vector
when Matrix
Matrix.column_vector(self) - v
else
- s, x = v.corece(self)
+ s, x = v.coerce(self)
s - x
end
end
@@ -920,7 +925,7 @@ class Vector
# VECTOR FUNCTIONS
def inner_product(v)
- Vector.fail ErrDimensionMismatch if size != v.size
+ Vector.Raise ErrDimensionMismatch if size != v.size
p = 0
each2(v) {
@@ -980,6 +985,8 @@ class Vector
case other
when Numeric
return Scalar.new(other), self
+ else
+ raise TypeError, "#{type} can't be coerced into #{other.type}"
end
end
diff --git a/lib/tempfile.rb b/lib/tempfile.rb
index bf51ac2788..ed376a5032 100644
--- a/lib/tempfile.rb
+++ b/lib/tempfile.rb
@@ -28,13 +28,14 @@ class Tempfile < SimpleDelegator
}
end
- def initialize(basename, tmpdir = '/tmp')
+ def initialize(basename, tmpdir = nil)
umask = File.umask(0177)
tmpname = lock = nil
begin
n = 0
while true
begin
+ tmpdir ||= ENV['TMPDIR'] || ENV['TMP'] || ENV['TEMP'] || '/tmp'
tmpname = sprintf('%s/%s.%d.%d', tmpdir, basename, $$, n)
lock = tmpname + '.lock'
unless File.exist?(lock)
diff --git a/marshal.c b/marshal.c
index 06a4ac6d3f..a22ddf244f 100644
--- a/marshal.c
+++ b/marshal.c
@@ -17,7 +17,7 @@ double strtod();
#endif
#define MARSHAL_MAJOR 4
-#define MARSHAL_MINOR 0
+#define MARSHAL_MINOR 1
#define TYPE_NIL '0'
#define TYPE_TRUE 'T'
@@ -168,7 +168,7 @@ w_unique(s, arg)
static void w_object _((VALUE,struct dump_arg*,int));
static int
-rb_hash_each(key, value, arg)
+hash_each(key, value, arg)
VALUE key, value;
struct dump_call_arg *arg;
{
@@ -178,7 +178,7 @@ rb_hash_each(key, value, arg)
}
static int
-rb_obj_each(id, value, arg)
+obj_each(id, value, arg)
ID id;
VALUE value;
struct dump_call_arg *arg;
@@ -324,7 +324,7 @@ w_object(obj, arg, limit)
w_uclass(obj, rb_cHash, arg);
w_byte(TYPE_HASH, arg);
w_long(RHASH(obj)->tbl->num_entries, arg);
- st_foreach(RHASH(obj)->tbl, rb_hash_each, &c_arg);
+ st_foreach(RHASH(obj)->tbl, hash_each, &c_arg);
break;
case T_STRUCT:
@@ -361,7 +361,7 @@ w_object(obj, arg, limit)
w_unique(path, arg);
if (ROBJECT(obj)->iv_tbl) {
w_long(ROBJECT(obj)->iv_tbl->num_entries, arg);
- st_foreach(ROBJECT(obj)->iv_tbl, rb_obj_each, &c_arg);
+ st_foreach(ROBJECT(obj)->iv_tbl, obj_each, &c_arg);
}
else {
w_long(0, arg);
diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el
index cf53574481..af59f709a6 100644
--- a/misc/ruby-mode.el
+++ b/misc/ruby-mode.el
@@ -89,7 +89,7 @@
(modify-syntax-entry ?# "<" ruby-mode-syntax-table)
(modify-syntax-entry ?\n ">" ruby-mode-syntax-table)
(modify-syntax-entry ?\\ "\\" ruby-mode-syntax-table)
- (modify-syntax-entry ?$ "/" ruby-mode-syntax-table)
+ (modify-syntax-entry ?$ "." ruby-mode-syntax-table)
(modify-syntax-entry ?? "_" ruby-mode-syntax-table)
(modify-syntax-entry ?_ "_" ruby-mode-syntax-table)
(modify-syntax-entry ?< "." ruby-mode-syntax-table)
@@ -194,7 +194,7 @@ The variable ruby-indent-level controls the amount of indentation.
(indent-to x)
(move-to-column (+ x shift))))))
-(defun ruby-expr-beg (&optional modifier pnt)
+(defun ruby-expr-beg (&optional modifier)
(save-excursion
(if (looking-at "\\?")
(progn
@@ -216,7 +216,8 @@ The variable ruby-indent-level controls the amount of indentation.
(looking-at ruby-block-mid-re))
(progn
(goto-char (match-end 0))
- (looking-at "\\>")))))))))
+ (looking-at "\\>"))
+ (looking-at "[a-zA-Z][a-zA-z0-9_]* /[^ \t]"))))))))
(defun ruby-parse-region (start end)
(let ((indent-point end)
@@ -249,6 +250,7 @@ The variable ruby-indent-level controls the amount of indentation.
(setq in-string (point))
(goto-char indent-point))))
((looking-at "/")
+ (echo "here %s" (ruby-expr-beg))
(cond
((and (not (eobp)) (ruby-expr-beg))
(if (re-search-forward "[^\\]/" indent-point t)
@@ -689,9 +691,13 @@ An end of a defun is found by moving forward from the beginning of one."
(add-hook
'ruby-mode-hook
(lambda ()
+ (make-local-variable 'font-lock-syntactic-keywords)
+ (setq font-lock-syntactic-keywords
+ '(("\\$\\([#\"'$\\]\\)" 1 (1 . nil))
+ ("\\(#\\)[{$@]" 1 (1 . nil))))
(make-local-variable 'font-lock-defaults)
(setq font-lock-defaults
- '((ruby-font-lock-keywords) nil nil ((?\_ . "w"))))))
+ '((ruby-font-lock-keywords) nil nil ((?\_ . "w") (?$ . "/"))))))
(add-hook 'ruby-mode-hook
(lambda ()
(setq font-lock-keywords ruby-font-lock-keywords))))))
diff --git a/missing/fnmatch.c b/missing/fnmatch.c
new file mode 100644
index 0000000000..5bc8d7d402
--- /dev/null
+++ b/missing/fnmatch.c
@@ -0,0 +1,192 @@
+/*
+ * Copyright (c) 1989, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Guido van Rossum.
+ *
+ * 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
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)fnmatch.c 8.2 (Berkeley) 4/16/94";
+#endif /* LIBC_SCCS and not lint */
+
+/*
+ * Function fnmatch() as specified in POSIX 1003.2-1992, section B.6.
+ * Compares a filename or pathname to a pattern.
+ */
+
+#include "missing/fnmatch.h"
+#include <string.h>
+
+#define EOS '\0'
+
+static const char *rangematch(const char *, int, int);
+
+int fnmatch(const char *pattern, const char *string, int flags)
+{
+ const char *stringstart;
+ char c, test;
+
+ for (stringstart = string;;) {
+ switch (c = *pattern++) {
+ case EOS:
+ return (*string == EOS ? 0 : FNM_NOMATCH);
+ case '?':
+ if (*string == EOS) {
+ return (FNM_NOMATCH);
+ }
+ if (*string == '/' && (flags & FNM_PATHNAME)) {
+ return (FNM_NOMATCH);
+ }
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
+ return (FNM_NOMATCH);
+ }
+ ++string;
+ break;
+ case '*':
+ c = *pattern;
+ /* Collapse multiple stars. */
+ while (c == '*') {
+ c = *++pattern;
+ }
+
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
+ return (FNM_NOMATCH);
+ }
+
+ /* Optimize for pattern with * at end or before /. */
+ if (c == EOS) {
+ if (flags & FNM_PATHNAME) {
+ return (strchr(string, '/') == NULL ? 0 : FNM_NOMATCH);
+ }
+ else {
+ return (0);
+ }
+ }
+ else if (c == '/' && flags & FNM_PATHNAME) {
+ if ((string = strchr(string, '/')) == NULL) {
+ return (FNM_NOMATCH);
+ }
+ break;
+ }
+
+ /* General case, use recursion. */
+ while ((test = *string) != EOS) {
+ if (!fnmatch(pattern, string, flags & ~FNM_PERIOD)) {
+ return (0);
+ }
+ if (test == '/' && flags & FNM_PATHNAME) {
+ break;
+ }
+ ++string;
+ }
+ return (FNM_NOMATCH);
+ case '[':
+ if (*string == EOS) {
+ return (FNM_NOMATCH);
+ }
+ if (*string == '/' && flags & FNM_PATHNAME) {
+ return (FNM_NOMATCH);
+ }
+ if (*string == '.' && (flags & FNM_PERIOD) &&
+ (string == stringstart ||
+ ((flags & FNM_PATHNAME) && *(string - 1) == '/'))) {
+ return (FNM_NOMATCH);
+ }
+ if ((pattern = rangematch(pattern, *string, flags)) == NULL) {
+ return (FNM_NOMATCH);
+ }
+ ++string;
+ break;
+ case '\\':
+ if (!(flags & FNM_NOESCAPE)) {
+ if ((c = *pattern++) == EOS) {
+ c = '\\';
+ --pattern;
+ }
+ }
+ /* FALLTHROUGH */
+ default:
+ if (c != *string) {
+ return (FNM_NOMATCH);
+ }
+ string++;
+ break;
+ }
+ /* NOTREACHED */
+ }
+}
+
+static const char *rangematch(const char *pattern, int test, int flags)
+{
+ int negate, ok;
+ char c, c2;
+
+ /*
+ * A bracket expression starting with an unquoted circumflex
+ * character produces unspecified results (IEEE 1003.2-1992,
+ * 3.13.2). This implementation treats it like '!', for
+ * consistency with the regular expression syntax.
+ * J.T. Conklin (conklin@ngai.kaleida.com)
+ */
+ if ((negate = (*pattern == '!' || *pattern == '^'))) {
+ ++pattern;
+ }
+
+ for (ok = 0; (c = *pattern++) != ']';) {
+ if (c == '\\' && !(flags & FNM_NOESCAPE)) {
+ c = *pattern++;
+ }
+ if (c == EOS) {
+ return (NULL);
+ }
+ if (*pattern == '-' && (c2 = *(pattern + 1)) != EOS && c2 != ']') {
+ pattern += 2;
+ if (c2 == '\\' && !(flags & FNM_NOESCAPE)) {
+ c2 = *pattern++;
+ }
+ if (c2 == EOS) {
+ return (NULL);
+ }
+ if (c <= test && test <= c2) {
+ ok = 1;
+ }
+ }
+ else if (c == test) {
+ ok = 1;
+ }
+ }
+ return (ok == negate ? NULL : pattern);
+}
diff --git a/missing/fnmatch.h b/missing/fnmatch.h
new file mode 100644
index 0000000000..66f36a1537
--- /dev/null
+++ b/missing/fnmatch.h
@@ -0,0 +1,57 @@
+/*-
+ * Copyright (c) 1992, 1993
+ * The Regents of the University of California. 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
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS 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 REGENTS 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.
+ *
+ * @(#)fnmatch.h 8.1 (Berkeley) 6/2/93
+ */
+
+/* This file has been modified by matz@netlab.co.jp */
+
+#ifndef _FNMATCH_H_
+#define _FNMATCH_H_
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define FNM_NOMATCH 1 /* Match failed. */
+
+#define FNM_NOESCAPE 0x01 /* Disable backslash escaping. */
+#define FNM_PATHNAME 0x02 /* Slash must be matched by slash. */
+#define FNM_PERIOD 0x04 /* Period must be matched by period. */
+
+int fnmatch(const char *, const char *, int);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* !_FNMATCH_H_ */
diff --git a/missing/strftime.c b/missing/strftime.c
index 478471c37d..18a6a7bf0b 100644
--- a/missing/strftime.c
+++ b/missing/strftime.c
@@ -92,23 +92,25 @@
#ifndef __STDC__
#define const /**/
-extern void *malloc();
-extern void *realloc();
extern void tzset();
-extern char *strchr();
-extern char *getenv();
static int weeknumber();
adddecl(static int iso8601wknum();)
#else
-extern void *malloc(unsigned count);
-extern void *realloc(void *ptr, unsigned count);
extern void tzset(void);
-extern char *strchr(const char *str, int ch);
-extern char *getenv(const char *v);
static int weeknumber(const struct tm *timeptr, int firstweekday);
adddecl(static int iso8601wknum(const struct tm *timeptr);)
#endif
+#ifdef STDC_HEADERS
+#include <stdlib.h>
+#include <string.h>
+#else
+extern void *malloc();
+extern void *realloc();
+extern char *getenv();
+extern char *strchr();
+#endif
+
#ifdef __GNUC__
#define inline __inline__
#else
@@ -348,8 +350,8 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
strcpy(tbuf, ampm[1]);
break;
- case 'S': /* second, 00 - 61 */
- i = range(0, timeptr->tm_sec, 61);
+ case 'S': /* second, 00 - 60 */
+ i = range(0, timeptr->tm_sec, 60);
sprintf(tbuf, "%02d", i);
break;
@@ -504,7 +506,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
#ifdef VMS_EXT
case 'v': /* date as dd-bbb-YYYY */
- sprintf(tbuf, "%02d-%3.3s-%4d",
+ sprintf(tbuf, "%2d-%3.3s-%4d",
range(1, timeptr->tm_mday, 31),
months_a[range(0, timeptr->tm_mon, 11)],
timeptr->tm_year + 1900);
@@ -562,7 +564,7 @@ strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
else
sprintf(tbuf, "%02d", y % 100);
break;
-#endif ISO_DATE_EXT
+#endif /* ISO_DATE_EXT */
default:
tbuf[0] = '%';
tbuf[1] = *format;
@@ -826,7 +828,7 @@ static char *array[] =
"(%%M) minute (00..59) %M",
"(%%O) Locale extensions (ignored) %O",
"(%%R) time, 24-hour (%%H:%%M) %R",
- "(%%S) second (00..61) %S",
+ "(%%S) second (00..60) %S",
"(%%T) time, 24-hour (%%H:%%M:%%S) %T",
"(%%U) week of year, Sunday as first day of week (00..53) %U",
"(%%V) week of year according to ISO 8601 %V",
diff --git a/numeric.c b/numeric.c
index 804356d99a..65e27c0bd2 100644
--- a/numeric.c
+++ b/numeric.c
@@ -25,7 +25,8 @@ VALUE rb_cFloat;
VALUE rb_cInteger;
VALUE rb_cFixnum;
-VALUE rb_eZeroDiv;
+VALUE rb_eZeroDivError;
+VALUE rb_eFloatDomainError;
ID rb_frame_last_func();
VALUE rb_float_new();
@@ -34,7 +35,7 @@ double rb_big2dbl();
void
rb_num_zerodiv()
{
- rb_raise(rb_eZeroDiv, "divided by 0");
+ rb_raise(rb_eZeroDivError, "divided by 0");
}
static VALUE
@@ -188,13 +189,17 @@ flo_to_s(flt)
{
char buf[24];
char *s;
-
- sprintf(buf, "%-.10g", RFLOAT(flt)->value);
+ double value = RFLOAT(flt)->value;
+
+ if (isinf(value))
+ return rb_str_new2(value < 0 ? "-Infinity" : "Infinity");
+ else if(isnan(value))
+ return rb_str_new2("NaN");
+ else
+ sprintf(buf, "%-.10g", value);
if (s = strchr(buf, ' ')) *s = '\0';
s = buf; if (s[0] == '-') s++;
- if (strchr(s, '.') == 0 &&
- strcmp(s, "Inf") != 0 &&
- strcmp(s, "NaN") != 0) {
+ if (strchr(s, '.') == 0) {
int len = strlen(buf);
char *ind = strchr(buf, 'e');
@@ -686,6 +691,11 @@ rb_num2long(val)
rb_raise(rb_eTypeError, "no implicit conversion from string");
return Qnil; /* not reached */
+ case T_TRUE:
+ case T_FALSE:
+ rb_raise(rb_eTypeError, "no implicit conversion from boolean");
+ return Qnil; /* not reached */
+
default:
val = rb_rescue(to_integer, val, fail_to_integer, val);
if (!rb_obj_is_kind_of(val, rb_cInteger)) {
@@ -1405,12 +1415,13 @@ Init_Numeric()
{
#ifdef __FreeBSD__
/* allow divide by zero -- Inf */
- fpsetmask(fpgetmask() & ~(FP_X_DZ|FP_X_INV));
+ fpsetmask(fpgetmask() & ~(FP_X_DZ|FP_X_INV|FP_X_OFL));
#endif
coerce = rb_intern("coerce");
to_i = rb_intern("to_i");
- rb_eZeroDiv = rb_define_class("ZeroDivisionError", rb_eStandardError);
+ rb_eZeroDivError = rb_define_class("ZeroDivisionError", rb_eStandardError);
+ rb_eFloatDomainError = rb_define_class("FloatDomainError", rb_eStandardError);
rb_cNumeric = rb_define_class("Numeric", rb_cObject);
rb_include_module(rb_cNumeric, rb_mComparable);
diff --git a/parse.c b/parse.c
index bf0ee6bf2c..149c09506f 100644
--- a/parse.c
+++ b/parse.c
@@ -5386,6 +5386,11 @@ retry:
}
}
}
+ else if (c >= 0x80) {
+ if ((c = nextc()) != '\\') {
+ pushback(c);
+ }
+ }
}
/* fall through */
case '\n':
@@ -6096,6 +6101,13 @@ retry:
}
if ((c == '!' || c == '?') && is_identchar(tok()[0])) {
tokadd(c);
+ if (c == '!') {
+ c = nextc();
+ if (c == '=') {
+ rb_warn("identifier! immediately followed by `='");
+ }
+ pushback(c);
+ }
}
else {
pushback(c);
diff --git a/parse.y b/parse.y
index 899b08c3c4..6f654dfb2b 100644
--- a/parse.y
+++ b/parse.y
@@ -2475,6 +2475,11 @@ retry:
}
}
}
+ else if (c >= 0x80) {
+ if ((c = nextc()) != '\\') {
+ pushback(c);
+ }
+ }
}
/* fall through */
case '\n':
@@ -3185,6 +3190,13 @@ retry:
}
if ((c == '!' || c == '?') && is_identchar(tok()[0])) {
tokadd(c);
+ if (c == '!') {
+ c = nextc();
+ if (c == '=') {
+ rb_warn("identifier! immediately followed by `='");
+ }
+ pushback(c);
+ }
}
else {
pushback(c);
diff --git a/process.c b/process.c
index 8257812b91..70f29ea564 100644
--- a/process.c
+++ b/process.c
@@ -775,12 +775,12 @@ rb_f_sleep(argc, argv)
return INT2FIX(end);
}
-#if !defined(NT) && !defined(DJGPP) && !defined(__human68k__) && !defined(USE_CWGUSI)
static VALUE
proc_getpgrp(argc, argv)
int argc;
VALUE *argv;
{
+#ifdef HAVE_GETPGRP
int pgrp;
#ifndef GETPGRP_VOID
VALUE vpid;
@@ -795,6 +795,9 @@ proc_getpgrp(argc, argv)
#endif
if (pgrp < 0) rb_sys_fail(0);
return INT2FIX(pgrp);
+#else
+ rb_notimplement();
+#endif
}
static VALUE
@@ -902,7 +905,6 @@ proc_setpriority(obj, which, who, prio)
rb_notimplement();
#endif
}
-#endif
static VALUE
proc_getuid(obj)
@@ -1075,7 +1077,6 @@ Init_process()
#endif /* ifndef USE_CWGUSI */
#endif /* ifndef NT */
-#if !defined(NT) && !defined(DJGPP) && !defined(__human68k__) && !defined(USE_CWGUSI)
rb_define_module_function(rb_mProcess, "getpgrp", proc_getpgrp, -1);
rb_define_module_function(rb_mProcess, "setpgrp", proc_setpgrp, -1);
rb_define_module_function(rb_mProcess, "getpgid", proc_getpgid, 1);
@@ -1100,5 +1101,4 @@ Init_process()
rb_define_module_function(rb_mProcess, "euid=", proc_seteuid, 1);
rb_define_module_function(rb_mProcess, "egid", proc_getegid, 0);
rb_define_module_function(rb_mProcess, "egid=", proc_setegid, 1);
-#endif
}
diff --git a/re.c b/re.c
index 7cf085adc9..786e28f2fb 100644
--- a/re.c
+++ b/re.c
@@ -879,8 +879,11 @@ rb_reg_s_quote(re, str)
for (; s != send; s++) {
if (ismbchar(*s)) {
- *t++ = *s++;
- *t++ = *s;
+ size_t n = mbclen(*s);
+
+ while (n--)
+ *t++ = *s++;
+ s--;
continue;
}
if (*s == '[' || *s == ']'
@@ -979,7 +982,7 @@ rb_reg_regsub(str, src, regs)
c = *s++;
if (ismbchar(c)) {
- s++;
+ s += mbclen(c) - 1;
continue;
}
if (c != '\\' || s == e) continue;
diff --git a/regex.c b/regex.c
index 6992e7f702..d508f67ca7 100644
--- a/regex.c
+++ b/regex.c
@@ -1,29 +1,27 @@
/* Extended regular expression matching and search library.
- Copyright (C) 1985, 1989-90 Free Software Foundation, Inc.
+ Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc.
- This program 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 1, or (at your option)
- any later version.
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
- This program is distributed in the hope that it will be useful,
+ The GNU C Library 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.
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Library General Public License for more details.
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
+ You should have received a copy of the GNU Library General Public
+ License along with the GNU C Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA. */
/* Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto)
Last change: May 21, 1993 by t^2 */
-
-/* To test, compile with -Dtest. This Dtestable feature turns this into
- a self-contained program which reads a pattern, describes how it
- compiles, then reads a string and searches for it.
-
- On the other hand, if you compile with both -Dtest and -Dcanned you
- can run some tests we've already thought of. */
+#include "config.h"
+#ifdef RUBY_PLATFORM
+# define RUBY
+#endif
/* We write fatal error messages on standard error. */
#include <stdio.h>
@@ -32,25 +30,47 @@
#include <ctype.h>
#include <sys/types.h>
-#ifdef __STDC__
-#define P(s) s
-#define MALLOC_ARG_T size_t
+#ifndef PARAMS
+# if defined __GNUC__ || (defined __STDC__ && __STDC__)
+# define PARAMS(args) args
+# else
+# define PARAMS(args) ()
+# endif /* GCC. */
+#endif /* Not PARAMS. */
+
+#if defined(STDC_HEADERS)
+# include <stddef.h>
#else
-#define P(s) ()
-#define MALLOC_ARG_T unsigned
-#define volatile
-#define const
+/* We need this for `regex.h', and perhaps for the Emacs include files. */
+# include <sys/types.h>
#endif
-#include "config.h"
-#ifdef RUBY_PLATFORM
-# define RUBY
+#if defined(STDC_HEADERS)
+# include <stddef.h>
+#else
+/* We need this for `regex.h', and perhaps for the Emacs include files. */
+# include <sys/types.h>
+#endif
+
+#ifndef __STDC__
+# define volatile
+# ifdef __GNUC__
+# define const __const__
+# else
+# define const
+# endif
#endif
-void *xmalloc P((unsigned long));
-void *xcalloc P((unsigned long,unsigned long));
-void *xrealloc P((void*,unsigned long));
-void free P((void*));
+#ifdef HAVE_PROTOTYPES
+# define _(args) args
+#else
+# define _(args) ()
+#endif
+
+void *xmalloc _((unsigned long));
+void *xcalloc _((unsigned long,unsigned long));
+void *xrealloc _((void*,unsigned long));
+void free _((void*));
/* #define NO_ALLOCA /* try it out for now */
#ifndef NO_ALLOCA
@@ -132,16 +152,16 @@ char *alloca();
#include "regex.h"
/* Subroutines for re_compile_pattern. */
-static void store_jump P((char*, int, char*));
-static void insert_jump P((int, char*, char*, char*));
-static void store_jump_n P((char*, int, char*, unsigned));
-static void insert_jump_n P((int, char*, char*, char*, unsigned));
-static void insert_op P((int, char*, char*));
-static void insert_op_2 P((int, char*, char*, int, int));
-static int memcmp_translate P((unsigned char*, unsigned char*, int));
-static int alt_match_null_string_p ();
-static int common_op_match_null_string_p ();
-static int group_match_null_string_p ();
+static void store_jump _((char*, int, char*));
+static void insert_jump _((int, char*, char*, char*));
+static void store_jump_n _((char*, int, char*, unsigned));
+static void insert_jump_n _((int, char*, char*, char*, unsigned));
+static void insert_op _((int, char*, char*));
+static void insert_op_2 _((int, char*, char*, int, int));
+static int memcmp_translate _((unsigned char*, unsigned char*, int));
+static int alt_match_null_string_p();
+static int common_op_match_null_string_p();
+static int group_match_null_string_p();
/* Define the syntax stuff, so we can do the \<, \>, etc. */
@@ -153,15 +173,17 @@ static int group_match_null_string_p ();
#define SYNTAX(c) re_syntax_table[c]
static char re_syntax_table[256];
-static void init_syntax_once P((void));
+static void init_syntax_once _((void));
static unsigned char *translate = 0;
-static void init_regs P((struct re_registers*, unsigned int));
-static void bm_init_skip P((int *, unsigned char*, int, char*));
+static void init_regs _((struct re_registers*, unsigned int));
+static void bm_init_skip _((int *, unsigned char*, int, char*));
static int current_mbctype = MBCTYPE_ASCII;
#undef P
+#ifdef RUBY
#include "util.h"
+#endif
static void
init_syntax_once()
@@ -201,28 +223,54 @@ re_set_casetable(table)
STDC_HEADERS is defined, then autoconf has verified that the ctype
macros don't need to be guarded with references to isascii. ...
Defining isascii to 1 should let any compiler worth its salt
- eliminate the && through constant folding." */
+ eliminate the && through constant folding."
+ Solaris defines some of these symbols so we must undefine them first. */
+
+#undef ISASCII
+#if defined STDC_HEADERS || (!defined isascii && !defined HAVE_ISASCII)
+# define ISASCII(c) 1
+#else
+# define ISASCII(c) isascii(c)
+#endif
+
#ifdef isblank
-#define ISBLANK(c) isblank ((unsigned char)c)
+# define ISBLANK(c) (ISASCII (c) && isblank (c))
#else
-#define ISBLANK(c) ((c) == ' ' || (c) == '\t')
+# define ISBLANK(c) ((c) == ' ' || (c) == '\t')
#endif
#ifdef isgraph
-#define ISGRAPH(c) isgraph ((unsigned char)c)
+# define ISGRAPH(c) (ISASCII (c) && isgraph (c))
#else
-#define ISGRAPH(c) (isprint ((unsigned char)c) && !isspace ((unsigned char)c))
+# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c))
#endif
-#define ISPRINT(c) isprint ((unsigned char)c)
-#define ISDIGIT(c) isdigit ((unsigned char)c)
-#define ISALNUM(c) isalnum ((unsigned char)c)
-#define ISALPHA(c) isalpha ((unsigned char)c)
-#define ISCNTRL(c) iscntrl ((unsigned char)c)
-#define ISLOWER(c) islower ((unsigned char)c)
-#define ISPUNCT(c) ispunct ((unsigned char)c)
-#define ISSPACE(c) isspace ((unsigned char)c)
-#define ISUPPER(c) isupper ((unsigned char)c)
-#define ISXDIGIT(c) isxdigit ((unsigned char)c)
+#undef ISPRINT
+#define ISPRINT(c) (ISASCII (c) && isprint (c))
+#define ISDIGIT(c) (ISASCII (c) && isdigit (c))
+#define ISALNUM(c) (ISASCII (c) && isalnum (c))
+#define ISALPHA(c) (ISASCII (c) && isalpha (c))
+#define ISCNTRL(c) (ISASCII (c) && iscntrl (c))
+#define ISLOWER(c) (ISASCII (c) && islower (c))
+#define ISPUNCT(c) (ISASCII (c) && ispunct (c))
+#define ISSPACE(c) (ISASCII (c) && isspace (c))
+#define ISUPPER(c) (ISASCII (c) && isupper (c))
+#define ISXDIGIT(c) (ISASCII (c) && isxdigit (c))
+
+#ifndef NULL
+# define NULL (void *)0
+#endif
+
+/* We remove any previous definition of `SIGN_EXTEND_CHAR',
+ since ours (we hope) works properly with all combinations of
+ machines, compilers, `char' and `unsigned char' argument types.
+ (Per Bothner suggested the basic approach.) */
+#undef SIGN_EXTEND_CHAR
+#if __STDC__
+# define SIGN_EXTEND_CHAR(c) ((signed char) (c))
+#else /* not __STDC__ */
+/* As in Harbison and Steele. */
+# define SIGN_EXTEND_CHAR(c) ((((unsigned char) (c)) ^ 128) - 128)
+#endif
/* These are the command codes that appear in compiled regular
expressions, one per byte. Some command codes are followed by
@@ -324,14 +372,6 @@ enum regexpcode
#define NFAILURES 80
#endif
-#if defined(CHAR_UNSIGNED) || defined(__CHAR_UNSIGNED__)
-#define SIGN_EXTEND_CHAR(c) ((c)>(char)127?(c)-256:(c)) /* for IBM RT */
-#endif
-#ifndef SIGN_EXTEND_CHAR
-#define SIGN_EXTEND_CHAR(x) (x)
-#endif
-
-
/* Store NUMBER in two contiguous bytes starting at DESTINATION. */
#define STORE_NUMBER(destination, number) \
do { (destination)[0] = (number) & 0377; \
@@ -401,7 +441,7 @@ re_set_syntax(syntax)
#define MBC2WC(c, p)\
do {\
if (current_mbctype == MBCTYPE_UTF8) {\
- int n = ismbchar(c);\
+ int n = mbclen(c) - 1;\
int c1;\
c &= (1<<(BYTEWIDTH-2-n)) - 1;\
while (n--) {\
@@ -416,7 +456,7 @@ re_set_syntax(syntax)
#define PATFETCH_MBC(c) \
do {\
- if (p + ismbchar(c) == pend) goto end_of_pattern;\
+ if (p + mbclen(c) - 1 >= pend) goto end_of_pattern;\
MBC2WC(c, p);\
} while(0)
@@ -667,7 +707,7 @@ print_partial_compiled_pattern(start, end)
if (start == NULL)
{
- printf ("(null)\n");
+ printf("(null)\n");
return;
}
@@ -677,12 +717,12 @@ print_partial_compiled_pattern(start, end)
switch ((enum regexpcode)*p++)
{
case unused:
- printf ("/unused");
+ printf("/unused");
break;
case exactn:
mcnt = *p++;
- printf ("/exactn/%d", mcnt);
+ printf("/exactn/%d", mcnt);
do
{
putchar('/');
@@ -693,46 +733,46 @@ print_partial_compiled_pattern(start, end)
case start_memory:
mcnt = *p++;
- printf ("/start_memory/%d/%d", mcnt, *p++);
+ printf("/start_memory/%d/%d", mcnt, *p++);
break;
case stop_memory:
mcnt = *p++;
- printf ("/stop_memory/%d/%d", mcnt, *p++);
+ printf("/stop_memory/%d/%d", mcnt, *p++);
break;
case stop_paren:
- printf ("/stop_paren");
+ printf("/stop_paren");
break;
case casefold_on:
- printf ("/casefold_on");
+ printf("/casefold_on");
break;
case casefold_off:
- printf ("/casefold_off");
+ printf("/casefold_off");
break;
case start_nowidth:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- printf ("/start_nowidth//%d", mcnt);
+ printf("/start_nowidth//%d", mcnt);
break;
case stop_nowidth:
- printf ("/stop_nowidth//");
+ printf("/stop_nowidth//");
p += 2;
break;
case pop_and_fail:
- printf ("/pop_and_fail");
+ printf("/pop_and_fail");
break;
case duplicate:
- printf ("/duplicate/%d", *p++);
+ printf("/duplicate/%d", *p++);
break;
case anychar:
- printf ("/anychar");
+ printf("/anychar");
break;
case charset:
@@ -740,8 +780,8 @@ print_partial_compiled_pattern(start, end)
{
register int c;
- printf ("/charset%s",
- (enum regexpcode)*(p - 1) == charset_not ? "_not" : "");
+ printf("/charset%s",
+ (enum regexpcode)*(p - 1) == charset_not ? "_not" : "");
mcnt = *p++;
printf("/%d", mcnt);
@@ -768,121 +808,121 @@ print_partial_compiled_pattern(start, end)
}
case begline:
- printf ("/begline");
+ printf("/begline");
break;
case endline:
- printf ("/endline");
+ printf("/endline");
break;
case on_failure_jump:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- printf ("/on_failure_jump//%d", mcnt);
+ printf("/on_failure_jump//%d", mcnt);
break;
case dummy_failure_jump:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- printf ("/dummy_failure_jump//%d", mcnt);
+ printf("/dummy_failure_jump//%d", mcnt);
break;
case push_dummy_failure:
- printf ("/push_dummy_failure");
+ printf("/push_dummy_failure");
break;
case finalize_jump:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- printf ("/finalize_jump//%d", mcnt);
+ printf("/finalize_jump//%d", mcnt);
break;
case maybe_finalize_jump:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- printf ("/maybe_finalize_jump//%d", mcnt);
+ printf("/maybe_finalize_jump//%d", mcnt);
break;
case jump_past_alt:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- printf ("/jump_past_alt//%d", mcnt);
+ printf("/jump_past_alt//%d", mcnt);
break;
case jump:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- printf ("/jump//%d", mcnt);
+ printf("/jump//%d", mcnt);
break;
case succeed_n:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
EXTRACT_NUMBER_AND_INCR (mcnt2, p);
- printf ("/succeed_n//%d//%d", mcnt, mcnt2);
+ printf("/succeed_n//%d//%d", mcnt, mcnt2);
break;
case jump_n:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
EXTRACT_NUMBER_AND_INCR (mcnt2, p);
- printf ("/jump_n//%d//%d", mcnt, mcnt2);
+ printf("/jump_n//%d//%d", mcnt, mcnt2);
break;
case set_number_at:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
EXTRACT_NUMBER_AND_INCR (mcnt2, p);
- printf ("/set_number_at//%d//%d", mcnt, mcnt2);
+ printf("/set_number_at//%d//%d", mcnt, mcnt2);
break;
case try_next:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- printf ("/try_next//%d", mcnt);
+ printf("/try_next//%d", mcnt);
break;
case finalize_push:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
- printf ("/finalize_push//%d", mcnt);
+ printf("/finalize_push//%d", mcnt);
break;
case finalize_push_n:
EXTRACT_NUMBER_AND_INCR (mcnt, p);
EXTRACT_NUMBER_AND_INCR (mcnt2, p);
- printf ("/finalize_push_n//%d//%d", mcnt, mcnt2);
+ printf("/finalize_push_n//%d//%d", mcnt, mcnt2);
break;
case wordbound:
- printf ("/wordbound");
+ printf("/wordbound");
break;
case notwordbound:
- printf ("/notwordbound");
+ printf("/notwordbound");
break;
case wordbeg:
- printf ("/wordbeg");
+ printf("/wordbeg");
break;
case wordend:
- printf ("/wordend");
+ printf("/wordend");
case wordchar:
- printf ("/wordchar");
+ printf("/wordchar");
break;
case notwordchar:
- printf ("/notwordchar");
+ printf("/notwordchar");
break;
case begbuf:
- printf ("/begbuf");
+ printf("/begbuf");
break;
case endbuf:
- printf ("/endbuf");
+ printf("/endbuf");
break;
case endbuf2:
- printf ("/endbuf2");
+ printf("/endbuf2");
break;
default:
- printf ("?%d", *(p-1));
+ printf("?%d", *(p-1));
}
}
- printf ("/\n");
+ printf("/\n");
}
@@ -1269,7 +1309,8 @@ re_compile_pattern(pattern, size, bufp)
int size;
unsigned last = (unsigned)-1;
- if ((size = EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH]))) {
+ if ((size = EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH]))
+ || current_mbctype) {
/* Ensure the space is enough to hold another interval
of multi-byte chars in charset(_not)?. */
size = (1 << BYTEWIDTH) / BYTEWIDTH + 2 + size*8 + 8;
@@ -2026,7 +2067,7 @@ re_compile_pattern(pattern, size, bufp)
c1 = p - pattern;
}
numeric_char:
- nextp = p + ismbchar(c);
+ nextp = p + mbclen(c) - 1;
if (!pending_exact || pending_exact + *pending_exact + 1 != b
|| *pending_exact >= (c1 ? 0176 : 0177)
|| *nextp == '+' || *nextp == '?'
@@ -2044,7 +2085,7 @@ re_compile_pattern(pattern, size, bufp)
BUFPUSH(c);
(*pending_exact)++;
if (had_mbchar) {
- int len = ismbchar(c);
+ int len = mbclen(c) - 1;
while (len--) {
PATFETCH_RAW(c);
BUFPUSH(c);
@@ -2330,7 +2371,7 @@ slow_search(little, llen, big, blen, translate)
}
else if (translate && !ismbchar(c)) {
while (big < bend) {
- if (ismbchar(*big)) big+=ismbchar(*big);
+ if (ismbchar(*big)) big+=mbclen(*big)-1;
else if (translate[*big] == c) break;
big++;
}
@@ -2338,7 +2379,7 @@ slow_search(little, llen, big, blen, translate)
else {
while (big < bend) {
if (*big == c) break;
- if (ismbchar(*big)) big+=ismbchar(*big);
+ if (ismbchar(*big)) big+=mbclen(*big)-1;
big++;
}
}
@@ -2346,7 +2387,7 @@ slow_search(little, llen, big, blen, translate)
if (slow_match(little, little+llen, big, bend, translate))
return big - bsave;
- if (ismbchar(*big)) big+=ismbchar(*big);
+ if (ismbchar(*big)) big+=mbclen(*big);
big++;
}
return -1;
@@ -2857,7 +2898,7 @@ re_search(bufp, string, size, startpos, range, regs)
while (range > 0) {
c = *p++;
if (ismbchar(c)) {
- int len = ismbchar(c);
+ int len = mbclen(c) - 1;
if (fastmap[c])
break;
p += len;
@@ -2945,7 +2986,8 @@ re_search(bufp, string, size, startpos, range, regs)
const char *d = string + startpos;
if (ismbchar(*d)) {
- range-=ismbchar(*d), startpos+=ismbchar(*d);
+ int len = mbclen(*d) - 1;
+ range-=len, startpos+=len;
if (!range)
break;
}
@@ -2977,14 +3019,7 @@ re_search(bufp, string, size, startpos, range, regs)
/* The following are used for re_match, defined below: */
-/* Roughly the maximum number of failure points on the stack. Would be
- exactly that if always pushed MAX_NUM_FAILURE_ITEMS each time we failed. */
-
-int re_max_failures = 2000;
-
/* Routine used by re_match. */
-/* static int memcmp_translate(); *//* already declared */
-
/* Structure and accessing macros used in re_match: */
@@ -3239,7 +3274,7 @@ re_match(bufp, string_arg, size, pos, regs)
stacke = &stackb[MAX_NUM_FAILURE_ITEMS * NFAILURES];
#ifdef DEBUG_REGEX
- fprintf (stderr, "Entering re_match(%s%s)\n", string1_arg, string2_arg);
+ fprintf(stderr, "Entering re_match(%s%s)\n", string1_arg, string2_arg);
#endif
/* Initialize subexpression text positions to -1 to mark ones that no
@@ -3553,7 +3588,7 @@ re_match(bufp, string_arg, size, pos, regs)
PREFETCH;
cc = c = (unsigned char)*d++;
if (ismbchar(c)) {
- if (d + ismbchar(c) <= dend) {
+ if (d + mbclen(c) - 1 <= dend) {
MBC2WC(c, d);
}
}
@@ -3878,8 +3913,8 @@ re_match(bufp, string_arg, size, pos, regs)
PREFETCH;
if (!IS_A_LETTER(d))
goto fail;
- if (ismbchar(*d) && d + ismbchar(*d) < dend)
- d += ismbchar(*d);
+ if (ismbchar(*d) && d + mbclen(*d) - 1 < dend)
+ d += mbclen(*d) - 1;
d++;
SET_REGS_MATCHED;
break;
@@ -3888,8 +3923,8 @@ re_match(bufp, string_arg, size, pos, regs)
PREFETCH;
if (IS_A_LETTER(d))
goto fail;
- if (ismbchar(*d) && d + ismbchar(*d) < dend)
- d += ismbchar(*d);
+ if (ismbchar(*d) && d + mbclen(*d) - 1 < dend)
+ d += mbclen(*d) - 1;
d++;
SET_REGS_MATCHED;
break;
@@ -3917,12 +3952,16 @@ re_match(bufp, string_arg, size, pos, regs)
continue;
}
if (ismbchar(c)) {
- if (c != (unsigned char)*p++
- || !--mcnt /* redundant check if pattern was
- compiled properly. */
- || AT_STRINGS_END(d)
- || (unsigned char)*d++ != (unsigned char)*p++)
+ int n;
+
+ if (c != (unsigned char)*p++)
goto fail;
+ for (n = mbclen(c) - 1; n > 0; n--)
+ if (!--mcnt /* redundant check if pattern was
+ compiled properly. */
+ || AT_STRINGS_END(d)
+ || (unsigned char)*d++ != (unsigned char)*p++)
+ goto fail;
continue;
}
/* compiled code translation needed for ruby */
@@ -3945,8 +3984,10 @@ re_match(bufp, string_arg, size, pos, regs)
SET_REGS_MATCHED;
break;
}
+#if 0
while (stackp != stackb && (int)stackp[-1] == 1)
POP_FAILURE_POINT();
+#endif
continue; /* Successfully executed one pattern command; keep going. */
/* Jump here if any matching operation fails. */
@@ -4287,8 +4328,12 @@ memcmp_translate(s1, s2, len)
{
c = *p1++;
if (ismbchar(c)) {
+ int n;
+
if (c != *p2++) return 1;
- if (memcmp(p1, p2, ismbchar(c))) return 1;
+ for (n = mbclen(c) - 1; n > 0; n--)
+ if (!--len || *p1++ != *p2++)
+ return 1;
}
else
if (translate[c] != translate[*p2++])
diff --git a/regex.h b/regex.h
index 0f41931a9c..66ee23aa5a 100644
--- a/regex.h
+++ b/regex.h
@@ -24,15 +24,15 @@
/* symbol mangling for ruby */
#ifdef RUBY
-# define re_compile_fastmap rb_re_compile_fastmap
-# define re_compile_pattern rb_re_compile_pattern
-# define re_copy_registers rb_re_copy_registers
-# define re_free_pattern rb_re_free_pattern
-# define re_free_registers rb_re_free_registers
-# define re_match rb_re_match
-# define re_mbcinit rb_re_mbcinit
-# define re_search rb_re_search
-# define re_set_casetable rb_re_set_casetable
+# define re_compile_fastmap ruby_re_compile_fastmap
+# define re_compile_pattern ruby_re_compile_pattern
+# define re_copy_registers ruby_re_copy_registers
+# define re_free_pattern ruby_re_free_pattern
+# define re_free_registers ruby_re_free_registers
+# define re_match ruby_re_match
+# define re_mbcinit ruby_re_mbcinit
+# define re_search ruby_re_search
+# define re_set_casetable ruby_re_set_casetable
#endif
#include <stddef.h>
diff --git a/ruby.h b/ruby.h
index 2e470c640a..49169d94cb 100644
--- a/ruby.h
+++ b/ruby.h
@@ -39,10 +39,11 @@ extern "C" {
#include <stdio.h>
/* need to include <ctype.h> to use these macros */
+#undef ISPRINT
+#define ISPRINT(c) isprint((unsigned char)(c))
#define ISSPACE(c) isspace((unsigned char)(c))
#define ISUPPER(c) isupper((unsigned char)(c))
#define ISLOWER(c) islower((unsigned char)(c))
-#define ISPRINT(c) isprint((unsigned char)(c))
#define ISALNUM(c) isalnum((unsigned char)(c))
#define ISALPHA(c) isalpha((unsigned char)(c))
#define ISDIGIT(c) isdigit((unsigned char)(c))
@@ -480,7 +481,9 @@ EXTERN VALUE rb_cStruct;
EXTERN VALUE rb_eException;
EXTERN VALUE rb_eStandardError;
-EXTERN VALUE rb_eSystemExit, rb_eInterrupt, rb_eFatal;
+EXTERN VALUE rb_eSystemExit;
+EXTERN VALUE rb_eInterrupt;
+EXTERN VALUE rb_eFatal;
EXTERN VALUE rb_eArgError;
EXTERN VALUE rb_eEOFError;
EXTERN VALUE rb_eIndexError;
@@ -492,8 +495,9 @@ EXTERN VALUE rb_eSecurityError;
EXTERN VALUE rb_eSyntaxError;
EXTERN VALUE rb_eSystemCallError;
EXTERN VALUE rb_eTypeError;
-EXTERN VALUE rb_eZeroDiv;
+EXTERN VALUE rb_eZeroDivError;
EXTERN VALUE rb_eNotImpError;
+EXTERN VALUE rb_eFloatDomainError;
#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(RUBY_NO_INLINE)
extern __inline__ VALUE rb_class_of _((VALUE));
diff --git a/string.c b/string.c
index 1a6eb07959..4ba404d4d6 100644
--- a/string.c
+++ b/string.c
@@ -306,10 +306,14 @@ rb_str_substr(str, start, len)
{
VALUE str2;
+ if (len == 0) return rb_str_new(0,0);
+ if (len < 0) {
+ rb_raise(rb_eIndexError, "negative length %d", len);
+ }
if (start < 0) {
start = RSTRING(str)->len + start;
}
- if (RSTRING(str)->len <= start || len < 0) {
+ if (RSTRING(str)->len <= start) {
return rb_str_new(0,0);
}
if (RSTRING(str)->len < start + len) {
@@ -327,33 +331,27 @@ rb_str_subseq(str, beg, end)
VALUE str;
int beg, end;
{
- int len;
-
- if ((beg > 0 && end > 0 || beg < 0 && end < 0) && beg > end) {
- rb_raise(rb_eIndexError, "end smaller than beg [%d..%d]", beg, end);
- }
+ int b, e, len;
+ b = beg; e = end;
if (beg < 0) {
beg = RSTRING(str)->len + beg;
- if (beg < 0) beg = 0;
}
if (end < 0) {
end = RSTRING(str)->len + end;
- if (end < 0) end = -1;
- else if (RSTRING(str)->len < end) {
- end = RSTRING(str)->len;
- }
}
-
- if (beg >= RSTRING(str)->len) {
+ if (beg > end) {
+ if (e != -1) {
+ rb_raise(rb_eIndexError, "end smaller than beg [%d..%d]", b, e);
+ }
return rb_str_new(0, 0);
}
- len = end - beg + 1;
- if (len < 0) {
+ if (beg >= RSTRING(str)->len) {
len = 0;
}
+ len = end - beg + 1;
return rb_str_substr(str, beg, len);
}
@@ -863,41 +861,34 @@ rb_str_replace(str, beg, len, val)
RSTRING(str)->ptr[RSTRING(str)->len] = '\0';
}
-/* rb_str_replace2() understands negatice offset */
+/* rb_str_replace2() understands negative offset */
static void
rb_str_replace2(str, beg, end, val)
VALUE str, val;
int beg, end;
{
- int len;
-
- if ((beg > 0 && end > 0 || beg < 0 && end < 0) && beg > end) {
- rb_raise(rb_eIndexError, "end smaller than beg [%d..%d]", beg, end);
- }
+ int b, e, len;
+ b = beg; e = end;
if (beg < 0) {
beg = RSTRING(str)->len + beg;
- if (beg < 0) {
- beg = 0;
- }
- }
- if (RSTRING(str)->len <= beg) {
- beg = RSTRING(str)->len;
}
if (end < 0) {
end = RSTRING(str)->len + end;
- if (end < 0) {
- end = 0;
- }
}
- if (RSTRING(str)->len <= end) {
- end = RSTRING(str)->len - 1;
+ if (beg > end) {
+ if (e != -1) {
+ rb_raise(rb_eIndexError, "end smaller than beg [%d..%d]", b, e);
+ }
+ end = beg - 1;
}
- len = end - beg + 1; /* length of substring */
- if (len < 0) {
+ if (beg >= RSTRING(str)->len) {
+ beg = RSTRING(str)->len;
len = 0;
}
-
+ else {
+ len = end - beg + 1;
+ }
rb_str_replace(str, beg, len, val);
}
@@ -1529,7 +1520,7 @@ rb_str_upcase_bang(str)
s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;
while (s < send) {
if (ismbchar(*s)) {
- s+=mbclen(*s);
+ s+=mbclen(*s) - 1;
}
else if (islower(*s)) {
*s = toupper(*s);
@@ -1563,7 +1554,7 @@ rb_str_downcase_bang(str)
s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;
while (s < send) {
if (ismbchar(*s)) {
- s+=mbclen(*s);
+ s+=mbclen(*s) - 1;
}
else if (ISUPPER(*s)) {
*s = tolower(*s);
@@ -1601,7 +1592,7 @@ rb_str_capitalize_bang(str)
}
while (++s < send) {
if (ismbchar(*s)) {
- s+=mbclen(*s);
+ s+=mbclen(*s) - 1;
}
else if (ISUPPER(*s)) {
*s = tolower(*s);
@@ -1633,7 +1624,7 @@ rb_str_swapcase_bang(str)
s = RSTRING(str)->ptr; send = s + RSTRING(str)->len;
while (s < send) {
if (ismbchar(*s)) {
- s+=mbclen(*s);
+ s+=mbclen(*s) - 1;
}
else if (ISUPPER(*s)) {
*s = tolower(*s);
diff --git a/struct.c b/struct.c
index 3feceb33fd..5ed5038497 100644
--- a/struct.c
+++ b/struct.c
@@ -16,6 +16,8 @@
VALUE rb_cStruct;
+static VALUE struct_alloc _((int, VALUE*, VALUE));
+
static VALUE
class_of(obj)
VALUE obj;
@@ -150,8 +152,8 @@ make_struct(name, member, klass)
rb_iv_set(nstr, "__size__", INT2FIX(RARRAY(member)->len));
rb_iv_set(nstr, "__member__", member);
- rb_define_singleton_method(nstr, "new", rb_struct_alloc, -2);
- rb_define_singleton_method(nstr, "[]", rb_struct_alloc, -2);
+ rb_define_singleton_method(nstr, "new", struct_alloc, -1);
+ rb_define_singleton_method(nstr, "[]", struct_alloc, -1);
rb_define_singleton_method(nstr, "members", rb_struct_s_members, 0);
for (i=0; i< RARRAY(member)->len; i++) {
ID id = FIX2INT(RARRAY(member)->ptr[i]);
@@ -221,10 +223,11 @@ rb_struct_s_def(argc, argv, klass)
return st;
}
-VALUE
-rb_struct_alloc(klass, values)
- VALUE klass, values;
+static VALUE
+rb_struct_initialize(self, values)
+ VALUE self, values;
{
+ VALUE klass = CLASS_OF(self);
VALUE size;
int n;
@@ -233,18 +236,39 @@ rb_struct_alloc(klass, values)
if (n != RARRAY(values)->len) {
rb_raise(rb_eArgError, "struct size differs");
}
- else {
- NEWOBJ(st, struct RStruct);
- OBJSETUP(st, klass, T_STRUCT);
- st->len = 0; /* avoid GC crashing */
- st->ptr = ALLOC_N(VALUE, n);
- st->len = n;
- MEMCPY(st->ptr, RARRAY(values)->ptr, VALUE, RARRAY(values)->len);
- rb_obj_call_init((VALUE)st);
-
- return (VALUE)st;
- }
- return Qnil; /* not reached */
+ MEMCPY(RSTRUCT(self)->ptr, RARRAY(values)->ptr, VALUE, RARRAY(values)->len);
+ return Qnil;
+}
+
+static VALUE
+struct_alloc(argc, argv, klass)
+ int argc;
+ VALUE *argv;
+ VALUE klass;
+{
+ VALUE size;
+ int n;
+
+ NEWOBJ(st, struct RStruct);
+ OBJSETUP(st, klass, T_STRUCT);
+
+ size = rb_iv_get(klass, "__size__");
+ n = FIX2INT(size);
+
+ st->len = 0; /* avoid GC crashing */
+ st->ptr = ALLOC_N(VALUE, n);
+ rb_mem_clear(st->ptr, n);
+ st->len = n;
+ rb_obj_call_init2((VALUE)st, argc, argv);
+
+ return (VALUE)st;
+}
+
+VALUE
+rb_struct_alloc(klass, values)
+ VALUE klass, values;
+{
+ return struct_alloc(RARRAY(values)->len, RARRAY(values)->ptr, klass);
}
VALUE
@@ -256,21 +280,20 @@ rb_struct_new(klass, va_alist)
va_dcl
#endif
{
- VALUE val, mem;
+ VALUE sz, *mem;
int size, i;
va_list args;
- val = rb_iv_get(klass, "__size__");
- size = FIX2INT(val);
- mem = rb_ary_new2(size);
+ sz = rb_iv_get(klass, "__size__");
+ size = FIX2INT(sz);
+ mem = ALLOCA_N(VALUE, size);
va_init_list(args, klass);
for (i=0; i<size; i++) {
- val = va_arg(args, VALUE);
- rb_ary_store(mem, i, val);
+ mem[i] = va_arg(args, VALUE);
}
va_end(args);
- return rb_struct_alloc(klass, mem);
+ return struct_alloc(size, mem, klass);
}
static VALUE
@@ -511,6 +534,7 @@ Init_Struct()
rb_define_singleton_method(rb_cStruct, "new", rb_struct_s_def, -1);
+ rb_define_method(rb_cStruct, "initialize", rb_struct_initialize, -2);
rb_define_method(rb_cStruct, "clone", rb_struct_clone, 0);
rb_define_method(rb_cStruct, "==", rb_struct_equal, 1);
diff --git a/time.c b/time.c
index e58fc4cf70..e059273b72 100644
--- a/time.c
+++ b/time.c
@@ -13,11 +13,6 @@
#include "ruby.h"
#include <sys/types.h>
-#ifdef USE_CWGUSI
-int gettimeofday(struct timeval*, struct timezone*);
-int strcasecmp(char*, char*);
-#endif
-
#include <time.h>
#ifndef NT
#ifdef HAVE_SYS_TIME_H
@@ -33,7 +28,16 @@ struct timeval {
#ifdef HAVE_SYS_TIMES_H
#include <sys/times.h>
#endif
+
+#ifdef USE_CWGUSI
+typedef int time_t;
+time_t gettimeofday(struct timeval*, struct timezone*);
+time_t strcasecmp(char*, char*);
+#endif
+
+#if 0
#include <math.h>
+#endif
VALUE rb_cTime;
#if defined(HAVE_TIMES) || defined(NT)
@@ -63,7 +67,7 @@ time_s_now(klass)
obj = Data_Make_Struct(klass, struct time_object, 0, free, tobj);
tobj->tm_got=0;
- if (gettimeofday(&(tobj->tv), 0) == -1) {
+ if (gettimeofday(&(tobj->tv), 0) < 0) {
rb_sys_fail("gettimeofday");
}
rb_obj_call_init(obj);
@@ -74,7 +78,7 @@ time_s_now(klass)
static VALUE
time_new_internal(klass, sec, usec)
VALUE klass;
- int sec, usec;
+ time_t sec, usec;
{
VALUE obj;
struct time_object *tobj;
@@ -93,7 +97,7 @@ time_new_internal(klass, sec, usec)
VALUE
rb_time_new(sec, usec)
- int sec, usec;
+ time_t sec, usec;
{
return time_new_internal(rb_cTime, sec, usec);
}
@@ -107,7 +111,7 @@ rb_time_timeval(time)
switch (TYPE(time)) {
case T_FIXNUM:
- t.tv_sec = FIX2INT(time);
+ t.tv_sec = FIX2LONG(time);
if (t.tv_sec < 0)
rb_raise(rb_eArgError, "time must be positive");
t.tv_usec = 0;
@@ -121,7 +125,7 @@ rb_time_timeval(time)
break;
case T_BIGNUM:
- t.tv_sec = NUM2INT(time);
+ t.tv_sec = NUM2LONG(time);
if (t.tv_sec < 0)
rb_raise(rb_eArgError, "time must be positive");
t.tv_usec = 0;
@@ -154,22 +158,22 @@ static char *months [12] = {
"jul", "aug", "sep", "oct", "nov", "dec",
};
-static int
-obj2int(obj)
+static long
+obj2long(obj)
VALUE obj;
{
if (TYPE(obj) == T_STRING) {
obj = rb_str2inum(RSTRING(obj)->ptr, 10);
}
- return NUM2INT(obj);
+ return NUM2LONG(obj);
}
static void
-time_arg(argc, argv, args)
+time_arg(argc, argv, tm)
int argc;
VALUE *argv;
- int *args;
+ struct tm *tm;
{
VALUE v[6];
int i;
@@ -186,102 +190,91 @@ time_arg(argc, argv, args)
rb_scan_args(argc, argv, "15", &v[0],&v[1],&v[2],&v[3],&v[4],&v[5]);
}
- args[0] = obj2int(v[0]);
- if (args[0] < 70) args[0] += 100;
- if (args[0] > 1900) args[0] -= 1900;
+ tm->tm_year = obj2long(v[0]);
+ if (tm->tm_year < 69) tm->tm_year += 100;
+ if (tm->tm_year > 1900) tm->tm_year -= 1900;
if (NIL_P(v[1])) {
- args[1] = 0;
+ tm->tm_mon = 0;
}
else if (TYPE(v[1]) == T_STRING) {
- args[1] = -1;
+ tm->tm_mon = -1;
for (i=0; i<12; i++) {
- if (strcasecmp(months[i], RSTRING(v[1])->ptr) == 0) {
- args[1] = i;
+ if (RSTRING(v[1])->len == 3 &&
+ strcasecmp(months[i], RSTRING(v[1])->ptr) == 0) {
+ tm->tm_mon = i;
break;
}
}
- if (args[1] == -1) {
+ if (tm->tm_mon == -1) {
char c = RSTRING(v[1])->ptr[0];
if ('0' <= c && c <= '9') {
- args[1] = obj2int(v[1])-1;
+ tm->tm_mon = obj2long(v[1])-1;
}
}
}
else {
- args[1] = obj2int(v[1]) - 1;
+ tm->tm_mon = obj2long(v[1]) - 1;
}
if (NIL_P(v[2])) {
- args[2] = 1;
+ tm->tm_mday = 1;
}
else {
- args[2] = obj2int(v[2]);
- }
- for (i=3;i<6;i++) {
- if (NIL_P(v[i])) {
- args[i] = 0;
- }
- else {
- args[i] = obj2int(v[i]);
- }
+ tm->tm_mday = obj2long(v[2]);
}
+ tm->tm_hour = NIL_P(v[3])?0:obj2long(v[3]);
+ tm->tm_min = NIL_P(v[4])?0:obj2long(v[4]);
+ tm->tm_sec = NIL_P(v[5])?0:obj2long(v[5]);
/* value validation */
- if ( args[0] < 70|| args[0] > 137
- || args[1] < 0 || args[1] > 11
- || args[2] < 1 || args[2] > 31
- || args[3] < 0 || args[3] > 23
- || args[4] < 0 || args[4] > 59
- || args[5] < 0 || args[5] > 60)
+ if ( tm->tm_year < 69
+ || tm->tm_mon < 0 || tm->tm_mon > 11
+ || tm->tm_mday < 1 || tm->tm_mday > 31
+ || tm->tm_hour < 0 || tm->tm_hour > 23
+ || tm->tm_min < 0 || tm->tm_min > 59
+ || tm->tm_sec < 0 || tm->tm_sec > 60)
rb_raise(rb_eArgError, "argument out of range");
}
static VALUE time_gmtime _((VALUE));
static VALUE time_localtime _((VALUE));
-static VALUE
-time_gm_or_local(argc, argv, gm_or_local, klass)
- int argc;
- VALUE *argv;
- int gm_or_local;
- VALUE klass;
+
+static time_t
+make_time_t(tptr, fn)
+ struct tm *tptr;
+ struct tm *(*fn)();
{
- int args[6];
struct timeval tv;
- struct tm *tm;
time_t guess, t;
- int diff;
- struct tm *(*fn)();
- VALUE time;
-
- fn = (gm_or_local) ? gmtime : localtime;
- time_arg(argc, argv, args);
+ struct tm *tm;
+ long diff;
- gettimeofday(&tv, 0);
+ if (gettimeofday(&tv, 0) < 0) {
+ rb_sys_fail("gettimeofday");
+ }
guess = tv.tv_sec;
tm = (*fn)(&guess);
if (!tm) goto error;
- t = args[0];
+ t = tptr->tm_year;
while (diff = t - (tm->tm_year)) {
guess += diff * 364 * 24 * 3600;
- if (guess < 0) rb_raise(rb_eArgError, "too far future");
tm = (*fn)(&guess);
if (!tm) goto error;
}
- t = args[1];
+ t = tptr->tm_mon;
while (diff = t - tm->tm_mon) {
guess += diff * 27 * 24 * 3600;
tm = (*fn)(&guess);
if (!tm) goto error;
}
- guess += (args[2] - tm->tm_mday) * 3600 * 24;
- guess += (args[3] - tm->tm_hour) * 3600;
- guess += (args[4] - tm->tm_min) * 60;
- guess += args[5] - tm->tm_sec;
+ guess += (tptr->tm_mday - tm->tm_mday) * 3600 * 24;
+ guess += (tptr->tm_hour - tm->tm_hour) * 3600;
+ guess += (tptr->tm_min - tm->tm_min) * 60;
+ guess += tptr->tm_sec - tm->tm_sec;
+ if (guess < 0) rb_raise(rb_eArgError, "too far future");
- time = time_new_internal(klass, guess, 0);
- if (gm_or_local) return time_gmtime(time);
- return time_localtime(time);
+ return guess;
error:
rb_raise(rb_eArgError, "gmtime/localtime error");
@@ -289,6 +282,25 @@ time_gm_or_local(argc, argv, gm_or_local, klass)
}
static VALUE
+time_gm_or_local(argc, argv, gm_or_local, klass)
+ int argc;
+ VALUE *argv;
+ int gm_or_local;
+ VALUE klass;
+{
+ struct tm tm;
+ struct tm *(*fn)();
+ VALUE time;
+
+ fn = (gm_or_local) ? gmtime : localtime;
+ time_arg(argc, argv, &tm);
+
+ time = time_new_internal(klass, make_time_t(&tm, fn), 0);
+ if (gm_or_local) return time_gmtime(time);
+ return time_localtime(time);
+}
+
+static VALUE
time_s_timegm(argc, argv, klass)
int argc;
VALUE *argv;
@@ -313,7 +325,7 @@ time_to_i(time)
struct time_object *tobj;
GetTimeval(time, tobj);
- return rb_int2inum(tobj->tv.tv_sec);
+ return INT2NUM(tobj->tv.tv_sec);
}
static VALUE
@@ -333,7 +345,7 @@ time_usec(time)
struct time_object *tobj;
GetTimeval(time, tobj);
- return INT2FIX(tobj->tv.tv_usec);
+ return INT2NUM(tobj->tv.tv_usec);
}
static VALUE
@@ -341,12 +353,12 @@ time_cmp(time1, time2)
VALUE time1, time2;
{
struct time_object *tobj1, *tobj2;
- int i;
+ long i;
GetTimeval(time1, tobj1);
switch (TYPE(time2)) {
case T_FIXNUM:
- i = FIX2INT(time2);
+ i = FIX2LONG(time2);
if (tobj1->tv.tv_sec == i) return INT2FIX(0);
if (tobj1->tv.tv_sec > i) return INT2FIX(1);
return FIX2INT(-1);
@@ -355,7 +367,7 @@ time_cmp(time1, time2)
{
double t;
- if (tobj1->tv.tv_sec == (int)RFLOAT(time2)->value) return INT2FIX(0);
+ if (tobj1->tv.tv_sec == (long)RFLOAT(time2)->value) return INT2FIX(0);
t = (double)tobj1->tv.tv_sec + (double)tobj1->tv.tv_usec*1e-6;
if (tobj1->tv.tv_sec == RFLOAT(time2)->value) return INT2FIX(0);
if (tobj1->tv.tv_sec > RFLOAT(time2)->value) return INT2FIX(1);
@@ -373,7 +385,7 @@ time_cmp(time1, time2)
if (tobj1->tv.tv_sec > tobj2->tv.tv_sec) return INT2FIX(1);
return FIX2INT(-1);
}
- i = NUM2INT(time2);
+ i = NUM2LONG(time2);
if (tobj1->tv.tv_sec == i) return INT2FIX(0);
if (tobj1->tv.tv_sec > i) return INT2FIX(1);
return FIX2INT(-1);
@@ -400,7 +412,7 @@ time_hash(time)
VALUE time;
{
struct time_object *tobj;
- int hash;
+ long hash;
GetTimeval(time, tobj);
hash = tobj->tv.tv_sec ^ tobj->tv.tv_usec;
@@ -463,7 +475,7 @@ time_to_s(time)
VALUE time;
{
struct time_object *tobj;
- char buf[64];
+ char buf[128];
int len;
GetTimeval(time, tobj);
@@ -472,12 +484,12 @@ time_to_s(time)
}
#ifndef HAVE_TM_ZONE
if (tobj->gmt == 1) {
- len = strftime(buf, 64, "%a %b %d %H:%M:%S GMT %Y", &(tobj->tm));
+ len = strftime(buf, 128, "%a %b %d %H:%M:%S GMT %Y", &(tobj->tm));
}
else
#endif
{
- len = strftime(buf, 64, "%a %b %d %H:%M:%S %Z %Y", &(tobj->tm));
+ len = strftime(buf, 128, "%a %b %d %H:%M:%S %Z %Y", &(tobj->tm));
}
return rb_str_new(buf, len);
}
@@ -488,22 +500,14 @@ time_plus(time1, time2)
{
struct time_object *tobj1, *tobj2;
long sec, usec;
+ double f;
GetTimeval(time1, tobj1);
- if (TYPE(time2) == T_FLOAT) {
- unsigned int nsec = (unsigned int)RFLOAT(time2)->value;
- sec = tobj1->tv.tv_sec + nsec;
- usec = tobj1->tv.tv_usec + (long)(RFLOAT(time2)->value-(double)nsec)*1e6;
- }
- else if (rb_obj_is_instance_of(time2, rb_cTime)) {
- GetTimeval(time2, tobj2);
- sec = tobj1->tv.tv_sec + tobj2->tv.tv_sec;
- usec = tobj1->tv.tv_usec + tobj2->tv.tv_usec;
- }
- else {
- sec = tobj1->tv.tv_sec + NUM2INT(time2);
- usec = tobj1->tv.tv_usec;
- }
+
+ f = NUM2DBL(time2);
+ sec = (long)f;
+ usec = tobj1->tv.tv_usec + (long)((f - (double)sec)*1e6);
+ sec = tobj1->tv.tv_sec + sec;
if (usec >= 1000000) { /* usec overflow */
sec++;
@@ -517,26 +521,23 @@ time_minus(time1, time2)
VALUE time1, time2;
{
struct time_object *tobj1, *tobj2;
- int sec, usec;
+ long sec, usec;
+ double f;
GetTimeval(time1, tobj1);
if (rb_obj_is_instance_of(time2, rb_cTime)) {
- double f;
GetTimeval(time2, tobj2);
f = tobj1->tv.tv_sec - tobj2->tv.tv_sec;
-
f += (tobj1->tv.tv_usec - tobj2->tv.tv_usec)*1e-6;
return rb_float_new(f);
}
- else if (TYPE(time2) == T_FLOAT) {
- sec = tobj1->tv.tv_sec - (int)RFLOAT(time2)->value;
- usec = tobj1->tv.tv_usec - (RFLOAT(time2)->value - (double)sec)*1e6;
- }
else {
- sec = tobj1->tv.tv_sec - NUM2INT(time2);
- usec = tobj1->tv.tv_usec;
+ f = NUM2DBL(time2);
+ sec = (long)f;
+ usec = tobj1->tv.tv_usec - (long)((f - (double)sec)*1e6);
+ sec = tobj1->tv.tv_sec - sec;
}
if (usec < 0) { /* usec underflow */
@@ -647,7 +648,7 @@ time_yday(time)
if (tobj->tm_got == 0) {
time_localtime(time);
}
- return INT2FIX(tobj->tm.tm_yday);
+ return INT2FIX(tobj->tm.tm_yday+1);
}
static VALUE
@@ -668,7 +669,7 @@ time_zone(time)
VALUE time;
{
struct time_object *tobj;
- char buf[10];
+ char buf[64];
int len;
GetTimeval(time, tobj);
@@ -676,7 +677,7 @@ time_zone(time)
time_localtime(time);
}
- len = strftime(buf, 10, "%Z", &(tobj->tm));
+ len = strftime(buf, 64, "%Z", &(tobj->tm));
return rb_str_new(buf, len);
}
@@ -698,7 +699,7 @@ time_to_a(time)
INT2FIX(tobj->tm.tm_mon+1),
INT2FIX(tobj->tm.tm_year+1900),
INT2FIX(tobj->tm.tm_wday),
- INT2FIX(tobj->tm.tm_yday),
+ INT2FIX(tobj->tm.tm_yday+1),
tobj->tm.tm_isdst?Qtrue:Qfalse,
time_zone(time));
}
@@ -710,23 +711,31 @@ rb_strftime(buf, format, time)
char * volatile format;
struct tm * volatile time;
{
- volatile int i;
- int len;
+ volatile int size;
+ int len, flen;
+ buf[0] = '\0';
+ flen = strlen(format);
+ if (flen == 0) {
+ return 0;
+ }
len = strftime(*buf, SMALLBUF, format, time);
if (len != 0) return len;
- for (i=1024; i<8192; i+=1024) {
- *buf = xmalloc(i);
- len = strftime(*buf, i-1, format, time);
- if (len == 0) {
- free(*buf);
- continue;
- }
- return len;
+ for (size=1024; ; size*=2) {
+ *buf = xmalloc(size);
+ buf[0] = '\0';
+ len = strftime(*buf, size, format, time);
+ /*
+ * buflen can be zero EITHER because there's not enough
+ * room in the string, or because the control command
+ * goes to the empty string. Make a reasonable guess that
+ * if the buffer is 1024 times bigger than the length of the
+ * format string, it's not failing for lack of room.
+ */
+ if (len > 0 || len >= 1024 * flen) return len;
+ free(*buf);
}
-
- rb_raise(rb_eArgError, "bad strftime format or result too long");
- return Qnil; /* not reached */
+ /* not reached */
}
static VALUE
@@ -745,6 +754,9 @@ time_strftime(time, format)
time_localtime(time);
}
fmt = str2cstr(format, &len);
+ if (len == 0) {
+ rb_warning("strftime called with empty format string");
+ }
if (strlen(fmt) < len) {
/* Ruby string may contain \0's. */
char *p = fmt, *pe = fmt + len;
@@ -754,6 +766,8 @@ time_strftime(time, format)
len = rb_strftime(&buf, p, &(tobj->tm));
rb_str_cat(str, buf, len);
p += strlen(p) + 1;
+ if (p <= pe)
+ rb_str_cat(str, "\0", 1);
if (len > SMALLBUF) free(buf);
}
return str;
@@ -799,48 +813,92 @@ time_s_times(obj)
}
static VALUE
-time_dump(time, limit)
- VALUE time, limit;
+time_dump(argc, argv, time)
+ int argc;
+ VALUE *argv;
+ VALUE time;
{
+ VALUE dummy;
struct time_object *tobj;
- int sec, usec;
- unsigned char buf[8];
+ time_t sec, usec;
+ struct tm *tm;
+ unsigned char buf[11];
int i;
+ rb_scan_args(argc, argv, "01", &dummy);
GetTimeval(time, tobj);
sec = tobj->tv.tv_sec;
usec = tobj->tv.tv_usec;
+ tm = gmtime(&sec);
+
+ i = tm->tm_year;
+ buf[0] = i & 0xff;
+ i = RSHIFT(i, 8);
+ buf[1] = i & 0xff;
+
+ buf[2] = tm->tm_mon;
+ buf[3] = tm->tm_mday;
+ buf[4] = tm->tm_hour;
+ buf[5] = tm->tm_min;
+ buf[6] = tm->tm_sec;
+
+ for (i=7; i<11; i++) {
+ buf[i] = usec & 0xff;
+ usec = RSHIFT(usec, 8);
+ }
+ return rb_str_new(buf, 11);
+}
+
+static VALUE
+time_old_load(klass, buf)
+ VALUE klass;
+ unsigned char *buf;
+{
+ time_t sec, usec;
+ int i;
+
+ sec = usec = 0;
for (i=0; i<4; i++) {
- buf[i] = sec & 0xff;
- sec = RSHIFT(sec, 8);
+ sec |= buf[i]<<(8*i);
}
for (i=4; i<8; i++) {
- buf[i] = usec & 0xff;
- usec = RSHIFT(usec, 8);
+ usec |= buf[i]<<(8*(i-4));
}
- return rb_str_new(buf, 8);
+
+ return time_new_internal(klass, sec, usec);
}
static VALUE
time_load(klass, str)
VALUE klass, str;
{
- int sec, usec;
+ time_t sec, usec;
unsigned char *buf;
+ struct tm tm;
int i;
buf = str2cstr(str, &i);
- if (i != 8) {
+ if (i == 8) {
+ return time_old_load(klass, buf);
+ }
+ if (i != 11) {
rb_raise(rb_eTypeError, "marshaled time format differ");
}
- sec = usec = 0;
+ tm.tm_year = buf[0];
+ tm.tm_year |= buf[1]<<8;
+ tm.tm_mon = buf[2];
+ tm.tm_mday = buf[3];
+ tm.tm_hour = buf[4];
+ tm.tm_min = buf[5];
+ tm.tm_sec = buf[6];
+
+ sec = make_time_t(&tm, gmtime);
+
+ usec = 0;
for (i=0; i<4; i++) {
- sec |= buf[i]<<(8*i);
- }
- for (i=4; i<8; i++) {
- usec |= buf[i]<<(8*(i-4));
+ usec |= buf[i+7]<<(8*i);
}
return time_new_internal(klass, sec, usec);
@@ -902,6 +960,6 @@ Init_Time()
#endif
/* methods for marshaling */
+ rb_define_method(rb_cTime, "_dump", time_dump, -1);
rb_define_singleton_method(rb_cTime, "_load", time_load, 1);
- rb_define_method(rb_cTime, "_dump", time_dump, 1);
}
diff --git a/util.c b/util.c
index fb82a1f190..33d9b3d6f1 100644
--- a/util.c
+++ b/util.c
@@ -809,3 +809,4 @@ void ruby_qsort (base, nel, size, cmp) void* base; int nel; int size; int (*cmp)
else goto nxt; /* need not to sort both sides */
}
}
+
diff --git a/util.h b/util.h
index 52ac5e18d0..f2b66b6fc6 100644
--- a/util.h
+++ b/util.h
@@ -35,4 +35,8 @@ char *ruby_mktemp _((void));
void ruby_qsort _((void*, int, int, int (*)()));
#define qsort(b,n,s,c) ruby_qsort(b,n,s,c)
+void ruby_setenv _((char*, char*));
+void ruby_setenv2 _((char*, char*));
+void ruby_unsetenv _((char*));
+
#endif /* UTIL_H */
diff --git a/variable.c b/variable.c
index b4af07f9c2..a8322b7478 100644
--- a/variable.c
+++ b/variable.c
@@ -116,7 +116,7 @@ static VALUE
classname(klass)
VALUE klass;
{
- VALUE path;
+ VALUE path = Qnil;
ID classpath = rb_intern("__classpath__");
while (TYPE(klass) == T_ICLASS || FL_TEST(klass, FL_SINGLETON)) {
diff --git a/version.h b/version.h
index fadead04a2..c26df6524e 100644
--- a/version.h
+++ b/version.h
@@ -1,2 +1,2 @@
#define RUBY_VERSION "1.3.1"
-#define VERSION_DATE "99/02/15"
+#define VERSION_DATE "99/02/24"
diff --git a/win32/ruby.def b/win32/ruby.def
index 6c391dcff4..748a2cbfe1 100644
--- a/win32/ruby.def
+++ b/win32/ruby.def
@@ -31,6 +31,9 @@ EXPORTS
rb_cFile
;hash.c:
rb_cHash
+ ruby_setenv
+ ruby_setenv2
+ ruby_unsetenv
;io.c:
rb_cIO
;numeric.c: