From 2ffc5814a14ce44ab408d8aca922875ce8991643 Mon Sep 17 00:00:00 2001 From: "(no author)" <(no author)@b2dd03c8-39d4-4d8f-98ff-823fe69b080e> Date: Thu, 25 Feb 1999 06:39:12 +0000 Subject: This commit was manufactured by cvs2svn to create tag 'v1_3_1_990225'. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/tags/v1_3_1_990225@408 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- .cvsignore | 17 - ChangeLog | 413 ++++ MANIFEST | 10 +- Makefile.in | 42 +- README | 6 +- README.EXT | 301 ++- README.EXT.jp | 19 +- README.jp | 13 +- ToDo | 14 +- array.c | 154 +- bignum.c | 71 +- class.c | 22 +- compar.c | 2 +- config.dj | 36 - config.sub | 4 +- configure | 957 +++++--- configure.in | 250 +- defines.h | 4 +- dir.c | 2 +- dln.c | 37 +- enum.c | 28 +- env.h | 2 +- error.c | 78 +- eval.c | 573 +++-- ext/Win32API/Win32API.c | 38 +- ext/curses/curses.c | 16 +- ext/curses/extconf.rb | 2 + ext/dbm/dbm.c | 2 +- ext/etc/MANIFEST | 3 +- ext/extmk.rb.in | 30 +- ext/gtk/MANIFEST | 18 - ext/gtk/extconf.rb | 6 - ext/gtk/gtk.c | 5904 --------------------------------------------- ext/gtk/test.rb | 96 - ext/gtk/test.xpm | 92 - ext/gtk/test0.rb | 13 - ext/gtk/test1.rb | 41 - ext/gtk/test2.rb | 89 - ext/gtk/test3.rb | 16 - ext/gtk/test4.rb | 77 - ext/gtk/test5.rb | 63 - ext/gtk/test6.rb | 49 - ext/gtk/test7.rb | 49 - ext/gtk/test8.rb | 49 - ext/gtk/test9.rb | 98 - ext/gtk/testa.rb | 78 - ext/gtk/testb.rb | 78 - ext/gtk/testc.rb | 64 - ext/marshal/MANIFEST | 5 - ext/marshal/depend | 2 - ext/marshal/extconf.rb | 1 - ext/marshal/marshal.c | 850 ------- ext/marshal/marshal.doc | 48 - ext/md5/MANIFEST | 3 +- ext/md5/md5init.c | 2 +- ext/nkf/MANIFEST | 7 + ext/nkf/extconf.rb | 2 + ext/nkf/lib/kconv.rb | 58 + ext/nkf/nkf.c | 207 ++ ext/nkf/orig/nkf.c | 1897 +++++++++++++++ ext/nkf/test.rb | 318 +++ ext/socket/socket.c | 13 +- ext/tcltklib/tcltklib.c | 6 +- ext/tk/lib/tk.rb | 4 + ext/tk/lib/tkscrollbox.rb | 6 +- ext/tkutil/MANIFEST | 3 - ext/tkutil/depend | 1 - ext/tkutil/tkutil.c | 46 - file.c | 142 +- fnmatch.c | 243 -- fnmatch.h | 36 - gc.c | 22 +- glob.c | 6 +- hash.c | 116 +- inits.c | 4 +- instruby.rb | 53 +- intern.h | 35 +- io.c | 507 +++- io.h | 58 - lib/README | 23 +- lib/cgi-lib.rb | 275 ++- lib/complex.rb | 18 +- lib/date2.rb | 24 +- lib/e2mmap.rb | 269 ++- lib/e2mmap1_0.rb | 71 - lib/ftools.rb | 4 +- lib/matrix.rb | 67 +- lib/mkmf.rb | 4 +- lib/mutex_m.rb | 9 +- lib/parsedate.rb | 21 +- lib/profile.rb | 2 + lib/sync.rb | 14 +- lib/telnet.rb | 273 ++- lib/tempfile.rb | 3 +- lib/tk.rb | 1254 ---------- lib/tkcanvas.rb | 326 --- lib/tkclass.rb | 38 - lib/tkcore.rb | 528 ---- lib/tkdialog.rb | 62 - lib/tkentry.rb | 67 - lib/tkscrollbox.rb | 27 - lib/tktext.rb | 164 -- lib/tkthcore.rb | 550 ----- lib/weakref.rb | 7 +- main.c | 7 + marshal.c | 25 +- math.c | 2 +- misc/ruby-mode.el | 28 +- missing/fnmatch.c | 199 ++ missing/fnmatch.h | 57 + missing/nt.c | 2194 ----------------- missing/nt.h | 362 --- missing/setenv.c | 149 -- missing/strftime.c | 28 +- missing/strtod.c | 266 ++ missing/vsnprintf.c | 47 +- node.h | 2 +- numeric.c | 115 +- object.c | 129 +- pack.c | 349 ++- parse.c | 3253 +++++++++++++------------ parse.y | 144 +- process.c | 42 +- random.c | 2 +- range.c | 9 +- re.c | 52 +- re.h | 2 +- regex.c | 4485 ++++++++++++++++++++++++++++++++++ regex.h | 29 +- ruby.1 | 6 +- ruby.c | 106 +- ruby.h | 32 +- rubyio.h | 2 +- rubytest.rb | 6 +- sample/biorhythm.rb | 10 +- sample/cal.rb | 7 +- sample/io.rb | 44 - sample/list.rb | 16 +- sample/mine.rb | 40 +- sample/rbc.rb | 8 +- sample/rcs.rb | 10 +- sample/rename.rb | 6 +- sample/ruby-mode.el | 649 ----- sample/rubydb2x.el | 104 - sample/rubydb3x.el | 104 - sample/test.rb | 36 +- sample/tkbiff.rb | 149 -- sample/tkbrowse.rb | 69 - sample/tkdialog.rb | 62 - sample/tkfrom.rb | 126 - sample/tkhello.rb | 10 - sample/tkline.rb | 46 - sample/tktimer.rb | 50 - sample/uumerge.rb | 4 +- sig.h | 53 - signal.c | 10 +- sprintf.c | 15 +- st.c | 483 ++++ st.h | 46 + string.c | 223 +- struct.c | 76 +- time.c | 339 +-- util.c | 9 +- util.h | 5 +- variable.c | 47 +- version.c | 4 +- version.h | 2 +- win32/Makefile | 17 +- win32/config.h | 34 +- win32/ruby.def | 6 +- win32/win32.c | 2 +- win32/win32.h | 33 +- 172 files changed, 14343 insertions(+), 19567 deletions(-) delete mode 100644 .cvsignore delete mode 100644 config.dj delete mode 100644 ext/gtk/MANIFEST delete mode 100644 ext/gtk/extconf.rb delete mode 100644 ext/gtk/gtk.c delete mode 100644 ext/gtk/test.rb delete mode 100644 ext/gtk/test.xpm delete mode 100644 ext/gtk/test0.rb delete mode 100644 ext/gtk/test1.rb delete mode 100644 ext/gtk/test2.rb delete mode 100644 ext/gtk/test3.rb delete mode 100644 ext/gtk/test4.rb delete mode 100644 ext/gtk/test5.rb delete mode 100644 ext/gtk/test6.rb delete mode 100644 ext/gtk/test7.rb delete mode 100644 ext/gtk/test8.rb delete mode 100644 ext/gtk/test9.rb delete mode 100644 ext/gtk/testa.rb delete mode 100644 ext/gtk/testb.rb delete mode 100644 ext/gtk/testc.rb delete mode 100644 ext/marshal/MANIFEST delete mode 100644 ext/marshal/depend delete mode 100644 ext/marshal/extconf.rb delete mode 100644 ext/marshal/marshal.c delete mode 100644 ext/marshal/marshal.doc create mode 100644 ext/nkf/MANIFEST create mode 100644 ext/nkf/extconf.rb create mode 100644 ext/nkf/lib/kconv.rb create mode 100644 ext/nkf/nkf.c create mode 100644 ext/nkf/orig/nkf.c create mode 100644 ext/nkf/test.rb delete mode 100644 ext/tkutil/MANIFEST delete mode 100644 ext/tkutil/depend delete mode 100644 ext/tkutil/tkutil.c delete mode 100644 fnmatch.c delete mode 100644 fnmatch.h delete mode 100644 io.h delete mode 100644 lib/e2mmap1_0.rb delete mode 100644 lib/tk.rb delete mode 100644 lib/tkcanvas.rb delete mode 100644 lib/tkclass.rb delete mode 100644 lib/tkcore.rb delete mode 100644 lib/tkdialog.rb delete mode 100644 lib/tkentry.rb delete mode 100644 lib/tkscrollbox.rb delete mode 100644 lib/tktext.rb delete mode 100644 lib/tkthcore.rb create mode 100644 missing/fnmatch.c create mode 100644 missing/fnmatch.h delete mode 100644 missing/nt.c delete mode 100644 missing/nt.h delete mode 100644 missing/setenv.c create mode 100644 missing/strtod.c create mode 100644 regex.c delete mode 100644 sample/io.rb delete mode 100644 sample/ruby-mode.el delete mode 100644 sample/rubydb2x.el delete mode 100644 sample/rubydb3x.el delete mode 100644 sample/tkbiff.rb delete mode 100644 sample/tkbrowse.rb delete mode 100644 sample/tkdialog.rb delete mode 100644 sample/tkfrom.rb delete mode 100644 sample/tkhello.rb delete mode 100644 sample/tkline.rb delete mode 100644 sample/tktimer.rb delete mode 100644 sig.h create mode 100644 st.c create mode 100644 st.h diff --git a/.cvsignore b/.cvsignore deleted file mode 100644 index c1bdd084b3..0000000000 --- a/.cvsignore +++ /dev/null @@ -1,17 +0,0 @@ -parse.c -newver.rb -ruby -miniruby -README.fat-patch -config.cache -config.h -config.log -config.status -Makefile -ppack -archive -*.orig -*.rej -*.bak -*.sav -*~ diff --git a/ChangeLog b/ChangeLog index 6a317e294b..c6f41e43f6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,416 @@ +Thu Feb 25 12:50:25 1999 Yukihiro Matsumoto + + * time.c (make_time_t): add `future check' in loops. + + * object.c (rb_num2dbl): forbid implicit conversion from nil, or + strings. thus `Time.now + str' should raise error. + + * object.c (rb_Float): convert nil into 0.0. + + * object.c (rb_Integer): conversion method improved. + +Thu Feb 25 03:27:50 1999 Shugo Maeda + + * eval.c (rb_call): should handle T_ICLASS properly. + +Thu Feb 25 00:04:00 1999 Yukihiro Matsumoto + + * error.c (Init_Exception): global function Exception() removed. + + * variable.c (rb_class2name): returns "nil"/"true"/"false" for them. + + * time.c (time_dump): time marshaling format compressed size from + 11 bytes to 8 bytes. thanx to tadf@kt.rim.or.jp. + + * eval.c (rb_obj_call_init): should specify arguments explicitly. + +Wed Feb 24 15:43:28 1999 Yukihiro Matsumoto + + * parse.y (yylex): comment concatenation requires preceding space + before backslash at the end of line. + + * io.c (rb_f_pipe): global pipe is obsolete now. + + * object.c (Init_Object): remove true.to_i, false.to_i. + +Tue Feb 23 14:21:41 1999 Yukihiro Matsumoto + + * parse.y (yylex): warn if identifier! immediately followed by `='. + +Tue Feb 23 12:32:41 1999 WATANABE Hirofumi + + * 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 + + * 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 + + * 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 + + * numeric.c (rb_num2long): no implicit conversion from boolean. + +Sat Feb 20 09:58:42 1999 EGUCHI Osamu + + * numeric.c (flo_to_s): portable Infinity and NaN support. + +Sat Feb 20 07:13:31 1999 WATANABE Tetsuya + + * io.c (rb_file_sysopen): forgot to initialize a local variable. + +Fri Feb 19 23:05:07 1999 Yukihiro Matsumoto + + * 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 + + * 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 + + * 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 + + * missing/fnmatch.c: moved to missing directory. + +Wed Feb 17 16:22:26 1999 Yukihiro Matsumoto + + * struct.c (rb_struct_alloc): actual initialization now be done in + `initialize'. + +Wed Feb 17 09:47:15 1999 okabe katsuyuki + + * 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 + + * 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 + + * configure.in: BeOS patch. + +Tue Feb 16 14:25:00 1999 Yukihiro Matsumoto + + * 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 + + * configure.in: specify `-Wl,-E' only for GNU ld. + +Mon Feb 15 11:43:22 1999 GOTO Kentaro + + * array.c (rb_inspecting_p): should return Qfalse. + +Sun Feb 14 22:36:40 1999 EGUCHI Osamu + + * sprintf.c (rb_f_sprintf): `%G' was ommited. + +Sun Feb 14 12:47:48 1999 EGUCHI Osamu + + * 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 + + * eval.c (rb_thread_create_0): should protect th->thread. + +Fri Feb 12 16:16:47 1999 Yasuhiro Fukuma + + * string.c (rb_str_inspect): wrong mbc position. + +Fri Feb 12 16:21:17 1999 Yukihiro Matsumoto + + * eval.c (rb_thread_fd_close): + + * io.c (rb_io_fptr_close): tell scheduler that fd is closed. + + * io.c (rb_io_reopen): ditto. + + * io.c (READ_CHECK): check if closed after thread context switch. + + * ext/socket/socket.c (bsock_close_read): do not check + the return value from shutdown(2). + + * ext/socket/socket.c (bsock_close_write): ditto. + + * ext/socket/socket.c (sock_new): need to dup(fd) for close_read + and close_write. + + * parse.y (here_document): handle newlines within #{}. + + * regex.h: should replace symbols for ruby. + +Fri Feb 12 00:46:28 1999 Shugo Maeda + + * marshal.c (r_object): should update the method name in message. + + * marshal.c (w_object): limit should be converted into Fixnum. + +Wed Feb 10 15:20:03 1999 Yukihiro Matsumoto + + * regex.c (re_match): empty pattern should not cause infinite + pattern match loop. + + * regex.c (re_compile_pattern): RE_OPTIMIZE_ANCHOR for /.*/, not + for /(.|\n)/. + + * numeric.c (fix_pow): `fixnum**nil' should raise TypeError. + + * bignum.c (rb_big_pow): need to normalize results. + +Wed Feb 10 01:42:41 1999 EGUCHI Osamu + + * numeric.c (fix_pow): `(5**1).type' should be Integer. + +Tue Feb 9 01:22:49 1999 Yukihiro Matsumoto + + * parse.y (yylex): do not ignore newlines in mbchars. + + * io.c (rb_file_s_open): mode can be specified by flags like + open(2), e.g. File::open(path, File::CREAT|File::WRONLY). + + * io.c (rb_f_open): bit-wise mode flags for pipes + + * io.c (Init_IO): bit flags for open. + +Sat Feb 6 22:56:21 1999 Yukihiro Matsumoto + + * string.c (rb_str_sub_bang): should not overwrite match data by + regexp match within the block. + + * string.c (rb_str_gsub_bang): ditto. + +Sat Feb 6 03:06:17 1999 Yukihiro Matsumoto + + * re.c (match_getter): accessng $~ without matching caused SEGV. + +Fri Feb 5 22:11:08 1999 EGUCHI Osamu + + * parse.y (yylex): binary literal support, like 0b01001. + + * parse.y (yylex): octal numbers can contain `_'s. + + * parse.y (yylex): warns if non-octal number follows immediately + after octal literal. + + * parse.y (yylex): now need at least one digit after prefix such + as 0x, or 0b. + + * bignum.c (rb_str2inum): recognize binary numbers like 0b0101. + +Fri Feb 5 03:26:56 1999 Yasuhiro Fukuma + + * ruby.c (proc_options): -e without program prints error. + +Fri Feb 5 00:01:50 1999 Yukihiro Matsumoto + + * parse.y (terms): needed to clear heredoc_end. + + * numeric.c (flo_div): allow float division by zero. + +Thu Feb 4 11:56:24 1999 Yukihiro Matsumoto + + * missing/strtod.c: for compatibility. + + * configure.in (strtod): add strtod compatible check. + + * numeric.c (rb_num2long): missing/vsnprintf.c does not supprt + floating points. + + * numeric.c (flo_to_s): ditto. + +Wed Feb 3 23:02:12 1999 Yoshida Masato + + * regex.c (re_compile_pattern): use ismbchar() to get next char. + + * regex.c (re_search): wrong mbchar shift. + + * re.c (rb_reg_search): needed to reset $KCODE after match. + + * regex.c (re_compile_fastmap): mbchars should match with \w. + +Wed Feb 3 22:35:12 1999 EGUCHI Osamu + + * parse.y (yylex): too big float raise warning, not error. + +Tue Feb 2 23:41:42 1999 Yoshida Masato + + * regex.c (re_match): wrong boundary. + + * regex.c (IS_A_LETTER): re_mbctab[c] may not be 1 for mbc. + + * regex.c (re_search): mbchar support for shifting ranges. + + * regex.c (MBC2WC): wrong conversion. + +Wed Feb 3 15:03:16 1999 Yukihiro Matsumoto + + * parse.y (parse_regx): need to escape parens if terminators are + not any kind of parenthesis. + + * parse.y (parse_qstring): ditto. + + * parse.y (parse_string): ditto. + +Tue Feb 2 17:11:26 1999 WATANABE Tetsuya + + * string.c (rb_str_gsub_bang): too small realoc condition. + +Mon Feb 1 10:01:17 1999 EGUCHI Osamu + + * parse.y (yylex): range check for the float literal. + +Sat Jan 30 18:34:16 1999 Yukihiro Matsumoto + + * ruby.c (usage): -h option to show brief command description. + +Sat Jan 30 08:45:16 1999 IKARASHI Akira + + * lib/cgi-lib.rb: cookie support added. + +Sat Jan 30 13:38:24 1999 Yukihiro Matsumoto + + * regex.c (re_compile_pattern): mbchars should match with \w + within character classs. Was matching with \W. + + * regex.c (re_match): \w should match with multi byte characters, + not its first byte. + +Sat Jan 30 10:06:41 1999 Yoshida Masato + + * re.c (rb_reg_s_new): UTF-8 flag handle (/u, /U). + + * re.c (rb_kcode): $KCODE handle for UTF-8. + +Sat Jan 30 01:51:16 1999 Yukihiro Matsumoto + + * array.c (rb_ary_delete_if): RTEST() missing. + + * hash.c (delete_if_i): ditto. + + * enum.c (Init_Enumerable): select (=find_all), detect (=find) + added as aliases. + +Fri Jan 29 21:32:19 1999 WATANABE Tetsuya + + * hash.c (rb_f_setenv): SEGV caused by small typo. + +Fri Jan 29 00:15:58 1999 Yukihiro Matsumoto + + * lib/parsedate.rb (parsedate): support date format like + 23-Feb-93, which is required by HTTP/1.1. + + * variable.c (find_class_path): avoid calling rb_iv_set(). + + * eval.c (backtrace): do not need to modify $SAFE internally. + + * variable.c (classname): inline __classid__ access. + + * eval.c (THREAD_ALLOC): needed to initialize wrapper. + + * lib/ftools.rb (makedirs): allows slash at the end of the path. + + * numeric.c (rb_fix_induced_from): ensure result to be Fixnum. + +Thu Jan 28 17:31:43 1999 Yukihiro Matsumoto + + * numeric.c (flo_to_s): float format changed to "%16.10g". + +Thu Jan 28 02:13:11 1999 Yoshinori Toki + + * array.c (rb_ary_store): expand allocated buffer by 3/2. + +Wed Jan 27 17:50:02 1999 Kazuhiro HIWADA + + * bignum.c (dbl2big): raised error if double is too big to cast + into long. check added. + +Wed Jan 27 03:16:18 1999 Yukihiro Matsumoto + + * variable.c (rb_mod_const_at): can't list constants of the + untainted objects in safe mode. + + * class.c (method_list): can't list methods of untainted objects + in safe mode. + +Tue Jan 26 02:40:41 1999 GOTO Kentaro + + * prec.c: Precision support for numbers. + +Thu Jan 21 19:08:14 1999 Yukihiro Matsumoto + + * eval.c (rb_f_raise): calls `exception' method, not `new'. + + * error.c (exc_exception): renamed from `new'. + Wed Jan 20 03:39:48 1999 Yukihiro Matsumoto * parse.y (yycompile): rb_in_compile renamed to ruby_in_compile. diff --git a/MANIFEST b/MANIFEST index 5c697d612f..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 @@ -50,6 +49,7 @@ object.c pack.c parse.c parse.y +prec.c process.c random.c range.c @@ -142,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 @@ -152,6 +157,7 @@ missing/strdup.c missing/strerror.c missing/strftime.c missing/strstr.c +missing/strtod.c missing/strtol.c missing/strtoul.c missing/vsnprintf.c diff --git a/Makefile.in b/Makefile.in index 628b0e0778..f399fca6b1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -21,11 +21,19 @@ LDSHARED = @LDSHARED@ DLDFLAGS = @DLDFLAGS@ SOLIBS = @SOLIBS@ +RUBY_INSTALL_NAME=@RUBY_INSTALL_NAME@ binsuffix = @binsuffix@ +PROGRAM=$(RUBY_INSTALL_NAME)$(binsuffix) #### End of system configuration section. #### +MAJOR= @MAJOR@ +MINOR= @MINOR@ +TEENY= @TEENY@ +LIBRUBY_A = @LIBRUBY_A@ +LIBRUBY_SO = @LIBRUBY_SO@ +LIBRUBY_ALIASES= @LIBRUBY_ALIASES@ LIBRUBY = @LIBRUBY@ LIBRUBYARG = @LIBRUBYARG@ @@ -43,7 +51,6 @@ OBJS = array.o \ error.o \ eval.o \ file.o \ - fnmatch.o \ gc.o \ glob.o \ hash.o \ @@ -56,6 +63,7 @@ OBJS = array.o \ pack.o \ parse.o \ process.o \ + prec.o \ random.o \ range.o \ re.o \ @@ -75,35 +83,36 @@ OBJS = array.o \ all: miniruby$(binsuffix) rbconfig.rb @./miniruby$(binsuffix) -Xext extmk.rb @EXTSTATIC@ -miniruby$(binsuffix): libruby.a $(MAINOBJ) dmyext.o +miniruby$(binsuffix): config.status $(LIBRUBY_A) $(MAINOBJ) dmyext.o @rm -f $@ - $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) dmyext.o libruby.a $(LIBS) -o $@ + $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) dmyext.o $(LIBRUBY_A) $(LIBS) -o $@ -ruby$(binsuffix): $(LIBRUBY) $(MAINOBJ) $(EXTOBJS) +$(PROGRAM): $(LIBRUBY) $(MAINOBJ) $(EXTOBJS) @rm -f $@ $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@ -libruby.a: $(OBJS) dmyext.o +$(LIBRUBY_A): $(OBJS) dmyext.o @AR@ rcu $@ $(OBJS) dmyext.o @-@RANLIB@ $@ 2> /dev/null || true -libruby.so: $(OBJS) dmyext.o +$(LIBRUBY_SO): $(OBJS) dmyext.o $(LDSHARED) $(DLDFLAGS) $(SOLIBS) $(OBJS) dmyext.o -o $@ + @-./miniruby -e 'ARGV.each{|link| File.delete link if File.exist? link; \ + File.symlink "$(LIBRUBY_SO)", link}' \ + $(LIBRUBY_ALIASES) || true install: rbconfig.rb ./miniruby$(binsuffix) $(srcdir)/instruby.rb $(DESTDIR) -clean:; @rm -f $(OBJS) $(LIBRUBY) $(MAINOBJ) rbconfig.rb +clean:; @rm -f $(OBJS) $(LIBRUBY_A) $(LIBRUBY_SO) $(LIBRUBY_ALIASES) $(MAINOBJ) rbconfig.rb @rm -f ext/extinit.c ext/extinit.o dmyext.o - @if test -f ./miniruby$(binsuffix); then \ - ./miniruby$(binsuffix) -Xext extmk.rb clean; \ - fi + @-./miniruby$(binsuffix) -Xext extmk.rb clean 2> /dev/null || true distclean: clean @rm -f Makefile ext/extmk.rb config.h @rm -f ext/config.cache config.cache config.log config.status @rm -f parse.c *~ core *.core gmon.out y.tab.c y.output - @rm -f ruby$(binsuffix) miniruby$(binsuffix) + @rm -f $(PROGRAM) miniruby$(binsuffix) realclean: distclean @rm -f lex.c @@ -111,7 +120,7 @@ realclean: distclean test: miniruby$(binsuffix) @./miniruby$(binsuffix) $(srcdir)/rubytest.rb -rbconfig.rb: config.status miniruby$(binsuffix) +rbconfig.rb: miniruby$(binsuffix) @./miniruby$(binsuffix) $(srcdir)/mkconfig.rb rbconfig.rb config.status: $(srcdir)/configure @@ -142,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 @@ -172,6 +184,9 @@ strftime.o: @srcdir@/missing/strftime.c strstr.o: @srcdir@/missing/strstr.c $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strstr.c +strtod.o: @srcdir@/missing/strtod.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strtod.c + strtol.o: @srcdir@/missing/strtol.c $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strtol.c @@ -203,11 +218,12 @@ 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 marshal.o: marshal.c ruby.h config.h defines.h intern.h rubyio.h st.h +prec.o: prec.c ruby.h config.h defines.h intern.h math.o: math.c ruby.h config.h defines.h intern.h numeric.o: numeric.c ruby.h config.h defines.h intern.h object.o: object.c ruby.h config.h defines.h intern.h st.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 b/README.EXT index f169e54995..9a56bd99e8 100644 --- a/README.EXT +++ b/README.EXT @@ -109,35 +109,29 @@ bugs. 1.4 Convert C data into VALUE -VALUEの実際の構造は +To convert C data to the values of Ruby: - * FIXNUMの場合 + * FIXNUM - 1bit右シフトして,LSBを立てる. + left shift 1 bit, and turn on LSB. - * その他のポインタの場合 + * Other pointer values - そのままVALUEにキャストする. + cast to VALUE. -となっています.よって,LSBをチェックすればVALUEがFIXNUMかど -うかわかるわけです(ポインタのLSBが立っていないことを仮定して -いる). +You can determine whether VALUE is pointer or not, by checking LSB. -ですから,FIXNUM以外のRubyのオブジェクトの構造体は単にVALUE -にキャストするだけでVALUEに変換出来ます.ただし,任意の構造 -体がVALUEにキャスト出来るわけではありません.キャストするの -はRubyの知っている構造体(ruby.hで定義されているstruct RXxxx -のもの)だけにしておいてください. +Notice Ruby does not allow arbitrary pointer value to be VALUE. They +should be pointers to the structures which Ruby knows. The known +structures are defined in . -FIXNUMに関しては変換マクロを経由する必要があります.Cの整数 -からVALUEに変換するマクロは以下のものがあります.必要に応じ -て使い分けてください. +To convert C numbers to Ruby value, use these macros. - INT2FIX() もとの整数が31bit以内に収まる時 - INT2NUM() 任意の整数からVALUEへ + INT2FIX() for intergers within 31bits. + INT2NUM() for arbitrary sized integer. -INT2NUM()は整数がFIXNUMの範囲に収まらない場合,Bignumに変換 -してくれます(が,少し遅い). +INT2NUM() converts integers into Bignums, if it is out of FIXNUM +range, but bit slower. 1.5 Manipulate Ruby data @@ -197,16 +191,13 @@ interpreter. Useful functions are listed below (not all): 2.1 Add new features to Ruby -Rubyで提供されている関数を使えばRubyインタプリタに新しい機能 -を追加することができます.Rubyでは以下の機能を追加する関数が -提供されています. +You can add new features (classes, methods, etc.) to the Ruby +interpreter. Ruby provides the API to define things below: * Classes, Modules * Methods, Singleton Methods * Constants -では順に紹介します. - 2.1.1 Class/module definition To define class or module, use functions below: @@ -327,9 +318,9 @@ by the symbol mid. 2.2.4 Accessing the variables and constants -Cから関数を使って参照・更新できるのは,クラス定数,インスタ -ンス変数です.大域変数は一部のものはCの大域変数としてアクセ -スできます.ローカル変数を参照する方法は公開していません. +You can access class variables, and instance variables using access +functions. Also, global variables can be shared between both worlds. +There's no way to access Ruby's local variables. The functions to access/modify instance variables are below: @@ -346,9 +337,7 @@ See 2.1.3 for defining new constant. 3. Informatin sharing between Ruby and C -C言語とRubyの間で情報を共有する方法について解説します. - -3.1 Ruby constant that Cから参照できるRubyの定数 +3.1 Ruby constant that C can be accessed from C Following Ruby constants can be referred from C. @@ -363,43 +352,35 @@ Ruby nil in C scope. 3.2 Global variables shared between C and Ruby -CとRubyで大域変数を使って情報を共有できます.共有できる大域 -変数にはいくつかの種類があります.そのなかでもっとも良く使わ -れると思われるのはrb_define_variable()です. +Information can be shared between two worlds, using shared global +variables. To define them, you can use functions listed below: void rb_define_variable(char *name, VALUE *var) -この関数はRubyとCとで共有する大域変数を定義します.変数名が -`$'で始まらない時には自動的に追加されます.この変数の値を変 -更すると自動的にRubyの対応する変数の値も変わります. +This function defines the variable which is shared by the both world. +The value of the global variable pointerd by `var', can be accessed +through Ruby's global variable named `name'. -またRuby側からは更新できない変数もあります.このread onlyの -変数は以下の関数で定義します. +You can define read-only (from Ruby, of course) variable by the +function below. void rb_define_readonly_variable(char *name, VALUE *var) -これら変数の他にhookをつけた大域変数を定義できます.hook付き -の大域変数は以下の関数を用いて定義します.hook付き大域変数の -値の参照や設定はhookで行う必要があります. +You can defined hooked variables. The accessor functions (getter and +setter) are called on access to the hooked variables. void rb_define_hooked_variable(char *name, VALUE *var, VALUE (*getter)(), VALUE (*setter)()) -この関数はCの関数によってhookのつけられた大域変数を定義しま -す.変数が参照された時には関数getterが,変数に値がセットされ -た時には関数setterが呼ばれる.hookを指定しない場合はgetterや -setterに0を指定します. - -# getterもsetterも0ならばrb_define_variable()と同じになる. - -それから,Cの関数によって実現されるRubyの大域変数を定義する -関数があります. +If you need to supply either setter or getter, just supply 0 for the +hook you don't need. If both hooks are 0, rb_define_hooked_variable() +works just like rb_define_variable(). void rb_define_virtual_variable(char *name, VALUE (*getter)(), VALUE (*setter)()) -この関数によって定義されたRubyの大域変数が参照された時には -getterが,変数に値がセットされた時にはsetterが呼ばれます. +This function defines the Ruby global variable without corresponding C +variable. The value of the variable will be set/get only by hooks. The prototypes of the getter and setter functions are as following: @@ -408,54 +389,44 @@ The prototypes of the getter and setter functions are as following: 3.3 Encapsulate C data into Ruby object -Cの世界で定義されたデータ(構造体)をRubyのオブジェクトとして -取り扱いたい場合がありえます.このような場合には,Dataという -RubyオブジェクトにCの構造体(へのポインタ)をくるむことでRuby -オブジェクトとして取り扱えるようになります. - -Dataオブジェクトを生成して構造体をRubyオブジェクトにカプセル -化するためには,以下のマクロを使います. +To wrapping and objectify the C pointer as Ruby object (so called +DATA), use Data_Wrap_Struct(). Data_Wrap_Struct(class,mark,free,ptr) -このマクロの戻り値は生成されたDataオブジェクトです. - -classはこのDataオブジェクトのクラスです.ptrはカプセル化する -Cの構造体へのポインタです.markはこの構造体がRubyのオブジェ -クトへの参照がある時に使う関数です.そのような参照を含まない -時には0を指定します. +Data_Wrap_Struct() returns a created DATA object. The class argument +is the class for the DATA object. The mark argument is the function +to mark Ruby objects pointed by this data. The free argument is the +function to free the pointer allocation. The functions, mark and +free, will be called from garbage collector. -# そのような参照は勧められません. - -freeはこの構造体がもう不要になった時に呼ばれる関数です.この -関数がガーベージコレクタから呼ばれます. - -Cの構造体の割当とDataオブジェクトの生成を同時に行うマクロと -して以下のものが提供されています. +You can allocate and wrap the structure in one step. Data_Make_Struct(class, type, mark, free, sval) -このマクロの戻り値は生成されたDataオブジェクトです. +This macro returns an allocated Data object, wrapping the pointer to +the structure, which is also allocated. This macro works like: + + (sval = ALLOC(type), Data_Wrap_Struct(class, mark, free, sval)) -class, mark, freeはData_Wrap_Structと同じ働きをします.type -は割り当てるC構造体の型です.割り当てられた構造体は変数sval -に代入されます.この変数の型は (type*) である必要があります. +Arguments, class, mark, free, works like thier counterpart of +Data_Wrap_Struct(). The pointer to allocated structure will be +assigned to sval, which should be the pointer to the type specified. -Dataオブジェクトからポインタを取り出すのは以下のマクロを用い -ます. +To retrieve the C pointer from the Data object, use the macro +Data_Get_Struct(). Data_Get_Struct(obj, type, sval) -Cの構造体へのポインタは変数svalに代入されます. +The pointer to the structure will be assigned to the variable sval. -これらのDataの使い方はちょっと分かりにくいので,後で説明する -例題を参照してください. +See example below for detail. 4.Example - Create dbm module -ここまでの説明でとりあえず拡張ライブラリは作れるはずです. -Rubyのextディレクトリにすでに含まれているdbmモジュールを例に -して段階的に説明します. +OK, here's the example to make extension library. This is the +extension to access dbm. The full source is included in ext/ +directory in the Ruby's source tree. (1) make the directory @@ -600,16 +571,14 @@ Ruby -- static VALUE fdbm_indexes(obj, args) - VALUE obj; - struct RArray *args; + VALUE obj, args; { : } -- -第1引数はself,第2引数はRubyの配列です.ここではキャストを減 -らすため struct RArray* で受けていますが,VALUEでも同じこと -です. +The first argument is the receiver, the second one is the Ruby array +which contains the arguments to the method. ** Notice @@ -620,8 +589,9 @@ not exported to the Ruby world. You need to protect them by (5) prepare extconf.rb -もしディレクトリに「extconf.rb」というファイルが存在すれば, -make時に実行されます.なければ適当にMakefileが生成されます. +If there exists the file named extconf.rb, it will be executed to +generate Makefile. If not, compilation scheme try to generate +Makefile anyway. extconf.rbはモジュールのコンパイルに必要な条件のチェックなど を行うことが目的です.extconf.rbの中では以下のRuby関数を使う @@ -643,23 +613,21 @@ extconf.rb (6) prepare depend (optional) -もし,ディレクトリにdependというファイルが存在すれば, -Makefileが依存関係をチェックしてくれます. +If the file named depend exists, Makefile will include that file to +check dependency. You can make this file by invoking % gcc -MM *.c > depend -などで作ることが出来ます.あって損は無いでしょう. +It's no harm. Prepare it. (7) MANIFESTファイルにファイル名を入れる - % ls > MANIFEST + % find * -type f -print > MANIFEST % vi MANIFEST -*.o, *~など不必要なファイル以外はMANIFESTに追加しておきます. -make時にはMANIFESTの内容は参照しませんので,空のままでも問題 -は起きませんが,パッケージングの時に参照することがあるのと, -必要なファイルを区別できるので,用意しておいた方が良いでしょ -う. +Append file names into MANIFEST. The compilation scheme requires +MANIFEST only to be exist. But, you'd better take this step to +distinguish required files. (8) make @@ -676,9 +644,9 @@ so that you can inspect the module by the debugger. (10) done, now you have the extension library -後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお -使いください.Rubyの作者は拡張ライブラリに関して一切の権利を -主張しません. +You can do anything you want with your library. The author of Ruby +will not claim any restriction about your code depending Ruby API. +Feel free to use, modify, distribute or sell your program. Appendix A. Rubyのソースコードの分類 @@ -737,7 +705,7 @@ class library struct.c time.c -Appendix B. 拡張用関数リファレンス +Appendix B. Ruby extension API reference C言語からRubyの機能を利用するAPIは以下の通りである. @@ -758,13 +726,13 @@ const: nil object Qtrue -const: Qtrue object(default true value) +const: true object(default true value) Qfalse -const: Qfalse object +const: false object -** Cデータのカプセル化 +** C pointer wrapping Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval) @@ -776,40 +744,41 @@ C Data_Make_Struct(class, type, mark, free, sval) -type型のメモリをmallocし,変数svalに代入した後,それをカプセ -ル化したデータを返すマクロ. +This macro allocates memory using malloc(), assigns it to the variable +sval, and returns the DATA encapsulating the pointer to memory region. Data_Get_Struct(data, type, sval) -dataからtype型のポインタを取り出し変数svalに代入するマクロ. +This macro retrieves the pointer value from DATA, and assigns it to +the variable sval. -** クラス/モジュール定義 +** defining class/module VALUE rb_define_class(char *name, VALUE super) -superのサブクラスとして新しいRubyクラスを定義する. +Defines new Ruby class as subclass of super. VALUE rb_define_class_under(VALUE module, char *name, VALUE super) -superのサブクラスとして新しいRubyクラスを定義し,moduleの定 -数として定義する. +Creates new Ruby class as subclass of super, under the module's +namespace. VALUE rb_define_module(char *name) -新しいRubyモジュールを定義する. +Defines new Ruby module. VALUE rb_define_module_under(VALUE module, char *name, VALUE super) -新しいRubyモジュールを定義し,moduleの定数として定義する. +Defines new Ruby module, under the modules's namespace. void rb_include_module(VALUE class, VALUE module) -モジュールをインクルードする.classがすでにmoduleをインクルー -ドしている時には何もしない(多重インクルードの禁止). +Includes module into class. If class already includes it, just +ignore. void rb_extend_object(VALUE object, VALUE module) -オブジェクトをモジュール(で定義されているメソッド)で拡張する. +Extend the object with module's attribute. ** Defining Global Variables @@ -871,19 +840,20 @@ Defines global contant. This is just work as rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc) -メソッドを定義する.argcはselfを除く引数の数.argcが-1の時, -関数には引数の数(selfを含まない)を第1引数, 引数の配列を第2引 -数とする形式で与えられる(第3引数はself).argcが-2の時, 第1引 -数がself, 第2引数がargs(argsは引数を含むRubyの配列)という形 -式で与えられる. +Defines a method for the class. func is the function pointer. argc +is the number of arguments. if argc is -1, the function will receive +3 arguments argc, argv, and self. if argc is -2, the function will +receive 2 arguments, self and args, where args is the Ruby array of +the method arguments. rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc) -privateメソッドを定義する.引数はrb_define_method()と同じ. +Defines a private method for the class. Arguments are same as +rb_define_method(). rb_define_singleton_method(VALUE class, char *name, VALUE (*func)(), int argc) -特異メソッドを定義する.引数はrb_define_method()と同じ. +Defines a singleton method. Arguments are same as rb_define_method(). rb_scan_args(int atgc, VALUE *argv, char *fmt, ...) @@ -899,87 +869,91 @@ argc,argv VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) -メソッド呼び出し.文字列からmidを得るためにはrb_intern()を使う. +Invokes the method. To retrieve mid from method name, use rb_intern(). VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv) -メソッド呼び出し.引数をargc,argv形式で渡す. +Invokes method, passing arguments by array of values. VALUE rb_eval_string(char *str) -文字列をRubyとスクリプトしてコンパイル・実行する. +Compiles and executes the string as Ruby program. ID rb_intern(char *name) -文字列に対応するIDを返す. +Returns ID corresponding the name. char *rb_id2name(ID id) -IDに対応する文字列を返す(デバッグ用). +Returns the name corresponding ID. char *rb_class2name(VALUE class) -classの名前を返す(デバッグ用).classが名前を持たない時には, -祖先を遡って名前を持つクラスの名前を返す. +Returns the name of the class. -** インスタンス変数 +** Instance Variables VALUE rb_iv_get(VALUE obj, char *name) -objのインスタンス変数の値を得る.`@'で始まらないインスタンス -変数は Rubyプログラムからアクセスできない「隠れた」インスタ -ンス変数になる. +Retrieve the value of the instance variable. If the name is not +prefixed by `@', that variable shall be inaccessible from Ruby. VALUE rb_iv_set(VALUE obj, char *name, VALUE val) -objのインスタンス変数をvalにセットする. +Sets the value of the instance variable. -** 制御構造 +** Control Structure VALUE rb_iterate(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2) -func2をブロックとして設定し, func1をイテレータとして呼ぶ. -func1には arg1が引数として渡され, func2には第1引数にイテレー -タから与えられた値, 第2引数にarg2が渡される. +Calls the function func1, supplying func2 as the block. func1 will be +called with the argument arg1. func2 receives the value from yield as +the first argument, arg2 as the second argument. + VALUE rb_yield(VALUE val) -valを値としてイテレータブロックを呼び出す. +Evaluates the block with value val. VALUE rb_rescue(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2) -関数func1をarg1を引数に呼び出す.func1の実行中に例外が発生し -た時には func2をarg2を引数として呼ぶ.戻り値は例外が発生しな -かった時はfunc1の戻り値, 例外が発生した時にはfunc2の戻り値で -ある. +Calls the function func1, with arg1 as the argument. If exception +occurs during func1, it calls func2 with arg2 as the argument. The +return value of rb_rescue() is the return value from func1 if no +exception occurs, from func2 otherwise. VALUE rb_ensure(VALUE (*func1)(), void *arg1, void (*func2)(), void *arg2) -関数func1をarg1を引数として実行し, 実行終了後(たとえ例外が発 -生しても) func2をarg2を引数として実行する.戻り値はfunc1の戻 -り値である(例外が発生した時は戻らない). +Calls the function func1 with arg1 as the argument, then calls func2 +with arg2, whenever execution terminated. The return value from +rb_ensure() is that of func1. + +** Exceptions and Errors + + void rb_warn(char *fmt, ...) -** 例外・エラー +Prints warning message according to the printf-like format. void rb_warning(char *fmt, ...) -rb_verbose時に標準エラー出力に警告情報を表示する.引数はprintf()と同じ. +Prints warning message according to the printf-like format, if +$VERBOSE is true. - void rb_raise(rb_eRuntimeError, char *fmt, ...) + void rb_raise(VALUE exception, char *fmt, ...) -例外を発生させる.引数はprintf()と同じ. +Raises an exception of class exception. The fmt is the format string +just like printf(). void rb_fatal(char *fmt, ...) -致命的例外を発生させる.通常の例外処理は行なわれず, インター -プリタが終了する(ただしensureで指定されたコードは終了前に実 -行される). +Raises fatal error, terminates the interpreter. No exception handling +will be done for fatal error, but ensure blocks will be executed. void rb_bug(char *fmt, ...) -インタープリタなどプログラムのバグでしか発生するはずのない状 -況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.例外 -処理は一切行なわれない. +Termintates the interpreter immediately. This function should be +called under the situation caused by the bug in the interpreter. No +exception handling nor ensure execution will be done. ** Initialize and Starts the Interpreter @@ -999,8 +973,7 @@ Specifies the name of the script ($0). Appendix B. Functions Available in extconf.rb -extconf.rbの中では利用可能なコンパイル条件チェックの関数は以 -下の通りである. +These functions are available in extconf.rb: have_library(lib, func) @@ -1024,6 +997,6 @@ this method, the compilation will not be done. /* * Local variables: - * fill-column: 60 + * fill-column: 70 * end: */ diff --git a/README.EXT.jp b/README.EXT.jp index 87175be853..1d56f25501 100644 --- a/README.EXT.jp +++ b/README.EXT.jp @@ -134,7 +134,7 @@ VALUE * FIXNUMの場合 - 1bit右シフトして,LSBを立てる. + 1bit左シフトして,LSBを立てる. * その他のポインタの場合 @@ -265,10 +265,10 @@ Ruby ます. これらの関数の argcという引数はCの関数へ渡される引数の数(と -形式)を決めます.argcが正の時は関数に引き渡す引数の数を意味 -します.16個以上の引数は使えません(が,要りませんよね,そん -なに).実際の関数には先頭の引数としてselfが与えられますので, -指定した数より1多い引数を持つことになります. +形式)を決めます.argcが0以上の時は関数に引き渡す引数の数を意 +味します.16個以上の引数は使えません(が,要りませんよね,そ +んなに).実際の関数には先頭の引数としてselfが与えられますの +で,指定した数より1多い引数を持つことになります. argcが負の時は引数の数ではなく,形式を指定したことになります. argcが-1の時は引数を配列に入れて渡されます.argcが-2の時は引 @@ -666,16 +666,13 @@ Ruby -- static VALUE fdbm_indexes(obj, args) - VALUE obj; - struct RArray *args; + VALUE obj, args; { : } -- -第1引数はself,第2引数はRubyの配列です.ここではキャストを減 -らすため struct RArray* で受けていますが,VALUEでも同じこと -です. +第1引数はself,第2引数はRubyの配列です. ** 注意事項 @@ -723,7 +720,7 @@ Makefile (7) MANIFESTファイルにファイル名を入れる - % ls > MANIFEST + % find * -type f -print > MANIFEST % vi MANIFEST *.o, *~など不必要なファイル以外はMANIFESTに追加しておきます. diff --git a/README.jp b/README.jp index d137a435d8..5e3b2301b0 100644 --- a/README.jp +++ b/README.jp @@ -142,22 +142,21 @@ Licence) (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 3bc7887489..84bc89c781 100644 --- a/ToDo +++ b/ToDo @@ -1,8 +1,11 @@ Language Spec. * package or access control for global variables -* named arguments like foo(nation:="german"). +* named arguments like foo(nation:="german" or nation: "german"). +* 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 @@ -12,7 +15,13 @@ Hacking Interpreter * remove rb_eval() recursions * syntax tree -> bytecode ??? * scrambled script, or script filter -* regular expression bug /(?:\s+\d+){2}/ URGENT!! + +Standard Libraries + +* String#scanf(?) +* Object#fmt(?) +* Integer[num], Float[num] (String[str]?, Array[obj]??) +* Stream or Port, abstract superclass of IO. Extension Libraries @@ -30,6 +39,7 @@ Tools * extension library maker like XS or SWIG * freeze or undump to bundle everything +* eruby - embedded ruby Misc diff --git a/array.c b/array.c index 8f6c0c223f..92d83d5d00 100644 --- a/array.c +++ b/array.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Aug 6 09:46:12 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -49,7 +49,7 @@ rb_ary_modify(ary) rb_raise(rb_eTypeError, "can't modify frozen array"); if (FL_TEST(ary, ARY_TMPLOCK)) rb_raise(rb_eTypeError, "can't modify array during sort"); - if (rb_safe_level() >= 4 && !FL_TEST(ary, FL_TAINT)) + if (!FL_TEST(ary, FL_TAINT) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't modify array"); } @@ -72,7 +72,7 @@ rb_ary_frozen_p(ary) VALUE rb_ary_new2(len) - size_t len; + int len; { NEWOBJ(ary, struct RArray); OBJSETUP(ary, rb_cArray, T_ARRAY); @@ -107,16 +107,16 @@ rb_ary_new() VALUE #ifdef HAVE_STDARG_PROTOTYPES -rb_ary_new3(size_t n, ...) +rb_ary_new3(int n, ...) #else rb_ary_new3(n, va_alist) - size_t n; + int n; va_dcl #endif { va_list ar; VALUE ary; - size_t i; + int i; if (n < 0) { rb_raise(rb_eIndexError, "negative number of items(%d)", n); @@ -135,7 +135,7 @@ rb_ary_new3(n, va_alist) VALUE rb_ary_new4(n, elts) - size_t n; + int n; VALUE *elts; { VALUE ary; @@ -169,7 +169,7 @@ rb_ary_s_new(argc, argv, klass) VALUE *argv; VALUE klass; { - size_t len = 0; + int len = 0; VALUE size, val; NEWOBJ(ary, struct RArray); OBJSETUP(ary, klass, T_ARRAY); @@ -180,7 +180,7 @@ rb_ary_s_new(argc, argv, klass) ary->capa = ARY_DEFAULT_SIZE; } else { - size_t capa = NUM2UINT(size); + int capa = NUM2INT(size); if (capa < 0) { rb_raise(rb_eArgError, "negative array size"); @@ -194,7 +194,7 @@ rb_ary_s_new(argc, argv, klass) ary->ptr = ALLOC_N(VALUE, ary->capa); memfill(ary->ptr, len, val); ary->len = len; - rb_obj_call_init((VALUE)ary); + rb_obj_call_init((VALUE)ary, argc, argv); return (VALUE)ary; } @@ -224,7 +224,7 @@ rb_ary_s_create(argc, argv, klass) void rb_ary_store(ary, idx, val) VALUE ary; - size_t idx; + int idx; VALUE val; { rb_ary_modify(ary); @@ -236,7 +236,11 @@ rb_ary_store(ary, idx, val) } if (idx >= RARRAY(ary)->capa) { - RARRAY(ary)->capa = idx + ARY_DEFAULT_SIZE; + int capa_inc = RARRAY(ary)->capa / 2; + if (capa_inc < ARY_DEFAULT_SIZE) { + capa_inc = ARY_DEFAULT_SIZE; + } + RARRAY(ary)->capa = idx + capa_inc; REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa); } if (idx > RARRAY(ary)->len) { @@ -310,7 +314,11 @@ rb_ary_unshift(ary, item) { rb_ary_modify(ary); if (RARRAY(ary)->len >= RARRAY(ary)->capa) { - RARRAY(ary)->capa+=ARY_DEFAULT_SIZE; + int capa_inc = RARRAY(ary)->capa / 2; + if (capa_inc < ARY_DEFAULT_SIZE) { + capa_inc = ARY_DEFAULT_SIZE; + } + RARRAY(ary)->capa+=capa_inc; REALLOC_N(RARRAY(ary)->ptr, VALUE, RARRAY(ary)->capa); } @@ -326,7 +334,7 @@ rb_ary_unshift(ary, item) VALUE rb_ary_entry(ary, offset) VALUE ary; - size_t offset; + int offset; { if (RARRAY(ary)->len == 0) return Qnil; @@ -343,12 +351,13 @@ rb_ary_entry(ary, offset) static VALUE rb_ary_subseq(ary, beg, len) VALUE ary; - size_t beg, len; + int 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; @@ -371,11 +380,10 @@ rb_ary_subseq(ary, beg, len) static VALUE beg_len(range, begp, lenp, len) VALUE range; - size_t *begp, *lenp; - size_t len; + int *begp, *lenp, len; { - size_t beg, end; - size_t b, e; + int beg, end; + int b, e; if (!rb_range_beg_end(range, &beg, &end)) return Qfalse; b = beg; e = end; @@ -386,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; } @@ -408,11 +419,11 @@ rb_ary_aref(argc, argv, ary) VALUE ary; { VALUE arg1, arg2; - size_t beg, len; + int beg, len; if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) { - beg = NUM2UINT(arg1); - len = NUM2UINT(arg2); + beg = NUM2INT(arg1); + len = NUM2INT(arg2); if (beg < 0) { beg = RARRAY(ary)->len + beg; } @@ -421,7 +432,7 @@ rb_ary_aref(argc, argv, ary) /* special case - speeding up */ if (FIXNUM_P(arg1)) { - return rb_ary_entry(ary, FIX2UINT(arg1)); + return rb_ary_entry(ary, FIX2INT(arg1)); } else if (TYPE(arg1) == T_BIGNUM) { rb_raise(rb_eIndexError, "index too big"); @@ -430,7 +441,7 @@ rb_ary_aref(argc, argv, ary) /* check if idx is Range */ return rb_ary_subseq(ary, beg, len); } - return rb_ary_entry(ary, NUM2UINT(arg1)); + return rb_ary_entry(ary, NUM2INT(arg1)); } static VALUE @@ -438,7 +449,7 @@ rb_ary_index(ary, val) VALUE ary; VALUE val; { - size_t i; + int i; for (i=0; ilen; i++) { if (rb_equal(RARRAY(ary)->ptr[i], val)) @@ -452,7 +463,7 @@ rb_ary_rindex(ary, val) VALUE ary; VALUE val; { - size_t i = RARRAY(ary)->len; + int i = RARRAY(ary)->len; while (i--) { if (rb_equal(RARRAY(ary)->ptr[i], val)) @@ -468,11 +479,11 @@ rb_ary_indexes(argc, argv, ary) VALUE ary; { VALUE new_ary; - size_t i; + int i; new_ary = rb_ary_new2(argc); for (i=0; ilen = len; } else { - size_t alen; + int alen; if (beg + len > RARRAY(ary)->len) { len = RARRAY(ary)->len - beg; @@ -539,25 +550,30 @@ rb_ary_aset(argc, argv, ary) VALUE ary; { VALUE arg1, arg2, arg3; - size_t offset; - size_t beg, len; + int offset, beg, len; if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) { - beg = NUM2UINT(arg1); - len = NUM2UINT(arg2); + beg = NUM2INT(arg1); + len = NUM2INT(arg2); 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; } else if (FIXNUM_P(arg1)) { - offset = FIX2UINT(arg1); + offset = FIX2INT(arg1); goto fixnum; } 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; } @@ -565,7 +581,7 @@ rb_ary_aset(argc, argv, ary) rb_raise(rb_eIndexError, "index too big"); } - offset = NUM2UINT(arg1); + offset = NUM2INT(arg1); fixnum: rb_ary_store(ary, offset, arg2); return arg2; @@ -575,7 +591,7 @@ VALUE rb_ary_each(ary) VALUE ary; { - size_t i; + int i; for (i=0; ilen; i++) { rb_yield(RARRAY(ary)->ptr[i]); @@ -587,7 +603,7 @@ static VALUE rb_ary_each_index(ary) VALUE ary; { - size_t i; + int i; for (i=0; ilen; i++) { rb_yield(INT2FIX(i)); @@ -599,7 +615,7 @@ static VALUE rb_ary_reverse_each(ary) VALUE ary; { - size_t len = RARRAY(ary)->len; + int len = RARRAY(ary)->len; while (len--) { rb_yield(RARRAY(ary)->ptr[len]); @@ -663,7 +679,7 @@ VALUE rb_ary_join(ary, sep) VALUE ary, sep; { - size_t i; + int i; VALUE result, tmp; if (RARRAY(ary)->len == 0) return rb_str_new(0, 0); @@ -815,7 +831,7 @@ rb_inspecting_p(obj) inspect_tbl = rb_thread_local_aref(rb_thread_current(), inspect_key); if (NIL_P(inspect_tbl)) return Qfalse; #else - if (!inspect_tbl) return Qnil; + if (!inspect_tbl) return Qfalse; #endif return rb_ary_includes(inspect_tbl, obj); } @@ -824,7 +840,7 @@ static VALUE inspect_ary(ary) VALUE ary; { - size_t i = 0; + int i = 0; VALUE s, str; str = rb_str_new2("["); @@ -953,7 +969,7 @@ rb_ary_delete(ary, item) VALUE ary; VALUE item; { - size_t i1, i2; + int i1, i2; rb_ary_modify(ary); for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) { @@ -981,11 +997,11 @@ rb_ary_delete_at(ary, at) VALUE ary; VALUE at; { - size_t i1, i2, pos; + int i1, i2, pos; VALUE del = Qnil; rb_ary_modify(ary); - pos = NUM2UINT(at); + pos = NUM2INT(at); for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) { if (i1 == pos) { del = RARRAY(ary)->ptr[i1]; @@ -1005,11 +1021,11 @@ static VALUE rb_ary_delete_if(ary) VALUE ary; { - size_t i1, i2; + int i1, i2; rb_ary_modify(ary); for (i1 = i2 = 0; i1 < RARRAY(ary)->len; i1++) { - if (rb_yield(RARRAY(ary)->ptr[i1])) continue; + if (RTEST(rb_yield(RARRAY(ary)->ptr[i1]))) continue; if (i1 != i2) { RARRAY(ary)->ptr[i2] = RARRAY(ary)->ptr[i1]; } @@ -1024,7 +1040,7 @@ static VALUE rb_ary_filter(ary) VALUE ary; { - size_t i; + int i; rb_ary_modify(ary); for (i = 0; i < RARRAY(ary)->len; i++) { @@ -1061,7 +1077,7 @@ rb_ary_fill(argc, argv, ary) VALUE ary; { VALUE item, arg1, arg2; - size_t beg, len, end; + int beg, end, len; VALUE *p, *pend; if (rb_scan_args(argc, argv, "12", &item, &arg1, &arg2) == 2 && @@ -1069,12 +1085,12 @@ rb_ary_fill(argc, argv, ary) /* beg and len set already */ } else { - beg = NIL_P(arg1)?0:NUM2UINT(arg1); + beg = NIL_P(arg1)?0:NUM2INT(arg1); if (beg < 0) { beg = RARRAY(ary)->len + beg; if (beg < 0) beg = 0; } - len = NIL_P(arg2)?RARRAY(ary)->len - beg:NUM2UINT(arg2); + len = NIL_P(arg2)?RARRAY(ary)->len - beg:NUM2INT(arg2); } rb_ary_modify(ary); end = beg + len; @@ -1138,13 +1154,13 @@ rb_ary_times(ary, times) VALUE times; { VALUE ary2; - size_t i, len; + int i, len; if (TYPE(times) == T_STRING) { return rb_ary_join(ary, times); } - len = NUM2UINT(times); + len = NUM2INT(times); if (len < 0) { rb_raise(rb_eArgError, "negative argument"); } @@ -1200,7 +1216,7 @@ static VALUE rb_ary_equal(ary1, ary2) VALUE ary1, ary2; { - size_t i; + int i; if (TYPE(ary2) != T_ARRAY) return Qfalse; if (RARRAY(ary1)->len != RARRAY(ary2)->len) return Qfalse; @@ -1215,7 +1231,7 @@ static VALUE rb_ary_eql(ary1, ary2) VALUE ary1, ary2; { - size_t i; + int i; if (TYPE(ary2) != T_ARRAY) return Qfalse; if (RARRAY(ary1)->len != RARRAY(ary2)->len) @@ -1231,8 +1247,7 @@ static VALUE rb_ary_hash(ary) VALUE ary; { - size_t i; - int h; + int i, h; h = RARRAY(ary)->len; for (i=0; ilen; i++) { @@ -1247,7 +1262,7 @@ rb_ary_includes(ary, item) VALUE ary; VALUE item; { - size_t i; + int i; for (i=0; ilen; i++) { if (rb_equal(RARRAY(ary)->ptr[i], item)) { return Qtrue; @@ -1261,7 +1276,7 @@ rb_ary_cmp(ary, ary2) VALUE ary; VALUE ary2; { - size_t i, len; + int i, len; ary2 = to_ary(ary2); len = RARRAY(ary)->len; @@ -1285,7 +1300,7 @@ rb_ary_diff(ary1, ary2) VALUE ary1, ary2; { VALUE ary3; - size_t i; + int i; ary2 = to_ary(ary2); ary3 = rb_ary_new(); @@ -1302,7 +1317,7 @@ rb_ary_and(ary1, ary2) VALUE ary1, ary2; { VALUE ary3; - size_t i; + int i; ary2 = to_ary(ary2); ary3 = rb_ary_new(); @@ -1320,7 +1335,7 @@ rb_ary_or(ary1, ary2) VALUE ary1, ary2; { VALUE ary3; - size_t i; + int i; if (TYPE(ary2) != T_ARRAY) { if (rb_ary_includes(ary1, ary2)) return ary1; @@ -1414,7 +1429,7 @@ static VALUE rb_ary_nitems(ary) VALUE ary; { - size_t n = 0; + int n = 0; VALUE *p, *pend; p = RARRAY(ary)->ptr; @@ -1430,7 +1445,7 @@ static VALUE rb_ary_flatten_bang(ary) VALUE ary; { - size_t i; + int i; int mod = 0; rb_ary_modify(ary); @@ -1504,6 +1519,7 @@ Init_Array() rb_define_method(rb_cArray, "delete", rb_ary_delete, 1); rb_define_method(rb_cArray, "delete_at", rb_ary_delete_at, 1); rb_define_method(rb_cArray, "delete_if", rb_ary_delete_if, 0); + rb_define_method(rb_cArray, "reject!", rb_ary_delete_if, 0); rb_define_method(rb_cArray, "filter", rb_ary_filter, 0); rb_define_method(rb_cArray, "replace", rb_ary_replace_method, 1); rb_define_method(rb_cArray, "clear", rb_ary_clear, 0); diff --git a/bignum.c b/bignum.c index 770e86ad80..5050b50218 100644 --- a/bignum.c +++ b/bignum.c @@ -26,7 +26,7 @@ typedef unsigned short USHORT; static VALUE bignew_1(klass, len, sign) VALUE klass; - size_t len; + int len; char sign; { NEWOBJ(big, struct RBignum); @@ -79,7 +79,7 @@ static VALUE bignorm(x) VALUE x; { - size_t len = RBIGNUM(x)->len; + int len = RBIGNUM(x)->len; USHORT *ds = BDIGITS(x); while (len-- && !ds[len]) ; @@ -170,7 +170,7 @@ rb_str2inum(str, base) { char sign = 1, c; unsigned long num; - size_t len, blen = 1; + int len, blen = 1; int i; VALUE z; USHORT *zds; @@ -191,6 +191,10 @@ rb_str2inum(str, base) str++; base = 16; } + else if (*str == 'b' || *str == 'B') { + str++; + base = 2; + } else { base = 8; } @@ -204,10 +208,13 @@ rb_str2inum(str, base) while (str[0] == '0') str++; len = 3*strlen(str)*sizeof(char); } - else { /* base == 10 or 16 */ + else { /* base == 10, 2 or 16 */ if (base == 16 && str[0] == '0' && (str[1] == 'x'||str[1] == 'X')) { str += 2; } + if (base == 2 && str[0] == '0' && (str[1] == 'b'||str[1] == 'B')) { + str += 2; + } while (str[0] == '0') str++; len = 4*strlen(str)*sizeof(char); } @@ -352,7 +359,7 @@ rb_big2ulong(x) VALUE x; { unsigned long num; - size_t len = RBIGNUM(x)->len; + int len = RBIGNUM(x)->len; USHORT *ds; if (len > sizeof(long)/sizeof(USHORT)) @@ -396,7 +403,14 @@ rb_dbl2big(d) VALUE z; double u = (d < 0)?-d:d; - while (0 != (long)u) { + 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++; } @@ -417,7 +431,7 @@ rb_big2dbl(x) VALUE x; { double d = 0.0; - size_t i = RBIGNUM(x)->len; + int i = RBIGNUM(x)->len; USHORT *ds = BDIGITS(x); while (i--) { @@ -438,7 +452,7 @@ static VALUE rb_big_cmp(x, y) VALUE x, y; { - size_t xlen = RBIGNUM(x)->len; + int xlen = RBIGNUM(x)->len; switch (TYPE(y)) { case T_FIXNUM: @@ -490,7 +504,7 @@ rb_big_neg(x) VALUE x; { VALUE z = rb_big_clone(x); - size_t i = RBIGNUM(x)->len; + int i = RBIGNUM(x)->len; USHORT *ds = BDIGITS(z); if (!RBIGNUM(x)->sign) rb_big_2comp(z); @@ -508,7 +522,7 @@ bigsub(x, y) VALUE z = 0; USHORT *zds; long num; - size_t i; + int i; i = RBIGNUM(x)->len; /* if x is larger than y, swap */ @@ -556,7 +570,7 @@ bigadd(x, y, sign) { VALUE z; long num; - size_t i, len; + int i, len; sign = (sign == RBIGNUM(y)->sign); if (RBIGNUM(x)->sign != sign) { @@ -636,7 +650,7 @@ VALUE rb_big_mul(x, y) VALUE x, y; { - size_t i, j; + int i, j; unsigned long n = 0; VALUE z; USHORT *zds; @@ -685,11 +699,11 @@ bigdivmod(x, y, div, mod, modulo) VALUE *div, *mod; int modulo; { - size_t nx = RBIGNUM(x)->len, ny = RBIGNUM(y)->len; + int nx = RBIGNUM(x)->len, ny = RBIGNUM(y)->len; int i, j; VALUE yy, z; USHORT *xds, *yds, *zds, *tds; - size_t t2; + unsigned long t2; long num; USHORT dd, q; @@ -714,7 +728,7 @@ bigdivmod(x, y, div, mod, modulo) if (div) *div = bignorm(z); if (mod) { if (!RBIGNUM(y)->sign) t2 = -(long)t2; - *mod = INT2FIX(t2); + *mod = INT2NUM(t2); } return; } @@ -798,7 +812,7 @@ bigdivmod(x, y, div, mod, modulo) RBIGNUM(*mod)->len = ny; RBIGNUM(*mod)->sign = RBIGNUM(x)->sign; if (modulo && RBIGNUM(x)->sign != RBIGNUM(y)->sign) { - size_t len = ny; + int len = ny; zds = BDIGITS(*mod); while (len-- && !zds[len]); if (len > 0) { @@ -936,6 +950,7 @@ rb_big_pow(x, y) } z = rb_big_mul(z, x); } + if (!FIXNUM_P(z)) z = bignorm(z); return z; } d = (double)yy; @@ -953,7 +968,7 @@ rb_big_and(x, y) { VALUE z; USHORT *ds1, *ds2, *zds; - size_t i, l1, l2; + int i, l1, l2; char sign; if (FIXNUM_P(y)) { @@ -1112,11 +1127,11 @@ rb_big_lshift(x, y) { USHORT *xds, *zds; int shift = NUM2INT(y); - size_t s1 = shift/BITSPERDIG; - size_t s2 = shift%BITSPERDIG; + int s1 = shift/BITSPERDIG; + int s2 = shift%BITSPERDIG; VALUE z; unsigned long num = 0; - size_t len, i; + int len, i; if (shift < 0) return rb_big_rshift(x, INT2FIX(-shift)); xds = BDIGITS(x); @@ -1141,12 +1156,12 @@ rb_big_rshift(x, y) { USHORT *xds, *zds; int shift = NUM2INT(y); - size_t s1 = shift/BITSPERDIG; - size_t s2 = shift%BITSPERDIG; + int s1 = shift/BITSPERDIG; + int s2 = shift%BITSPERDIG; VALUE z; unsigned long num = 0; - size_t i = RBIGNUM(x)->len; - size_t j; + int i = RBIGNUM(x)->len; + int j; if (shift < 0) return rb_big_lshift(x, INT2FIX(-shift)); if (s1 > RBIGNUM(x)->len) { @@ -1173,7 +1188,7 @@ rb_big_aref(x, y) { USHORT *xds; int shift = NUM2INT(y); - size_t s1, s2; + int s1, s2; if (shift < 0) return INT2FIX(0); s1 = shift/BITSPERDIG; @@ -1197,7 +1212,7 @@ static VALUE rb_big_hash(x) VALUE x; { - size_t i, len; + int i, len; int key; USHORT *digits; @@ -1216,7 +1231,7 @@ rb_big_coerce(x, y) return rb_assoc_new(rb_int2big(FIX2LONG(y)), x); } else { - rb_raise(rb_eTypeError, "can't coerce %s to Bignum", + rb_raise(rb_eTypeError, "Can't coerce %s to Bignum", rb_class2name(CLASS_OF(y))); } /* not reached */ @@ -1243,7 +1258,7 @@ rb_big_rand(max) VALUE max; { struct RBignum *v; - size_t len; + int len; len = RBIGNUM(max)->len; v = RBIGNUM(bignew(len,1)); diff --git a/class.c b/class.c index 86ac8c5ae7..566dc70776 100644 --- a/class.c +++ b/class.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 15:05:44 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -365,6 +365,8 @@ method_list(mod, option, func) VALUE klass; VALUE *p, *q, *pend; + if (!FL_TEST(mod, FL_TAINT) && rb_safe_level() >= 4) + rb_raise(rb_eSecurityError, "Insecure: can't get metainfo"); ary = rb_ary_new(); for (klass = mod; klass; klass = RCLASS(klass)->super) { st_foreach(RCLASS(klass)->m_tbl, func, ary); @@ -426,6 +428,8 @@ rb_obj_singleton_methods(obj) VALUE klass; VALUE *p, *q, *pend; + if (rb_safe_level() >= 4 && !FL_TEST(obj, FL_TAINT)) + rb_raise(rb_eSecurityError, "Insecure: can't get metainfo"); ary = rb_ary_new(); klass = CLASS_OF(obj); while (klass && FL_TEST(klass, FL_SINGLETON)) { @@ -504,7 +508,7 @@ rb_singleton_class(obj) VALUE obj; { if (rb_special_const_p(obj)) { - rb_raise(rb_eTypeError, "cannot define singleton"); + rb_raise(rb_eTypeError, "can't define singleton"); } if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON)) { return RBASIC(obj)->klass; @@ -596,10 +600,10 @@ rb_scan_args(argc, argv, fmt, va_alist) if (ISDIGIT(*p)) { n = *p - '0'; if (n > argc) - rb_raise(rb_eArgError, "Wrong # of arguments (%d for %d)", argc, n); + rb_raise(rb_eArgError, "wrong # of arguments (%d for %d)", argc, n); for (i=0; i i) { - *var = argv[i]; + if (var) *var = argv[i]; } else { - *var = Qnil; + if (var) *var = Qnil; } } p++; @@ -624,15 +628,15 @@ 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') { if (argc > i) { - rb_raise(rb_eArgError, "Wrong # of arguments(%d for %d)", argc, i); + rb_raise(rb_eArgError, "wrong # of arguments(%d for %d)", argc, i); } } else { diff --git a/compar.c b/compar.c index a6212a86bb..50e4fa3a87 100644 --- a/compar.c +++ b/compar.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Aug 26 14:39:48 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ diff --git a/config.dj b/config.dj deleted file mode 100644 index 8ad3883380..0000000000 --- a/config.dj +++ /dev/null @@ -1,36 +0,0 @@ -#define THREAD 1 -#define HAVE_DIRENT_H 1 -#define HAVE_UNISTD_H 1 -#define HAVE_LIMITS_H 1 -#define HAVE_SYS_FILE_H 1 -#define HAVE_PWD_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_SYS_TIMES_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_WAIT_H 1 -#define HAVE_STRING_H 1 -#define HAVE_UTIME_H 1 -#define HAVE_MEMORY_H 1 -#define HAVE_ST_BLKSIZE 1 -#define HAVE_ST_RDEV 1 -#define GETGROUPS_T gid_t -#define RETSIGTYPE void -#define HAVE_ALLOCA 1 -#define vfork fork -#define HAVE_FMOD 1 -#define HAVE_RANDOM 1 -#define HAVE_WAITPID 1 -#define HAVE_GETCWD 1 -#define HAVE_TRUNCATE 1 -#define HAVE_CHSIZE 1 -#define HAVE_TIMES 1 -#define HAVE_UTIMES 1 -/* #define HAVE_FCNTL 1 */ -/* #define HAVE_SETITIMER 1 */ -#define HAVE_GETGROUPS 1 -#define HAVE_SIGPROCMASK 1 -#define FILE_COUNT _cnt -#define DLEXT ".so" -#define RUBY_LIB ";/usr/local/lib/ruby;." -#define RUBY_ARCHLIB "/usr/local/lib/ruby/i386-djgpp" -#define RUBY_PLATFORM "i386-djgpp" 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 31a40f05e8..906978c4d5 100644 --- a/configure +++ b/configure @@ -1,7 +1,7 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated automatically using autoconf version 2.12.2 +# Generated automatically using autoconf version 2.13 # Copyright (C) 1992, 93, 94, 95, 96 Free Software Foundation, Inc. # # This configure script is free software; the Free Software Foundation @@ -343,7 +343,7 @@ EOF verbose=yes ;; -version | --version | --versio | --versi | --vers) - echo "configure generated by autoconf version 2.12.2" + echo "configure generated by autoconf version 2.13" exit 0 ;; -with-* | --with-*) @@ -532,6 +532,13 @@ fi +rb_version=`grep RUBY_VERSION $srcdir/version.h` +MAJOR=`expr "$rb_version" : '#define RUBY_VERSION "\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*"'` +MINOR=`expr "$rb_version" : '#define RUBY_VERSION "[0-9][0-9]*\.\([0-9][0-9]*\)\.[0-9][0-9]*"'` +TEENY=`expr "$rb_version" : '#define RUBY_VERSION "[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\)"'` + + + # Check whether --with-gcc or --without-gcc was given. if test "${with_gcc+set}" = set; then withval="$with_gcc" @@ -596,7 +603,7 @@ else { echo "configure: error: can not run $ac_config_sub" 1>&2; exit 1; } fi echo $ac_n "checking host system type""... $ac_c" 1>&6 -echo "configure:600: checking host system type" >&5 +echo "configure:607: checking host system type" >&5 host_alias=$host case "$host_alias" in @@ -621,13 +628,13 @@ fat_binary=no # Check whether --enable-fat-binary or --disable-fat-binary was given. if test "${enable_fat_binary+set}" = set; then enableval="$enable_fat_binary" - fat_binary=$enableval + fat_binary=$enableval fi if test "$fat_binary" = yes ; then - echo $ac_n "checking target architecture ""... $ac_c" 1>&6 -echo "configure:631: checking target architecture " >&5 + echo $ac_n "checking target architecture""... $ac_c" 1>&6 +echo "configure:638: checking target architecture" >&5 case "$host_os" in rhapsody*) @@ -692,7 +699,7 @@ test "$program_transform_name" = "" && program_transform_name="s,x,x," # Extract the first word of "gcc", so it can be a program name with args. set dummy gcc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:696: checking for $ac_word" >&5 +echo "configure:703: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -722,7 +729,7 @@ if test -z "$CC"; then # Extract the first word of "cc", so it can be a program name with args. set dummy cc; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:726: checking for $ac_word" >&5 +echo "configure:733: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -773,7 +780,7 @@ fi # Extract the first word of "cl", so it can be a program name with args. set dummy cl; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:777: checking for $ac_word" >&5 +echo "configure:784: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_CC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -805,7 +812,7 @@ fi fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works""... $ac_c" 1>&6 -echo "configure:809: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 +echo "configure:816: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) works" >&5 ac_ext=c # CFLAGS is not in ac_cpp because -g, -O, etc. are not valid cpp options. @@ -816,12 +823,12 @@ cross_compiling=$ac_cv_prog_cc_cross cat > conftest.$ac_ext << EOF -#line 820 "configure" +#line 827 "configure" #include "confdefs.h" main(){return(0);} EOF -if { (eval echo configure:825: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:832: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then ac_cv_prog_cc_works=yes # If we can't run a trivial program, we are probably using a cross compiler. if (./conftest; exit) 2>/dev/null; then @@ -847,12 +854,12 @@ if test $ac_cv_prog_cc_works = no; then { echo "configure: error: installation or configuration problem: C compiler cannot create executables." 1>&2; exit 1; } fi echo $ac_n "checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler""... $ac_c" 1>&6 -echo "configure:851: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 +echo "configure:858: checking whether the C compiler ($CC $CFLAGS $LDFLAGS) is a cross-compiler" >&5 echo "$ac_t""$ac_cv_prog_cc_cross" 1>&6 cross_compiling=$ac_cv_prog_cc_cross echo $ac_n "checking whether we are using GNU C""... $ac_c" 1>&6 -echo "configure:856: checking whether we are using GNU C" >&5 +echo "configure:863: checking whether we are using GNU C" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -861,7 +868,7 @@ else yes; #endif EOF -if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:865: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then +if { ac_try='${CC-cc} -E conftest.c'; { (eval echo configure:872: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; }; } | egrep yes >/dev/null 2>&1; then ac_cv_prog_gcc=yes else ac_cv_prog_gcc=no @@ -880,7 +887,7 @@ ac_test_CFLAGS="${CFLAGS+set}" ac_save_CFLAGS="$CFLAGS" CFLAGS= echo $ac_n "checking whether ${CC-cc} accepts -g""... $ac_c" 1>&6 -echo "configure:884: checking whether ${CC-cc} accepts -g" >&5 +echo "configure:891: checking whether ${CC-cc} accepts -g" >&5 if eval "test \"`echo '$''{'ac_cv_prog_cc_g'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -912,7 +919,7 @@ else fi echo $ac_n "checking how to run the C preprocessor""... $ac_c" 1>&6 -echo "configure:916: checking how to run the C preprocessor" >&5 +echo "configure:923: checking how to run the C preprocessor" >&5 # On Suns, sometimes $CPP names a directory. if test -n "$CPP" && test -d "$CPP"; then CPP= @@ -927,13 +934,13 @@ else # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:937: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:944: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -944,13 +951,13 @@ else rm -rf conftest* CPP="${CC-cc} -E -traditional-cpp" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:954: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:961: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -961,13 +968,13 @@ else rm -rf conftest* CPP="${CC-cc} -nologo -E" cat > conftest.$ac_ext < Syntax Error EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:971: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:978: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then : @@ -993,13 +1000,13 @@ echo "$ac_t""$CPP" 1>&6 if test $ac_cv_prog_gcc = yes; then echo $ac_n "checking whether ${CC-cc} needs -traditional""... $ac_c" 1>&6 -echo "configure:997: checking whether ${CC-cc} needs -traditional" >&5 +echo "configure:1004: checking whether ${CC-cc} needs -traditional" >&5 if eval "test \"`echo '$''{'ac_cv_prog_gcc_traditional'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else ac_pattern="Autoconf.*'x'" cat > conftest.$ac_ext < Autoconf TIOCGETP @@ -1017,7 +1024,7 @@ rm -f conftest* if test $ac_cv_prog_gcc_traditional = no; then cat > conftest.$ac_ext < Autoconf TCGETA @@ -1043,7 +1050,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1047: checking for $ac_word" >&5 +echo "configure:1054: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_YACC'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1076,7 +1083,7 @@ test -n "$YACC" || YACC="yacc" # Extract the first word of "ranlib", so it can be a program name with args. set dummy ranlib; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1080: checking for $ac_word" >&5 +echo "configure:1087: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_RANLIB'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1109,7 +1116,7 @@ do # Extract the first word of "$ac_prog", so it can be a program name with args. set dummy $ac_prog; ac_word=$2 echo $ac_n "checking for $ac_word""... $ac_c" 1>&6 -echo "configure:1113: checking for $ac_word" >&5 +echo "configure:1120: checking for $ac_word" >&5 if eval "test \"`echo '$''{'ac_cv_prog_AR'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1151,7 +1158,7 @@ test -n "$AR" || AR="ar" # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" # ./install, which can be erroneously created by make from ./install.sh. echo $ac_n "checking for a BSD compatible install""... $ac_c" 1>&6 -echo "configure:1155: checking for a BSD compatible install" >&5 +echo "configure:1162: checking for a BSD compatible install" >&5 if test -z "$INSTALL"; then if eval "test \"`echo '$''{'ac_cv_path_install'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1203,8 +1210,29 @@ test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL_PROGRAM}' test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' +echo $ac_n "checking whether ln -s works""... $ac_c" 1>&6 +echo "configure:1215: checking whether ln -s works" >&5 +if eval "test \"`echo '$''{'ac_cv_prog_LN_S'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + rm -f conftestdata +if ln -s X conftestdata 2>/dev/null +then + rm -f conftestdata + ac_cv_prog_LN_S="ln -s" +else + ac_cv_prog_LN_S=ln +fi +fi +LN_S="$ac_cv_prog_LN_S" +if test "$ac_cv_prog_LN_S" = "ln -s"; then + echo "$ac_t""yes" 1>&6 +else + echo "$ac_t""no" 1>&6 +fi + echo $ac_n "checking whether ${MAKE-make} sets \${MAKE}""... $ac_c" 1>&6 -echo "configure:1208: checking whether ${MAKE-make} sets \${MAKE}" >&5 +echo "configure:1236: checking whether ${MAKE-make} sets \${MAKE}" >&5 set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_prog_make_${ac_make}_set'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1234,17 +1262,17 @@ fi # checks for UNIX variants that set C preprocessor variables ac_safe=`echo "minix/config.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for minix/config.h""... $ac_c" 1>&6 -echo "configure:1238: checking for minix/config.h" >&5 +echo "configure:1266: checking for minix/config.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1248: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:1276: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1283,7 +1311,7 @@ fi echo $ac_n "checking size of int""... $ac_c" 1>&6 -echo "configure:1287: checking size of int" >&5 +echo "configure:1315: checking size of int" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_int'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1291,7 +1319,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -1302,7 +1330,7 @@ main() exit(0); } EOF -if { (eval echo configure:1306: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1334: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_int=`cat conftestval` else @@ -1321,8 +1349,47 @@ cat >> confdefs.h <&6 +echo "configure:1354: checking size of short" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_short'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + 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 < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(short)); + exit(0); +} +EOF +if { (eval echo configure:1373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_short=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_short=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_short" 1>&6 +cat >> confdefs.h <&6 -echo "configure:1326: checking size of long" >&5 +echo "configure:1393: checking size of long" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_long'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1330,7 +1397,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -1341,7 +1408,7 @@ main() exit(0); } EOF -if { (eval echo configure:1345: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1412: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_long=`cat conftestval` else @@ -1361,7 +1428,7 @@ EOF echo $ac_n "checking size of void*""... $ac_c" 1>&6 -echo "configure:1365: checking size of void*" >&5 +echo "configure:1432: checking size of void*" >&5 if eval "test \"`echo '$''{'ac_cv_sizeof_voidp'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -1369,7 +1436,7 @@ else { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < main() @@ -1380,7 +1447,7 @@ main() exit(0); } EOF -if { (eval echo configure:1384: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:1451: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_sizeof_voidp=`cat conftestval` else @@ -1399,21 +1466,99 @@ cat >> confdefs.h <&6 +echo "configure:1471: checking size of float" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_float'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + 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 < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(float)); + exit(0); +} +EOF +if { (eval echo configure:1490: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_float=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_float=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_float" 1>&6 +cat >> confdefs.h <&6 +echo "configure:1510: checking size of double" >&5 +if eval "test \"`echo '$''{'ac_cv_sizeof_double'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + 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 < +main() +{ + FILE *f=fopen("conftestval", "w"); + if (!f) exit(1); + fprintf(f, "%d\n", sizeof(double)); + exit(0); +} +EOF +if { (eval echo configure:1529: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +then + ac_cv_sizeof_double=`cat conftestval` +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_sizeof_double=0 +fi +rm -fr conftest* +fi + +fi +echo "$ac_t""$ac_cv_sizeof_double" 1>&6 +cat >> confdefs.h <&6 -echo "configure:1405: checking for prototypes" >&5 +echo "configure:1550: checking for prototypes" >&5 if eval "test \"`echo '$''{'rb_cv_have_prototypes'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1562: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* rb_cv_have_prototypes=yes else @@ -1433,13 +1578,51 @@ EOF fi +echo $ac_n "checking token paste string""... $ac_c" 1>&6 +echo "configure:1583: checking token paste string" >&5 +if eval "test \"`echo '$''{'rb_cv_tokenpaste'+set}'`\" = set"; then + echo $ac_n "(cached) $ac_c" 1>&6 +else + cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then + rm -rf conftest* + rb_cv_tokenpaste=ansi +else + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -rf conftest* + rb_cv_tokenpaste=knr +fi +rm -f conftest* +fi + +echo "$ac_t""$rb_cv_tokenpaste" 1>&6 +if test "$rb_cv_tokenpaste" = ansi; then + cat >> confdefs.h <<\EOF +#define TOKEN_PASTE(x,y) x##y +EOF + +else + cat >> confdefs.h <<\EOF +#define TOKEN_PASTE(x,y) x/**/y +EOF + +fi + echo $ac_n "checking for variable length prototypes and stdarg.h""... $ac_c" 1>&6 -echo "configure:1438: checking for variable length prototypes and stdarg.h" >&5 +echo "configure:1621: checking for variable length prototypes and stdarg.h" >&5 if eval "test \"`echo '$''{'rb_cv_stdarg'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < @@ -1456,7 +1639,7 @@ int main() { return foo(10, "", 3.14); ; return 0; } EOF -if { (eval echo configure:1460: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1643: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* rb_cv_stdarg=yes else @@ -1477,19 +1660,19 @@ EOF fi echo $ac_n "checking for gcc attribute noreturn""... $ac_c" 1>&6 -echo "configure:1481: checking for gcc attribute noreturn" >&5 +echo "configure:1664: checking for gcc attribute noreturn" >&5 if eval "test \"`echo '$''{'rb_cv_have_attr_noreturn'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1676: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* rb_cv_have_attr_noreturn=yes else @@ -1518,7 +1701,7 @@ beos*) ;; *) LIBS="-lm $LIBS";; esac echo $ac_n "checking for crypt in -lcrypt""... $ac_c" 1>&6 -echo "configure:1522: checking for crypt in -lcrypt" >&5 +echo "configure:1705: checking for crypt in -lcrypt" >&5 ac_lib_var=`echo crypt'_'crypt | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1526,7 +1709,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lcrypt $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1724: \"$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 @@ -1565,7 +1748,7 @@ else fi echo $ac_n "checking for dlopen in -ldl""... $ac_c" 1>&6 -echo "configure:1569: checking for dlopen in -ldl" >&5 +echo "configure:1752: checking for dlopen in -ldl" >&5 ac_lib_var=`echo dl'_'dlopen | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1573,7 +1756,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldl $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1771: \"$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 @@ -1612,7 +1795,7 @@ else fi # Dynamic linking for SunOS/Solaris and SYSV echo $ac_n "checking for shl_load in -ldld""... $ac_c" 1>&6 -echo "configure:1616: checking for shl_load in -ldld" >&5 +echo "configure:1799: checking for shl_load in -ldld" >&5 ac_lib_var=`echo dld'_'shl_load | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1620,7 +1803,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldld $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1818: \"$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 @@ -1659,7 +1842,7 @@ else fi # Dynamic linking for HP-UX echo $ac_n "checking for setlocale in -lxpg4""... $ac_c" 1>&6 -echo "configure:1663: checking for setlocale in -lxpg4" >&5 +echo "configure:1846: checking for setlocale in -lxpg4" >&5 ac_lib_var=`echo xpg4'_'setlocale | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1667,7 +1850,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lxpg4 $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1865: \"$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 @@ -1711,12 +1894,12 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr that defines DIR""... $ac_c" 1>&6 -echo "configure:1715: checking for $ac_hdr that defines DIR" >&5 +echo "configure:1898: checking for $ac_hdr that defines DIR" >&5 if eval "test \"`echo '$''{'ac_cv_header_dirent_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include <$ac_hdr> @@ -1724,7 +1907,7 @@ int main() { DIR *dirp = 0; ; return 0; } EOF -if { (eval echo configure:1728: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:1911: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* eval "ac_cv_header_dirent_$ac_safe=yes" else @@ -1749,7 +1932,7 @@ done # Two versions of opendir et al. are in -ldir and -lx on SCO Xenix. if test $ac_header_dirent = dirent.h; then echo $ac_n "checking for opendir in -ldir""... $ac_c" 1>&6 -echo "configure:1753: checking for opendir in -ldir" >&5 +echo "configure:1936: checking for opendir in -ldir" >&5 ac_lib_var=`echo dir'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1757,7 +1940,7 @@ else ac_save_LIBS="$LIBS" LIBS="-ldir $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1955: \"$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 @@ -1790,7 +1973,7 @@ fi else echo $ac_n "checking for opendir in -lx""... $ac_c" 1>&6 -echo "configure:1794: checking for opendir in -lx" >&5 +echo "configure:1977: checking for opendir in -lx" >&5 ac_lib_var=`echo x'_'opendir | sed 'y%./+-%__p_%'` if eval "test \"`echo '$''{'ac_cv_lib_$ac_lib_var'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 @@ -1798,7 +1981,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lx $LIBS" cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:1996: \"$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 @@ -1832,12 +2015,12 @@ fi fi echo $ac_n "checking for ANSI C header files""... $ac_c" 1>&6 -echo "configure:1836: checking for ANSI C header files" >&5 +echo "configure:2019: checking for ANSI C header files" >&5 if eval "test \"`echo '$''{'ac_cv_header_stdc'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -1845,7 +2028,7 @@ else #include EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1849: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2032: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1862,7 +2045,7 @@ rm -f conftest* if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1880,7 +2063,7 @@ fi if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat > conftest.$ac_ext < EOF @@ -1901,7 +2084,7 @@ if test "$cross_compiling" = yes; then : else cat > conftest.$ac_ext < #define ISLOWER(c) ('a' <= (c) && (c) <= 'z') @@ -1912,7 +2095,7 @@ if (XOR (islower (i), ISLOWER (i)) || toupper (i) != TOUPPER (i)) exit(2); exit (0); } EOF -if { (eval echo configure:1916: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2099: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then : else @@ -1937,21 +2120,21 @@ fi for ac_hdr in stdlib.h unistd.h limits.h sys/file.h sys/ioctl.h pwd.h \ sys/select.h sys/time.h sys/times.h sys/param.h sys/wait.h\ - syscall.h a.out.h string.h utime.h memory.h direct.h + syscall.h a.out.h string.h utime.h memory.h direct.h fnmatch.h do ac_safe=`echo "$ac_hdr" | sed 'y%./+-%__p_%'` echo $ac_n "checking for $ac_hdr""... $ac_c" 1>&6 -echo "configure:1945: checking for $ac_hdr" >&5 +echo "configure:2128: checking for $ac_hdr" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:1955: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2138: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -1979,12 +2162,12 @@ done echo $ac_n "checking for uid_t in sys/types.h""... $ac_c" 1>&6 -echo "configure:1983: checking for uid_t in sys/types.h" >&5 +echo "configure:2166: checking for uid_t in sys/types.h" >&5 if eval "test \"`echo '$''{'ac_cv_type_uid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF @@ -2013,12 +2196,12 @@ EOF fi echo $ac_n "checking for size_t""... $ac_c" 1>&6 -echo "configure:2017: checking for size_t" >&5 +echo "configure:2200: checking for size_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_size_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2046,12 +2229,12 @@ EOF fi echo $ac_n "checking for st_blksize in struct stat""... $ac_c" 1>&6 -echo "configure:2050: checking for st_blksize in struct stat" >&5 +echo "configure:2233: checking for st_blksize in struct stat" >&5 if eval "test \"`echo '$''{'ac_cv_struct_st_blksize'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2059,7 +2242,7 @@ int main() { struct stat s; s.st_blksize; ; return 0; } EOF -if { (eval echo configure:2063: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2246: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_st_blksize=yes else @@ -2081,12 +2264,12 @@ fi save_LIBOJBS="$LIBOBJS" echo $ac_n "checking for st_blocks in struct stat""... $ac_c" 1>&6 -echo "configure:2085: checking for st_blocks in struct stat" >&5 +echo "configure:2268: checking for st_blocks in struct stat" >&5 if eval "test \"`echo '$''{'ac_cv_struct_st_blocks'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2094,7 +2277,7 @@ int main() { struct stat s; s.st_blocks; ; return 0; } EOF -if { (eval echo configure:2098: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2281: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_st_blocks=yes else @@ -2118,12 +2301,12 @@ fi LIBOBJS="$save_LIBOBJS" echo $ac_n "checking for st_rdev in struct stat""... $ac_c" 1>&6 -echo "configure:2122: checking for st_rdev in struct stat" >&5 +echo "configure:2305: checking for st_rdev in struct stat" >&5 if eval "test \"`echo '$''{'ac_cv_struct_st_rdev'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2131,7 +2314,7 @@ int main() { struct stat s; s.st_rdev; ; return 0; } EOF -if { (eval echo configure:2135: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2318: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_struct_st_rdev=yes else @@ -2153,7 +2336,7 @@ fi echo $ac_n "checking type of array argument to getgroups""... $ac_c" 1>&6 -echo "configure:2157: checking type of array argument to getgroups" >&5 +echo "configure:2340: checking type of array argument to getgroups" >&5 if eval "test \"`echo '$''{'ac_cv_type_getgroups'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2161,7 +2344,7 @@ else ac_cv_type_getgroups=cross else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2373: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_type_getgroups=gid_t else @@ -2200,7 +2383,7 @@ fi if test $ac_cv_type_getgroups = cross; then cat > conftest.$ac_ext < EOF @@ -2224,12 +2407,12 @@ EOF echo $ac_n "checking return type of signal handlers""... $ac_c" 1>&6 -echo "configure:2228: checking return type of signal handlers" >&5 +echo "configure:2411: checking return type of signal handlers" >&5 if eval "test \"`echo '$''{'ac_cv_type_signal'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #include @@ -2246,7 +2429,7 @@ int main() { int i; ; return 0; } EOF -if { (eval echo configure:2250: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then +if { (eval echo configure:2433: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then rm -rf conftest* ac_cv_type_signal=void else @@ -2267,19 +2450,19 @@ EOF # The Ultrix 4.2 mips builtin alloca declared by alloca.h only works # for constant arguments. Useless! echo $ac_n "checking for working alloca.h""... $ac_c" 1>&6 -echo "configure:2271: checking for working alloca.h" >&5 +echo "configure:2454: checking for working alloca.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_alloca_h'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < int main() { char *p = alloca(2 * sizeof(int)); ; return 0; } EOF -if { (eval echo configure:2283: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2466: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_header_alloca_h=yes else @@ -2300,12 +2483,12 @@ EOF fi echo $ac_n "checking for alloca""... $ac_c" 1>&6 -echo "configure:2304: checking for alloca" >&5 +echo "configure:2487: checking for alloca" >&5 if eval "test \"`echo '$''{'ac_cv_func_alloca_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2520: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* ac_cv_func_alloca_works=yes else @@ -2365,12 +2548,12 @@ EOF echo $ac_n "checking whether alloca needs Cray hooks""... $ac_c" 1>&6 -echo "configure:2369: checking whether alloca needs Cray hooks" >&5 +echo "configure:2552: checking whether alloca needs Cray hooks" >&5 if eval "test \"`echo '$''{'ac_cv_os_cray'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&6 if test $ac_cv_os_cray = yes; then for ac_func in _getb67 GETB67 getb67; do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:2399: checking for $ac_func" >&5 +echo "configure:2582: 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 <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2610: \"$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 @@ -2450,7 +2633,7 @@ done fi echo $ac_n "checking stack direction for C alloca""... $ac_c" 1>&6 -echo "configure:2454: checking stack direction for C alloca" >&5 +echo "configure:2637: checking stack direction for C alloca" >&5 if eval "test \"`echo '$''{'ac_cv_c_stack_direction'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2458,7 +2641,7 @@ else ac_cv_c_stack_direction=0 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2664: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_c_stack_direction=1 else @@ -2499,12 +2682,12 @@ EOF fi echo $ac_n "checking for pid_t""... $ac_c" 1>&6 -echo "configure:2503: checking for pid_t" >&5 +echo "configure:2686: checking for pid_t" >&5 if eval "test \"`echo '$''{'ac_cv_type_pid_t'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < #if STDC_HEADERS @@ -2533,17 +2716,17 @@ fi ac_safe=`echo "vfork.h" | sed 'y%./+-%__p_%'` echo $ac_n "checking for vfork.h""... $ac_c" 1>&6 -echo "configure:2537: checking for vfork.h" >&5 +echo "configure:2720: checking for vfork.h" >&5 if eval "test \"`echo '$''{'ac_cv_header_$ac_safe'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext < EOF ac_try="$ac_cpp conftest.$ac_ext >/dev/null 2>conftest.out" -{ (eval echo configure:2547: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } +{ (eval echo configure:2730: \"$ac_try\") 1>&5; (eval $ac_try) 2>&5; } ac_err=`grep -v '^ *+' conftest.out | grep -v "^conftest.${ac_ext}\$"` if test -z "$ac_err"; then rm -rf conftest* @@ -2568,18 +2751,18 @@ else fi echo $ac_n "checking for working vfork""... $ac_c" 1>&6 -echo "configure:2572: checking for working vfork" >&5 +echo "configure:2755: checking for working vfork" >&5 if eval "test \"`echo '$''{'ac_cv_func_vfork_works'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else if test "$cross_compiling" = yes; then echo $ac_n "checking for vfork""... $ac_c" 1>&6 -echo "configure:2578: checking for vfork" >&5 +echo "configure:2761: checking for vfork" >&5 if eval "test \"`echo '$''{'ac_cv_func_vfork'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then +if { (eval echo configure:2789: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext}; then rm -rf conftest* eval "ac_cv_func_vfork=yes" else @@ -2624,7 +2807,7 @@ fi ac_cv_func_vfork_works=$ac_cv_func_vfork else cat > conftest.$ac_ext < @@ -2719,7 +2902,7 @@ main() { } } EOF -if { (eval echo configure:2723: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2906: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_vfork_works=yes else @@ -2742,7 +2925,7 @@ EOF fi echo $ac_n "checking for 8-bit clean memcmp""... $ac_c" 1>&6 -echo "configure:2746: checking for 8-bit clean memcmp" >&5 +echo "configure:2929: checking for 8-bit clean memcmp" >&5 if eval "test \"`echo '$''{'ac_cv_func_memcmp_clean'+set}'`\" = set"; then echo $ac_n "(cached) $ac_c" 1>&6 else @@ -2750,7 +2933,7 @@ else ac_cv_func_memcmp_clean=no else cat > conftest.$ac_ext <&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null +if { (eval echo configure:2947: \"$ac_link\") 1>&5; (eval $ac_link) 2>&5; } && test -s conftest${ac_exeext} && (./conftest; exit) 2>/dev/null then ac_cv_func_memcmp_clean=yes else @@ -2778,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:2785: 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 <&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 @@ -2838,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:2846: 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 <&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 @@ -2896,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:2900: 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 < #include @@ -2909,7 +3093,7 @@ int main() { struct tm *tp; tp->tm_sec; ; return 0; } EOF -if { (eval echo configure:2913: \"$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 @@ -2930,12 +3114,12 @@ EOF fi echo $ac_n "checking for tm_zone in struct tm""... $ac_c" 1>&6 -echo "configure:2934: 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 < #include <$ac_cv_struct_tm> @@ -2943,7 +3127,7 @@ int main() { struct tm tm; tm.tm_zone; ; return 0; } EOF -if { (eval echo configure:2947: \"$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 @@ -2963,12 +3147,12 @@ EOF else echo $ac_n "checking for tzname""... $ac_c" 1>&6 -echo "configure:2967: 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 < #ifndef tzname /* For SGI. */ @@ -2978,7 +3162,7 @@ int main() { atoi(*tzname); ; return 0; } EOF -if { (eval echo configure:2982: \"$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 @@ -3000,14 +3184,14 @@ EOF fi cat > conftest.$ac_ext <&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 @@ -3027,15 +3211,15 @@ EOF else echo $ac_n "checking for BSD signal semantics""... $ac_c" 1>&6 -echo "configure:3031: checking for BSD signal semantics" >&5 - if eval "test \"`echo '$''{'rb_cv_bsd_signal'+set}'`\" = set"; then +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 if test "$cross_compiling" = yes; then - { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + rb_cv_bsd_signal=no else cat > conftest.$ac_ext < @@ -3057,7 +3241,7 @@ main() } EOF -if { (eval echo configure:3061: \"$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 @@ -3071,7 +3255,7 @@ fi fi - echo "$ac_t""$rb_cv_bsd_signal" 1>&6 +echo "$ac_t""$rb_cv_bsd_signal" 1>&6 if test "$rb_cv_bsd_signal" = yes; then cat >> confdefs.h <<\EOF #define BSD_SIGNAL 1 @@ -3080,92 +3264,211 @@ EOF fi fi -if test "$ac_cv_func_setpgrp2" = yes; then - cat >> confdefs.h <<\EOF -#define BSD_GETPGRP getpgrp2 +echo $ac_n "checking whether getpgrp takes no argument""... $ac_c" 1>&6 +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 + if test "$cross_compiling" = yes; then + { echo "configure: error: cannot check getpgrp if cross compiling" 1>&2; exit 1; } +else + cat > conftest.$ac_ext < +#include + +int pid; +int pg1, pg2, pg3, pg4; +int ng, np, s, child; + +main() +{ + pid = getpid(); + pg1 = getpgrp(0); + pg2 = getpgrp(); + pg3 = getpgrp(pid); + pg4 = getpgrp(1); + + /* + * If all of these values are the same, it's pretty sure that + * we're on a system that ignores getpgrp's first argument. + */ + if (pg2 == pg4 && pg1 == pg3 && pg2 == pg3) + exit(0); + + child = fork(); + if (child < 0) + exit(1); + else if (child == 0) { + np = getpid(); + /* + * If this is Sys V, this will not work; pgrp will be + * set to np because setpgrp just changes a pgrp to be + * the same as the pid. + */ + setpgrp(np, pg1); + ng = getpgrp(0); /* Same result for Sys V and BSD */ + if (ng == pg1) { + exit(1); + } else { + exit(0); + } + } else { + wait(&s); + exit(s>>8); + } +} + EOF +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 + echo "configure: failed program was:" >&5 + cat conftest.$ac_ext >&5 + rm -fr conftest* + ac_cv_func_getpgrp_void=no +fi +rm -fr conftest* +fi + +fi + +echo "$ac_t""$ac_cv_func_getpgrp_void" 1>&6 +if test $ac_cv_func_getpgrp_void = yes; then cat >> confdefs.h <<\EOF -#define BSD_SETPGRP setpgrp2 +#define GETPGRP_VOID 1 EOF -else - echo $ac_n "checking whether getpgrp() has arg""... $ac_c" 1>&6 -echo "configure:3095: checking whether getpgrp() has arg" >&5 - if eval "test \"`echo '$''{'rb_cv_bsdgetpgrp'+set}'`\" = set"; then +fi + +echo $ac_n "checking whether setpgrp takes no argument""... $ac_c" 1>&6 +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 + if test "$cross_compiling" = yes; then + { echo "configure: error: cannot check setpgrp if cross compiling" 1>&2; exit 1; } else cat > conftest.$ac_ext < -int main() { -getpgrp(0); -; return 0; } +#endif + +/* + * If this system has a BSD-style setpgrp, which takes arguments, exit + * successfully. + */ +main() +{ + if (setpgrp(1,1) == -1) + exit(0); + else + exit(1); +} + EOF -if { (eval echo configure:3107: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - rb_cv_bsdgetpgrp=yes +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 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 - rm -rf conftest* - rb_cv_bsdgetpgrp=no + rm -fr conftest* + ac_cv_func_setpgrp_void=yes fi -rm -f conftest* +rm -fr conftest* fi - echo "$ac_t""$rb_cv_bsdgetpgrp" 1>&6 - if test "$rb_cv_bsdgetpgrp" = yes; then - cat >> confdefs.h <<\EOF -#define BSD_GETPGRP getpgrp + +fi + +echo "$ac_t""$ac_cv_func_setpgrp_void" 1>&6 +if test $ac_cv_func_setpgrp_void = yes; then + cat >> confdefs.h <<\EOF +#define SETPGRP_VOID 1 EOF - fi +fi + - echo $ac_n "checking whether setpgrp() has args""... $ac_c" 1>&6 -echo "configure:3128: checking whether setpgrp() has args" >&5 - if eval "test \"`echo '$''{'rb_cv_bsdsetpgrp'+set}'`\" = set"; then +echo $ac_n "checking for working strtod""... $ac_c" 1>&6 +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 + if test "$cross_compiling" = yes; then + rb_cv_func_strtod=no else cat > conftest.$ac_ext < -int main() { -setpgrp(1, 1); -; return 0; } + +double strtod (); +int +main() +{ + { + /* Some versions of Linux strtod mis-parse strings with leading '+'. */ + char *string = " +69"; + char *term; + double value; + value = strtod(string, &term); + if (value != 69 || term != (string + 4)) + exit(1); + } + + { + /* Under Solaris 2.4, strtod returns the wrong value for the + terminating character under some conditions. */ + char *string = "NaN"; + char *term; + strtod(string, &term); + if (term != string && *(term - 1) == 0) + exit(1); + } + exit(0); +} + EOF -if { (eval echo configure:3140: \"$ac_compile\") 1>&5; (eval $ac_compile) 2>&5; }; then - rm -rf conftest* - rb_cv_bsdsetpgrp=yes +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 echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 - rm -rf conftest* - rb_cv_bsdsetpgrp=no + rm -fr conftest* + rb_cv_func_strtod=no fi -rm -f conftest* +rm -fr conftest* fi - echo "$ac_t""$rb_cv_bsdsetpgrp" 1>&6 - if test "$rb_cv_bsdsetpgrp" = yes; then - cat >> confdefs.h <<\EOF -#define BSD_SETPGRP setpgrp -EOF - - fi fi +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:3162: 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 < #include @@ -3176,11 +3479,11 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3180: \"$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 < #include @@ -3191,7 +3494,7 @@ int main() { #endif ; return 0; } EOF -if { (eval echo configure:3195: \"$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 @@ -3211,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 <&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 @@ -3248,14 +3551,14 @@ EOF fi echo $ac_n "checking whether char is unsigned""... $ac_c" 1>&6 -echo "configure:3252: 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 <&2; exit 1; } else cat > conftest.$ac_ext <&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 @@ -3312,15 +3615,15 @@ fi echo $ac_n "checking whether right shift preserve sign bit""... $ac_c" 1>&6 -echo "configure:3316: 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 if test "$cross_compiling" = yes; then - { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + rb_cv_rshift_sign=yes else cat > conftest.$ac_ext <&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 @@ -3346,7 +3649,7 @@ fi fi - echo "$ac_t""$rb_cv_rshift_sign" 1>&6 +echo "$ac_t""$rb_cv_rshift_sign" 1>&6 if test "$rb_cv_rshift_sign" = yes; then cat >> confdefs.h <<\EOF #define RSHIFT(x,y) ((x)>>y) @@ -3360,19 +3663,19 @@ EOF fi echo $ac_n "checking count field in FILE structures""... $ac_c" 1>&6 -echo "configure:3364: 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 < int main() { FILE *f = stdin; f->_cnt = 0; ; return 0; } EOF -if { (eval echo configure:3376: \"$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 @@ -3382,14 +3685,14 @@ fi rm -f conftest* if test "$rb_cv_fcnt" = ""; then cat > conftest.$ac_ext < int main() { FILE *f = stdin; f->__cnt = 0; ; return 0; } EOF -if { (eval echo configure:3393: \"$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 @@ -3400,14 +3703,14 @@ rm -f conftest* fi if test "$rb_cv_fcnt" = ""; then cat > conftest.$ac_ext < int main() { FILE *f = stdin; f->_r = 0; ; return 0; } EOF -if { (eval echo configure:3411: \"$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 @@ -3418,14 +3721,14 @@ rm -f conftest* fi if test "$rb_cv_fcnt" = ""; then cat > conftest.$ac_ext < int main() { FILE *f = stdin; f->readCount = 0; ; return 0; } EOF -if { (eval echo configure:3429: \"$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 @@ -3464,15 +3767,15 @@ fi case "$host_os" in linux*) echo $ac_n "checking whether ELF binaries are produced""... $ac_c" 1>&6 -echo "configure:3468: checking whether ELF binaries are produced" >&5 - if eval "test \"`echo '$''{'rb_cv_linux_elf'+set}'`\" = set"; then +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 if test "$cross_compiling" = yes; then - : + rb_cv_binary_elf=yes else cat > conftest.$ac_ext <&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_linux_elf=yes + rb_cv_binary_elf=yes else echo "configure: failed program was:" >&5 cat conftest.$ac_ext >&5 rm -fr conftest* - rb_cv_linux_elf=no + rb_cv_binary_elf=no fi rm -fr conftest* fi fi - echo "$ac_t""$rb_cv_linux_elf" 1>&6 - if test "$rb_cv_linux_elf" = no; then +echo "$ac_t""$rb_cv_binary_elf" 1>&6 + if test "$rb_cv_binary_elf" = no; then with_dln_a_out=yes - host_os=linux-a.out + host_os=${host_os}-a_out else LDFLAGS="-rdynamic" fi;; @@ -3522,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:3526: 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*) ;; @@ -3530,14 +3833,14 @@ echo "configure:3526: checking whether OS depend dynamic link works" >&5 rhapsody*) ;; human*) ;; cygwin*) CCDLFLAGS=-DDLLIMPORT;; - *) CCDLFLAGS=-fpic;; + *) CCDLFLAGS=-fPIC;; esac else case "$host_os" in hpux*) CCDLFLAGS='+z';; - solaris*|irix*) CCDLFLAGS='-K pic' ;; - sunos*) CCDLFLAGS='-pic' ;; - esix*|uxpds*) CCDLFLAGS='-Kpic' ;; + solaris*|irix*) CCDLFLAGS='-K PIC' ;; + sunos*) CCDLFLAGS='-PIC' ;; + esix*|uxpds*) CCDLFLAGS='-KPIC' ;; *) CCDLFLAGS='' ;; esac fi @@ -3548,6 +3851,7 @@ echo "configure:3526: checking whether OS depend dynamic link works" >&5 LDFLAGS="-Wl,-E" rb_cv_dlopen=yes;; solaris*) LDSHARED='ld -G' + test "$GCC" = yes && `$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null && LDFLAGS="-Wl,-E" rb_cv_dlopen=yes;; sunos*) LDSHARED='ld -assert nodefinitions' rb_cv_dlopen=yes;; @@ -3559,15 +3863,25 @@ echo "configure:3526: checking whether OS depend dynamic link works" >&5 rb_cv_dlopen=yes ;; linux*) LDSHARED="gcc -shared" rb_cv_dlopen=yes ;; - freebsd3*) LDSHARED="ld -Bshareable" - LDFLAGS="-rdynamic" - rb_cv_dlopen=yes ;; - freebsd*) LDSHARED="ld -Bshareable" + freebsd*) LDSHARED="gcc -shared" + if test -x /usr/bin/objformat && \ + test `/usr/bin/objformat` = "elf" ; 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" + case "$host_cpu" in + alpha|mips) + LDFLAGS="-export-dynamic" ;; + *) + ;; + esac rb_cv_dlopen=yes ;; openbsd*) LDSHARED="ld -Bforcearchive -Bshareable" - CCDLFLAGS=-fPIC rb_cv_dlopen=yes ;; nextstep*) LDSHARED='cc -r' LDFLAGS="-u libsys_s" @@ -3586,11 +3900,15 @@ echo "configure:3526: 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" ;; @@ -3605,14 +3923,14 @@ fi dln_a_out_works=no if test "$ac_cv_header_a_out_h" = yes; then if test "$with_dln_a_out" = yes || test "$rb_cv_dlopen" = unknown; then - echo $ac_n "checking whether matz's dln works""... $ac_c" 1>&6 -echo "configure:3610: checking whether matz's dln works" >&5 cat confdefs.h > config.h - if eval "test \"`echo '$''{'rb_cv_dln_a_out'+set}'`\" = set"; then + echo $ac_n "checking whether matz's dln works""... $ac_c" 1>&6 +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 <&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 @@ -3634,7 +3952,7 @@ fi rm -f conftest* fi - echo "$ac_t""$rb_cv_dln_a_out" 1>&6 +echo "$ac_t""$rb_cv_dln_a_out" 1>&6 if test "$rb_cv_dln_a_out" = yes; then dln_a_out_works=yes cat >> confdefs.h <<\EOF @@ -3724,7 +4042,7 @@ fi case "$host_os" in human*) echo $ac_n "checking for _harderr in -lsignal""... $ac_c" 1>&6 -echo "configure:3728: 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 @@ -3732,7 +4050,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lsignal $LIBS" cat > conftest.$ac_ext <&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 @@ -3771,7 +4089,7 @@ else fi echo $ac_n "checking for hmemset in -lhmem""... $ac_c" 1>&6 -echo "configure:3775: 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 @@ -3779,7 +4097,7 @@ else ac_save_LIBS="$LIBS" LIBS="-lhmem $LIBS" cat > conftest.$ac_ext <&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 @@ -3820,12 +4138,12 @@ fi for ac_func in select do echo $ac_n "checking for $ac_func""... $ac_c" 1>&6 -echo "configure:3824: 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 <&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 @@ -3873,15 +4191,15 @@ fi done echo $ac_n "checking whether PD libc _dtos18 fail to convert big number""... $ac_c" 1>&6 -echo "configure:3877: checking whether PD libc _dtos18 fail to convert big number" >&5 - if eval "test \"`echo '$''{'rb_cv_missing__dtos18'+set}'`\" = set"; then +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 if test "$cross_compiling" = yes; then - { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + rb_cv_missing__dtos18=no else cat > conftest.$ac_ext < @@ -3893,7 +4211,7 @@ main () } EOF -if { (eval echo configure:3897: \"$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 @@ -3907,7 +4225,7 @@ fi fi - echo "$ac_t""$rb_cv_missing__dtos18" 1>&6 +echo "$ac_t""$rb_cv_missing__dtos18" 1>&6 if test "$rb_cv_missing__dtos18" = yes; then cat >> confdefs.h <<\EOF #define MISSING__DTOS18 1 @@ -3915,15 +4233,15 @@ EOF fi echo $ac_n "checking whether PD libc fconvert fail to round""... $ac_c" 1>&6 -echo "configure:3919: checking whether PD libc fconvert fail to round" >&5 - if eval "test \"`echo '$''{'rb_cv_missing_fconvert'+set}'`\" = set"; then +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 if test "$cross_compiling" = yes; then - { echo "configure: error: can not run test program while cross compiling" 1>&2; exit 1; } + rb_cv_missing_fconvert=no else cat > conftest.$ac_ext < @@ -3936,7 +4254,7 @@ main () } EOF -if { (eval echo configure:3940: \"$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 @@ -3950,7 +4268,7 @@ fi fi - echo "$ac_t""$rb_cv_missing_fconvert" 1>&6 +echo "$ac_t""$rb_cv_missing_fconvert" 1>&6 if test "$rb_cv_missing_fconvert" = yes; then cat >> confdefs.h <<\EOF #define MISSING_FCONVERT 1 @@ -3985,18 +4303,22 @@ if test "$fat_binary" = yes ; then CFLAGS="$CFLAGS $ARCH_FLAG" fi -LIBRUBY='libruby.a' -LIBRUBYARG='libruby.a' +LIBRUBY_A='lib$(RUBY_INSTALL_NAME).a' +LIBRUBY='$(LIBRUBY_A)' +LIBRUBYARG='$(LIBRUBY_A)' SOLIBS= if test "$host_os" = "beos"; then - CFLAGS="$CFLAGS -relax_pointers" - LIBRUBY='libruby.so' - LIBRUBYARG='-lruby' + LIBRUBY='$(LIBRUBY_SO)' + LIBRUBYARG='-l$(RUBY_INSTALL_NAME)' SOLIBS='-lnet' echo creating ruby.def case "$host_cpu" in powerpc*) cp beos/ruby.def.in ruby.exp + CFLAGS="$CFLAGS -relax_pointers" + ;; + i586*) + LDFLAGS="$LDFLAGS -L." ;; *) echo EXPORTS > ruby.def @@ -4005,9 +4327,30 @@ if test "$host_os" = "beos"; then esac fi +LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR).$(TEENY)' +LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so' if test "$enable_shared" = 'yes'; then - LIBRUBY='libruby.so' - LIBRUBYARG='-L./ -lruby' + LIBRUBY='$(LIBRUBY_SO)' + LIBRUBYARG='-L./ -l$(RUBY_INSTALL_NAME)' + CFLAGS="$CFLAGS $CCDLFLAGS" + case "$host_os" in + sunos4*|linux*) + LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so' + ;; + freebsd*) + LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR)$(MINOR)' + if test "$rb_cv_freebsd_elf" != "yes" ; then + LIBRUBY_SO="$LIBRUBY_SO.\$(TEENY)" + LIBRUBY_ALIASES='' + fi + ;; + hpux*) + LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR).$(TEENY)' + LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).sl' + ;; + *) + ;; + esac fi case "$host_os" in @@ -4029,6 +4372,9 @@ esac + + + ri_prefix= test "$program_prefix" != NONE && ri_prefix=$program_prefix @@ -4038,12 +4384,14 @@ test "$program_suffix" != NONE && ri_suffix=$program_suffix RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}" +#RUBY_LIB_PATH="${prefix}/lib/${RUBY_INSTALL_NAME}/${MAJOR}.${MINOR}" +RUBY_LIB_PATH="${prefix}/lib/ruby/${MAJOR}.${MINOR}" cat >> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h <> confdefs.h < config.h @@ -4193,7 +4528,7 @@ do echo "running \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion" exec \${CONFIG_SHELL-/bin/sh} $0 $ac_configure_args --no-create --no-recursion ;; -version | --version | --versio | --versi | --vers | --ver | --ve | --v) - echo "$CONFIG_STATUS generated by autoconf version 2.12.2" + echo "$CONFIG_STATUS generated by autoconf version 2.13" exit 0 ;; -help | --help | --hel | --he | --h) echo "\$ac_cs_usage"; exit 0 ;; @@ -4236,6 +4571,9 @@ s%@includedir@%$includedir%g s%@oldincludedir@%$oldincludedir%g s%@infodir@%$infodir%g s%@mandir@%$mandir%g +s%@MAJOR@%$MAJOR%g +s%@MINOR@%$MINOR%g +s%@TEENY@%$TEENY%g s%@host@%$host%g s%@host_alias@%$host_alias%g s%@host_cpu@%$host_cpu%g @@ -4249,6 +4587,7 @@ s%@AR@%$AR%g s%@INSTALL_PROGRAM@%$INSTALL_PROGRAM%g s%@INSTALL_SCRIPT@%$INSTALL_SCRIPT%g s%@INSTALL_DATA@%$INSTALL_DATA%g +s%@LN_S@%$LN_S%g s%@SET_MAKE@%$SET_MAKE%g s%@LIBOBJS@%$LIBOBJS%g s%@ALLOCA@%$ALLOCA%g @@ -4261,6 +4600,10 @@ s%@STRIP@%$STRIP%g s%@EXTSTATIC@%$EXTSTATIC%g s%@binsuffix@%$binsuffix%g s%@setup@%$setup%g +s%@RUBY_INSTALL_NAME@%$RUBY_INSTALL_NAME%g +s%@LIBRUBY_A@%$LIBRUBY_A%g +s%@LIBRUBY_SO@%$LIBRUBY_SO%g +s%@LIBRUBY_ALIASES@%$LIBRUBY_ALIASES%g s%@LIBRUBY@%$LIBRUBY%g s%@LIBRUBYARG@%$LIBRUBYARG%g s%@SOLIBS@%$SOLIBS%g diff --git a/configure.in b/configure.in index 0477ade03e..0b107e093c 100644 --- a/configure.in +++ b/configure.in @@ -1,6 +1,13 @@ dnl Process this file with autoconf to produce a configure script. AC_INIT(ruby.h) +rb_version=`grep RUBY_VERSION $srcdir/version.h` +MAJOR=`expr "$rb_version" : '#define RUBY_VERSION "\([0-9][0-9]*\)\.[0-9][0-9]*\.[0-9][0-9]*"'` +MINOR=`expr "$rb_version" : '#define RUBY_VERSION "[0-9][0-9]*\.\([0-9][0-9]*\)\.[0-9][0-9]*"'` +TEENY=`expr "$rb_version" : '#define RUBY_VERSION "[0-9][0-9]*\.[0-9][0-9]*\.\([0-9][0-9]*\)"'` +AC_SUBST(MAJOR) +AC_SUBST(MINOR) +AC_SUBST(TEENY) dnl checks for alternative programs AC_ARG_WITH(gcc, [--without-gcc never use gcc], [ case $withval in @@ -31,12 +38,12 @@ AC_CANONICAL_HOST dnl checks for fat-binary fat_binary=no -AC_ARG_ENABLE( fat-binary, +AC_ARG_ENABLE(fat-binary, [--enable-fat-binary build a NeXT/Apple Multi Architecture Binary. ], - [ fat_binary=$enableval ] ) + [fat_binary=$enableval]) if test "$fat_binary" = yes ; then - AC_MSG_CHECKING( target architecture ) + AC_MSG_CHECKING(target architecture) case "$host_os" in rhapsody*) @@ -85,27 +92,39 @@ AC_PROG_RANLIB AC_SUBST(AR) AC_CHECK_PROGS(AR, ar aal, ar) AC_PROG_INSTALL +AC_PROG_LN_S AC_PROG_MAKE_SET # checks for UNIX variants that set C preprocessor variables AC_MINIX AC_CHECK_SIZEOF(int) +AC_CHECK_SIZEOF(short) AC_CHECK_SIZEOF(long) AC_CHECK_SIZEOF(void*) +AC_CHECK_SIZEOF(float) +AC_CHECK_SIZEOF(double) -AC_MSG_CHECKING(for prototypes) -AC_CACHE_VAL(rb_cv_have_prototypes, +AC_CACHE_CHECK(for prototypes, rb_cv_have_prototypes, [AC_TRY_COMPILE([int foo(int x) { return 0; }], [return foo(10);], rb_cv_have_prototypes=yes, rb_cv_have_prototypes=no)]) -AC_MSG_RESULT($rb_cv_have_prototypes) if test "$rb_cv_have_prototypes" = yes; then AC_DEFINE(HAVE_PROTOTYPES) fi -AC_MSG_CHECKING(for variable length prototypes and stdarg.h) -AC_CACHE_VAL(rb_cv_stdarg, +AC_CACHE_CHECK(token paste string, rb_cv_tokenpaste, + [AC_TRY_COMPILE([#define paste(a,b) a##b], + [int xy = 1; return paste(x,y);], + rb_cv_tokenpaste=ansi, + rb_cv_tokenpaste=knr)]) +if test "$rb_cv_tokenpaste" = ansi; then + AC_DEFINE(TOKEN_PASTE(x,y),[x##y]) +else + AC_DEFINE(TOKEN_PASTE(x,y),[x/**/y]) +fi + +AC_CACHE_CHECK(for variable length prototypes and stdarg.h, rb_cv_stdarg, [AC_TRY_COMPILE([ #include int foo(int x, ...) { @@ -119,17 +138,14 @@ int foo(int x, ...) { ], [return foo(10, "", 3.14);], rb_cv_stdarg=yes, rb_cv_stdarg=no)]) -AC_MSG_RESULT($rb_cv_stdarg) if test "$rb_cv_stdarg" = yes; then AC_DEFINE(HAVE_STDARG_PROTOTYPES) fi -AC_MSG_CHECKING(for gcc attribute noreturn) -AC_CACHE_VAL(rb_cv_have_attr_noreturn, +AC_CACHE_CHECK(for gcc attribute noreturn, rb_cv_have_attr_noreturn, [AC_TRY_COMPILE([void exit(int x) __attribute__ ((noreturn));], [], rb_cv_have_attr_noreturn=yes, rb_cv_have_attr_noreturn=no)]) -AC_MSG_RESULT($rb_cv_have_attr_noreturn) if test "$rb_cv_have_attr_noreturn" = yes; then AC_DEFINE(HAVE_ATTR_NORETURN) fi @@ -153,7 +169,7 @@ AC_HEADER_DIRENT AC_HEADER_STDC AC_CHECK_HEADERS(stdlib.h unistd.h limits.h sys/file.h sys/ioctl.h pwd.h \ sys/select.h sys/time.h sys/times.h sys/param.h sys/wait.h\ - syscall.h a.out.h string.h utime.h memory.h direct.h) + syscall.h a.out.h string.h utime.h memory.h direct.h fnmatch.h) dnl Checks for typedefs, structures, and compiler characteristics. AC_TYPE_UID_T @@ -171,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([], @@ -186,8 +203,7 @@ fi if test "$ac_cv_func_sigprocmask" = yes && test "$ac_cv_func_sigaction" = yes; then AC_DEFINE(POSIX_SIGNAL) else - AC_MSG_CHECKING(for BSD signal semantics) - AC_CACHE_VAL(rb_cv_bsd_signal, + AC_CACHE_CHECK(for BSD signal semantics, rb_cv_bsd_signal, [AC_TRY_RUN([ #include #include @@ -208,43 +224,50 @@ main() } ], rb_cv_bsd_signal=yes, + rb_cv_bsd_signal=no, rb_cv_bsd_signal=no)]) - AC_MSG_RESULT($rb_cv_bsd_signal) if test "$rb_cv_bsd_signal" = yes; then AC_DEFINE(BSD_SIGNAL) fi fi -if test "$ac_cv_func_setpgrp2" = yes; then - AC_DEFINE(BSD_GETPGRP, getpgrp2) - AC_DEFINE(BSD_SETPGRP, setpgrp2) -else - AC_MSG_CHECKING(whether getpgrp() has arg) - AC_CACHE_VAL(rb_cv_bsdgetpgrp, - [AC_TRY_COMPILE([#include ], [getpgrp(0);], - rb_cv_bsdgetpgrp=yes, - rb_cv_bsdgetpgrp=no)]) - AC_MSG_RESULT($rb_cv_bsdgetpgrp) - if test "$rb_cv_bsdgetpgrp" = yes; then - AC_DEFINE(BSD_GETPGRP, getpgrp) - fi +AC_FUNC_GETPGRP +AC_FUNC_SETPGRP - AC_MSG_CHECKING(whether setpgrp() has args) - AC_CACHE_VAL(rb_cv_bsdsetpgrp, - [AC_TRY_COMPILE([#include ], [setpgrp(1, 1);], - rb_cv_bsdsetpgrp=yes, - rb_cv_bsdsetpgrp=no)]) - AC_MSG_RESULT($rb_cv_bsdsetpgrp) - if test "$rb_cv_bsdsetpgrp" = yes; then - AC_DEFINE(BSD_SETPGRP, setpgrp) - fi -fi +AC_CACHE_CHECK(for working strtod, rb_cv_func_strtod, +[AC_TRY_RUN([ +double strtod (); +int +main() +{ + { + /* Some versions of Linux strtod mis-parse strings with leading '+'. */ + char *string = " +69"; + char *term; + double value; + value = strtod(string, &term); + if (value != 69 || term != (string + 4)) + exit(1); + } + + { + /* Under Solaris 2.4, strtod returns the wrong value for the + terminating character under some conditions. */ + char *string = "NaN"; + char *term; + strtod(string, &term); + if (term != string && *(term - 1) == 0) + exit(1); + } + exit(0); +} +], rb_cv_func_strtod=yes, rb_cv_func_strtod=no, rb_cv_func_strtod=no)]) +test $rb_cv_func_strtod = no && LIBOBJS="$LIBOBJS strtod.o" AC_C_BIGENDIAN AC_CHAR_UNSIGNED -AC_MSG_CHECKING(whether right shift preserve sign bit) -AC_CACHE_VAL(rb_cv_rshift_sign, +AC_CACHE_CHECK(whether right shift preserve sign bit, rb_cv_rshift_sign, [AC_TRY_RUN([ int main() @@ -255,15 +278,15 @@ main() } ], rb_cv_rshift_sign=yes, - rb_cv_rshift_sign=no)]) - AC_MSG_RESULT($rb_cv_rshift_sign) + rb_cv_rshift_sign=no, + rb_cv_rshift_sign=yes)]) if test "$rb_cv_rshift_sign" = yes; then AC_DEFINE(RSHIFT(x,y), ((x)>>y)) else AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>y) : (x)>>y)) fi -AC_MSG_CHECKING([count field in FILE structures]) +AC_MSG_CHECKING(count field in FILE structures) AC_CACHE_VAL(rb_cv_fcnt, [AC_TRY_COMPILE([#include ], [FILE *f = stdin; f->_cnt = 0;], rb_cv_fcnt="_cnt", ) @@ -296,8 +319,7 @@ AC_ARG_WITH(dln-a-out, [--with-dln-a-out use dln_a_out if possible], [ case "$host_os" in linux*) - AC_MSG_CHECKING(whether ELF binaries are produced) - AC_CACHE_VAL(rb_cv_linux_elf, + AC_CACHE_CHECK(whether ELF binaries are produced, rb_cv_binary_elf, [AC_TRY_RUN([ /* Test for whether ELF binaries are produced */ #include @@ -315,13 +337,12 @@ main() { exit(0); /* succeed (yes, it's ELF) */ } ], - rb_cv_linux_elf=yes, - rb_cv_linux_elf=no, - [:])]) - AC_MSG_RESULT($rb_cv_linux_elf) - if test "$rb_cv_linux_elf" = no; then + rb_cv_binary_elf=yes, + rb_cv_binary_elf=no, + rb_cv_binary_elf=yes)]) + if test "$rb_cv_binary_elf" = no; then with_dln_a_out=yes - host_os=linux-a.out + host_os=${host_os}-a_out else LDFLAGS="-rdynamic" fi;; @@ -346,14 +367,14 @@ if test "$with_dln_a_out" != yes; then rhapsody*) ;; human*) ;; cygwin*) CCDLFLAGS=-DDLLIMPORT;; - *) CCDLFLAGS=-fpic;; + *) CCDLFLAGS=-fPIC;; esac else case "$host_os" in hpux*) CCDLFLAGS='+z';; - solaris*|irix*) CCDLFLAGS='-K pic' ;; - sunos*) CCDLFLAGS='-pic' ;; - esix*|uxpds*) CCDLFLAGS='-Kpic' ;; + solaris*|irix*) CCDLFLAGS='-K PIC' ;; + sunos*) CCDLFLAGS='-PIC' ;; + esix*|uxpds*) CCDLFLAGS='-KPIC' ;; *) CCDLFLAGS='' ;; esac fi @@ -364,6 +385,7 @@ if test "$with_dln_a_out" != yes; then LDFLAGS="-Wl,-E" rb_cv_dlopen=yes;; solaris*) LDSHARED='ld -G' + test "$GCC" = yes && `$CC --print-prog-name=ld` -v 2>&1 | grep "GNU ld" > /dev/null && LDFLAGS="-Wl,-E" rb_cv_dlopen=yes;; sunos*) LDSHARED='ld -assert nodefinitions' rb_cv_dlopen=yes;; @@ -375,15 +397,25 @@ if test "$with_dln_a_out" != yes; then rb_cv_dlopen=yes ;; linux*) LDSHARED="gcc -shared" rb_cv_dlopen=yes ;; - freebsd3*) LDSHARED="ld -Bshareable" - LDFLAGS="-rdynamic" - rb_cv_dlopen=yes ;; - freebsd*) LDSHARED="ld -Bshareable" + freebsd*) LDSHARED="gcc -shared" + if test -x /usr/bin/objformat && \ + test `/usr/bin/objformat` = "elf" ; 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" + case "$host_cpu" in + alpha|mips) + LDFLAGS="-export-dynamic" ;; + *) + ;; + esac rb_cv_dlopen=yes ;; openbsd*) LDSHARED="ld -Bforcearchive -Bshareable" - CCDLFLAGS=-fPIC rb_cv_dlopen=yes ;; nextstep*) LDSHARED='cc -r' LDFLAGS="-u libsys_s" @@ -402,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" ;; @@ -421,9 +457,8 @@ fi dln_a_out_works=no if test "$ac_cv_header_a_out_h" = yes; then if test "$with_dln_a_out" = yes || test "$rb_cv_dlopen" = unknown; then - AC_MSG_CHECKING(whether matz's dln works) cat confdefs.h > config.h - AC_CACHE_VAL(rb_cv_dln_a_out, + AC_CACHE_CHECK(whether matz's dln works, rb_cv_dln_a_out, [AC_TRY_COMPILE([ #define USE_DLN_A_OUT #include "dln.c" @@ -431,7 +466,6 @@ if test "$ac_cv_header_a_out_h" = yes; then [], rb_cv_dln_a_out=yes, rb_cv_dln_a_out=no)]) - AC_MSG_RESULT($rb_cv_dln_a_out) if test "$rb_cv_dln_a_out" = yes; then dln_a_out_works=yes AC_DEFINE(USE_DLN_A_OUT) @@ -498,8 +532,8 @@ case "$host_os" in AC_CHECK_LIB(signal, _harderr) AC_CHECK_LIB(hmem, hmemset) AC_CHECK_FUNCS(select) - AC_MSG_CHECKING(whether PD libc _dtos18 fail to convert big number) - AC_CACHE_VAL(rb_cv_missing__dtos18, + AC_CACHE_CHECK(whether PD libc _dtos18 fail to convert big number, + rb_cv_missing__dtos18, [AC_TRY_RUN( changequote(<<, >>)dnl << @@ -512,13 +546,12 @@ main () } >>, changequote([, ])dnl -rb_cv_missing__dtos18=yes, rb_cv_missing__dtos18=no)]) - AC_MSG_RESULT($rb_cv_missing__dtos18) +rb_cv_missing__dtos18=yes, rb_cv_missing__dtos18=no, rb_cv_missing__dtos18=no)]) if test "$rb_cv_missing__dtos18" = yes; then AC_DEFINE(MISSING__DTOS18) fi - AC_MSG_CHECKING(whether PD libc fconvert fail to round) - AC_CACHE_VAL(rb_cv_missing_fconvert, + AC_CACHE_CHECK(whether PD libc fconvert fail to round, + rb_cv_missing_fconvert, [AC_TRY_RUN( changequote(<<, >>)dnl << @@ -532,8 +565,7 @@ main () } >>, changequote([, ])dnl -rb_cv_missing_fconvert=yes, rb_cv_missing_fconvert=no)]) - AC_MSG_RESULT($rb_cv_missing_fconvert) +rb_cv_missing_fconvert=yes, rb_cv_missing_fconvert=no, rb_cv_missing_fconvert=no)]) if test "$rb_cv_missing_fconvert" = yes; then AC_DEFINE(MISSING_FCONVERT) fi @@ -565,18 +597,22 @@ if test "$fat_binary" = yes ; then CFLAGS="$CFLAGS $ARCH_FLAG" fi -LIBRUBY='libruby.a' -LIBRUBYARG='libruby.a' +LIBRUBY_A='lib$(RUBY_INSTALL_NAME).a' +LIBRUBY='$(LIBRUBY_A)' +LIBRUBYARG='$(LIBRUBY_A)' SOLIBS= if test "$host_os" = "beos"; then - CFLAGS="$CFLAGS -relax_pointers" - LIBRUBY='libruby.so' - LIBRUBYARG='-lruby' + LIBRUBY='$(LIBRUBY_SO)' + LIBRUBYARG='-l$(RUBY_INSTALL_NAME)' SOLIBS='-lnet' echo creating ruby.def case "$host_cpu" in powerpc*) cp beos/ruby.def.in ruby.exp + CFLAGS="$CFLAGS -relax_pointers" + ;; + i586*) + LDFLAGS="$LDFLAGS -L." ;; *) echo EXPORTS > ruby.def @@ -585,9 +621,30 @@ if test "$host_os" = "beos"; then esac fi +LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR).$(TEENY)' +LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so' if test "$enable_shared" = 'yes'; then - LIBRUBY='libruby.so' - LIBRUBYARG='-L./ -lruby' + LIBRUBY='$(LIBRUBY_SO)' + LIBRUBYARG='-L./ -l$(RUBY_INSTALL_NAME)' + CFLAGS="$CFLAGS $CCDLFLAGS" + case "$host_os" in + sunos4*|linux*) + LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).so.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).so' + ;; + freebsd*) + LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).so.$(MAJOR)$(MINOR)' + if test "$rb_cv_freebsd_elf" != "yes" ; then + LIBRUBY_SO="$LIBRUBY_SO.\$(TEENY)" + LIBRUBY_ALIASES='' + fi + ;; + hpux*) + LIBRUBY_SO='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR).$(TEENY)' + LIBRUBY_ALIASES='lib$(RUBY_INSTALL_NAME).sl.$(MAJOR).$(MINOR) lib$(RUBY_INSTALL_NAME).sl' + ;; + *) + ;; + esac fi case "$host_os" in @@ -604,7 +661,10 @@ case "$host_os" in ;; esac - +AC_SUBST(RUBY_INSTALL_NAME) +AC_SUBST(LIBRUBY_A) +AC_SUBST(LIBRUBY_SO) +AC_SUBST(LIBRUBY_ALIASES) AC_SUBST(LIBRUBY) AC_SUBST(LIBRUBYARG) AC_SUBST(SOLIBS) @@ -618,28 +678,26 @@ test "$program_suffix" != NONE && ri_suffix=$program_suffix RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}" -AC_DEFINE_UNQUOTED(RUBY_LIB, "${prefix}/lib/${RUBY_INSTALL_NAME}") -AC_DEFINE_UNQUOTED(RUBY_SITE_LIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby") +#RUBY_LIB_PATH="${prefix}/lib/${RUBY_INSTALL_NAME}/${MAJOR}.${MINOR}" +RUBY_LIB_PATH="${prefix}/lib/ruby/${MAJOR}.${MINOR}" +AC_DEFINE_UNQUOTED(RUBY_LIB, "${RUBY_LIB_PATH}") +AC_DEFINE_UNQUOTED(RUBY_SITE_LIB, "${RUBY_LIB_PATH}/site_ruby") AC_SUBST(arch)dnl if test "$fat_binary" = yes ; then arch="fat-${host_os}" AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB, - "${prefix}/lib/${RUBY_INSTALL_NAME}/" __ARCHITECTURE__ "-${host_os}" ) + "${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}" ) AC_DEFINE_UNQUOTED(RUBY_SITE_THIN_ARCHLIB, - "${prefix}/lib/${RUBY_INSTALL_NAME}/" __ARCHITECTURE__ "-${host_os}" ) - - AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/${arch}") - AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby/${arch}") - AC_DEFINE_UNQUOTED(RUBY_PLATFORM, __ARCHITECTURE__ "-${host_os}" ) + "${RUBY_LIB_PATH}/" __ARCHITECTURE__ "-${host_os}" ) else arch="${host_cpu}-${host_os}" - AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/${arch}") - AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby/${arch}") - AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "${arch}") fi +AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${RUBY_LIB_PATH}/${arch}") +AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${RUBY_LIB_PATH}/site_ruby/${arch}") +AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "${arch}") echo "creating config.h" cat confdefs.h > config.h diff --git a/defines.h b/defines.h index fb10d628b4..d9b744b71f 100644 --- a/defines.h +++ b/defines.h @@ -31,7 +31,7 @@ #endif /* NeXT */ #ifdef NT -#include "missing/nt.h" +#include "win32/win32.h" #endif #ifndef EXTERN @@ -44,7 +44,7 @@ #define FLUSH_REGISTER_WINDOWS /* empty */ #endif -#if defined(MSDOS) || defined(NT) || defined(__human68k__) || defined(__MACOS__) +#if defined(MSDOS) || defined(NT) || defined(__human68k__) #define RUBY_PATH_SEP ";" #else #define RUBY_PATH_SEP ":" diff --git a/dir.c b/dir.c index 51d7f9e344..c77294cd3b 100644 --- a/dir.c +++ b/dir.c @@ -6,7 +6,7 @@ $Date$ created at: Wed Jan 5 09:51:01 JST 1994 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ diff --git a/dln.c b/dln.c index 858291d5b7..d8f6ec6995 100644 --- a/dln.c +++ b/dln.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Jan 18 17:05:06 JST 1994 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -64,6 +64,7 @@ char *getenv(); # include # include # include +# include "macruby_private.h" #endif #ifdef __BEOS__ @@ -78,7 +79,7 @@ int eaccess(); #endif #ifndef FUNCNAME_PATTERN -# if defined(__hp9000s300) || defined(__NetBSD__) || defined(__BORLANDC__) || (defined(__FreeBSD__) && __FreeBSD__ < 3) || defined(NeXT) || defined(__WATCOMC__) +# if defined(__hp9000s300) || (defined(__NetBSD__) && (!defined(__alpha__) && !defined(__mips__))) || defined(__BORLANDC__) || (defined(__FreeBSD__) && __FreeBSD__ < 3) || defined(NeXT) || defined(__WATCOMC__) # define FUNCNAME_PATTERN "_Init_%.200s" # else # define FUNCNAME_PATTERN "Init_%.200s" @@ -1406,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)) { @@ -1522,8 +1523,13 @@ dln_find_file(fname, path) char *fname; char *path; { +#ifndef __MACOS__ if (!path) path = "."; return dln_find_1(fname, path, 0); +#else + if (!path) path = "."; + return _macruby_path_conv_posix_to_macos(dln_find_1(fname, path, 0)); +#endif } #if defined(__CYGWIN32__) @@ -1561,14 +1567,17 @@ dln_find_1(fname, path, exe_flag) register char *dp; register char *ep; register char *bp; +#ifndef __MACOS__ struct stat st; +#else + const char* mac_fullpath; +#endif #if defined(__CYGWIN32__) char rubypath[MAXPATHLEN]; conv_to_posix_path(path, rubypath); path = rubypath; #endif -#ifndef __MACOS__ if (fname[0] == '/') return fname; if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0) return fname; @@ -1580,7 +1589,6 @@ dln_find_1(fname, path, exe_flag) return fname; if (exe_flag && strchr(fname, '\\')) return fname; #endif -#endif /* __MACOS__ */ for (dp = path;; dp = ++ep) { register int l; @@ -1632,11 +1640,7 @@ dln_find_1(fname, path, exe_flag) /* add a "/" between directory and filename */ if (ep[-1] != '/') -#ifdef __MACOS__ - *bp++ = ':'; -#else *bp++ = '/'; -#endif } /* now append the file name */ @@ -1651,11 +1655,19 @@ dln_find_1(fname, path, exe_flag) } memcpy(bp, fname, i + 1); +#ifndef __MACOS__ if (stat(fbuf, &st) == 0) { if (exe_flag == 0) return fbuf; /* looking for executable */ if (eaccess(fbuf, X_OK) == 0) return fbuf; } +#else + if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) { + if (exe_flag == 0) return mac_fullpath; + /* looking for executable */ + if (eaccess(mac_fullpath, X_OK) == 0) return mac_fullpath; + } +#endif #if defined(MSDOS) || defined(NT) || defined(__human68k__) if (exe_flag) { static const char *extension[] = { @@ -1679,8 +1691,13 @@ dln_find_1(fname, path, exe_flag) continue; } strcpy(bp + i, extension[j]); +#ifndef __MACOS__ if (stat(fbuf, &st) == 0) return fbuf; +#else + if (mac_fullpath = _macruby_exist_file_in_libdir_as_posix_name(fbuf)) + return mac_fullpath; +#endif } } #endif /* MSDOS or NT or __human68k__ */ diff --git a/enum.c b/enum.c index 2b4b904018..dc7e2112a4 100644 --- a/enum.c +++ b/enum.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 1 15:15:19 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -56,6 +56,7 @@ enum_grep(obj, pat) arg[0] = pat; arg[1] = tmp = rb_ary_new(); rb_iterate(rb_each, obj, grep_i, (VALUE)arg); + if (RARRAY(tmp)->len == 0) return Qnil; return tmp; } } @@ -121,6 +122,28 @@ enum_find_all(obj) return tmp; } +static VALUE +reject_i(i, tmp) + VALUE i, tmp; +{ + if (!RTEST(rb_yield(i))) { + rb_ary_push(tmp, i); + } + return Qnil; +} + +static VALUE +enum_reject(obj) + VALUE obj; +{ + VALUE tmp; + + tmp = rb_ary_new(); + rb_iterate(rb_each, obj, reject_i, tmp); + + return tmp; +} + static VALUE collect_i(i, tmp) VALUE i, tmp; @@ -373,7 +396,10 @@ Init_Enumerable() rb_define_method(rb_mEnumerable,"sort", enum_sort, 0); rb_define_method(rb_mEnumerable,"grep", enum_grep, 1); rb_define_method(rb_mEnumerable,"find", enum_find, -1); + rb_define_method(rb_mEnumerable,"detect", enum_find, -1); rb_define_method(rb_mEnumerable,"find_all", enum_find_all, 0); + rb_define_method(rb_mEnumerable,"select", enum_find_all, 0); + rb_define_method(rb_mEnumerable,"reject", enum_reject, 0); rb_define_method(rb_mEnumerable,"collect", enum_collect, 0); rb_define_method(rb_mEnumerable,"min", enum_min, 0); rb_define_method(rb_mEnumerable,"max", enum_max, 0); diff --git a/env.h b/env.h index 79fdfc2bef..bdaac91950 100644 --- a/env.h +++ b/env.h @@ -37,7 +37,7 @@ extern struct SCOPE { #define SCOPE_MALLOC 1 #define SCOPE_NOSTACK 2 -extern int rb_in_eval; +extern int ruby_in_eval; extern VALUE ruby_class; diff --git a/error.c b/error.c index 44ca067472..71a6ea622e 100644 --- a/error.c +++ b/error.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Aug 9 16:11:34 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -124,7 +124,7 @@ rb_warning(fmt, va_alist) char buf[BUFSIZ]; va_list args; - if (!RTEST(rb_verbose)) return; + if (!RTEST(ruby_verbose)) return; snprintf(buf, BUFSIZ, "warning: %s", fmt); @@ -146,7 +146,7 @@ rb_bug(fmt, va_alist) va_list args; snprintf(buf, BUFSIZ, "[BUG] %s", fmt); - rb_in_eval = 0; + ruby_in_eval = 0; va_init_list(args, fmt); err_print(buf, args); @@ -283,20 +283,21 @@ exc_initialize(argc, argv, exc) } static VALUE -exc_new(argc, argv, self) +exc_exception(argc, argv, self) int argc; VALUE *argv; VALUE 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)) { etype = RCLASS(etype)->super; } exc = rb_obj_alloc(etype); - rb_obj_call_init(exc); + rb_obj_call_init(exc, argc, argv); return exc; } @@ -337,7 +338,10 @@ static VALUE exc_backtrace(exc) VALUE exc; { - return rb_iv_get(exc, "bt"); + ID bt = rb_intern("bt"); + + if (!rb_ivar_defined(exc, bt)) return Qnil; + return rb_ivar_get(exc, bt); } static VALUE @@ -370,54 +374,15 @@ exc_set_backtrace(exc, bt) return rb_iv_set(exc, "bt", check_backtrace(bt)); } -static VALUE -exception(argc, argv) - int argc; - VALUE *argv; -{ - VALUE v = Qnil; - VALUE etype = rb_eStandardError; - int i; - ID id; - - if (argc == 0) { - rb_raise(rb_eArgError, "wrong # of arguments"); - } - rb_warn("Exception() is now obsolete"); - if (TYPE(argv[argc-1]) == T_CLASS) { - etype = argv[argc-1]; - argc--; - if (!rb_funcall(etype, '<', 1, rb_eException)) { - rb_raise(rb_eTypeError, "exception should be subclass of Exception"); - } - } - for (i=0; i #endif +#ifdef __MACOS__ +#include "macruby_private.h" +#endif + #ifndef setjmp #ifdef HAVE__SETJMP #define setjmp(env) _setjmp(env) @@ -203,9 +207,9 @@ rb_alias(klass, name, def) } body = orig->nd_body; if (nd_type(body) == NODE_FBODY) { /* was alias */ - body = body->nd_head; def = body->nd_mid; origin = body->nd_orig; + body = body->nd_head; } st_insert(RCLASS(klass)->m_tbl, name, @@ -367,7 +371,7 @@ rb_attr(klass, id, read, write, ex) } static ID init, eqq, each, aref, aset, match; -VALUE rb_errinfo = Qnil; +VALUE ruby_errinfo = Qnil; extern NODE *ruby_eval_tree_begin; extern NODE *ruby_eval_tree; extern int ruby_nerrs; @@ -629,22 +633,33 @@ static VALUE ruby_wrapper; /* security wrapper */ ruby_scope = _scope; \ scope_vmode = SCOPE_PUBLIC; +#ifdef USE_THREAD #define SCOPE_DONT_RECYCLE FL_USER2 - -static void scope_dup(struct SCOPE *); - #define POP_SCOPE() \ - if (ruby_scope->flag == SCOPE_ALLOCA) {\ - if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) {\ - scope_dup(ruby_scope);\ - FL_SET(_old, SCOPE_DONT_RECYCLE);\ - }\ - else {\ + if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) {\ + FL_SET(_old, SCOPE_DONT_RECYCLE);\ + }\ + else {\ + if (ruby_scope->flag == SCOPE_ALLOCA) {\ ruby_scope->local_vars = 0;\ ruby_scope->local_tbl = 0;\ if (ruby_scope != top_scope)\ rb_gc_force_recycle((VALUE)ruby_scope);\ }\ + else {\ + ruby_scope->flag |= SCOPE_NOSTACK;\ + }\ + }\ + ruby_scope = _old;\ + scope_vmode = _vmode;\ +} +#else /* not USE_THREAD */ +#define POP_SCOPE() \ + if (ruby_scope->flag == SCOPE_ALLOCA) {\ + ruby_scope->local_vars = 0;\ + ruby_scope->local_tbl = 0;\ + if (ruby_scope != top_scope)\ + rb_gc_force_recycle((VALUE)ruby_scope);\ }\ else {\ ruby_scope->flag |= SCOPE_NOSTACK;\ @@ -652,6 +667,7 @@ static void scope_dup(struct SCOPE *); ruby_scope = _old;\ scope_vmode = _vmode;\ } +#endif /* USE_THREAD */ static VALUE rb_eval _((VALUE,NODE*)); static VALUE eval _((VALUE,VALUE,VALUE,char*,int)); @@ -770,12 +786,19 @@ error_print() { VALUE errat; VALUE eclass; - VALUE einfo; - volatile int safe = safe_level; + char *einfo; + int elen; - if (NIL_P(rb_errinfo)) return; + if (NIL_P(ruby_errinfo)) return; - errat = get_backtrace(rb_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]; @@ -785,38 +808,46 @@ error_print() } } - eclass = CLASS_OF(rb_errinfo); - einfo = rb_obj_as_string(rb_errinfo); - if (eclass == rb_eRuntimeError && RSTRING(einfo)->len == 0) { + eclass = CLASS_OF(ruby_errinfo); + 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); } } @@ -842,7 +873,6 @@ error_print() } } } - safe_level = safe; } #if !defined(NT) && !defined(__MACOS__) @@ -879,13 +909,16 @@ 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; ruby_frame->self = ruby_top_self; ruby_frame->cbase = (VALUE)rb_node_newnode(NODE_CREF,rb_cObject,0,0); rb_define_global_const("TOPLEVEL_BINDING", rb_f_binding(ruby_top_self)); +#ifdef __MACOS__ + _macruby_init(); +#endif ruby_prog_init(); } POP_TAG(); @@ -943,7 +976,7 @@ eval_node(self) return result; } -int rb_in_eval; +int ruby_in_eval; #ifdef USE_THREAD static void rb_thread_cleanup _((void)); @@ -1021,7 +1054,7 @@ ruby_run() break; case TAG_RAISE: case TAG_FATAL: - if (rb_obj_is_kind_of(rb_errinfo, rb_eSystemExit)) { + if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) { exit(exit_status); } error_print(); @@ -1044,7 +1077,7 @@ compile_error(at) char *mesg; int len; - mesg = str2cstr(rb_errinfo, &len); + mesg = str2cstr(ruby_errinfo, &len); ruby_nerrs = 0; str = rb_str_new2("compile error"); if (at) { @@ -1121,6 +1154,10 @@ rb_eval_cmd(cmd, arg) val = eval(ruby_top_self, cmd, Qnil, 0, 0); } +#ifdef USE_THREAD + if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) + FL_SET(saved_scope, SCOPE_DONT_RECYCLE); +#endif ruby_scope = saved_scope; safe_level = safe; POP_TAG(); @@ -1959,7 +1996,7 @@ rb_eval(self, node) case NODE_RESCUE: retry_entry: { - volatile VALUE e_info = rb_errinfo; + volatile VALUE e_info = ruby_errinfo; PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { @@ -1978,7 +2015,7 @@ rb_eval(self, node) } POP_TAG(); if (state == 0) { - rb_errinfo = e_info; + ruby_errinfo = e_info; } else if (state == TAG_RETRY) { state = 0; @@ -2031,9 +2068,6 @@ rb_eval(self, node) case NODE_DOT2: case NODE_DOT3: result = rb_range_new(rb_eval(self, node->nd_beg), rb_eval(self, node->nd_end)); -#if 0 - break; -#else result = rb_range_new(rb_eval(self, node->nd_beg), rb_eval(self, node->nd_end)); if (node->nd_state) break; if (nd_type(node->nd_beg) == NODE_LIT && FIXNUM_P(node->nd_beg->nd_lit) && @@ -2045,7 +2079,6 @@ rb_eval(self, node) else { node->nd_state = 1; } -#endif break; case NODE_FLIP2: /* like AWK */ @@ -2297,9 +2330,9 @@ rb_eval(self, node) } result = rb_eval(self, node->nd_value); /* check for static scope constants */ - if (RTEST(rb_verbose) && + if (RTEST(ruby_verbose) && ev_const_defined((NODE*)ruby_frame->cbase, node->nd_vid)) { - if (RTEST(rb_verbose)) { + if (RTEST(ruby_verbose)) { rb_warning("already initialized constant %s", rb_id2name(node->nd_vid)); } @@ -2445,10 +2478,10 @@ rb_eval(self, node) str2 = list->nd_head->nd_lit; break; case NODE_EVSTR: - rb_in_eval++; + ruby_in_eval++; list->nd_head = compile(list->nd_head->nd_lit,0); ruby_eval_tree = 0; - rb_in_eval--; + ruby_in_eval--; if (ruby_nerrs > 0) { compile_error("string expansion"); } @@ -2494,7 +2527,7 @@ rb_eval(self, node) case NODE_ATTRSET: if (ruby_frame->argc != 1) - rb_raise(rb_eArgError, "Wrong # of arguments(%d for 1)", + rb_raise(rb_eArgError, "wrong # of arguments(%d for 1)", ruby_frame->argc); result = rb_ivar_set(self, node->nd_vid, ruby_frame->argv[0]); break; @@ -2514,10 +2547,10 @@ rb_eval(self, node) body = search_method(ruby_class, node->nd_mid, &origin); if (body) { if (origin == ruby_class) { - if (safe_level >= 3) { + if (safe_level >= 4) { rb_raise(rb_eSecurityError, "re-defining method prohibited"); } - if (RTEST(rb_verbose)) { + if (RTEST(ruby_verbose)) { rb_warning("discarding old %s", rb_id2name(node->nd_mid)); } } @@ -2562,18 +2595,11 @@ rb_eval(self, node) VALUE klass; NODE *body = 0; - if (FIXNUM_P(recv)) { - rb_raise(rb_eTypeError, "Can't define method \"%s\" for Fixnum", - rb_id2name(node->nd_mid)); - } - if (NIL_P(recv)) { - rb_raise(rb_eTypeError, "Can't define method \"%s\" for nil", - rb_id2name(node->nd_mid)); - } if (rb_special_const_p(recv)) { rb_raise(rb_eTypeError, - "Can't define method \"%s\" for special constants", - rb_id2name(node->nd_mid)); + "can't define method \"%s\" for %s", + rb_id2name(node->nd_mid), + rb_class2name(CLASS_OF(recv))); } if (rb_safe_level() >= 4 && !FL_TEST(recv, FL_TAINT)) { @@ -2581,10 +2607,10 @@ rb_eval(self, node) } klass = rb_singleton_class(recv); if (st_lookup(RCLASS(klass)->m_tbl, node->nd_mid, &body)) { - if (safe_level >= 3) { + if (safe_level >= 4) { rb_raise(rb_eSecurityError, "re-defining method prohibited"); } - if (RTEST(rb_verbose)) { + if (RTEST(ruby_verbose)) { rb_warning("redefine %s", rb_id2name(node->nd_mid)); } } @@ -2686,7 +2712,7 @@ rb_eval(self, node) rb_id2name(node->nd_cname)); } } - if (safe_level >= 3) { + if (safe_level >= 4) { rb_raise(rb_eSecurityError, "extending class prohibited"); } rb_clear_cache(); @@ -2696,7 +2722,7 @@ rb_eval(self, node) klass = rb_define_class_id(node->nd_cname, super); rb_const_set(ruby_class, node->nd_cname, klass); rb_set_class_path(klass,ruby_class,rb_id2name(node->nd_cname)); - rb_obj_call_init(klass); + rb_obj_call_init(klass, 0, 0); } if (ruby_wrapper) { rb_extend_object(klass, ruby_wrapper); @@ -2728,7 +2754,7 @@ rb_eval(self, node) rb_raise(rb_eTypeError, "%s is not a module", rb_id2name(node->nd_cname)); } - if (safe_level >= 3) { + if (safe_level >= 4) { rb_raise(rb_eSecurityError, "extending module prohibited"); } } @@ -2736,7 +2762,7 @@ rb_eval(self, node) module = rb_define_module_id(node->nd_cname); rb_const_set(ruby_class, node->nd_cname, module); rb_set_class_path(module,ruby_class,rb_id2name(node->nd_cname)); - rb_obj_call_init(module); + rb_obj_call_init(module, 0, 0); } if (ruby_wrapper) { rb_extend_object(module, ruby_wrapper); @@ -2752,14 +2778,9 @@ rb_eval(self, node) VALUE klass; klass = rb_eval(self, node->nd_recv); - if (FIXNUM_P(klass)) { - rb_raise(rb_eTypeError, "No virtual class for Fixnums"); - } - if (NIL_P(klass)) { - rb_raise(rb_eTypeError, "No virtual class for nil"); - } if (rb_special_const_p(klass)) { - rb_raise(rb_eTypeError, "No virtual class for special constants"); + rb_raise(rb_eTypeError, "no virtual class for %s", + rb_class2name(CLASS_OF(klass))); } if (FL_TEST(CLASS_OF(klass), FL_SINGLETON)) { rb_clear_cache(); @@ -2939,7 +2960,7 @@ rb_f_exit(argc, argv, obj) static void rb_abort() { - if (rb_errinfo) { + if (ruby_errinfo) { error_print(); } rb_exit(1); @@ -2969,7 +2990,7 @@ rb_longjmp(tag, mesg) { VALUE at; - if (NIL_P(mesg)) mesg = rb_errinfo; + if (NIL_P(mesg)) mesg = ruby_errinfo; if (NIL_P(mesg)) { mesg = rb_exc_new(rb_eRuntimeError, 0, 0); } @@ -2982,13 +3003,13 @@ rb_longjmp(tag, mesg) } } if (!NIL_P(mesg)) { - rb_errinfo = mesg; + ruby_errinfo = mesg; } - if (RTEST(rb_debug) && !NIL_P(rb_errinfo) - && !rb_obj_is_kind_of(rb_errinfo, rb_eSystemExit)) { + if (RTEST(ruby_debug) && !NIL_P(ruby_errinfo) + && !rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) { fprintf(stderr, "Exception `%s' at %s:%d\n", - rb_class2name(CLASS_OF(rb_errinfo)), + rb_class2name(CLASS_OF(ruby_errinfo)), ruby_sourcefile, ruby_sourceline); } @@ -3028,32 +3049,34 @@ rb_f_raise(argc, argv) int argc; VALUE *argv; { - VALUE arg1, arg2, arg3; VALUE mesg; int n; mesg = Qnil; - switch (n = rb_scan_args(argc, argv, "03", &arg1, &arg2, &arg3)) { + switch (argc) { + case 0: + mesg = Qnil; + break; case 1: - mesg = arg1; + if (NIL_P(argv[0])) break; + if (TYPE(argv[0]) == T_STRING) { + mesg = rb_exc_new3(rb_eRuntimeError, argv[0]); + break; + } + mesg = rb_funcall(argv[0], rb_intern("exception"), 0, 0); break; case 3: case 2: - mesg = arg2; + mesg = rb_funcall(argv[0], rb_intern("exception"), 1, argv[1]); + break; + default: + rb_raise(rb_eArgError, "wrong # of arguments"); break; } - if (!NIL_P(mesg)) { - if (n == 1 && TYPE(mesg) == T_STRING) { - mesg = rb_exc_new3(rb_eRuntimeError, mesg); - } - else { - mesg = rb_funcall(arg1, rb_intern("new"), 1, mesg); - } - if (!rb_obj_is_kind_of(mesg, rb_eException)) { + if (!rb_obj_is_kind_of(mesg, rb_eException)) rb_raise(rb_eTypeError, "exception object expected"); - } - set_backtrace(mesg, arg3); + set_backtrace(mesg, (argc>2)?argv[2]:Qnil); } PUSH_FRAME(); /* fake frame */ @@ -3159,8 +3182,10 @@ rb_yield_0(val, self, klass) POP_VARS(); ruby_block = block; ruby_frame = ruby_frame->prev; +#ifdef USE_THREAD if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) FL_SET(old_scope, SCOPE_DONT_RECYCLE); +#endif ruby_scope = old_scope; if (state) JUMP_TAG(state); return result; @@ -3339,7 +3364,7 @@ handle_rescue(self, node) TMP_PROTECT; if (!node->nd_args) { - return rb_obj_is_kind_of(rb_errinfo, rb_eStandardError); + return rb_obj_is_kind_of(ruby_errinfo, rb_eStandardError); } BEGIN_CALLARGS; @@ -3350,7 +3375,7 @@ handle_rescue(self, node) if (!rb_obj_is_kind_of(argv[0], rb_cModule)) { rb_raise(rb_eTypeError, "class or module required for rescue clause"); } - if (rb_obj_is_kind_of(rb_errinfo, argv[0])) return 1; + if (rb_obj_is_kind_of(ruby_errinfo, argv[0])) return 1; argv++; } return 0; @@ -3363,18 +3388,18 @@ rb_rescue(b_proc, data1, r_proc, data2) { int state; volatile VALUE result; - volatile VALUE e_info = rb_errinfo; + volatile VALUE e_info = ruby_errinfo; PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { retry_entry: result = (*b_proc)(data1); } - else if (state == TAG_RAISE && rb_obj_is_kind_of(rb_errinfo, rb_eStandardError)) { + else if (state == TAG_RAISE && rb_obj_is_kind_of(ruby_errinfo, rb_eStandardError)) { if (r_proc) { PUSH_TAG(PROT_NONE); if ((state = EXEC_TAG()) == 0) { - result = (*r_proc)(data2, rb_errinfo); + result = (*r_proc)(data2, ruby_errinfo); } POP_TAG(); if (state == TAG_RETRY) { @@ -3387,7 +3412,7 @@ rb_rescue(b_proc, data1, r_proc, data2) state = 0; } if (state == 0) { - rb_errinfo = e_info; + ruby_errinfo = e_info; } } POP_TAG(); @@ -3456,8 +3481,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; @@ -3469,19 +3495,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"; } @@ -3501,9 +3527,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; @@ -3511,9 +3538,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 */ @@ -3570,7 +3595,7 @@ call_cfunc(func, recv, len, argc, argv) VALUE *argv; { if (len >= 0 && argc != len) { - rb_raise(rb_eArgError, "Wrong # of arguments(%d for %d)", + rb_raise(rb_eArgError, "wrong # of arguments(%d for %d)", argc, len); } @@ -3681,7 +3706,6 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper) rb_raise(rb_eSysStackError, "stack level too deep"); } } - PUSH_ITER(itr); PUSH_FRAME(); @@ -3775,7 +3799,7 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper) i = node->nd_cnt; if (i > argc) { - rb_raise(rb_eArgError, "Wrong # of arguments(%d for %d)", + rb_raise(rb_eArgError, "wrong # of arguments(%d for %d)", argc, i); } if (node->nd_rest == -1) { @@ -3787,7 +3811,7 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper) optnode = optnode->nd_next; } if (opt > 0) { - rb_raise(rb_eArgError, "Wrong # of arguments(%d for %d)", + rb_raise(rb_eArgError, "wrong # of arguments(%d for %d)", argc, argc-opt); } } @@ -3901,8 +3925,13 @@ rb_call(klass, recv, mid, argc, argv, scope) return rb_undefined(recv, mid, argc, argv, CSTAT_PRIV); /* self must be kind of a specified form for private method */ - if ((noex & NOEX_PROTECTED) && !rb_obj_is_kind_of(ruby_frame->self, klass)) - return rb_undefined(recv, mid, argc, argv, CSTAT_PROT); + if ((noex & NOEX_PROTECTED)) { + VALUE defined_class = klass; + while (TYPE(defined_class) == T_ICLASS) + defined_class = RBASIC(defined_class)->klass; + if (!rb_obj_is_kind_of(ruby_frame->self, defined_class)) + return rb_undefined(recv, mid, argc, argv, CSTAT_PROT); + } return rb_call0(klass, recv, id, argc, argv, body, noex & NOEX_UNDEF); } @@ -3998,9 +4027,7 @@ backtrace(lev) struct FRAME *frame = ruby_frame; char buf[BUFSIZ]; VALUE ary; - int slev = safe_level; - safe_level = 0; ary = rb_ary_new(); if (lev < 0) { if (frame->last_func) { @@ -4016,7 +4043,10 @@ backtrace(lev) else { while (lev-- > 0) { frame = frame->prev; - if (!frame) return Qnil; + if (!frame) { + ary = Qnil; + break; + } } } while (frame && frame->file) { @@ -4031,7 +4061,7 @@ backtrace(lev) rb_ary_push(ary, rb_str_new2(buf)); frame = frame->prev; } - safe_level = slev; + return ary; } @@ -4152,7 +4182,7 @@ eval(self, src, scope, file, line) PUSH_CLASS(); ruby_class = ((NODE*)ruby_frame->cbase)->nd_clss; - rb_in_eval++; + ruby_in_eval++; if (TYPE(ruby_class) == T_ICLASS) { ruby_class = RBASIC(ruby_class)->klass; } @@ -4168,11 +4198,13 @@ eval(self, src, scope, file, line) } POP_TAG(); POP_CLASS(); - rb_in_eval--; + ruby_in_eval--; if (!NIL_P(scope)) { ruby_frame = ruby_frame->prev; +#ifdef USE_THREAD if (FL_TEST(ruby_scope, SCOPE_DONT_RECYCLE)) FL_SET(old_scope, SCOPE_DONT_RECYCLE); +#endif ruby_scope = old_scope; ruby_block = old_block; ruby_calling_block = old_call_block; @@ -4191,20 +4223,20 @@ eval(self, src, scope, file, line) VALUE err; VALUE errat; - errat = get_backtrace(rb_errinfo); + errat = get_backtrace(ruby_errinfo); if (strcmp(file, "(eval)") == 0) { if (ruby_sourceline > 1) { err = RARRAY(errat)->ptr[0]; rb_str_cat(err, ": ", 2); - rb_str_concat(err, rb_errinfo); + rb_str_concat(err, ruby_errinfo); } else { - err = rb_str_dup(rb_errinfo); + err = rb_str_dup(ruby_errinfo); } errat = Qnil; - rb_exc_raise(rb_exc_new3(CLASS_OF(rb_errinfo), err)); + rb_exc_raise(rb_exc_new3(CLASS_OF(ruby_errinfo), err)); } - rb_exc_raise(rb_errinfo); + rb_exc_raise(ruby_errinfo); } JUMP_TAG(state); } @@ -4303,7 +4335,8 @@ static VALUE yield_under(under, self) VALUE under, self; { - rb_secure(4); + if (rb_safe_level() >= 4 && !FL_TEST(self, FL_TAINT)) + rb_raise(rb_eSecurityError, "Insecure: can't eval"); return exec_under(yield_under_i, under, self); } @@ -4328,7 +4361,7 @@ rb_obj_instance_eval(argc, argv, self) if (argc > 2) line = NUM2INT(argv[2]); } else { - rb_raise(rb_eArgError, "Wrong # of arguments: %s(src) or %s{..}", + rb_raise(rb_eArgError, "wrong # of arguments: %s(src) or %s{..}", rb_id2name(ruby_frame->last_func), rb_id2name(ruby_frame->last_func)); } @@ -4367,7 +4400,7 @@ rb_mod_module_eval(argc, argv, mod) if (argc > 2) line = NUM2INT(argv[2]); } else { - rb_raise(rb_eArgError, "Wrong # of arguments: %s(src) or %s{..}", + rb_raise(rb_eArgError, "wrong # of arguments: %s(src) or %s{..}", rb_id2name(ruby_frame->last_func), rb_id2name(ruby_frame->last_func)); } @@ -4394,6 +4427,16 @@ is_absolute_path(path) return 0; } +#ifdef __MACOS__ +static int +is_macos_native_path(path) + char *path; +{ + if (strchr(path, ':')) return 1; + return 0; +} +#endif + static char* find_file(file) char *file; @@ -4402,6 +4445,16 @@ find_file(file) volatile VALUE vpath; char *path; +#ifdef __MACOS__ + if (is_macos_native_path(file)) { + FILE *f = fopen(file, "r"); + + if (f == NULL) return 0; + fclose(f); + return file; + } +#endif + if (is_absolute_path(file)) { FILE *f = fopen(file, "r"); @@ -4410,6 +4463,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; @@ -4447,11 +4506,6 @@ rb_load(fname, wrap) else { Check_SafeStr(fname); } -#ifndef __MACOS__ - if (RSTRING(fname)->ptr[0] == '~') { - fname = rb_file_s_expand_path(1, &fname); - } -#endif file = find_file(RSTRING(fname)->ptr); if (!file) { rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr); @@ -4491,9 +4545,9 @@ rb_load(fname, wrap) state = EXEC_TAG(); last_func = ruby_frame->last_func; if (state == 0) { - rb_in_eval++; + ruby_in_eval++; rb_load_file(file); - rb_in_eval--; + ruby_in_eval--; if (ruby_nerrs == 0) { eval_node(self); } @@ -4510,7 +4564,7 @@ rb_load(fname, wrap) POP_VARS(); ruby_wrapper = 0; if (ruby_nerrs > 0) { - rb_exc_raise(rb_errinfo); + rb_exc_raise(ruby_errinfo); } if (state) JUMP_TAG(state); } @@ -4609,7 +4663,7 @@ rb_f_require(obj, fname) if (strcmp(".rb", ext) == 0) { feature = file = RSTRING(fname)->ptr; file = find_file(file); - if (file) goto rb_load; + if (file) goto load_rb; } else if (strcmp(".so", ext) == 0 || strcmp(".o", ext) == 0) { file = feature = RSTRING(fname)->ptr; @@ -4621,12 +4675,12 @@ rb_f_require(obj, fname) file = feature = buf; } file = find_file(file); - if (file) goto dyna_load; + if (file) goto load_dyna; } else if (strcmp(DLEXT, ext) == 0) { feature = RSTRING(fname)->ptr; file = find_file(feature); - if (file) goto dyna_load; + if (file) goto load_dyna; } } buf = ALLOCA_N(char, strlen(RSTRING(fname)->ptr) + 5); @@ -4636,19 +4690,19 @@ rb_f_require(obj, fname) if (file) { fname = rb_str_new2(file); feature = buf; - goto rb_load; + goto load_rb; } strcpy(buf, RSTRING(fname)->ptr); strcat(buf, DLEXT); file = find_file(buf); if (file) { feature = buf; - goto dyna_load; + goto load_dyna; } rb_raise(rb_eLoadError, "No such file to load -- %s", RSTRING(fname)->ptr); - dyna_load: + load_dyna: #ifdef USE_THREAD if (rb_thread_loading(feature)) return Qfalse; else { @@ -4669,7 +4723,7 @@ rb_f_require(obj, fname) #endif return Qtrue; - rb_load: + load_rb: #ifdef USE_THREAD if (rb_thread_loading(feature)) return Qfalse; else { @@ -4689,6 +4743,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; iargc, ruby_frame->argv); + rb_funcall2(obj, init, argc, argv); POP_ITER(); } @@ -4866,7 +4936,7 @@ rb_class_new_instance(argc, argv, klass) rb_raise(rb_eTypeError, "can't create instance of virtual class"); } obj = rb_obj_alloc(klass); - rb_obj_call_init(obj); + rb_obj_call_init(obj, argc, argv); return obj; } @@ -4919,7 +4989,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; @@ -4929,7 +4999,7 @@ static VALUE errat_getter(id) ID id; { - return get_backtrace(rb_errinfo); + return get_backtrace(ruby_errinfo); } static void @@ -4938,10 +5008,10 @@ errat_setter(val, id, var) ID id; VALUE *var; { - if (NIL_P(rb_errinfo)) { + if (NIL_P(ruby_errinfo)) { rb_raise(rb_eArgError, "$! not set"); } - set_backtrace(rb_errinfo, val); + set_backtrace(ruby_errinfo, val); } VALUE rb_f_global_variables(); @@ -5055,7 +5125,7 @@ Init_eval() rb_global_variable((VALUE*)&ruby_dyna_vars); rb_define_virtual_variable("$@", errat_getter, errat_setter); - rb_define_hooked_variable("$!", &rb_errinfo, 0, errinfo_setter); + rb_define_hooked_variable("$!", &ruby_errinfo, 0, errinfo_setter); rb_define_global_function("eval", rb_f_eval, -1); rb_define_global_function("iterator?", rb_f_iterator_p, 0); @@ -5131,7 +5201,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); } @@ -5334,7 +5404,7 @@ proc_s_new(klass) scope_dup(data->scope); proc_save_safe_level(proc); - rb_obj_call_init(proc); + rb_obj_call_init(proc, 0, 0); return proc; } @@ -5740,7 +5810,7 @@ struct thread { char *file; int line; - VALUE rb_errinfo; + VALUE errinfo; VALUE last_status; VALUE last_line; VALUE last_match; @@ -5801,9 +5871,10 @@ thread_mark(th) rb_gc_mark(th->scope); rb_gc_mark(th->dyna_vars); - rb_gc_mark(th->rb_errinfo); + rb_gc_mark(th->errinfo); rb_gc_mark(th->last_line); rb_gc_mark(th->last_match); + rb_mark_tbl(th->locals); /* mark data in copied stack */ if (th->status == THREAD_KILLED) return; @@ -5830,7 +5901,6 @@ thread_mark(th) } block = block->prev; } - rb_mark_tbl(th->locals); } void @@ -5893,7 +5963,7 @@ rb_thread_save_context(th) th->misc = scope_vmode | (rb_trap_immediate<<8); th->iter = ruby_iter; th->tag = prot_tag; - th->rb_errinfo = rb_errinfo; + th->errinfo = ruby_errinfo; th->last_status = rb_last_status; th->last_line = rb_lastline_get(); th->last_match = rb_backref_get(); @@ -5926,6 +5996,12 @@ static int th_raise_line; static VALUE th_cmd; static int th_sig; +#define RESTORE_NORMAL 0 +#define RESTORE_FATAL 1 +#define RESTORE_INTERRUPT 2 +#define RESTORE_TRAP 3 +#define RESTORE_RAISE 4 + static void rb_thread_restore_context(th, exit) thread_t th; @@ -5957,7 +6033,7 @@ rb_thread_restore_context(th, exit) rb_trap_immediate = th->misc>>8; ruby_iter = th->iter; prot_tag = th->tag; - rb_errinfo = th->rb_errinfo; + ruby_errinfo = th->errinfo; rb_last_status = th->last_status; safe_level = th->safe; @@ -5974,26 +6050,27 @@ rb_thread_restore_context(th, exit) rb_backref_set(tmp->last_match); switch (ex) { - case 1: + case RESTORE_FATAL: JUMP_TAG(TAG_FATAL); break; - case 2: + case RESTORE_INTERRUPT: rb_interrupt(); break; - case 3: + case RESTORE_TRAP: rb_trap_eval(th_cmd, th_sig); errno = EINTR; break; - case 4: + case RESTORE_RAISE: ruby_frame->last_func = 0; ruby_sourcefile = th_raise_file; ruby_sourceline = th_raise_line; rb_f_raise(th_raise_argc, th_raise_argv); break; + case RESTORE_NORMAL: default: longjmp(tmp->context, 1); } @@ -6033,15 +6110,45 @@ rb_thread_dead(th) return th->status == THREAD_KILLED; } +void +rb_thread_fd_close(fd) + int fd; +{ + thread_t th; + + FOREACH_THREAD(th) { + if ((th->wait_for & WAIT_FD) && th->fd == fd) { + th_raise_argc = 1; + th_raise_argv[0] = rb_exc_new2(rb_eIOError, "stream closed"); + th_raise_file = ruby_sourcefile; + th_raise_line = ruby_sourceline; + curr_thread = th; + rb_thread_restore_context(main_thread, RESTORE_RAISE); + } + } + END_FOREACH(th); +} + static void rb_thread_deadlock() { +#if 1 curr_thread = main_thread; th_raise_argc = 1; th_raise_argv[0] = rb_exc_new2(rb_eFatal, "Thread: deadlock"); th_raise_file = ruby_sourcefile; th_raise_line = ruby_sourceline; + rb_thread_restore_context(main_thread, RESTORE_RAISE); +#else + static int invoked = 0; + + if (invoked) return; + invoked = 1; + rb_prohibit_interrupt = 1; + ruby_errinfo = rb_exc_new2(rb_eFatal, "Thread: deadlock"); + set_backtrace(ruby_errinfo, make_backtrace()); rb_abort(); +#endif } void @@ -6143,7 +6250,14 @@ rb_thread_schedule() n = select(max+1, &readfds, 0, 0, delay_ptr); if (n < 0) { if (rb_trap_pending) rb_trap_exec(); - goto select_err; + switch (errno) { + case EBADF: + case ENOMEM: + n = 0; + break; + default: + goto select_err; + } } if (n > 0) { /* Some descriptors are ready. @@ -6175,10 +6289,15 @@ rb_thread_schedule() fprintf(stderr, "%s:%d:deadlock 0x%x: %d:%d %s\n", th->file, th->line, th->thread, th->status, th->wait_for, th==main_thread?"(main)":""); + if (th->status == THREAD_STOPPED) { + next = th; + } } END_FOREACH_FROM(curr, th); /* raise fatal error to main thread */ rb_thread_deadlock(); + rb_thread_ready(next); + next->status = THREAD_TO_KILL; } if (next->status == THREAD_RUNNABLE && next == curr_thread) { return; @@ -6195,9 +6314,9 @@ rb_thread_schedule() curr_thread = next; if (next->status == THREAD_TO_KILL) { /* execute ensure-clause if any */ - rb_thread_restore_context(next, 1); + rb_thread_restore_context(next, RESTORE_FATAL); } - rb_thread_restore_context(next, 0); + rb_thread_restore_context(next, RESTORE_NORMAL); } void @@ -6213,20 +6332,20 @@ rb_thread_wait_fd(fd) rb_thread_schedule(); } -void +int rb_thread_fd_writable(fd) int fd; { struct timeval zero; fd_set fds; - if (curr_thread == curr_thread->next) return; + if (curr_thread == curr_thread->next) return 1; zero.tv_sec = zero.tv_usec = 0; for (;;) { FD_ZERO(&fds); FD_SET(fd, &fds); - if (select(fd+1, 0, &fds, 0, &zero) == 1) break; + if (select(fd+1, 0, &fds, 0, &zero) == 1) return 0; rb_thread_schedule(); } } @@ -6545,41 +6664,44 @@ rb_thread_abort_exc_set(thread, val) return val; } +#define THREAD_ALLOC(th) do {\ + th = ALLOC(struct thread);\ +\ + th->status = 0;\ + th->result = 0;\ + th->errinfo = Qnil;\ +\ + th->stk_ptr = 0;\ + th->stk_len = 0;\ + th->stk_max = 0;\ + th->wait_for = 0;\ + th->fd = 0;\ + th->delay = 0.0;\ + th->join = 0;\ +\ + th->frame = 0;\ + th->scope = 0;\ + th->klass = 0;\ + th->wrapper = 0;\ + th->dyna_vars = 0;\ + th->block = 0;\ + th->iter = 0;\ + th->tag = 0;\ + th->errinfo = 0;\ + th->last_status = 0;\ + th->last_line = 0;\ + th->last_match = 0;\ + th->abort = 0;\ + th->locals = 0;\ +} while(0) + static thread_t rb_thread_alloc(klass) VALUE klass; { thread_t th; - th = ALLOC(struct thread); - th->status = THREAD_RUNNABLE; - - th->status = 0; - th->result = 0; - th->rb_errinfo = Qnil; - - th->stk_ptr = 0; - th->stk_len = 0; - th->stk_max = 0; - th->wait_for = 0; - th->fd = 0; - th->delay = 0.0; - th->join = 0; - - th->frame = 0; - th->scope = 0; - th->klass = 0; - th->wrapper = 0; - th->dyna_vars = 0; - th->block = 0; - th->iter = 0; - th->tag = 0; - th->rb_errinfo = 0; - th->last_status = 0; - th->last_line = 0; - th->last_match = 0; - th->abort = 0; - + THREAD_ALLOC(th); th->thread = Data_Wrap_Struct(klass, thread_mark, thread_free, th); if (curr_thread) { @@ -6654,6 +6776,7 @@ rb_thread_create_0(fn, arg, klass) VALUE klass; { thread_t th = rb_thread_alloc(klass); + volatile VALUE thread = th->thread; enum thread_status status; int state; @@ -6673,7 +6796,7 @@ rb_thread_create_0(fn, arg, klass) FL_SET(ruby_scope, SCOPE_SHARED); rb_thread_save_context(curr_thread); if (setjmp(curr_thread->context)) { - return th->thread; + return thread; } PUSH_TAG(PROT_THREAD); @@ -6687,24 +6810,24 @@ rb_thread_create_0(fn, arg, klass) POP_TAG(); status = th->status; rb_thread_remove(); - if (state && status != THREAD_TO_KILL && !NIL_P(rb_errinfo)) { + if (state && status != THREAD_TO_KILL && !NIL_P(ruby_errinfo)) { if (state == TAG_FATAL) { /* fatal error within this thread, need to stop whole script */ - main_thread->rb_errinfo = rb_errinfo; + main_thread->errinfo = ruby_errinfo; rb_thread_cleanup(); } - else if (rb_obj_is_kind_of(rb_errinfo, rb_eSystemExit)) { + else if (rb_obj_is_kind_of(ruby_errinfo, rb_eSystemExit)) { /* delegate exception to main_thread */ - rb_thread_raise(1, &rb_errinfo, main_thread->thread); + rb_thread_raise(1, &ruby_errinfo, main_thread->thread); } - else if (rb_thread_abort || curr_thread->abort || RTEST(rb_debug)) { + else if (rb_thread_abort || curr_thread->abort || RTEST(ruby_debug)) { VALUE err = rb_exc_new(rb_eSystemExit, 0, 0); error_print(); /* exit on main_thread */ rb_thread_raise(1, &err, main_thread->thread); } else { - curr_thread->rb_errinfo = rb_errinfo; + curr_thread->errinfo = ruby_errinfo; } } rb_thread_schedule(); @@ -6751,13 +6874,13 @@ rb_thread_value(thread) thread_t th = rb_thread_check(thread); rb_thread_join(thread); - if (!NIL_P(th->rb_errinfo)) { - VALUE oldbt = get_backtrace(th->rb_errinfo); + if (!NIL_P(th->errinfo)) { + VALUE oldbt = get_backtrace(th->errinfo); VALUE errat = make_backtrace(); rb_ary_unshift(errat, rb_ary_entry(oldbt, 0)); - set_backtrace(th->rb_errinfo, errat); - rb_exc_raise(th->rb_errinfo); + set_backtrace(th->errinfo, errat); + rb_exc_raise(th->errinfo); } return th->result; @@ -6770,7 +6893,7 @@ rb_thread_status(thread) thread_t th = rb_thread_check(thread); if (rb_thread_dead(th)) { - if (NIL_P(th->rb_errinfo)) return Qfalse; + if (NIL_P(th->errinfo)) return Qfalse; return Qnil; } @@ -6844,7 +6967,7 @@ rb_thread_interrupt() return; } curr_thread = main_thread; - rb_thread_restore_context(curr_thread, 2); + rb_thread_restore_context(curr_thread, RESTORE_INTERRUPT); } void @@ -6866,7 +6989,7 @@ rb_thread_trap_eval(cmd, sig) th_cmd = cmd; th_sig = sig; curr_thread = main_thread; - rb_thread_restore_context(curr_thread, 3); + rb_thread_restore_context(curr_thread, RESTORE_TRAP); } static VALUE @@ -6895,7 +7018,7 @@ rb_thread_raise(argc, argv, thread) th_raise_argc = argc; th_raise_file = ruby_sourcefile; th_raise_line = ruby_sourceline; - rb_thread_restore_context(curr_thread, 4); + rb_thread_restore_context(curr_thread, RESTORE_RAISE); return Qnil; /* not reached */ } @@ -6957,13 +7080,11 @@ rb_thread_local_aset(thread, id, val) ID id; VALUE val; { - thread_t th; - + thread_t th = rb_thread_check(thread); if (safe_level >= 4 && !FL_TEST(thread, FL_TAINT)) rb_raise(rb_eSecurityError, "Insecure: can't modify thread values"); - th = rb_thread_check(thread); if (!th->locals) { th->locals = st_init_numtable(); } @@ -7002,35 +7123,9 @@ rb_callcc(self) VALUE self; { volatile VALUE cont; - thread_t th = ALLOC(struct thread); - - th->status = THREAD_RUNNABLE; - - th->status = 0; - th->result = 0; - th->rb_errinfo = Qnil; - - th->stk_ptr = 0; - th->stk_len = 0; - th->stk_max = 0; - th->wait_for = 0; - th->fd = 0; - th->delay = 0.0; - th->join = 0; - - th->frame = 0; - th->scope = 0; - th->klass = 0; - th->dyna_vars = 0; - th->block = 0; - th->iter = 0; - th->tag = 0; - th->rb_errinfo = 0; - th->last_status = 0; - th->last_line = 0; - th->last_match = 0; - th->abort = 0; + thread_t th; + THREAD_ALLOC(th); th->thread = cont = Data_Wrap_Struct(rb_cContinuation, thread_mark, thread_free, th); @@ -7063,7 +7158,7 @@ rb_continuation_call(argc, argv, cont) th->result = rb_ary_new4(argc, argv); break; } - rb_thread_restore_context(th, 0); + rb_thread_restore_context(th, RESTORE_NORMAL); return Qnil; } diff --git a/ext/Win32API/Win32API.c b/ext/Win32API/Win32API.c index f4cb5c726f..b57cf8101f 100644 --- a/ext/Win32API/Win32API.c +++ b/ext/Win32API/Win32API.c @@ -2,9 +2,11 @@ Win32API - Ruby Win32 API Import Facility */ +#ifndef _MSC_VER #define WIN32_LEAN_AND_MEAN #include #include +#endif #define _T_VOID 0 #define _T_NUMBER 1 @@ -54,35 +56,35 @@ Win32API_initialize(self, dllname, proc, import, export) if (!hdll) { hdll = LoadLibrary(RSTRING(dllname)->ptr); if (!hdll) - Fail("LoadLibrary: %s\n", RSTRING(dllname)->ptr); + rb_raise(rb_eRuntimeError, "LoadLibrary: %s\n", RSTRING(dllname)->ptr); Data_Wrap_Struct(self, 0, Win32API_FreeLibrary, hdll); } hproc = GetProcAddress(hdll, RSTRING(proc)->ptr); if (!hproc) { - str = str_new3(proc); - str = str_cat(str, "A", 1); + str = rb_str_new3(proc); + str = rb_str_cat(str, "A", 1); hproc = GetProcAddress(hdll, RSTRING(str)->ptr); if (!hproc) - Fail("GetProcAddress: %s or %s\n", + rb_raise(rb_eRuntimeError, "GetProcAddress: %s or %s\n", RSTRING(proc)->ptr, RSTRING(str)->ptr); } rb_iv_set(self, "__dll__", INT2NUM((int)hdll)); rb_iv_set(self, "__dllname__", dllname); rb_iv_set(self, "__proc__", INT2NUM((int)hproc)); - a_import = ary_new(); + a_import = rb_ary_new(); ptr = RARRAY(import)->ptr; for (i = 0, len = RARRAY(import)->len; i < len; i++) { int c = *(char *)RSTRING(ptr[i])->ptr; switch (c) { case 'N': case 'n': case 'L': case 'l': - ary_push(a_import, INT2FIX(_T_NUMBER)); + rb_ary_push(a_import, INT2FIX(_T_NUMBER)); break; case 'P': case 'p': - ary_push(a_import, INT2FIX(_T_POINTER)); + rb_ary_push(a_import, INT2FIX(_T_POINTER)); break; case 'I': case 'i': - ary_push(a_import, INT2FIX(_T_INTEGER)); + rb_ary_push(a_import, INT2FIX(_T_INTEGER)); break; } } @@ -146,18 +148,18 @@ Win32API_Call(argc, argv, obj) texport = FIX2INT(obj_export); if (items != nimport) - Fail("Wrong number of parameters: expected %d, got %d.\n", + rb_raise(rb_eRuntimeError, "Wrong number of parameters: expected %d, got %d.\n", nimport, items); if (0 < nimport) { for (i = nimport - 1; 0 <= i; i--) { VALUE str; - import_type = ary_entry(obj_import, i); + import_type = rb_ary_entry(obj_import, i); timport = FIX2INT(import_type); switch (timport) { case _T_NUMBER: case _T_INTEGER: - lParam = NUM2INT(ary_entry(args, i)); + lParam = NUM2INT(rb_ary_entry(args, i)); #if defined(_MSC_VER) || defined(__LCC__) _asm { mov eax, lParam @@ -170,9 +172,9 @@ Win32API_Call(argc, argv, obj) #endif break; case _T_POINTER: - str = ary_entry(args, i); + str = rb_ary_entry(args, i); Check_Type(str, T_STRING); - str_modify(str); + rb_str_modify(str); pParam = RSTRING(str)->ptr; #if defined(_MSC_VER) || defined(__LCC__) _asm { @@ -197,7 +199,7 @@ Win32API_Call(argc, argv, obj) break; case _T_POINTER: ApiFunctionPointer = (ApiPointer *) ApiFunction; - Return = str_new2((char *)ApiFunctionPointer()); + Return = rb_str_new2((char *)ApiFunctionPointer()); break; case _T_INTEGER: ApiFunctionInteger = (ApiInteger *) ApiFunction; @@ -216,8 +218,14 @@ Win32API_Call(argc, argv, obj) void Init_Win32API() { - VALUE cWin32API = rb_define_class("Win32API", cObject); + VALUE cWin32API = rb_define_class("Win32API", rb_cObject); rb_define_method(cWin32API, "initialize", Win32API_initialize, 4); rb_define_method(cWin32API, "call", Win32API_Call, -1); rb_define_alias(cWin32API, "Call", "call"); } + +void +Init_win32api() +{ + Init_Win32API(); +} diff --git a/ext/curses/curses.c b/ext/curses/curses.c index f3d1bc0970..49fa07bd5c 100644 --- a/ext/curses/curses.c +++ b/ext/curses/curses.c @@ -11,6 +11,9 @@ # ifdef HAVE_NCURSES_CURSES_H # include # else +#ifdef __hpux +#include +#else # include # if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_maxx) # define _maxx maxx @@ -26,6 +29,7 @@ # endif # endif #endif +#endif #include "ruby.h" @@ -408,11 +412,13 @@ window_s_new(class, lines, cols, top, left) { VALUE w; WINDOW *window; + VALUE args[4]; window = newwin(NUM2INT(lines), NUM2INT(cols), NUM2INT(top), NUM2INT(left)); wclear(window); w = prep_window(class, window); - rb_obj_call_init(w); + args[0] = lines; args[1] = cols; args[2] = top; args[3] = left; + rb_obj_call_init(w, 4, args); return w; } @@ -428,11 +434,17 @@ window_subwin(obj, lines, cols, top, left) { struct windata *winp; WINDOW *window; + VALUE w; + VALUE args[4]; GetWINDOW(obj, winp); window = subwin(winp->window, NUM2INT(lines), NUM2INT(cols), NUM2INT(top), NUM2INT(left)); - return prep_window(cWindow, window); + w = prep_window(cWindow, window); + args[0] = lines; args[1] = cols; args[2] = top; args[3] = left; + rb_obj_call_init(w, 4, args); + + return w; } /* def close */ 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/dbm/dbm.c b/ext/dbm/dbm.c index 2764a325e1..c4a47e8004 100644 --- a/ext/dbm/dbm.c +++ b/ext/dbm/dbm.c @@ -84,7 +84,7 @@ fdbm_s_open(argc, argv, klass) obj = Data_Make_Struct(klass,struct dbmdata,0,free_dbm,dbmp); dbmp->di_dbm = dbm; dbmp->di_size = -1; - rb_obj_call_init(obj); + rb_obj_call_init(obj, argc, argv); return obj; } diff --git a/ext/etc/MANIFEST b/ext/etc/MANIFEST index a0f521b386..79fb1ff34c 100644 --- a/ext/etc/MANIFEST +++ b/ext/etc/MANIFEST @@ -1,5 +1,6 @@ MANIFEST etc.c -etc.doc +etc.txt +etc.txt.jp depend extconf.rb diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in index 058c144f94..ceadc4dd77 100644 --- a/ext/extmk.rb.in +++ b/ext/extmk.rb.in @@ -272,7 +272,7 @@ def create_makefile(target) $DLDFLAGS = $DLDFLAGS + " -L" + $topdir end - $srcdir = $top_srcdir + "/ext/" + target + $srcdir = $top_srcdir + "/ext/" + $mdir mfile = open("Makefile", "w") mfile.printf "\ SHELL = /bin/sh @@ -288,19 +288,19 @@ CC = @CC@ prefix = @prefix@ CFLAGS = %s -I#{$topdir} -I#{$top_srcdir} -I@includedir@ #{CFLAGS} #$CFLAGS %s -DLDFLAGS = #$DLDFLAGS @LDFLAGS@ #$LDFLAGS +DLDFLAGS = #$DLDFLAGS #$LDFLAGS LDSHARED = @LDSHARED@ ", if $static then "" else "@CCDLFLAGS@" end, $defs.join(" ") mfile.printf "\ -program_transform_name = -e @program_transform_name@ -RUBY_INSTALL_NAME = `t='$(program_transform_name)'; echo ruby | sed $$t` +RUBY_INSTALL_NAME = @RUBY_INSTALL_NAME@ prefix = @prefix@ exec_prefix = @exec_prefix@ libdir = @libdir@ -pkglibdir = $(libdir)/$(RUBY_INSTALL_NAME) +#pkglibdir = $(libdir)/$(RUBY_INSTALL_NAME)/@MAJOR@.@MINOR@ +pkglibdir = $(libdir)/ruby/@MAJOR@.@MINOR@ archdir = $(pkglibdir)/@arch@ @SET_MAKE@ @@ -448,7 +448,7 @@ def extmake(target) elsif $clean system "make clean" else - system "make all" + system "make all" or exit end end if $static @@ -513,13 +513,17 @@ 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) if File.exist?(f) $extinit += format("\ \tInit_%s();\n\ -\trb_provide(\"%s.o\");\n\ +\trb_provide(\"%s.so\");\n\ ", t, t) $extobjs = "" unless $extobjs $extobjs += "ext/" @@ -545,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 @@ -557,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@binsuffix@", "miniruby@binsuffix@") - `rm -f ruby@binsuffix@` - system("make ruby@binsuffix@") + if older(ruby, miniruby) + system("rm -f #{ruby}") + system("make #{ruby}") end end diff --git a/ext/gtk/MANIFEST b/ext/gtk/MANIFEST deleted file mode 100644 index 3e1962e1f3..0000000000 --- a/ext/gtk/MANIFEST +++ /dev/null @@ -1,18 +0,0 @@ -MANIFEST -extconf.rb -gtk.c -test.rb -test.xpm -test0.rb -test1.rb -test2.rb -test3.rb -test4.rb -test5.rb -test6.rb -test7.rb -test8.rb -test9.rb -testa.rb -testb.rb -testc.rb diff --git a/ext/gtk/extconf.rb b/ext/gtk/extconf.rb deleted file mode 100644 index 621e0739a5..0000000000 --- a/ext/gtk/extconf.rb +++ /dev/null @@ -1,6 +0,0 @@ -require "mkmf" -if have_library("glib", "g_print") and - have_library("gdk", "gdk_init") and - have_library("gtk", "gtk_init") - create_makefile("gtk") -end diff --git a/ext/gtk/gtk.c b/ext/gtk/gtk.c deleted file mode 100644 index 9114312195..0000000000 --- a/ext/gtk/gtk.c +++ /dev/null @@ -1,5904 +0,0 @@ -/************************************************ - - gtk.c - - - $Author$ - $Date$ - created at: Wed Jan 7 23:55:11 JST 1998 - -************************************************/ - -#include "ruby.h" -#include "sig.h" -#include -#include - -extern VALUE rb_argv, rb_argv0; -extern VALUE cData; - -static VALUE mGtk; - -static VALUE gObject; -static VALUE gWidget; -static VALUE gContainer; -static VALUE gBin; -static VALUE gAlignment; -static VALUE gMisc; -static VALUE gArrow; -static VALUE gFrame; -static VALUE gAspectFrame; -static VALUE gData; -static VALUE gAdjustment; -static VALUE gBox; -static VALUE gButton; -static VALUE gTButton; -static VALUE gCButton; -static VALUE gRButton; -static VALUE gBBox; -static VALUE gCList; -static VALUE gWindow; -static VALUE gDialog; -static VALUE gFileSel; -static VALUE gVBox; -static VALUE gColorSel; -static VALUE gColorSelDialog; -static VALUE gImage; -static VALUE gDrawArea; -static VALUE gEntry; -static VALUE gEventBox; -static VALUE gFixed; -static VALUE gGamma; -static VALUE gHBBox; -static VALUE gVBBox; -static VALUE gHBox; -static VALUE gPaned; -static VALUE gHPaned; -static VALUE gVPaned; -static VALUE gRuler; -static VALUE gHRuler; -static VALUE gVRuler; -static VALUE gRange; -static VALUE gScale; -static VALUE gHScale; -static VALUE gVScale; -static VALUE gScrollbar; -static VALUE gHScrollbar; -static VALUE gVScrollbar; -static VALUE gSeparator; -static VALUE gHSeparator; -static VALUE gVSeparator; -static VALUE gInputDialog; -static VALUE gLabel; -static VALUE gList; -static VALUE gItem; -static VALUE gListItem; -static VALUE gMenuShell; -static VALUE gMenu; -static VALUE gMenuBar; -static VALUE gMenuItem; -static VALUE gCMenuItem; -static VALUE gRMenuItem; -static VALUE gNotebook; -static VALUE gOptionMenu; -static VALUE gPixmap; -static VALUE gPreview; -static VALUE gProgressBar; -static VALUE gScrolledWin; -static VALUE gTable; -static VALUE gText; -static VALUE gToolbar; -static VALUE gTooltips; -static VALUE gTree; -static VALUE gTreeItem; -static VALUE gViewPort; - -static VALUE gAcceleratorTable; -static VALUE gStyle; -static VALUE gPreviewInfo; -static VALUE gAllocation; -static VALUE gRequisiton; - -static VALUE mGdk; - -static VALUE gdkFont; -static VALUE gdkColor; -static VALUE gdkColormap; -static VALUE gdkPixmap; -static VALUE gdkBitmap; -static VALUE gdkWindow; -static VALUE gdkImage; -static VALUE gdkVisual; -static VALUE gdkGC; -static VALUE gdkRectangle; -static VALUE gdkGCValues; -static VALUE gdkRectangle; -static VALUE gdkSegment; -static VALUE gdkWindowAttr; -static VALUE gdkCursor; -static VALUE gdkAtom; -static VALUE gdkColorContext; -static VALUE gdkEvent; - -ID id_gtkdata, id_relatives, id_call; - -static void gobj_free(); - -static char* -get_cstring(str) - VALUE str; -{ - if (NIL_P(str)) return NULL; - Check_Type(str, T_STRING); - return RSTRING(str)->ptr; -} - -static GtkObject* -get_gobject(obj) - VALUE obj; -{ - struct RData *data; - GtkObject *gtkp; - - if (NIL_P(obj)) return NULL; - - Check_Type(obj, T_OBJECT); - data = RDATA(rb_ivar_get(obj, id_gtkdata)); - if (NIL_P(data) || data->dfree != gobj_free) { - TypeError("not a Gtk object"); - } - Data_Get_Struct(data, GtkObject, gtkp); - if (!GTK_IS_OBJECT(gtkp)) { - TypeError("not a GtkObject"); - } - - return gtkp; -} - -static GtkWidget* -get_widget(obj) - VALUE obj; -{ - GtkObject *data = get_gobject(obj); - - return GTK_WIDGET(data); -} - -static VALUE -get_value_from_gobject(obj) - GtkObject *obj; -{ - return (VALUE)gtk_object_get_user_data(obj); -} - -static void -clear_gobject(obj) - VALUE obj; -{ - rb_ivar_set(obj, id_relatives, Qnil); -} - -static void -add_relative(obj, relative) - VALUE obj, relative; -{ - VALUE ary = rb_ivar_get(obj, id_relatives); - - if (TYPE(ary) != T_ARRAY) { - ary = ary_new(); - rb_ivar_set(obj, id_relatives, ary); - } - ary_push(ary, relative); -} - -static VALUE gtk_object_list; - -static void -gobj_free(obj) - GtkObject *obj; -{ - VALUE self = get_value_from_gobject(obj); - - if (GTK_OBJECT_NEED_DESTROY(obj)) { - gtk_object_destroy(obj); - } - rb_ivar_set(self, id_relatives, Qnil); -} - -static void -delete_gobject(obj) - GtkObject *obj; -{ - ary_delete(gtk_object_list, get_value_from_gobject(obj)); -} - -static VALUE -make_gobject(klass, gtkobj) - VALUE klass; - GtkObject *gtkobj; -{ - VALUE obj = obj_alloc(klass); - VALUE data; - - data = Data_Wrap_Struct(cData, 0, gobj_free, gtkobj); - gtk_object_set_user_data(gtkobj, (gpointer)obj); - - rb_ivar_set(obj, id_gtkdata, data); - gtk_signal_connect(gtkobj, "destroy", (GtkSignalFunc)delete_gobject, 0); - ary_push(gtk_object_list, obj); - return obj; -} - -static VALUE -make_widget(klass, widget) - VALUE klass; - GtkWidget *widget; -{ - return make_gobject(klass, GTK_OBJECT(widget)); -} - -static void -free_gstyle(style) - GtkStyle *style; -{ - gtk_style_unref(style); -} - -static VALUE -make_gstyle(style) - GtkStyle *style; -{ - gtk_style_ref(style); - return Data_Wrap_Struct(gStyle, 0, free_gstyle, style); -} - -static GtkStyle* -get_gstyle(style) - VALUE style; -{ - GtkStyle *gstyle; - - if (NIL_P(style)) return NULL; - if (!obj_is_instance_of(style, gStyle)) { - TypeError("not a GtkStyle"); - } - Data_Get_Struct(style, GtkStyle, gstyle); - - return gstyle; -} - -static void -free_gaccel(tbl) - GtkAcceleratorTable *tbl; -{ - gtk_accelerator_table_unref(tbl); -} - -static VALUE -make_gtkacceltbl(tbl) - GtkAcceleratorTable *tbl; -{ - gtk_accelerator_table_ref(tbl); - return Data_Wrap_Struct(gAcceleratorTable, 0, free_gaccel, tbl); -} - -static GtkAcceleratorTable* -get_gtkacceltbl(value) - VALUE value; -{ - GtkAcceleratorTable *tbl; - - if (NIL_P(value)) return NULL; - - if (!obj_is_instance_of(value, gAcceleratorTable)) { - TypeError("not an AcceleratorTable"); - } - Data_Get_Struct(value, GtkAcceleratorTable, tbl); - - return tbl; -} - -static VALUE -make_gtkprevinfo(info) - GtkPreviewInfo *info; -{ - return Data_Wrap_Struct(gAcceleratorTable, 0, 0, info); -} - -static GtkPreviewInfo* -get_gtkprevinfo(value) - VALUE value; -{ - GtkPreviewInfo *info; - - if (NIL_P(value)) return NULL; - - if (!obj_is_instance_of(value, gPreviewInfo)) { - TypeError("not a PreviewInfo"); - } - Data_Get_Struct(value, GtkPreviewInfo, info); - - return info; -} - -static void -exec_callback(widget, data, nparams, params) - GtkWidget *widget; - VALUE data; - int nparams; - GtkType *params; -{ - VALUE self = get_value_from_gobject(GTK_OBJECT(widget)); - VALUE proc = RARRAY(data)->ptr[0]; - VALUE event = RARRAY(data)->ptr[1]; - ID id = NUM2INT(event); - - if (NIL_P(proc) && rb_respond_to(self, id)) { - rb_funcall(self, id, 3, self, - INT2FIX(nparams), INT2NUM((INT)params)); - } - else { - rb_funcall(proc, id_call, 1, self); - } -} - -static void -free_ttips(tips) - GtkTooltips *tips; -{ - gtk_tooltips_unref(tips); -} - -static VALUE -make_ttips(klass, tips) - VALUE klass; - GtkTooltips *tips; -{ - gtk_tooltips_ref(tips); - return Data_Wrap_Struct(klass, 0, free_ttips, tips); -} - -static GtkTooltips* -get_ttips(tips) - VALUE tips; -{ - GtkTooltips *gtips; - - if (NIL_P(tips)) return NULL; - - if (!obj_is_instance_of(tips, gTooltips)) { - TypeError("not a GtkTooltips"); - } - Data_Get_Struct(tips, GtkTooltips, gtips); - - return gtips; -} - -static void -free_gdkfont(font) - GdkFont *font; -{ - gdk_font_unref(font); -} - -static VALUE -make_gdkfont(font) - GdkFont *font; -{ - gdk_font_ref(font); - return Data_Wrap_Struct(gdkFont, 0, free_gdkfont, font); -} - -static GdkFont* -get_gdkfont(font) - VALUE font; -{ - GdkFont *gfont; - - if (NIL_P(font)) return NULL; - - if (!obj_is_instance_of(font, gdkFont)) { - TypeError("not a GdkFont"); - } - Data_Get_Struct(font, GdkFont, gfont); - - return gfont; -} - -static VALUE -gdkfnt_equal(fn1, fn2) - VALUE fn1, fn2; -{ - if (gdk_font_equal(get_gdkfont(fn1), get_gdkfont(fn2))) - return TRUE; - return FALSE; -} - -static void -free_tobj(obj) - gpointer obj; -{ - free(obj); -} - -static VALUE -make_tobj(obj, klass, size) - gpointer obj; - VALUE klass; - int size; -{ - gpointer copy; - VALUE data; - - copy = xmalloc(size); - memcpy(copy, obj, size); - data = Data_Wrap_Struct(klass, 0, free_tobj, copy); - - return data; -} - -static gpointer -get_tobj(obj, klass) - VALUE obj, klass; -{ - void *ptr; - - if (NIL_P(obj)) return NULL; - - if (!obj_is_instance_of(obj, klass)) { - TypeError("not a %s", rb_class2name(klass)); - } - Data_Get_Struct(obj, void, ptr); - - return ptr; -} - -#define make_gdkcolor(c) make_tobj(c, gdkColor, sizeof(GdkColor)) -#define get_gdkcolor(c) ((GdkColor*)get_tobj(c, gdkColor)) - -#define make_gdkrect(c) make_tobj(c, gdkRectangle, sizeof(GdkRectangle)) -#define get_gdkrect(c) ((GdkRectangle*)get_tobj(c, gdkRectangle)) - -#define make_gdksegment(c) make_tobj(c, gdkSegment, sizeof(GdkSegment)) -#define get_gdksegment(c) ((GdkSegment*)get_tobj(c, gdkSegment)) - -#define make_gdkwinattr(c) make_tobj(c, gdkWindowAttr, sizeof(GdkWindowAttr)) -#define get_gdkwinattr(c) ((GdkWindowAttr*)get_tobj(c, gdkWindowAttr)) - -#define make_gdkwinattr(c) make_tobj(c, gdkWindowAttr, sizeof(GdkWindowAttr)) -#define get_gdkwinattr(c) ((GdkWindowAttr*)get_tobj(c, gdkWindowAttr)) - -#define make_gallocation(c) make_tobj(c, gAllocation, sizeof(GtkAllocation)) -#define get_gallocation(c) ((GtkAllocation*)get_tobj(c, gAllocation)) - -#define make_grequisiton(c) make_tobj(c, gRequisiton, sizeof(GtkRequisition)) -#define get_grequisiton(c) ((GtkRequisition*)get_tobj(c, gRequisiton)) - -#define make_gdkrectangle(r) make_tobj(r, gdkRectangle, sizeof(GdkRectangle)) -#define get_gdkrectangle(r) ((GdkRectangle*)get_tobj(r, gdkRectangle)) - -static void -free_gdkcmap(cmap) - GdkColormap *cmap; -{ - gdk_colormap_unref(cmap); -} - -static VALUE -make_gdkcmap(cmap) - GdkColormap *cmap; -{ - gdk_colormap_ref(cmap); - return Data_Wrap_Struct(gdkColormap, 0, free_gdkcmap, cmap); -} - -static GdkColormap* -get_gdkcmap(cmap) - VALUE cmap; -{ - GdkColormap *gcmap; - - if (NIL_P(cmap)) return NULL; - - if (!obj_is_kind_of(cmap, gdkColormap)) { - TypeError("not a GdkColormap"); - } - Data_Get_Struct(cmap, GdkColormap, gcmap); - - return gcmap; -} - -static VALUE -make_gdkvisual(visual) - GdkVisual *visual; -{ - return Data_Wrap_Struct(gdkVisual, 0, 0, visual); -} - -static GdkVisual* -get_gdkvisual(visual) - VALUE visual; -{ - GdkVisual *gvisual; - - if (NIL_P(visual)) return NULL; - - if (!obj_is_kind_of(visual, gdkVisual)) { - TypeError("not a GdkVisual"); - } - Data_Get_Struct(visual, GdkVisual, gvisual); - - return gvisual; -} - -static void -free_gdkwindow(window) - GdkWindow *window; -{ - gdk_window_unref(window); -} - -static VALUE -make_gdkwindow(window) - GdkWindow *window; -{ - gdk_window_ref(window); - return Data_Wrap_Struct(gdkWindow, 0, free_gdkwindow, window); -} - -static GdkWindow* -get_gdkwindow(window) - VALUE window; -{ - GdkWindow *gwindow; - - if (NIL_P(window)) return NULL; - - if (!obj_is_kind_of(window, gdkWindow)) { - TypeError("not a GdkWindow"); - } - Data_Get_Struct(window, GdkWindow, gwindow); - - return gwindow; -} - -static void -free_gdkpixmap(pixmap) - GdkPixmap *pixmap; -{ - gdk_pixmap_unref(pixmap); -} - -static VALUE -make_gdkpixmap(klass, pixmap) - VALUE klass; - GdkPixmap *pixmap; -{ - gdk_pixmap_ref(pixmap); - return Data_Wrap_Struct(klass, 0, free_gdkpixmap, pixmap); -} - -static GdkPixmap* -get_gdkpixmap(pixmap) - VALUE pixmap; -{ - GdkPixmap *gpixmap; - - if (NIL_P(pixmap)) return NULL; - - if (!obj_is_kind_of(pixmap, gdkPixmap)) { - TypeError("not a GdkPixmap"); - } - Data_Get_Struct(pixmap, GdkPixmap, gpixmap); - - return gpixmap; -} - -static VALUE -gdkpmap_s_new(self, win, w, h, depth) - VALUE self, win, w, h, depth; -{ - GdkPixmap *new; - GdkWindow *window = get_gdkwindow(win); - - new = gdk_pixmap_new(window, NUM2INT(w), NUM2INT(h), NUM2INT(depth)); - return make_gdkpixmap(self, new); -} - -static VALUE -gdkpmap_create_from_data(self, win, data, w, h, depth, fg, bg) - VALUE self, win, data, w, h, depth, fg, bg; -{ - GdkPixmap *new; - GdkWindow *window = get_gdkwindow(win); - - Check_Type(data, T_STRING); - new = gdk_pixmap_create_from_data(window, - RSTRING(data)->ptr, - NUM2INT(w), NUM2INT(h), - NUM2INT(depth), - get_gdkcolor(fg), - get_gdkcolor(bg)); - return make_gdkpixmap(self, new); -} - -static VALUE -gdkpmap_create_from_xpm(self, win, tcolor, fname) - VALUE self, win, tcolor, fname; -{ - GdkPixmap *new; - GdkBitmap *mask; - GdkWindow *window = get_gdkwindow(win); - - Check_Type(fname, T_STRING); - new = gdk_pixmap_create_from_xpm(window, &mask, - get_gdkcolor(tcolor), - RSTRING(fname)->ptr); - if (!new) { - ArgError("Pixmap not created from %s", RSTRING(fname)->ptr); - } - return assoc_new(make_gdkpixmap(self, new), - make_gdkpixmap(gdkBitmap, mask)); -} - -static VALUE -gdkpmap_create_from_xpm_d(self, win, tcolor, data) - VALUE self, win, tcolor, data; -{ - GdkPixmap *new; - GdkBitmap *mask; - GdkWindow *window = get_gdkwindow(win); - int i; - gchar **buf; - - Check_Type(data, T_ARRAY); - buf = ALLOCA_N(char*, RARRAY(data)->len); - for (i=0; ilen; i++) { - Check_Type(RARRAY(data)->ptr[i], T_STRING); - buf[i] = RSTRING(RARRAY(data)->ptr[i])->ptr; - } - - new = gdk_pixmap_create_from_xpm_d(window, &mask, - get_gdkcolor(tcolor), - buf); - - return assoc_new(make_gdkpixmap(self, new), - make_gdkpixmap(gdkBitmap, mask)); -} - -static VALUE -gdkbmap_s_new(self, win, w, h) - VALUE self, win, w, h; -{ - GdkPixmap *new; - GdkWindow *window = get_gdkwindow(win); - - new = gdk_pixmap_new(window, NUM2INT(w), NUM2INT(h), 1); - return make_gdkpixmap(self, new); -} - -static VALUE -gdkbmap_create_from_data(self, win, data, w, h) - VALUE self, win, data, w, h; -{ - GdkBitmap *new; - GdkWindow *window = get_gdkwindow(win); - - Check_Type(data, T_STRING); - new = gdk_bitmap_create_from_data(window, - RSTRING(data)->ptr, - NUM2INT(w), NUM2INT(h)); - return make_gdkpixmap(self, (GdkPixmap*)new); -} - -static void -free_gdkimage(image) - GdkImage *image; -{ - gdk_image_destroy(image); -} - -static VALUE -make_gdkimage(image) - GdkImage *image; -{ - return Data_Wrap_Struct(gdkImage, 0, free_gdkimage, image); -} - -static GdkImage* -get_gdkimage(image) - VALUE image; -{ - GdkImage *gimage; - - if (NIL_P(image)) return NULL; - - if (!obj_is_instance_of(image, gdkImage)) { - TypeError("not a GdkImage"); - } - Data_Get_Struct(image, GdkImage, gimage); - - return gimage; -} - -static void -free_gdkevent(event) - GdkEvent *event; -{ - gdk_event_free(event); -} - -static VALUE -make_gdkevent(event) - GdkEvent *event; -{ - event = gdk_event_copy(event); - return Data_Wrap_Struct(gdkEvent, 0, free_gdkevent, event); -} - -static GdkEvent* -get_gdkevent(event) - VALUE event; -{ - GdkEvent *gevent; - - if (NIL_P(event)) return NULL; - - if (!obj_is_instance_of(event, gdkEvent)) { - TypeError("not a GdkEvent"); - } - Data_Get_Struct(event, GdkEvent, gevent); - - return gevent; -} - -static VALUE -glist2ary(list) - GList *list; -{ - VALUE ary = ary_new(); - - while (list) { - ary_push(ary, get_value_from_gobject(GTK_OBJECT(list->data))); - list = list->next; - } - - return ary; -} - -static GList* -ary2glist(ary) - VALUE ary; -{ - int i; - GList *glist = NULL; - - Check_Type(ary, T_ARRAY); - for (i=0; ilen; i++) { - glist = g_list_prepend(glist,get_widget(RARRAY(ary)->ptr[i])); - } - - return g_list_reverse(glist); -} - -static GSList* -ary2gslist(ary) - VALUE ary; -{ - int i; - GSList *glist = NULL; - - if (NIL_P(ary)) return NULL; - Check_Type(ary, T_ARRAY); - for (i=0; ilen; i++) { - glist = g_slist_append(glist,get_widget(RARRAY(ary)->ptr[i])); - } - - return glist; -} - -static VALUE -gslist2ary(list) - GSList *list; -{ - VALUE ary = ary_new(); - - while (list) { - ary_push(ary, get_value_from_gobject(GTK_OBJECT(list->data))); - list = list->next; - } - - return ary; -} - -static VALUE -gobj_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - Fail("can't instantiate class %s", rb_class2name(self)); -} - -static VALUE -gobj_smethod_added(self, id) - VALUE self, id; -{ - GtkObject *obj = get_gobject(self); - char *name = rb_id2name(NUM2INT(id)); - - - if (gtk_signal_lookup(name, GTK_OBJECT_TYPE(obj))) { - VALUE handler = assoc_new(Qnil, id); - - add_relative(self, handler); - gtk_signal_connect_interp(obj, name, - exec_callback, (gpointer)handler, - NULL, 0); - } - return Qnil; -} - -static VALUE -gobj_destroy(self) - VALUE self; -{ - printf("a\n"); - gtk_object_destroy(get_gobject(self)); - printf("b\n"); - clear_gobject(self); - return Qnil; -} - -static VALUE -gobj_set_flags(self, flags) - VALUE self, flags; -{ - GtkObject *object = get_gobject(self); - GTK_OBJECT_SET_FLAGS(object, NUM2INT(flags)); - return self; -} - -static VALUE -gobj_unset_flags(self, flags) - VALUE self, flags; -{ - GtkObject *object = get_gobject(self); - GTK_OBJECT_UNSET_FLAGS(object, NUM2INT(flags)); - return self; -} - -static VALUE -gobj_sig_connect(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE sig, handler; - GtkWidget *widget = get_widget(self); - ID id = 0; - int n; - - rb_scan_args(argc, argv, "11", &sig, &handler); - Check_Type(sig, T_STRING); - if (NIL_P(handler) && iterator_p()) { - handler = f_lambda(); - id = rb_intern(RSTRING(sig)->ptr); - } - handler = assoc_new(handler, INT2NUM(id)); - add_relative(self, handler); - n = gtk_signal_connect_interp(GTK_OBJECT(widget), RSTRING(sig)->ptr, - exec_callback, (gpointer)handler, - NULL, 0); - - return INT2FIX(n); -} - -static VALUE -gobj_sig_connect_after(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE sig, handler; - GtkWidget *widget = get_widget(self); - ID id = 0; - int n; - - rb_scan_args(argc, argv, "11", &sig, &handler); - Check_Type(sig, T_STRING); - if (NIL_P(handler) && iterator_p()) { - handler = f_lambda(); - id = rb_intern(RSTRING(sig)->ptr); - } - add_relative(self, handler); - n = gtk_signal_connect_interp(GTK_OBJECT(widget), RSTRING(sig)->ptr, - exec_callback, (gpointer)handler, - NULL, 1); - - return INT2FIX(n); -} - -static VALUE -cont_bwidth(self, width) - VALUE self, width; -{ - GtkWidget *widget = get_widget(self); - gtk_container_border_width(GTK_CONTAINER(widget), NUM2INT(width)); - return self; -} - -static VALUE -cont_add(self, other) - VALUE self, other; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_add(GTK_CONTAINER(widget), get_widget(other)); - return self; -} - -static VALUE -cont_disable_resize(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_disable_resize(GTK_CONTAINER(widget)); - return self; -} - -static VALUE -cont_enable_resize(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_enable_resize(GTK_CONTAINER(widget)); - return self; -} - -static VALUE -cont_block_resize(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_block_resize(GTK_CONTAINER(widget)); - return self; -} - -static VALUE -cont_unblock_resize(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_unblock_resize(GTK_CONTAINER(widget)); - return self; -} - -static VALUE -cont_need_resize(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_need_resize(GTK_CONTAINER(widget)); - return self; -} - -static VALUE -cont_foreach(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE callback; - GtkWidget *widget = get_widget(self); - - rb_scan_args(argc, argv, "01", &callback); - if (NIL_P(callback)) { - callback = f_lambda(); - } - gtk_container_foreach(GTK_CONTAINER(widget), - exec_callback, (gpointer)callback); - return self; -} - -static void -yield_callback(widget) - GtkWidget *widget; -{ - rb_yield(get_value_from_gobject(GTK_OBJECT(widget))); -} - -static VALUE -cont_each(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_foreach(GTK_CONTAINER(widget), - yield_callback, 0); - return self; -} - -static VALUE -cont_focus(self, direction) - VALUE self, direction; -{ - GtkWidget *widget = get_widget(self); - - gtk_container_focus(GTK_CONTAINER(widget), - (GtkDirectionType)NUM2INT(direction)); - return self; -} - -static void -cont_children_callback(widget, data) - GtkWidget *widget; - gpointer data; -{ - VALUE ary = (VALUE)data; - - ary_push(ary, get_value_from_gobject(GTK_OBJECT(widget))); -} - -static VALUE -cont_children(self, direction) - VALUE self, direction; -{ - GtkWidget *widget = get_widget(self); - VALUE ary = ary_new(); - - gtk_container_foreach(GTK_CONTAINER(widget), - cont_children_callback, - (gpointer)ary); - return ary; -} - -static VALUE -align_s_new(self, xalign, yalign, xscale, yscale) - VALUE self, xalign, yalign, xscale, yscale; -{ - return make_widget(self, gtk_alignment_new(NUM2DBL(xalign), - NUM2DBL(yalign), - NUM2DBL(xscale), - NUM2DBL(yscale))); -} - -static VALUE -align_set(self, xalign, yalign, xscale, yscale) - VALUE self, xalign, yalign, xscale, yscale; -{ - GtkWidget *widget = get_widget(self); - - gtk_alignment_set(GTK_ALIGNMENT(widget), - NUM2DBL(xalign), NUM2DBL(yalign), - NUM2DBL(xscale), NUM2DBL(yscale)); - return self; -} - -static VALUE -misc_set_align(self, xalign, yalign) - VALUE self, xalign, yalign; -{ - GtkWidget *widget = get_widget(self); - - gtk_misc_set_alignment(GTK_MISC(widget), - NUM2DBL(xalign), NUM2DBL(yalign)); - return self; -} - -static VALUE -misc_set_padding(self, xpad, ypad) - VALUE self, xpad, ypad; -{ - GtkWidget *widget = get_widget(self); - - gtk_misc_set_padding(GTK_MISC(widget), - NUM2DBL(xpad), NUM2DBL(ypad)); - return self; -} - -static VALUE -arrow_s_new(self, arrow_t, shadow_t) - VALUE self, arrow_t, shadow_t; -{ - return make_widget(self, gtk_arrow_new((GtkArrowType)NUM2INT(arrow_t), - (GtkShadowType)NUM2INT(shadow_t))); -} - -static VALUE -arrow_set(self, arrow_t, shadow_t) - VALUE self, arrow_t, shadow_t; -{ - GtkWidget *widget = get_widget(self); - - gtk_arrow_set(GTK_ARROW(widget), - (GtkArrowType)NUM2INT(arrow_t), - (GtkShadowType)NUM2INT(shadow_t)); - return self; -} - -static VALUE -frame_s_new(self, label) - VALUE self, label; -{ - return make_widget(self, gtk_frame_new(get_cstring(label))); -} - -static VALUE -frame_set_label(self, label) - VALUE self, label; -{ - GtkWidget *widget = get_widget(self); - - gtk_frame_set_label(GTK_FRAME(widget), get_cstring(label)); - return self; -} - -static VALUE -frame_set_label_align(self, xalign, yalign) - VALUE self, xalign, yalign; -{ - GtkWidget *widget = get_widget(self); - - gtk_frame_set_label_align(GTK_FRAME(widget), - NUM2DBL(xalign), - NUM2DBL(yalign)); - - return self; -} - -static VALUE -frame_set_shadow_type(self, type) - VALUE self, type; -{ - GtkWidget *widget = get_widget(self); - - gtk_frame_set_shadow_type(GTK_FRAME(widget), - (GtkShadowType)NUM2INT(type)); - return self; -} - -static VALUE -aframe_s_new(self, label, xalign, yalign, ratio, obey_child) - VALUE self, label, xalign, yalign, ratio, obey_child; -{ - return make_widget(self, gtk_aspect_frame_new(get_cstring(label), - NUM2DBL(xalign), - NUM2DBL(yalign), - NUM2DBL(ratio), - RTEST(obey_child))); -} - -static VALUE -aframe_set(self, xalign, yalign, ratio, obey_child) - VALUE self, xalign, yalign, ratio, obey_child; -{ - GtkWidget *widget = get_widget(self); - - gtk_aspect_frame_set(GTK_ASPECT_FRAME(widget), - NUM2DBL(xalign), NUM2DBL(yalign), - NUM2DBL(ratio), RTEST(obey_child)); - return self; -} - -static VALUE -adj_s_new(self, value, lower, upper, step_inc, page_inc, page_size) - VALUE self, value, lower, upper, step_inc, page_inc, page_size; -{ - return make_widget(self, gtk_adjustment_new(NUM2DBL(value), - NUM2DBL(lower), - NUM2DBL(upper), - NUM2DBL(step_inc), - NUM2DBL(page_inc), - NUM2DBL(page_size))); -} - -static VALUE -widget_destroy(self) - VALUE self; -{ - gtk_widget_destroy(get_widget(self)); - clear_gobject(self); - - return Qnil; -} - -static VALUE -widget_show(self) - VALUE self; -{ - gtk_widget_show(get_widget(self)); - return self; -} - -static VALUE -widget_show_all(self) - VALUE self; -{ - gtk_widget_show_all(get_widget(self)); - return self; -} - -static VALUE -widget_hide(self) - VALUE self; -{ - gtk_widget_hide(get_widget(self)); - return self; -} - -static VALUE -widget_hide_all(self) - VALUE self; -{ - gtk_widget_hide_all(get_widget(self)); - return self; -} - -static VALUE -widget_map(self) - VALUE self; -{ - gtk_widget_map(get_widget(self)); - return self; -} - -static VALUE -widget_unmap(self) - VALUE self; -{ - gtk_widget_unmap(get_widget(self)); - return self; -} - -static VALUE -widget_realize(self) - VALUE self; -{ - gtk_widget_realize(get_widget(self)); - return self; -} - -static VALUE -widget_unrealize(self) - VALUE self; -{ - gtk_widget_unrealize(get_widget(self)); - return self; -} - -static VALUE -widget_queue_draw(self) - VALUE self; -{ - gtk_widget_queue_draw(get_widget(self)); - return self; -} - -static VALUE -widget_queue_resize(self) - VALUE self; -{ - gtk_widget_queue_resize(get_widget(self)); - return self; -} - -static VALUE -widget_draw(self, rect) - VALUE self, rect; -{ - gtk_widget_draw(get_widget(self), get_gdkrectangle(rect)); - return self; -} - -static VALUE -widget_draw_focus(self) - VALUE self; -{ - gtk_widget_draw_focus(get_widget(self)); - return self; -} - -static VALUE -widget_draw_default(self) - VALUE self; -{ - gtk_widget_draw_default(get_widget(self)); - return self; -} - -static VALUE -widget_draw_children(self) - VALUE self; -{ - gtk_widget_draw_children(get_widget(self)); - return self; -} - -static VALUE -widget_size_request(self, req) - VALUE self, req; -{ - gtk_widget_size_request(get_widget(self), get_grequisiton(req)); - return self; -} - -static VALUE -widget_size_allocate(self, alloc) - VALUE self, alloc; -{ - gtk_widget_size_allocate(get_widget(self), get_gallocation(alloc)); - return self; -} - -static VALUE -widget_inst_accel(self, accel, sig, key, mod) - VALUE self, accel, sig, key, mod; -{ - gtk_widget_install_accelerator(get_widget(self), - get_gtkacceltbl(accel), - get_cstring(sig), - NUM2INT(key), - (guint8)NUM2INT(mod)); - return self; -} - -static VALUE -widget_rm_accel(self, accel, sig) - VALUE self, accel, sig; -{ - gtk_widget_remove_accelerator(get_widget(self), - get_gtkacceltbl(accel), - get_cstring(sig)); - return self; -} - -static VALUE -widget_event(self, event) - VALUE self, event; -{ - int n = gtk_widget_event(get_widget(self), get_gdkevent(event)); - return NUM2INT(n); -} - -static VALUE -widget_activate(self) - VALUE self; -{ - gtk_widget_activate(get_widget(self)); - return self; -} - -static VALUE -widget_grab_focus(self) - VALUE self; -{ - gtk_widget_grab_focus(get_widget(self)); - return self; -} - -static VALUE -widget_grab_default(self) - VALUE self; -{ - gtk_widget_grab_default(get_widget(self)); - return self; -} - -static VALUE -widget_restore_state(self) - VALUE self; -{ - gtk_widget_restore_state(get_widget(self)); - return self; -} - -static VALUE -widget_visible(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - if (GTK_WIDGET_VISIBLE(widget)) - return TRUE; - return FALSE; -} - -static VALUE -widget_reparent(self, parent) - VALUE self, parent; -{ - gtk_widget_reparent(get_widget(self), get_widget(parent)); - return self; -} - -static VALUE -widget_popup(self, x, y) - VALUE self, x, y; -{ - gtk_widget_popup(get_widget(self), NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -widget_intersect(self, area, intersect) - VALUE self, area, intersect; -{ - int n = gtk_widget_intersect(get_widget(self), - get_gdkrectangle(area), - get_gdkrectangle(intersect)); - return NUM2INT(n); -} - -static VALUE -widget_basic(self) - VALUE self; -{ - int n = gtk_widget_basic(get_widget(self)); - return NUM2INT(n); -} - -static VALUE -widget_set_state(self, state) - VALUE self, state; -{ - gtk_widget_set_state(get_widget(self), (GtkStateType)NUM2INT(state)); - return self; -} - -static VALUE -widget_set_style(self, style) - VALUE self, style; -{ - gtk_widget_set_style(get_widget(self), - get_gstyle(style)); - return self; -} - -static VALUE -widget_set_parent(self, parent) - VALUE self, parent; -{ - gtk_widget_set_parent(get_widget(self), get_widget(parent)); - return self; -} - -static VALUE -widget_set_name(self, name) - VALUE self, name; -{ - gtk_widget_set_name(get_widget(self), get_cstring(name)); - return self; -} - -static VALUE -widget_get_name(self) - VALUE self; -{ - char *name = gtk_widget_get_name(get_widget(self)); - - return str_new2(name); -} - -static VALUE -widget_set_sensitive(self, sensitive) - VALUE self, sensitive; -{ - gtk_widget_set_sensitive(get_widget(self), RTEST(sensitive)); - return self; -} - -static VALUE -widget_set_uposition(self, x, y) - VALUE self, x, y; -{ - gtk_widget_set_uposition(get_widget(self), NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -widget_set_usize(self, w, h) - VALUE self, w, h; -{ - gtk_widget_set_usize(get_widget(self), NUM2INT(w), NUM2INT(h)); - return self; -} - -static VALUE -widget_set_events(self, events) - VALUE self, events; -{ - gtk_widget_set_events(get_widget(self), NUM2INT(events)); - return self; -} - -static VALUE -widget_set_eevents(self, mode) - VALUE self, mode; -{ - gtk_widget_set_extension_events(get_widget(self), - (GdkExtensionMode)NUM2INT(mode)); - return self; -} - -static VALUE -widget_unparent(self) - VALUE self; -{ - gtk_widget_unparent(get_widget(self)); - return self; -} - -static VALUE -widget_window(self) - VALUE self; -{ - return make_gdkwindow(get_widget(self)->window); -} - -static VALUE -widget_get_toplevel(self) - VALUE self; -{ - return get_value_from_gobject(gtk_widget_get_toplevel(get_widget(self))); -} - -static VALUE -widget_get_ancestor(self, type) - VALUE self, type; -{ - GtkWidget *widget = get_widget(self); -#if 0 - if (obj_is_kind_of(type, cClass)) { - } -#endif - widget = gtk_widget_get_ancestor(widget, NUM2INT(type)); - - return get_value_from_gobject(widget); -} - -static VALUE -widget_get_colormap(self) - VALUE self; -{ - GdkColormap *cmap = gtk_widget_get_colormap(get_widget(self)); - - return make_gdkcmap(cmap); -} - -static VALUE -widget_get_visual(self) - VALUE self; -{ - GdkVisual *v = gtk_widget_get_visual(get_widget(self)); - - return make_gdkvisual(v); -} - -static VALUE -widget_get_style(self) - VALUE self; -{ - GtkStyle *s = gtk_widget_get_style(get_widget(self)); - - return make_gstyle(s); -} - -static VALUE -widget_get_pointer(self) - VALUE self; -{ - int x, y; - - gtk_widget_get_pointer(get_widget(self), &x, &y); - return assoc_new(INT2FIX(x), INT2FIX(y)); -} - -static VALUE -widget_is_ancestor(self, ancestor) - VALUE self, ancestor; -{ - if (gtk_widget_is_ancestor(get_widget(self), get_widget(ancestor))) { - return TRUE; - } - return FALSE; -} - -static VALUE -widget_is_child(self, child) - VALUE self, child; -{ - if (gtk_widget_is_child(get_widget(self), get_widget(child))) { - return TRUE; - } - return FALSE; -} - -static VALUE -widget_get_events(self) - VALUE self; -{ - int n = gtk_widget_get_events(get_widget(self)); - return NUM2INT(n); -} - -static VALUE -widget_get_eevents(self) - VALUE self; -{ - GdkExtensionMode m; - m = gtk_widget_get_extension_events(get_widget(self)); - return NUM2INT((int)m); -} - -static VALUE -widget_push_cmap(self, cmap) - VALUE self, cmap; -{ - gtk_widget_push_colormap(get_gdkcmap(cmap)); - return Qnil; -} - -static VALUE -widget_push_visual(self, visual) - VALUE self, visual; -{ - gtk_widget_push_visual(get_gdkvisual(visual)); - return make_gdkcmap(visual); -} - -static VALUE -widget_push_style(self, style) - VALUE self, style; -{ - gtk_widget_push_style(get_gstyle(style)); - return Qnil; -} - -static VALUE -widget_pop_cmap(self, cmap) - VALUE self, cmap; -{ - gtk_widget_pop_colormap(); - return Qnil; -} - -static VALUE -widget_pop_visual(self, visual) - VALUE self, visual; -{ - gtk_widget_pop_visual(); - return Qnil; -} - -static VALUE -widget_pop_style(self, style) - VALUE self, style; -{ - gtk_widget_pop_style(); - return Qnil; -} - -static VALUE -widget_set_default_cmap(self, cmap) - VALUE self, cmap; -{ - gtk_widget_set_default_colormap(get_gdkcmap(cmap)); - return Qnil; -} - -static VALUE -widget_set_default_visual(self, visual) - VALUE self, visual; -{ - gtk_widget_set_default_visual(get_gdkvisual(visual)); - return make_gdkcmap(visual); -} - -static VALUE -widget_set_default_style(self, style) - VALUE self, style; -{ - gtk_widget_set_default_style(get_gstyle(style)); - return Qnil; -} - -static VALUE -widget_get_default_cmap(self) - VALUE self; -{ - GdkColormap *cmap = gtk_widget_get_default_colormap(); - - return make_gdkcmap(cmap); -} - -static VALUE -widget_get_default_visual(self) - VALUE self; -{ - GdkVisual *v = gtk_widget_get_default_visual(); - - return make_gdkvisual(v); -} - -static VALUE -widget_get_default_style(self) - VALUE self; -{ - GtkStyle *s = gtk_widget_get_default_style(); - - return make_gstyle(s); -} - -static VALUE -widget_propagate_default_style(self) - VALUE self; -{ - gtk_widget_propagate_default_style(); - return Qnil; -} - -static VALUE -bbox_get_child_size_default(self) - VALUE self; -{ - int min_width, max_width; - - gtk_button_box_get_child_size_default(&min_width, &max_width); - - return assoc_new(INT2FIX(min_width), INT2FIX(max_width)); -} - -static VALUE -bbox_get_child_ipadding_default(self) - VALUE self; -{ - int ipad_x, ipad_y; - - gtk_button_box_get_child_ipadding_default(&ipad_x, &ipad_y); - return assoc_new(INT2FIX(ipad_x), INT2FIX(ipad_y)); -} - -static VALUE -bbox_set_child_size_default(self, min_width, max_width) - VALUE self, min_width, max_width; -{ - gtk_button_box_set_child_size_default(NUM2INT(min_width), - NUM2INT(max_width)); - return Qnil; -} - -static VALUE -bbox_set_child_ipadding_default(self, ipad_x, ipad_y) - VALUE self, ipad_x, ipad_y; -{ - gtk_button_box_set_child_ipadding_default(NUM2INT(ipad_x), - NUM2INT(ipad_y)); - return Qnil; -} - -static VALUE -bbox_get_spacing(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int n = gtk_button_box_get_spacing(GTK_BUTTON_BOX(widget)); - - return INT2FIX(n); -} - -static VALUE -bbox_get_layout(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int n = gtk_button_box_get_layout(GTK_BUTTON_BOX(widget)); - - return INT2FIX(n); -} - -static VALUE -bbox_get_child_size(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int min_width, max_width; - - gtk_button_box_get_child_size(GTK_BUTTON_BOX(widget), - &min_width, &max_width); - return assoc_new(INT2FIX(min_width), INT2FIX(max_width)); -} - -static VALUE -bbox_get_child_ipadding(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int ipad_x, ipad_y; - - gtk_button_box_get_child_ipadding(GTK_BUTTON_BOX(widget), - &ipad_x, &ipad_y); - return assoc_new(INT2FIX(ipad_x), INT2FIX(ipad_y)); -} - -static VALUE -bbox_set_spacing(self, spacing) - VALUE self, spacing; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_box_set_spacing(GTK_BUTTON_BOX(widget), - NUM2INT(spacing)); - return self; -} - -static VALUE -bbox_set_layout(self, layout) - VALUE self, layout; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_box_set_layout(GTK_BUTTON_BOX(widget), - NUM2INT(layout)); - return self; -} - -static VALUE -bbox_set_child_size(self, min_width, max_width) - VALUE self, min_width, max_width; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_box_set_child_size(GTK_BUTTON_BOX(widget), - NUM2INT(min_width), - NUM2INT(max_width)); - return self; -} - -static VALUE -bbox_set_child_ipadding(self, ipad_x, ipad_y) - VALUE self, ipad_x, ipad_y; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_box_set_child_ipadding(GTK_BUTTON_BOX(widget), - NUM2INT(ipad_x), - NUM2INT(ipad_y)); - return self; -} - -static VALUE -clist_s_new(self, titles) - VALUE self, titles; -{ - char **buf; - int i, len; - - Check_Type(titles, T_ARRAY); - len = RARRAY(titles)->len; - buf = ALLOCA_N(char*, len); - for (i=0; iptr[i], T_STRING); - buf[i] = RSTRING(RARRAY(titles)->ptr[i])->ptr; - } - return make_widget(self, gtk_clist_new(len, buf)); -} - -static VALUE -clist_set_border(self, border) - VALUE self, border; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_border(GTK_CLIST(widget), (GtkShadowType)NUM2INT(border)); - return self; -} - -static VALUE -clist_set_sel_mode(self, mode) - VALUE self, mode; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_selection_mode(GTK_CLIST(widget), - (GtkSelectionMode)NUM2INT(mode)); - return self; -} - -static VALUE -clist_set_policy(self, vpolicy, hpolicy) - VALUE self, vpolicy, hpolicy; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_policy(GTK_CLIST(widget), - (GtkPolicyType)NUM2INT(vpolicy), - (GtkPolicyType)NUM2INT(hpolicy)); - return self; -} - -static VALUE -clist_freeze(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_freeze(GTK_CLIST(widget)); - return self; -} - -static VALUE -clist_thaw(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_thaw(GTK_CLIST(widget)); - return self; -} - -static VALUE -clist_set_col_title(self, col, title) - VALUE self, col, title; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_column_title(GTK_CLIST(widget), - NUM2INT(col), - get_cstring(title)); - return self; -} - -static VALUE -clist_set_col_wigdet(self, col, win) - VALUE self, col, win; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_column_widget(GTK_CLIST(widget), - NUM2INT(col), - get_widget(win)); - return self; -} - -static VALUE -clist_set_col_just(self, col, just) - VALUE self, col, just; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_column_justification(GTK_CLIST(widget), - NUM2INT(col), - (GtkJustification)NUM2INT(just)); - return self; -} - -static VALUE -clist_set_col_width(self, col, width) - VALUE self, col, width; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_column_width(GTK_CLIST(widget), - NUM2INT(col), NUM2INT(width)); - return self; -} - -static VALUE -clist_set_row_height(self, height) - VALUE self, height; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_row_height(GTK_CLIST(widget), NUM2INT(height)); - return self; -} - -static VALUE -clist_moveto(self, row, col, row_align, col_align) - VALUE self, row, col, row_align, col_align; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_moveto(GTK_CLIST(widget), - NUM2INT(row), NUM2INT(col), - NUM2INT(row_align), NUM2INT(col_align)); - return self; -} - -static VALUE -clist_set_text(self, row, col, text) - VALUE self, row, col, text; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_text(GTK_CLIST(widget), - NUM2INT(row), NUM2INT(col), - get_cstring(text)); - return self; -} - -static VALUE -clist_set_pixmap(self, row, col, pixmap, mask) - VALUE self, row, col, pixmap, mask; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_pixmap(GTK_CLIST(widget), - NUM2INT(row), NUM2INT(col), - get_gdkpixmap(pixmap), - (GdkBitmap*)get_gdkpixmap(mask)); - return self; -} - -static VALUE -clist_set_pixtext(self, row, col, text, spacing, pixmap, mask) - VALUE self, row, col, text, spacing, pixmap, mask; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_pixtext(GTK_CLIST(widget), - NUM2INT(row), NUM2INT(col), - get_cstring(text), - NUM2INT(spacing), - get_gdkpixmap(pixmap), - (GdkBitmap*)get_gdkpixmap(mask)); - return self; -} - -static VALUE -clist_set_foreground(self, row, color) - VALUE self, row, color; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_foreground(GTK_CLIST(widget), - NUM2INT(row), get_gdkcolor(color)); - return self; -} - -static VALUE -clist_set_background(self, row, color) - VALUE self, row, color; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_background(GTK_CLIST(widget), - NUM2INT(row), get_gdkcolor(color)); - return self; -} - -static VALUE -clist_set_shift(self, row, col, verticle, horizontal) - VALUE self, row, col, verticle, horizontal; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_set_shift(GTK_CLIST(widget), - NUM2INT(row), NUM2INT(col), - NUM2INT(verticle), NUM2INT(horizontal)); - return self; -} - -static VALUE -clist_append(self, text) - VALUE self, text; -{ - GtkWidget *widget = get_widget(self); - char **buf; - int i, len; - - Check_Type(text, T_ARRAY); - len = GTK_CLIST(widget)->columns; - if (len > RARRAY(text)->len) { - ArgError("text too short"); - } - buf = ALLOCA_N(char*, len); - for (i=0; iptr[i], T_STRING); - buf[i] = RSTRING(RARRAY(text)->ptr[i])->ptr; - } - i = gtk_clist_append(GTK_CLIST(widget), buf); - return INT2FIX(i); -} - -static VALUE -clist_insert(self, row, text) - VALUE self, row, text; -{ - GtkWidget *widget = get_widget(self); - char **buf; - int i, len; - - Check_Type(text, T_ARRAY); - len = GTK_CLIST(widget)->columns; - if (len > RARRAY(text)->len) { - ArgError("text too short"); - } - buf = ALLOCA_N(char*, len); - for (i=0; iptr[i], T_STRING); - buf[i] = RSTRING(RARRAY(text)->ptr[i])->ptr; - } - gtk_clist_insert(GTK_CLIST(widget), NUM2INT(row), buf); - return self; -} - -static VALUE -clist_remove(self, row) - VALUE self, row; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_remove(GTK_CLIST(widget), NUM2INT(row)); - return self; -} - -static VALUE -clist_set_row_data(self, row, data) - VALUE self, row, data; -{ - GtkWidget *widget = get_widget(self); - - add_relative(self, data); - gtk_clist_set_row_data(GTK_CLIST(widget), NUM2INT(row), (gpointer)data); - return self; -} - -static VALUE -clist_get_row_data(self, row) - VALUE self, row; -{ - GtkWidget *widget = get_widget(self); - - return (VALUE)gtk_clist_get_row_data(GTK_CLIST(widget), NUM2INT(row)); -} - -static VALUE -clist_select_row(self, row, col) - VALUE self, row, col; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_select_row(GTK_CLIST(widget), NUM2INT(row), NUM2INT(col)); - return self; -} - -static VALUE -clist_unselect_row(self, row, col) - VALUE self, row, col; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_unselect_row(GTK_CLIST(widget), NUM2INT(row), NUM2INT(col)); - return self; -} - -static VALUE -clist_clear(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_clist_clear(GTK_CLIST(widget)); - return self; -} - -static VALUE -gwin_s_new(self, type) - VALUE self, type; -{ - return make_widget(self, gtk_window_new(NUM2INT(type))); -} - -static VALUE -gwin_set_policy(self, shrink, grow, auto_shrink) - VALUE self, shrink, grow, auto_shrink; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_set_policy(GTK_WINDOW(widget), - RTEST(shrink), RTEST(grow), RTEST(auto_shrink)); - return self; -} - -static VALUE -gwin_set_title(self, title) - VALUE self, title; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_set_title(GTK_WINDOW(widget), get_cstring(title)); - return self; -} - -static VALUE -gwin_position(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_position(GTK_WINDOW(widget), - (GtkWindowPosition)NUM2INT(pos)); - - return self; -} - -static VALUE -gwin_set_wmclass(self, wmclass1, wmclass2) - VALUE self, wmclass1, wmclass2; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_set_wmclass(GTK_WINDOW(widget), - get_cstring(wmclass1), - get_cstring(wmclass2)); - return self; -} - -static VALUE -gwin_set_focus(self, win) - VALUE self, win; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_set_focus(GTK_WINDOW(widget), get_widget(win)); - return self; -} - -static VALUE -gwin_set_default(self, win) - VALUE self, win; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_set_default(GTK_WINDOW(widget), get_widget(win)); - return self; -} - -static VALUE -gwin_add_accel(self, accel) - VALUE self, accel; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_add_accelerator_table(GTK_WINDOW(widget), - get_gtkacceltbl(accel)); - return self; -} - -static VALUE -gwin_rm_accel(self, accel) - VALUE self, accel; -{ - GtkWidget *widget = get_widget(self); - - gtk_window_remove_accelerator_table(GTK_WINDOW(widget), - get_gtkacceltbl(accel)); - return self; -} - -static VALUE -dialog_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_dialog_new()); -} - -static VALUE -fsel_s_new(self, title) - VALUE self, title; -{ - return make_widget(self, gtk_file_selection_new(get_cstring(title))); -} - -static VALUE -fsel_set_fname(self, fname) - VALUE self, fname; -{ - GtkWidget *widget = get_widget(self); - - Check_Type(fname, T_STRING); - gtk_file_selection_set_filename(GTK_FILE_SELECTION(widget), - RSTRING(fname)->ptr); - - return self; -} - -static VALUE -fsel_get_fname(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - gchar *fname; - - fname = gtk_file_selection_get_filename(GTK_FILE_SELECTION(widget)); - - return str_new2(fname); -} - -static VALUE -fsel_ok_button(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - VALUE b = rb_iv_get(self, "ok_button"); - - if (NIL_P(b)) { - GtkWidget *w = GTK_FILE_SELECTION(widget)->ok_button; - b = make_widget(gButton, w); - rb_iv_set(self, "ok_button", b); - } - - return b; -} - -static VALUE -fsel_cancel_button(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - VALUE b = rb_iv_get(self, "cancel_button"); - - if (NIL_P(b)) { - GtkWidget *w = GTK_FILE_SELECTION(widget)->cancel_button; - b = make_widget(gButton, w); - rb_iv_set(self, "cancel_button", b); - } - - return b; -} - -static VALUE -fsel_help_button(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - VALUE b = rb_iv_get(self, "help_button"); - - if (NIL_P(b)) { - GtkWidget *w = GTK_FILE_SELECTION(widget)->help_button; - b = make_widget(gButton, w); - rb_iv_set(self, "help_button", b); - } - - return b; -} - -static VALUE -label_s_new(self, label) - VALUE self, label; -{ - return make_widget(self, gtk_label_new(get_cstring(label))); -} - -static VALUE -list_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_list_new()); -} - -static VALUE -list_set_sel_mode(self, mode) - VALUE self, mode; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_set_selection_mode(GTK_LIST(widget), - (GtkSelectionMode)NUM2INT(mode)); - return self; -} - -static VALUE -list_sel_mode(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return INT2FIX(GTK_LIST(widget)->selection_mode); -} - -static VALUE -list_selection(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - return glist2ary(GTK_LIST(widget)->selection); -} - -static VALUE -list_insert_items(self, items, pos) - VALUE self, items, pos; -{ - GtkWidget *widget = get_widget(self); - GList *glist; - - glist = ary2glist(items); - - gtk_list_insert_items(GTK_LIST(widget), glist, NUM2INT(pos)); - g_list_free(glist); - - return self; -} - -static VALUE -list_append_items(self, items) - VALUE self, items; -{ - GtkWidget *widget = get_widget(self); - GList *glist; - - glist = ary2glist(items); - - gtk_list_append_items(GTK_LIST(widget), glist); - g_list_free(glist); - - return self; -} - -static VALUE -list_prepend_items(self, items) - VALUE self, items; -{ - GtkWidget *widget = get_widget(self); - GList *glist; - - glist = ary2glist(items); - gtk_list_prepend_items(GTK_LIST(widget), glist); - g_list_free(glist); - - return self; -} - -static VALUE -list_remove_items(self, items) - VALUE self, items; -{ - GtkWidget *widget = get_widget(self); - GList *glist; - - glist = ary2glist(items); - gtk_list_remove_items(GTK_LIST(widget), glist); - g_list_free(glist); - - return self; -} - -static VALUE -list_clear_items(self, start, end) - VALUE self, start, end; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_clear_items(GTK_LIST(widget), NUM2INT(start), NUM2INT(end)); - return self; -} - -static VALUE -list_select_item(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_select_item(GTK_LIST(widget), NUM2INT(pos)); - return self; -} - -static VALUE -list_unselect_item(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_unselect_item(GTK_LIST(widget), NUM2INT(pos)); - return self; -} - -static VALUE -list_select_child(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_select_child(GTK_LIST(widget), get_widget(child)); - return self; -} - -static VALUE -list_unselect_child(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_list_unselect_child(GTK_LIST(widget), get_widget(child)); - return self; -} - -static VALUE -list_child_position(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - gint pos; - - pos = gtk_list_child_position(GTK_LIST(widget), get_widget(child)); - return INT2FIX(pos); -} - -static VALUE -item_select(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_item_select(GTK_ITEM(widget)); - return self; -} - -static VALUE -item_deselect(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_item_deselect(GTK_ITEM(widget)); - return self; -} - -static VALUE -item_toggle(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_item_toggle(GTK_ITEM(widget)); - return self; -} - -static VALUE -litem_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - widget = gtk_list_item_new_with_label(get_cstring(label)); - } - else { - widget = gtk_list_item_new(); - } - - return make_widget(self, widget); -} - -static VALUE -mshell_append(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_shell_append(GTK_MENU_SHELL(widget), get_widget(child)); - return self; -} - -static VALUE -mshell_prepend(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_shell_prepend(GTK_MENU_SHELL(widget), get_widget(child)); - return self; -} - -static VALUE -mshell_insert(self, child, pos) - VALUE self, child, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_shell_insert(GTK_MENU_SHELL(widget), get_widget(child), - NUM2INT(pos)); - return self; -} - -static VALUE -mshell_deactivate(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_shell_deactivate(GTK_MENU_SHELL(widget)); - return self; -} - -static VALUE -menu_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_menu_new()); -} - -static VALUE -menu_append(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_append(GTK_MENU(widget), get_widget(child)); - return self; -} - -static VALUE -menu_prepend(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_prepend(GTK_MENU(widget), get_widget(child)); - return self; -} - -static VALUE -menu_insert(self, child, pos) - VALUE self, child, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_insert(GTK_MENU(widget), get_widget(child), NUM2INT(pos)); - return self; -} - -static void -menu_pos_func(menu, x, y, data) - GtkMenu *menu; - gint x, y; - gpointer data; -{ - VALUE m = get_value_from_gobject(GTK_OBJECT(menu)); - - rb_funcall((VALUE)data, 3, m, INT2FIX(x), INT2FIX(y)); -} - -static VALUE -menu_popup(self, pshell, pitem, func, button, activate_time) - VALUE self, pshell, pitem, func, button, activate_time; -{ - GtkWidget *widget = get_widget(self); - GtkMenuPositionFunc pfunc = NULL; - gpointer data = NULL; - - if (!NIL_P(func)) { - pfunc = menu_pos_func; - data = (gpointer)func; - add_relative(self, func); - } - gtk_menu_popup(GTK_MENU(widget), - get_widget(pshell), get_widget(pitem), - pfunc, - data, - NUM2INT(button), - NUM2INT(activate_time)); - return self; -} - -static VALUE -menu_popdown(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_popdown(GTK_MENU(widget)); - return self; -} - -static VALUE -menu_get_active(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - GtkWidget *mitem = gtk_menu_get_active(GTK_MENU(widget)); - - return make_widget(gMenuItem, mitem); -} - -static VALUE -menu_set_active(self, active) - VALUE self, active; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_set_active(GTK_MENU(widget), NUM2INT(active)); - return self; -} - -static VALUE -menu_set_acceltbl(self, table) - VALUE self, table; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_set_accelerator_table(GTK_MENU(widget), - get_gtkacceltbl(table)); - return self; -} - -static VALUE -mbar_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_menu_bar_new()); -} - -static VALUE -mbar_append(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_bar_append(GTK_MENU_BAR(widget), get_widget(child)); - return self; -} - -static VALUE -mbar_prepend(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_bar_prepend(GTK_MENU_BAR(widget), get_widget(child)); - return self; -} -static VALUE -mbar_insert(self, child, pos) - VALUE self, child, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_bar_insert(GTK_MENU_BAR(widget), - get_widget(child), NUM2INT(pos)); - return self; -} - -static VALUE -mitem_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - widget = gtk_menu_item_new_with_label(get_cstring(label)); - } - else { - widget = gtk_menu_item_new(); - } - - return make_widget(self, widget); -} - -static VALUE -mitem_set_submenu(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_set_submenu(GTK_MENU_ITEM(widget), get_widget(child)); - return self; -} - -static VALUE -mitem_set_placement(self, place) - VALUE self, place; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_set_placement(GTK_MENU_ITEM(widget), - (GtkSubmenuPlacement)NUM2INT(place)); - return self; -} - -static VALUE -mitem_accelerator_size(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_accelerator_size(GTK_MENU_ITEM(widget)); - return self; -} - -static VALUE -mitem_accelerator_text(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - char buf[1024]; /* enough? */ - - gtk_menu_item_accelerator_text(GTK_MENU_ITEM(widget), buf); - return str_new2(buf); -} - -static VALUE -mitem_configure(self, show_toggle, show_submenu) - VALUE self, show_toggle, show_submenu; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_configure(GTK_MENU_ITEM(widget), - NUM2INT(show_toggle), - NUM2INT(show_submenu)); - return self; -} - -static VALUE -mitem_select(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_select(GTK_MENU_ITEM(widget)); - return self; -} - -static VALUE -mitem_deselect(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_deselect(GTK_MENU_ITEM(widget)); - return self; -} - -static VALUE -mitem_activate(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_activate(GTK_MENU_ITEM(widget)); - return self; -} - -static VALUE -mitem_right_justify(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_menu_item_right_justify(GTK_MENU_ITEM(widget)); - return self; -} - -static VALUE -cmitem_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - widget = gtk_check_menu_item_new_with_label(get_cstring(label)); - } - else { - widget = gtk_check_menu_item_new(); - } - - return make_widget(self, widget); -} - -static VALUE -cmitem_set_state(self, state) - VALUE self, state; -{ - GtkWidget *widget = get_widget(self); - - gtk_check_menu_item_set_state(GTK_CHECK_MENU_ITEM(widget), - NUM2INT(state)); - return self; -} - -static VALUE -cmitem_set_show_toggle(self, always) - VALUE self, always; -{ - GtkWidget *widget = get_widget(self); - - gtk_check_menu_item_set_show_toggle(GTK_CHECK_MENU_ITEM(widget), - (gboolean)RTEST(always)); - return self; -} - -static VALUE -cmitem_toggled(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_check_menu_item_toggled(GTK_CHECK_MENU_ITEM(widget)); - return self; -} - -static VALUE -rmitem_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE arg1, arg2; - GtkWidget *widget; - GSList *list = NULL; - char *label = NULL; - - if (rb_scan_args(argc, argv, "02", &arg1, &arg2) == 1 && - TYPE(arg1) == T_STRING) { - label = RSTRING(arg1)->ptr; - } - else { - if (!NIL_P(arg2)) { - Check_Type(arg2, T_STRING); - label = RSTRING(arg2)->ptr; - } - if (obj_is_kind_of(arg1, gRMenuItem)) { - GtkWidget *b = get_widget(arg1); - list = GTK_RADIO_MENU_ITEM(b)->group; - } - else { - list = ary2gslist(arg1); - } - } - if (label) { - widget = gtk_radio_menu_item_new_with_label(list, label); - } - else { - widget = gtk_radio_menu_item_new(list); - } - return make_widget(self, widget); -} - -static VALUE -rmitem_group(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return gslist2ary(gtk_radio_menu_item_group(GTK_RADIO_MENU_ITEM(widget))); -} - -static VALUE -note_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_notebook_new()); -} - -static VALUE -note_append_page(self, child, label) - VALUE self, child, label; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_append_page(GTK_NOTEBOOK(widget), - get_widget(child), - get_widget(label)); - return self; -} - -static VALUE -note_prepend_page(self, child, label) - VALUE self, child, label; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_prepend_page(GTK_NOTEBOOK(widget), - get_widget(child), - get_widget(label)); - return self; -} - -static VALUE -note_insert_page(self, child, label, pos) - VALUE self, child, label, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_insert_page(GTK_NOTEBOOK(widget), - get_widget(child), - get_widget(label), - NUM2INT(pos)); - return self; -} - -static VALUE -note_remove_page(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_remove_page(GTK_NOTEBOOK(widget), NUM2INT(pos)); - return self; -} - -static VALUE -note_set_page(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_set_page(GTK_NOTEBOOK(widget), NUM2INT(pos)); - return self; -} - -static VALUE -note_cur_page(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return INT2FIX(GTK_NOTEBOOK(widget)->cur_page); -} - -static VALUE -note_next_page(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_next_page(GTK_NOTEBOOK(widget)); - return self; -} - -static VALUE -note_prev_page(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_prev_page(GTK_NOTEBOOK(widget)); - return self; -} - -static VALUE -note_set_tab_pos(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(widget), NUM2INT(pos)); - return self; -} - -static VALUE -note_tab_pos(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - return INT2FIX(GTK_NOTEBOOK(widget)->tab_pos); -} - -static VALUE -note_set_show_tabs(self, show_tabs) - VALUE self, show_tabs; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(widget), RTEST(show_tabs)); - return self; -} - -static VALUE -note_show_tabs(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return GTK_NOTEBOOK(widget)->show_tabs?TRUE:FALSE; -} - -static VALUE -note_set_show_border(self, show_border) - VALUE self, show_border; -{ - GtkWidget *widget = get_widget(self); - - gtk_notebook_set_tab_pos(GTK_NOTEBOOK(widget), RTEST(show_border)); - return self; -} - -static VALUE -note_show_border(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return GTK_NOTEBOOK(widget)->show_border?TRUE:FALSE; -} - -static VALUE -omenu_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_option_menu_new()); -} - -static VALUE -omenu_set_menu(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - rb_iv_set(self, "option_menu", child); - gtk_option_menu_set_menu(GTK_OPTION_MENU(widget), get_widget(child)); - return self; -} - -static VALUE -omenu_get_menu(self) - VALUE self; -{ - return rb_iv_get(self, "option_menu"); -} - -static VALUE -omenu_remove_menu(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_option_menu_remove_menu(GTK_OPTION_MENU(widget)); - return self; -} - -static VALUE -omenu_set_history(self, index) - VALUE self, index; -{ - GtkWidget *widget = get_widget(self); - - gtk_option_menu_set_history(GTK_OPTION_MENU(widget), NUM2INT(index)); - return self; -} - -static VALUE -image_s_new(self, val, mask) - VALUE self, val, mask; -{ - return make_widget(self, gtk_image_new(get_gdkimage(val), - (GdkBitmap*)get_gdkpixmap(mask))); -} - -static VALUE -image_set(self, val, mask) - VALUE self, val, mask; -{ - GtkWidget *widget = get_widget(self); - - gtk_image_set(GTK_IMAGE(widget), get_gdkimage(val), get_gdkpixmap(mask)); - return self; -} - -static VALUE -image_get(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - GdkImage *val; - GdkBitmap *mask; - - gtk_image_get(GTK_IMAGE(widget), &val, &mask); - - return assoc_new(make_gdkimage(self, val), - make_gdkpixmap(self, mask)); -} - -static VALUE -preview_s_new(self, type) - VALUE self, type; -{ - return make_widget(self, gtk_preview_new((GtkPreviewType)NUM2INT(type))); -} - - -static VALUE -preview_size(self, w, h) - VALUE self, w, h; -{ - GtkWidget *widget = get_widget(self); - - gtk_preview_size(GTK_PREVIEW(widget), NUM2INT(w), NUM2INT(h)); - return self; -} - -#if 0 - rb_define_method(gPixmap, "put", preview_size, 8); - rb_define_method(gPixmap, "put_row", preview_size, 5); - rb_define_method(gPixmap, "draw_row", preview_size, 4); -#endif - -static VALUE -preview_set_expand(self, expand) - VALUE self, expand; -{ - GtkWidget *widget = get_widget(self); - - gtk_preview_set_expand(GTK_PREVIEW(widget), NUM2INT(expand)); - return self; -} - -static VALUE -preview_set_gamma(self, gamma) - VALUE self, gamma; -{ - gtk_preview_set_gamma(NUM2DBL(gamma)); - return Qnil; -} - -static VALUE -preview_set_color_cube(self, nred, ngreen, nblue, ngray) - VALUE self, nred, ngreen, nblue, ngray; -{ - gtk_preview_set_color_cube(NUM2INT(nred), - NUM2INT(ngreen), - NUM2INT(nblue), - NUM2INT(ngray)); - return Qnil; -} - -static VALUE -preview_set_install_cmap(self, cmap) - VALUE self, cmap; -{ - gtk_preview_set_install_cmap(NUM2INT(cmap)); - return Qnil; -} - -static VALUE -preview_set_reserved(self, nreserved) - VALUE self, nreserved; -{ - gtk_preview_set_reserved(NUM2INT(nreserved)); - return Qnil; -} - -static VALUE -preview_get_visual(self) - VALUE self; -{ - GdkVisual *v = gtk_preview_get_visual(); - return make_gdkvisual(v); -} - -static VALUE -preview_get_cmap(self) - VALUE self; -{ - GdkColormap *c = gtk_preview_get_cmap(); - return make_gdkcmap(c); -} - -static VALUE -preview_get_info(self) - VALUE self; -{ - GtkPreviewInfo *i = gtk_preview_get_info(); - return make_gtkprevinfo(i); -} - -static VALUE -pbar_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_progress_bar_new()); -} - -static VALUE -pbar_update(self, percentage) - VALUE self, percentage; -{ - GtkWidget *widget = get_widget(self); - - gtk_progress_bar_update(GTK_PROGRESS_BAR(widget), - NUM2DBL(percentage)); - return self; -} - -static VALUE -scwin_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1, arg2; - GtkAdjustment *h_adj = NULL; - GtkAdjustment *v_adj = NULL; - - rb_scan_args(argc, argv, "02", &arg1, &arg2); - if (!NIL_P(arg1)) h_adj = (GtkAdjustment*)get_gobject(arg1); - if (!NIL_P(arg2)) v_adj = (GtkAdjustment*)get_gobject(arg2); - - return make_widget(self, gtk_scrolled_window_new(h_adj, v_adj)); -} - -static VALUE -scwin_set_policy(self, hpolicy, vpolicy) - VALUE self, hpolicy, vpolicy; -{ - GtkWidget *widget = get_widget(self); - - gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(widget), - (GtkPolicyType)NUM2INT(hpolicy), - (GtkPolicyType)NUM2INT(vpolicy)); - return self; -} - - -static VALUE -tbl_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE row, col, homogeneous; - - rb_scan_args(argc, argv, "21", &row, &col, &homogeneous); - return make_widget(self, gtk_table_new(NUM2INT(row), - NUM2INT(col), - RTEST(homogeneous))); -} - -static VALUE -tbl_attach(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - GtkWidget *widget = get_widget(self); - VALUE child, left, right, top, bottom; - VALUE arg0, arg1, arg2, arg3; - int xopt, yopt, xspc, yspc; - - xopt = yopt = GTK_EXPAND | GTK_FILL; - xspc = yspc = 0; - rb_scan_args(argc, argv, "54", - &child, &left, &right, &top, &bottom, - &arg0, &arg1, &arg2, &arg3); - if (!NIL_P(arg0)) xopt = NUM2INT(arg0); - if (!NIL_P(arg1)) yopt = NUM2INT(arg1); - if (!NIL_P(arg2)) xspc = NUM2INT(arg2); - if (!NIL_P(arg3)) yspc = NUM2INT(arg3); - - gtk_table_attach(GTK_TABLE(widget), - get_widget(child), - NUM2INT(left),NUM2INT(right), - NUM2INT(top),NUM2INT(bottom), - xopt, yopt, xspc, yspc); - - return self; -} - -static VALUE -tbl_set_row_spacing(self, row, spc) - VALUE self, row, spc; -{ - GtkWidget *widget = get_widget(self); - - gtk_table_set_row_spacing(GTK_TABLE(widget), NUM2INT(row), NUM2INT(spc)); - return self; -} - -static VALUE -tbl_set_col_spacing(self, col, spc) - VALUE self, col, spc; -{ - GtkWidget *widget = get_widget(self); - - gtk_table_set_col_spacing(GTK_TABLE(widget), NUM2INT(col), NUM2INT(spc)); - return self; -} - -static VALUE -tbl_set_row_spacings(self, spc) - VALUE self, spc; -{ - GtkWidget *widget = get_widget(self); - - gtk_table_set_row_spacings(GTK_TABLE(widget), NUM2INT(spc)); - return self; -} - -static VALUE -tbl_set_col_spacings(self, spc) - VALUE self, spc; -{ - GtkWidget *widget = get_widget(self); - - gtk_table_set_col_spacings(GTK_TABLE(widget), NUM2INT(spc)); - return self; -} - -static VALUE -txt_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1, arg2; - GtkAdjustment *h_adj = NULL; - GtkAdjustment *v_adj = NULL; - - rb_scan_args(argc, argv, "02", &arg1, &arg2); - if (!NIL_P(arg1)) h_adj = (GtkAdjustment*)get_gobject(arg1); - if (!NIL_P(arg2)) v_adj = (GtkAdjustment*)get_gobject(arg2); - - return make_widget(self, gtk_text_new(h_adj, v_adj)); -} - -static VALUE -txt_set_editable(self, editable) - VALUE self, editable; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_set_editable(GTK_TEXT(widget), RTEST(editable)); - return self; -} - -static VALUE -txt_set_adjustment(self, h_adj, v_adj) - VALUE self, h_adj, v_adj; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_set_adjustments(GTK_TEXT(widget), - (GtkAdjustment*)get_gobject(h_adj), - (GtkAdjustment*)get_gobject(v_adj)); - - return self; -} - -static VALUE -txt_set_point(self, index) - VALUE self, index; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_set_point(GTK_TEXT(widget), NUM2INT(index)); - return self; -} - -static VALUE -txt_get_point(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int index = gtk_text_get_point(GTK_TEXT(widget)); - - return INT2FIX(index); -} - -static VALUE -txt_get_length(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int len = gtk_text_get_length(GTK_TEXT(widget)); - - return INT2FIX(len); -} - -static VALUE -txt_freeze(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_freeze(GTK_TEXT(widget)); - return self; -} - -static VALUE -txt_thaw(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_thaw(GTK_TEXT(widget)); - return self; -} - -static VALUE -txt_insert(self, font, fore, back, str) - VALUE self, font, fore, back, str; -{ - GtkWidget *widget = get_widget(self); - - Check_Type(str, T_STRING); - gtk_text_insert(GTK_TEXT(widget), - get_gdkfont(font), - get_gdkcolor(fore), - get_gdkcolor(back), - RSTRING(str)->ptr, - RSTRING(str)->len); - - return self; -} - -static VALUE -txt_backward_delete(self, nchars) - VALUE self, nchars; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_backward_delete(GTK_TEXT(widget), NUM2INT(nchars)); - return self; -} - -static VALUE -txt_forward_delete(self, nchars) - VALUE self, nchars; -{ - GtkWidget *widget = get_widget(self); - - gtk_text_forward_delete(GTK_TEXT(widget), NUM2INT(nchars)); - return self; -} - -static VALUE -tbar_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1, arg2; - GtkOrientation orientation = GTK_ORIENTATION_HORIZONTAL; - GtkToolbarStyle style = GTK_TOOLBAR_BOTH; - - rb_scan_args(argc, argv, "02", &arg1, &arg2); - if (!NIL_P(arg1)) orientation = (GtkOrientation)NUM2INT(arg1); - if (!NIL_P(arg2)) style = (GtkToolbarStyle)NUM2INT(arg2); - - return make_widget(self, gtk_toolbar_new(orientation, style)); -} - -static VALUE -tbar_append_item(self, text, ttext, icon, func) - VALUE self, text, ttext, icon, func; -{ - GtkWidget *widget = get_widget(self); - GtkObject *pixmap = get_gobject(icon); - - if (NIL_P(func)) { - func = f_lambda(); - } - gtk_toolbar_append_item(GTK_TOOLBAR(widget), - get_cstring(text), - get_cstring(ttext), - GTK_PIXMAP(pixmap), - exec_callback, - (gpointer)ary_new3(1, func)); - return self; -} - -static VALUE -tbar_prepend_item(self, text, ttext, icon, func) - VALUE self, text, ttext, icon, func; -{ - GtkWidget *widget = get_widget(self); - GtkObject *pixmap = get_gobject(icon); - - if (NIL_P(func)) { - func = f_lambda(); - } - gtk_toolbar_prepend_item(GTK_TOOLBAR(widget), - get_cstring(text), - get_cstring(ttext), - GTK_PIXMAP(pixmap), - exec_callback, - (gpointer)ary_new3(1, func)); - return self; -} - -static VALUE -tbar_insert_item(self, text, ttext, icon, func, pos) - VALUE self, text, ttext, icon, func, pos; -{ - GtkWidget *widget = get_widget(self); - GtkObject *pixmap = get_gobject(icon); - - if (NIL_P(func)) { - func = f_lambda(); - } - gtk_toolbar_insert_item(GTK_TOOLBAR(widget), - get_cstring(text), - get_cstring(ttext), - GTK_PIXMAP(pixmap), - exec_callback, - (gpointer)ary_new3(1, func), - NUM2INT(pos)); - return self; -} - -static VALUE -tbar_append_space(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_append_space(GTK_TOOLBAR(widget)); - return self; -} - -static VALUE -tbar_prepend_space(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_prepend_space(GTK_TOOLBAR(widget)); - return self; -} - -static VALUE -tbar_insert_space(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_insert_space(GTK_TOOLBAR(widget), NUM2INT(pos)); - return self; -} - -static VALUE -tbar_set_orientation(self, orientation) - VALUE self, orientation; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_set_orientation(GTK_TOOLBAR(widget), - (GtkOrientation)NUM2INT(orientation)); - return self; -} - -static VALUE -tbar_set_style(self, style) - VALUE self, style; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_set_style(GTK_TOOLBAR(widget), - (GtkToolbarStyle)NUM2INT(style)); - return self; -} - -static VALUE -tbar_set_space_size(self, size) - VALUE self, size; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_set_space_size(GTK_TOOLBAR(widget), NUM2INT(size)); - return self; -} - -static VALUE -tbar_set_tooltips(self, enable) - VALUE self, enable; -{ - GtkWidget *widget = get_widget(self); - - gtk_toolbar_set_tooltips(GTK_TOOLBAR(widget), RTEST(enable)); - return self; -} - -static VALUE -ttips_s_new(self) - VALUE self; -{ - return make_ttips(self, gtk_tooltips_new()); -} - -static VALUE -ttips_set_tips(self, win, text) - VALUE self, win, text; -{ - Check_Type(text, T_STRING); - gtk_tooltips_set_tips(get_ttips(self), - get_widget(win), - RSTRING(text)->ptr); - - return self; -} - -static VALUE -ttips_set_delay(self, delay) - VALUE self, delay; -{ - gtk_tooltips_set_delay(get_ttips(self), NUM2INT(delay)); - - return self; -} - -static VALUE -ttips_enable(self) - VALUE self; -{ - gtk_tooltips_enable(get_ttips(self)); - return self; -} - -static VALUE -ttips_disable(self) - VALUE self; -{ - gtk_tooltips_enable(get_ttips(self)); - return self; -} - -static VALUE -tree_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_tree_new()); -} - -static VALUE -tree_append(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_append(GTK_TREE(widget), get_widget(child)); - return self; -} - -static VALUE -tree_prepend(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_prepend(GTK_TREE(widget), get_widget(child)); - return self; -} - -static VALUE -tree_insert(self, child, pos) - VALUE self, child, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_insert(GTK_TREE(widget), get_widget(child), NUM2INT(pos)); - return self; -} - -static VALUE -titem_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - Check_Type(label, T_STRING); - widget = gtk_tree_item_new_with_label(RSTRING(label)->ptr); - } - else { - widget = gtk_tree_item_new(); - } - - return make_widget(self, widget); -} - -static VALUE -titem_set_subtree(self, subtree) - VALUE self, subtree; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_item_set_subtree(GTK_TREE_ITEM(widget), get_widget(subtree)); - return self; -} - -static VALUE -titem_select(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_item_select(GTK_TREE_ITEM(widget)); - return self; -} - -static VALUE -titem_deselect(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_item_deselect(GTK_TREE_ITEM(widget)); - return self; -} - -static VALUE -titem_expand(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_item_expand(GTK_TREE_ITEM(widget)); - return self; -} - -static VALUE -titem_collapse(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_tree_item_collapse(GTK_TREE_ITEM(widget)); - return self; -} - -static VALUE -vport_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1, arg2; - GtkAdjustment *h_adj = NULL; - GtkAdjustment *v_adj = NULL; - - rb_scan_args(argc, argv, "02", &arg1, &arg2); - if (!NIL_P(arg1)) h_adj = (GtkAdjustment*)get_gobject(arg1); - if (!NIL_P(arg2)) v_adj = (GtkAdjustment*)get_gobject(arg2); - - return make_widget(self, gtk_viewport_new(h_adj, v_adj)); -} - -static VALUE -vport_get_hadj(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - GtkAdjustment *adj = gtk_viewport_get_hadjustment(GTK_VIEWPORT(widget)); - - return make_gobject(gAdjustment, GTK_OBJECT(adj)); -} - -static VALUE -vport_get_vadj(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - GtkAdjustment *adj = gtk_viewport_get_vadjustment(GTK_VIEWPORT(widget)); - - return make_gobject(gAdjustment, GTK_OBJECT(adj)); -} - -static VALUE -vport_set_vadj(self, adj) - VALUE self, adj; -{ - GtkWidget *widget = get_widget(self); - GtkObject *adjustment = get_gobject(adj); - - gtk_viewport_set_vadjustment(GTK_VIEWPORT(widget), - GTK_ADJUSTMENT(adj)); - - return self; -} - -static VALUE -vport_set_hadj(self, adj) - VALUE self, adj; -{ - GtkWidget *widget = get_widget(self); - GtkObject *adjustment = get_gobject(adj); - - gtk_viewport_set_hadjustment(GTK_VIEWPORT(widget), - GTK_ADJUSTMENT(adj)); - - return self; -} - -static VALUE -vport_set_shadow(self, type) - VALUE self, type; -{ - GtkWidget *widget = get_widget(self); - - gtk_viewport_set_shadow_type(GTK_VIEWPORT(widget), - (GtkShadowType)NUM2INT(type)); - - return self; -} - -static VALUE -button_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - Check_Type(label, T_STRING); - widget = gtk_button_new_with_label(RSTRING(label)->ptr); - } - else { - widget = gtk_button_new(); - } - - return make_widget(self, widget); -} - -static VALUE -button_pressed(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_pressed(GTK_BUTTON(widget)); - return self; -} - -static VALUE -button_released(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_released(GTK_BUTTON(widget)); - return self; -} - -static VALUE -button_clicked(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_clicked(GTK_BUTTON(widget)); - return self; -} - -static VALUE -button_enter(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_enter(GTK_BUTTON(widget)); - return self; -} - -static VALUE -button_leave(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_button_leave(GTK_BUTTON(widget)); - return self; -} - -static VALUE -tbtn_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - Check_Type(label, T_STRING); - widget = gtk_toggle_button_new_with_label(RSTRING(label)->ptr); - } - else { - widget = gtk_toggle_button_new(); - } - - return make_widget(self, widget); -} - -static VALUE -tbtn_set_mode(self, mode) - VALUE self, mode; -{ - GtkWidget *widget = get_widget(self); - - gtk_toggle_button_set_mode(GTK_TOGGLE_BUTTON(widget), NUM2INT(mode)); - return self; -} - -static VALUE -tbtn_set_state(self, state) - VALUE self, state; -{ - GtkWidget *widget = get_widget(self); - - gtk_toggle_button_set_state(GTK_TOGGLE_BUTTON(widget), NUM2INT(state)); - return self; -} - -static VALUE -tbtn_toggled(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_toggle_button_toggled(GTK_TOGGLE_BUTTON(widget)); - return self; -} - -static VALUE -cbtn_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE label; - GtkWidget *widget; - - if (rb_scan_args(argc, argv, "01", &label) == 1) { - Check_Type(label, T_STRING); - widget = gtk_check_button_new_with_label(RSTRING(label)->ptr); - } - else { - widget = gtk_check_button_new(); - } - - return make_widget(self, widget); -} - -static VALUE -rbtn_s_new(argc, argv, self) - int argc; - VALUE *argv; -{ - VALUE arg1, arg2; - GtkWidget *widget; - GSList *list = NULL; - char *label = NULL; - - if (rb_scan_args(argc, argv, "02", &arg1, &arg2) == 1 && - TYPE(arg1) == T_STRING) { - label = RSTRING(arg1)->ptr; - } - else { - if (!NIL_P(arg2)) { - Check_Type(arg2, T_STRING); - label = RSTRING(arg2)->ptr; - } - if (obj_is_kind_of(arg1, gRButton)) { - GtkWidget *b = get_widget(arg1); - list = GTK_RADIO_BUTTON(b)->group; - } - else { - list = ary2gslist(arg1); - } - } - if (label) { - widget = gtk_radio_button_new_with_label(list, label); - } - else { - widget = gtk_radio_button_new(list); - } - return make_widget(self, widget); -} - -static VALUE -rbtn_group(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return gslist2ary(gtk_radio_button_group(GTK_RADIO_BUTTON(widget))); -} - -static void -box_pack_start_or_end(argc, argv, self, start) - int argc; - VALUE *argv; - VALUE self; - int start; -{ - VALUE arg0, arg1, arg2, arg3; - gint expand, fill, padding; - GtkWidget *widget, *child; - - expand = fill = TRUE; padding = 0; - switch (rb_scan_args(argc, argv, "13", &arg0, &arg1, &arg2, &arg3)) { - case 4: - padding = NUM2INT(arg3); - case 3: - fill = RTEST(arg2); - case 2: - expand = RTEST(arg1); - default: - child = get_widget(arg0); - break; - } - widget = get_widget(self); - - if (start) - gtk_box_pack_start(GTK_BOX(widget), child, expand, fill, padding); - else - gtk_box_pack_end(GTK_BOX(widget), child, expand, fill, padding); -} - -static VALUE -box_pack_start(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - box_pack_start_or_end(argc, argv, self, 1); - return self; -} - -static VALUE -box_pack_end(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - box_pack_start_or_end(argc, argv, self, 0); - return self; -} - -static VALUE -vbox_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE homogeneous, spacing; - GtkWidget *widget; - - rb_scan_args(argc, argv, "02", &homogeneous, &spacing); - widget = gtk_vbox_new(RTEST(homogeneous), NUM2INT(spacing)); - - return make_widget(self, widget); -} - -static VALUE -colorsel_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_color_selection_new()); -} - -static VALUE -colorsel_set_update_policy(self, policy) - VALUE self, policy; -{ - GtkWidget *widget = get_widget(self); - - gtk_color_selection_set_update_policy(GTK_COLOR_SELECTION(widget), - (GtkUpdateType)NUM2INT(policy)); - return self; -} - -static VALUE -colorsel_set_opacity(self, opacity) - VALUE self, opacity; -{ - GtkWidget *widget = get_widget(self); - - gtk_color_selection_set_opacity(GTK_COLOR_SELECTION(widget), - RTEST(opacity)); - return self; -} - -static VALUE -colorsel_set_color(self, color) - VALUE self, color; -{ - GtkWidget *widget = get_widget(self); - double buf[3]; - - Check_Type(color, T_ARRAY); - if (RARRAY(color)->len < 3) { - ArgError("color array too small"); - } - buf[0] = NUM2DBL(RARRAY(color)->ptr[0]); - buf[1] = NUM2DBL(RARRAY(color)->ptr[1]); - buf[2] = NUM2DBL(RARRAY(color)->ptr[2]); - - gtk_color_selection_set_color(GTK_COLOR_SELECTION(widget), buf); - return self; -} - -static VALUE -colorsel_get_color(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - double buf[3]; - VALUE ary; - - gtk_color_selection_get_color(GTK_COLOR_SELECTION(widget), buf); - ary = ary_new2(3); - ary_push(ary, NUM2DBL(buf[0])); - ary_push(ary, NUM2DBL(buf[1])); - ary_push(ary, NUM2DBL(buf[2])); - return ary; -} - -static VALUE -cdialog_s_new(self, title) - VALUE self; -{ - char *t; - - Check_Type(title, T_STRING); - t = RSTRING(title)->ptr; - return make_widget(self, gtk_color_selection_dialog_new(t)); -} - -static VALUE -pixmap_s_new(self, val, mask) - VALUE self, val, mask; -{ - return make_widget(self, gtk_pixmap_new(get_gdkpixmap(val), - get_gdkpixmap(mask))); -} - -static VALUE -pixmap_set(self, val, mask) - VALUE self, val, mask; -{ - GtkWidget *widget = get_widget(self); - - gtk_pixmap_set(GTK_PIXMAP(widget), - get_gdkpixmap(val), get_gdkpixmap(mask)); - return self; -} - -static VALUE -pixmap_get(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - GdkPixmap *val; - GdkBitmap *mask; - - gtk_pixmap_get(GTK_PIXMAP(widget), &val, &mask); - - return assoc_new(make_gdkpixmap(self, val), - make_gdkpixmap(self, mask)); -} - -static VALUE -darea_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_drawing_area_new()); -} - -static VALUE -darea_size(self, w, h) - VALUE self, w, h; -{ - GtkWidget *widget = get_widget(self); - - gtk_drawing_area_size(GTK_DRAWING_AREA(widget), NUM2INT(w), NUM2INT(h)); - return self; -} - -static VALUE -entry_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_entry_new()); -} - -static VALUE -entry_set_text(self, text) - VALUE self, text; -{ - GtkWidget *widget = get_widget(self); - - Check_Type(text, T_STRING); - gtk_entry_set_text(GTK_ENTRY(widget), RSTRING(text)->ptr); - - return self; -} - -static VALUE -eventbox_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_event_box_new()); -} - -static VALUE -fixed_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_fixed_new()); -} - -static VALUE -fixed_put(self, win, x, y) - VALUE self, win, x, y; -{ - GtkWidget *widget = get_widget(self); - - gtk_fixed_put(GTK_FIXED(widget), get_widget(win), NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -fixed_move(self, win, x, y) - VALUE self, win, x, y; -{ - GtkWidget *widget = get_widget(self); - - gtk_fixed_move(GTK_FIXED(widget), get_widget(win), NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -gamma_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_gamma_curve_new()); -} - -static VALUE -gamma_gamma(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - return float_new(GTK_GAMMA_CURVE(widget)->gamma); -} - -static VALUE -hbbox_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_hbutton_box_new()); -} - -static VALUE -hbbox_get_spacing_default(self) - VALUE self; -{ - int n = gtk_hbutton_box_get_spacing_default(); - - return INT2FIX(n); -} - -static VALUE -hbbox_get_layout_default(self) - VALUE self; -{ - int n = gtk_hbutton_box_get_layout_default(); - - return INT2FIX(n); -} - -static VALUE -hbbox_set_spacing_default(self, spacing) - VALUE self, spacing; -{ - gtk_hbutton_box_set_spacing_default(NUM2INT(spacing)); - return Qnil; -} - -static VALUE -hbbox_set_layout_default(self, layout) - VALUE self, layout; -{ - gtk_hbutton_box_set_layout_default(NUM2INT(layout)); - return Qnil; -} - -static VALUE -vbbox_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_vbutton_box_new()); -} - -static VALUE -vbbox_get_spacing_default(self) - VALUE self; -{ - int n = gtk_vbutton_box_get_spacing_default(); - - return INT2FIX(n); -} - -static VALUE -vbbox_get_layout_default(self) - VALUE self; -{ - int n = gtk_vbutton_box_get_layout_default(); - - return INT2FIX(n); -} - -static VALUE -vbbox_set_spacing_default(self, spacing) - VALUE self, spacing; -{ - gtk_vbutton_box_set_spacing_default(NUM2INT(spacing)); - return Qnil; -} - -static VALUE -vbbox_set_layout_default(self, layout) - VALUE self, layout; -{ - gtk_vbutton_box_set_layout_default(NUM2INT(layout)); - return Qnil; -} - -static VALUE -hbox_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE homogeneous, spacing; - GtkWidget *widget; - - rb_scan_args(argc, argv, "02", &homogeneous, &spacing); - widget = gtk_hbox_new(RTEST(homogeneous), NUM2INT(spacing)); - - return make_widget(self, widget); -} - -static VALUE -paned_add1(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_paned_add1(GTK_PANED(widget), get_widget(child)); - return self; -} - -static VALUE -paned_add2(self, child) - VALUE self, child; -{ - GtkWidget *widget = get_widget(self); - - gtk_paned_add2(GTK_PANED(widget), get_widget(child)); - return self; -} - -static VALUE -paned_handle_size(self, size) - VALUE self, size; -{ - GtkWidget *widget = get_widget(self); - - gtk_paned_handle_size(GTK_PANED(widget), NUM2INT(size)); - return self; -} - -static VALUE -paned_gutter_size(self, size) - VALUE self, size; -{ - GtkWidget *widget = get_widget(self); - - gtk_paned_gutter_size(GTK_PANED(widget), NUM2INT(size)); - return self; -} - -static VALUE -hpaned_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_hpaned_new()); -} - -static VALUE -vpaned_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_vpaned_new()); -} - -static VALUE -ruler_set_metric(self, metric) - VALUE self, metric; -{ - GtkWidget *widget = get_widget(self); - - gtk_ruler_set_metric(GTK_RULER(widget), - (GtkMetricType)NUM2INT(metric)); - - return self; -} - -static VALUE -ruler_set_range(self, lower, upper, position, max_size) - VALUE self, lower, upper, position, max_size; -{ - GtkWidget *widget = get_widget(self); - - gtk_ruler_set_range(GTK_RULER(widget), - NUM2DBL(lower), NUM2DBL(upper), - NUM2DBL(position), NUM2DBL(max_size)); - - return self; -} - -static VALUE -ruler_draw_ticks(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_ruler_draw_ticks(GTK_RULER(widget)); - return self; -} - -static VALUE -ruler_draw_pos(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_ruler_draw_pos(GTK_RULER(widget)); - return self; -} - -static VALUE -hruler_s_new(self) -{ - return make_widget(self, gtk_hruler_new()); -} - -static VALUE -vruler_s_new(self) -{ - return make_widget(self, gtk_vruler_new()); -} - -static VALUE -range_get_adj(self) -{ - GtkWidget *widget = get_widget(self); - GtkAdjustment *adj = gtk_range_get_adjustment(GTK_RANGE(widget)); - - return make_gobject(gAdjustment, GTK_OBJECT(adj)); -} - -static VALUE -range_set_update_policy(self, policy) - VALUE self, policy; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_set_update_policy(GTK_RANGE(widget), - (GtkUpdateType)NUM2INT(policy)); - return self; -} - -static VALUE -range_set_adj(self, adj) - VALUE self, adj; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_set_adjustment(GTK_RANGE(widget), - (GtkAdjustment*)get_gobject(adj)); - - return self; -} - -static VALUE -range_draw_bg(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_draw_background(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_draw_trough(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_draw_trough(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_draw_slider(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_draw_slider(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_draw_step_forw(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_draw_step_forw(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_draw_step_back(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_draw_step_back(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_slider_update(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_slider_update(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_trough_click(self, x, y) - VALUE self, x, y; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_trough_click(GTK_RANGE(widget), NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -range_default_hslider_update(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_hslider_update(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_default_vslider_update(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_vslider_update(GTK_RANGE(widget)); - return self; -} - -static VALUE -range_default_htrough_click(self, x, y) - VALUE self, x, y; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_htrough_click(GTK_RANGE(widget), - NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -range_default_vtrough_click(self, x, y) - VALUE self, x, y; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_vtrough_click(GTK_RANGE(widget), - NUM2INT(x), NUM2INT(y)); - return self; -} - -static VALUE -range_default_hmotion(self, xdelta, ydelta) - VALUE self, xdelta, ydelta; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_hmotion(GTK_RANGE(widget), - NUM2INT(xdelta), NUM2INT(ydelta)); - return self; -} - -static VALUE -range_default_vmotion(self, xdelta, ydelta) - VALUE self, xdelta, ydelta; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_default_vmotion(GTK_RANGE(widget), - NUM2INT(xdelta), NUM2INT(ydelta)); - return self; -} - -static VALUE -range_calc_value(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_range_calc_value(GTK_RANGE(widget), NUM2INT(pos)); - return self; -} - -static VALUE -scale_set_digits(self, digits) - VALUE self, digits; -{ - GtkWidget *widget = get_widget(self); - - gtk_scale_set_digits(GTK_SCALE(widget), NUM2INT(digits)); - return self; -} - -static VALUE -scale_set_draw_value(self, draw_value) - VALUE self, draw_value; -{ - GtkWidget *widget = get_widget(self); - - gtk_scale_set_draw_value(GTK_SCALE(widget), NUM2INT(draw_value)); - return self; -} - -static VALUE -scale_set_value_pos(self, pos) - VALUE self, pos; -{ - GtkWidget *widget = get_widget(self); - - gtk_scale_set_value_pos(GTK_SCALE(widget), - (GtkPositionType)NUM2INT(pos)); - return self; -} - -static VALUE -scale_value_width(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - int i = gtk_scale_value_width(GTK_SCALE(widget)); - - return INT2FIX(i); -} - -static VALUE -scale_draw_value(self) - VALUE self; -{ - GtkWidget *widget = get_widget(self); - - gtk_scale_draw_value(GTK_SCALE(widget)); - return self; -} - -static VALUE -hscale_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1; - GtkAdjustment *adj = NULL; - - rb_scan_args(argc, argv, "01", &arg1); - if (!NIL_P(arg1)) adj = (GtkAdjustment*)get_gobject(arg1); - - return make_widget(self, gtk_hscale_new(adj)); -} - -static VALUE -vscale_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1; - GtkAdjustment *adj = NULL; - - rb_scan_args(argc, argv, "01", &arg1); - if (!NIL_P(arg1)) adj = (GtkAdjustment*)get_gobject(arg1); - - return make_widget(self, gtk_vscale_new(adj)); -} - -static VALUE -hscrollbar_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1; - GtkAdjustment *adj = NULL; - - rb_scan_args(argc, argv, "01", &arg1); - if (!NIL_P(arg1)) adj = (GtkAdjustment*)get_gobject(arg1); - - return make_widget(self, gtk_hscrollbar_new(adj)); -} - -static VALUE -vscrollbar_s_new(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE arg1; - GtkAdjustment *adj = NULL; - - rb_scan_args(argc, argv, "01", &arg1); - if (!NIL_P(arg1)) adj = (GtkAdjustment*)get_gobject(arg1); - - return make_widget(self, gtk_vscrollbar_new(adj)); -} - -static VALUE -hsep_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_hseparator_new()); -} - -static VALUE -vsep_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_vseparator_new()); -} - -static VALUE -idiag_s_new(self) - VALUE self; -{ - return make_widget(self, gtk_input_dialog_new()); -} - -static VALUE -gtk_m_main(self) - VALUE self; -{ - gtk_main(); - return Qnil; -} - -static gint -idle() -{ - CHECK_INTS; - return TRUE; -} - -static void -exec_interval(proc) - VALUE proc; -{ - rb_funcall(proc, id_call, 0); -} - -static VALUE -timeout_add(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE interval, func; - int id; - - rb_scan_args(argc, argv, "11", &interval, &func); - if (NIL_P(func)) { - func = f_lambda(); - } - id = gtk_timeout_add_interp(NUM2INT(interval), exec_interval, - (gpointer)func, 0); - return INT2FIX(id); -} - -static VALUE -timeout_remove(self, id) - VALUE self, id; -{ - gtk_timeout_remove(NUM2INT(id)); - return Qnil; -} - -static VALUE -idle_add(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE func; - int id; - - rb_scan_args(argc, argv, "01", &func); - if (NIL_P(func)) { - func = f_lambda(); - } - id = gtk_idle_add_interp(exec_interval, (gpointer)func, 0); - return INT2FIX(id); -} - -static VALUE -idle_remove(self, id) - VALUE self, id; -{ - gtk_idle_remove(NUM2INT(id)); - return Qnil; -} - -static VALUE warn_handler; -static VALUE mesg_handler; -static VALUE print_handler; - -static void -gtkwarn(mesg) - char *mesg; -{ - rb_funcall(warn_handler, id_call, 1, str_new2(mesg)); -} - -static void -gtkmesg(mesg) - char *mesg; -{ - rb_funcall(mesg_handler, id_call, 1, str_new2(mesg)); -} - -static void -gtkprint(mesg) - char *mesg; -{ - rb_funcall(print_handler, id_call, 1, str_new2(mesg)); -} - -static VALUE -set_warning_handler(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE handler; - - rb_scan_args(argc, argv, "01", &handler); - if (NIL_P(handler)) { - handler = f_lambda(); - } - g_set_warning_handler(gtkwarn); -} - -static VALUE -set_message_handler(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE handler; - - rb_scan_args(argc, argv, "01", &handler); - if (NIL_P(handler)) { - handler = f_lambda(); - } - g_set_message_handler(gtkmesg); -} - -static VALUE -set_print_handler(argc, argv, self) - int argc; - VALUE *argv; - VALUE self; -{ - VALUE handler; - - rb_scan_args(argc, argv, "01", &handler); - if (NIL_P(handler)) { - handler = f_lambda(); - } - g_set_print_handler(gtkprint); -} - -static void -gtkerr(mesg) - char *mesg; -{ - Fail("%s", mesg); -} - -void -Init_gtk() -{ - int argc, i; - char **argv; - - gtk_object_list = ary_new(); - rb_global_variable(>k_object_list); - - mGtk = rb_define_module("Gtk"); - - gObject = rb_define_class_under(mGtk, "GtkObject", cObject); - gWidget = rb_define_class_under(mGtk, "Widget", gObject); - gContainer = rb_define_class_under(mGtk, "Container", gWidget); - gBin = rb_define_class_under(mGtk, "Bin", gContainer); - gAlignment = rb_define_class_under(mGtk, "Alignment", gBin); - gMisc = rb_define_class_under(mGtk, "Misc", gWidget); - gArrow = rb_define_class_under(mGtk, "Arrow", gMisc); - gFrame = rb_define_class_under(mGtk, "Frame", gBin); - gAspectFrame = rb_define_class_under(mGtk, "AspectFrame", gFrame); - gData = rb_define_class_under(mGtk, "Data", gObject); - gAdjustment = rb_define_class_under(mGtk, "Adjustment", gData); - gBox = rb_define_class_under(mGtk, "Box", gContainer); - gButton = rb_define_class_under(mGtk, "Button", gContainer); - gTButton = rb_define_class_under(mGtk, "ToggleButton", gButton); - gCButton = rb_define_class_under(mGtk, "CheckButton", gTButton); - gRButton = rb_define_class_under(mGtk, "RadioButton", gCButton); - gBBox = rb_define_class_under(mGtk, "ButtonBox", gBox); - gCList = rb_define_class_under(mGtk, "CList", gContainer); - gWindow = rb_define_class_under(mGtk, "Window", gBin); - gDialog = rb_define_class_under(mGtk, "Dialog", gWindow); - gFileSel = rb_define_class_under(mGtk, "FileSelection", gWindow); - gVBox = rb_define_class_under(mGtk, "VBox", gBox); - gColorSel = rb_define_class_under(mGtk, "ColorSelection", gVBox); - gColorSelDialog = rb_define_class_under(mGtk, "ColorSelectionDialog", gWindow); - gImage = rb_define_class_under(mGtk, "Image", gMisc); - gDrawArea = rb_define_class_under(mGtk, "DrawingArea", gWidget); - gEntry = rb_define_class_under(mGtk, "Entry", gWidget); - gEventBox = rb_define_class_under(mGtk, "EventBox", gBin); - gFixed = rb_define_class_under(mGtk, "Fixed", gContainer); - gGamma = rb_define_class_under(mGtk, "GammaCurve", gVBox); - gHBBox = rb_define_class_under(mGtk, "HButtonBox", gBBox); - gVBBox = rb_define_class_under(mGtk, "VButtonBox", gBBox); - gHBox = rb_define_class_under(mGtk, "HBox", gBox); - gPaned = rb_define_class_under(mGtk, "Paned", gContainer); - gHPaned = rb_define_class_under(mGtk, "HPaned", gPaned); - gVPaned = rb_define_class_under(mGtk, "VPaned", gPaned); - gRuler = rb_define_class_under(mGtk, "Ruler", gWidget); - gHRuler = rb_define_class_under(mGtk, "HRuler", gRuler); - gVRuler = rb_define_class_under(mGtk, "VRuler", gRuler); - gRange = rb_define_class_under(mGtk, "Range", gWidget); - gScale = rb_define_class_under(mGtk, "Scale", gRange); - gHScale = rb_define_class_under(mGtk, "HScale", gScale); - gVScale = rb_define_class_under(mGtk, "VScale", gScale); - gScrollbar = rb_define_class_under(mGtk, "Scrollbar", gRange); - gHScrollbar = rb_define_class_under(mGtk, "HScrollbar", gScrollbar); - gVScrollbar = rb_define_class_under(mGtk, "VScrollbar", gScrollbar); - gSeparator = rb_define_class_under(mGtk, "Separator", gWidget); - gHSeparator = rb_define_class_under(mGtk, "HSeparator", gSeparator); - gVSeparator = rb_define_class_under(mGtk, "VSeparator", gSeparator); - gInputDialog = rb_define_class_under(mGtk, "InputDialog", gDialog); - gLabel = rb_define_class_under(mGtk, "Label", gMisc); - gList = rb_define_class_under(mGtk, "List", gContainer); - gItem = rb_define_class_under(mGtk, "Item", gBin); - gListItem = rb_define_class_under(mGtk, "ListItem", gItem); - gMenuShell = rb_define_class_under(mGtk, "MenuShell", gContainer); - gMenu = rb_define_class_under(mGtk, "Menu", gMenuShell); - gMenuBar = rb_define_class_under(mGtk, "MenuBar", gMenuShell); - gMenuItem = rb_define_class_under(mGtk, "MenuItem", gItem); - gCMenuItem = rb_define_class_under(mGtk, "CheckMenuItem", gMenuItem); - gRMenuItem = rb_define_class_under(mGtk, "RadioMenuItem", gCMenuItem); - gNotebook = rb_define_class_under(mGtk, "Notebook", gContainer); - gOptionMenu = rb_define_class_under(mGtk, "OptionMenu", gButton); - gPixmap = rb_define_class_under(mGtk, "Pixmap", gMisc); - gPreview = rb_define_class_under(mGtk, "Preview", gWidget); - gProgressBar = rb_define_class_under(mGtk, "ProgressBar", gWidget); - gScrolledWin = rb_define_class_under(mGtk, "ScrolledWindow", gContainer); - gTable = rb_define_class_under(mGtk, "Table", gContainer); - gText = rb_define_class_under(mGtk, "Text", gWidget); - gToolbar = rb_define_class_under(mGtk, "Toolbar", gContainer); - gTooltips = rb_define_class_under(mGtk, "Tooltips", cObject); - gTree = rb_define_class_under(mGtk, "Tree", gContainer); - gTreeItem = rb_define_class_under(mGtk, "TreeItem", gItem); - gViewPort = rb_define_class_under(mGtk, "ViewPort", gBin); - - gAcceleratorTable = rb_define_class_under(mGtk, "AcceleratorTable", cObject); - gStyle = rb_define_class_under(mGtk, "Style", cObject); - gPreviewInfo = rb_define_class_under(mGtk, "PreviewInfo", cObject); - gRequisiton = rb_define_class_under(mGtk, "Requisiton", cObject); - gAllocation = rb_define_class_under(mGtk, "Allocation", cObject); - - mGdk = rb_define_module("Gdk"); - - gdkFont = rb_define_class_under(mGdk, "Font", cObject); - gdkColor = rb_define_class_under(mGdk, "Color", cObject); - gdkPixmap = rb_define_class_under(mGdk, "Pixmap", cObject); - gdkBitmap = rb_define_class_under(mGdk, "Bitmap", gdkPixmap); - gdkWindow = rb_define_class_under(mGdk, "Window", cObject); - gdkImage = rb_define_class_under(mGdk, "Image", cObject); - gdkVisual = rb_define_class_under(mGdk, "Visual", cObject); - gdkGC = rb_define_class_under(mGdk, "GC", cObject); - gdkGCValues = rb_define_class_under(mGdk, "GCValues", cObject); - gdkRectangle = rb_define_class_under(mGdk, "Rectangle", cObject); - gdkSegment = rb_define_class_under(mGdk, "Segment", cObject); - gdkWindowAttr = rb_define_class_under(mGdk, "WindowAttr", cObject); - gdkCursor = rb_define_class_under(mGdk, "Cursor", cObject); - gdkAtom = rb_define_class_under(mGdk, "Atom", cObject); - gdkColorContext = rb_define_class_under(mGdk, "ColotContext", cObject); - gdkEvent = rb_define_class_under(mGdk, "gdkEvent", cObject); - - /* GtkObject */ - rb_define_singleton_method(gObject, "new", gobj_s_new, -1); - rb_define_method(gObject, "set_flags", gobj_set_flags, 1); - rb_define_method(gObject, "unset_flags", gobj_unset_flags, 1); - rb_define_method(gObject, "destroy", gobj_destroy, 0); - rb_define_method(gObject, "signal_connect", gobj_sig_connect, -1); - rb_define_method(gObject, "signal_connect_after", gobj_sig_connect_after, -1); - rb_define_method(gObject, "singleton_method_added", gobj_smethod_added, 1); - - /* Widget */ - rb_define_method(gWidget, "destroy", widget_destroy, 0); - rb_define_method(gWidget, "show", widget_show, 0); - rb_define_method(gWidget, "show_all", widget_show_all, 0); - rb_define_method(gWidget, "hide", widget_hide, 0); - rb_define_method(gWidget, "hide_all", widget_hide_all, 0); - rb_define_method(gWidget, "map", widget_map, 0); - rb_define_method(gWidget, "unmap", widget_unmap, 0); - rb_define_method(gWidget, "realize", widget_realize, 0); - rb_define_method(gWidget, "unrealize", widget_unrealize, 0); - rb_define_method(gWidget, "queue_draw", widget_queue_draw, 0); - rb_define_method(gWidget, "queue_resize", widget_queue_resize, 0); - rb_define_method(gWidget, "draw", widget_draw, 1); - rb_define_method(gWidget, "draw_focus", widget_draw_focus, 0); - rb_define_method(gWidget, "draw_default", widget_draw_default, 0); - rb_define_method(gWidget, "draw_children", widget_draw_children, 0); - rb_define_method(gWidget, "size_request", widget_size_request, 1); - rb_define_method(gWidget, "size_alocate", widget_size_allocate, 1); - rb_define_method(gWidget, "install_accelerator", widget_inst_accel, 4); - rb_define_method(gWidget, "remove_accelerator", widget_rm_accel, 4); - rb_define_method(gWidget, "event", widget_event, 1); - rb_define_method(gWidget, "activate", widget_activate, 0); - rb_define_method(gWidget, "grab_focus", widget_grab_focus, 0); - rb_define_method(gWidget, "grab_default", widget_grab_default, 0); - rb_define_method(gWidget, "restore_state", widget_restore_state, 0); - rb_define_method(gWidget, "visible?", widget_visible, 0); - rb_define_method(gWidget, "reparent", widget_reparent, 1); - rb_define_method(gWidget, "popup", widget_popup, 2); - rb_define_method(gWidget, "intersect", widget_intersect, 2); - rb_define_method(gWidget, "basic", widget_basic, 0); - rb_define_method(gWidget, "get_name", widget_set_name, 0); - rb_define_method(gWidget, "set_name", widget_set_name, 1); - rb_define_method(gWidget, "set_parent", widget_set_parent, 1); - rb_define_method(gWidget, "set_sensitive", widget_set_sensitive, 1); - rb_define_method(gWidget, "set_usize", widget_set_usize, 2); - rb_define_method(gWidget, "set_uposition", widget_set_uposition, 2); - rb_define_method(gWidget, "set_style", widget_set_style, 1); - rb_define_method(gWidget, "set_events", widget_set_events, 1); - rb_define_method(gWidget, "set_extension_events", widget_set_eevents, 1); - rb_define_method(gWidget, "unparent", widget_unparent, 0); - rb_define_method(gWidget, "get_toplevel", widget_get_toplevel, 0); - rb_define_method(gWidget, "get_ancestor", widget_get_ancestor, 1); - rb_define_method(gWidget, "get_colormap", widget_get_colormap, 0); - rb_define_method(gWidget, "get_visual", widget_get_visual, 0); - rb_define_method(gWidget, "get_style", widget_get_style, 0); - rb_define_method(gWidget, "style", widget_get_style, 0); - rb_define_method(gWidget, "get_events", widget_get_events, 0); - rb_define_method(gWidget, "get_extension_events", widget_get_eevents, 0); - rb_define_method(gWidget, "get_pointer", widget_get_eevents, 0); - rb_define_method(gWidget, "ancestor?", widget_is_ancestor, 1); - rb_define_method(gWidget, "child?", widget_is_child, 1); - rb_define_method(gWidget, "window", widget_window, 0); - - rb_define_singleton_method(gWidget, "push_colomap", widget_push_cmap, 1); - rb_define_singleton_method(gWidget, "push_visual", widget_push_visual, 1); - rb_define_singleton_method(gWidget, "push_style", widget_push_style, 1); - rb_define_singleton_method(gWidget, "pop_colomap", widget_pop_cmap, 0); - rb_define_singleton_method(gWidget, "pop_visual", widget_pop_visual, 0); - rb_define_singleton_method(gWidget, "pop_style", widget_pop_style, 0); - - rb_define_singleton_method(gWidget, "set_default_colomap", - widget_set_default_cmap, 1); - rb_define_singleton_method(gWidget, "set_default_visual", - widget_set_default_visual, 1); - rb_define_singleton_method(gWidget, "set_default_style", - widget_set_default_style, 1); - rb_define_singleton_method(gWidget, "get_default_colomap", - widget_get_default_cmap, 0); - rb_define_singleton_method(gWidget, "get_default_visual", - widget_get_default_visual, 0); - rb_define_singleton_method(gWidget, "get_default_style", - widget_get_default_style, 0); - rb_define_singleton_method(gWidget, "set_default_colomap", - widget_set_default_cmap, 1); - rb_define_singleton_method(gWidget, "set_default_visual", - widget_set_default_visual, 1); - rb_define_singleton_method(gWidget, "set_default_style", - widget_set_default_style, 1); - rb_define_singleton_method(gWidget, "set_default_colomap", - widget_set_default_cmap, 1); - rb_define_singleton_method(gWidget, "set_default_visual", - widget_set_default_visual, 1); - rb_define_singleton_method(gWidget, "propagage_default_style", - widget_propagate_default_style, 0); - - /* Container */ - rb_define_method(gContainer, "border_width", cont_bwidth, 1); - rb_define_method(gContainer, "add", cont_add, 1); - rb_define_method(gContainer, "disable_resize", cont_disable_resize, 0); - rb_define_method(gContainer, "enable_resize", cont_enable_resize, 0); - rb_define_method(gContainer, "block_resize", cont_block_resize, 0); - rb_define_method(gContainer, "unblock_resize", cont_unblock_resize, 0); - rb_define_method(gContainer, "need_resize", cont_need_resize, 0); - rb_define_method(gContainer, "foreach", cont_foreach, -1); - rb_define_method(gContainer, "each", cont_each, 0); - rb_define_method(gContainer, "focus", cont_focus, 1); - rb_define_method(gContainer, "children", cont_children, 0); - - /* Bin */ - /* -- */ - - /* Alignment */ - rb_define_singleton_method(gAlignment, "new", align_s_new, 4); - rb_define_method(gAlignment, "set", align_set, 4); - - /* Misc */ - rb_define_method(gMisc, "set_alignment", misc_set_align, 2); - rb_define_method(gMisc, "set_padding", misc_set_padding, 2); - - /* Arrow */ - rb_define_singleton_method(gArrow, "new", arrow_s_new, 2); - rb_define_method(gArrow, "set", arrow_s_new, 2); - - /* Frame */ - rb_define_singleton_method(gFrame, "new", frame_s_new, 1); - rb_define_method(gFrame, "set_label", frame_set_label, 1); - rb_define_method(gFrame, "set_label_align", frame_set_label_align, 2); - rb_define_method(gFrame, "set_shadow_type", frame_set_shadow_type, 1); - - /* AspectFrame */ - rb_define_singleton_method(gAspectFrame, "new", aframe_s_new, 5); - rb_define_method(gAspectFrame, "set", aframe_set, 4); - - /* Data */ - /* -- */ - - /* Adjustment */ - rb_define_singleton_method(gAdjustment, "new", adj_s_new, 6); - - /* Box */ - rb_define_method(gBox, "pack_start", box_pack_start, -1); - rb_define_method(gBox, "pack_end", box_pack_end, -1); - - /* Button */ - rb_define_singleton_method(gButton, "new", button_s_new, -1); - rb_define_method(gButton, "pressed", button_pressed, 0); - rb_define_method(gButton, "released", button_released, 0); - rb_define_method(gButton, "clicked", button_clicked, 0); - rb_define_method(gButton, "enter", button_enter, 0); - rb_define_method(gButton, "leave", button_leave, 0); - - /* ToggleButton */ - rb_define_singleton_method(gTButton, "new", tbtn_s_new, -1); - rb_define_method(gTButton, "set_mode", tbtn_set_mode, 1); - rb_define_method(gTButton, "set_state", tbtn_set_state, 1); - rb_define_method(gTButton, "toggled", tbtn_toggled, 0); - - /* CheckButton */ - rb_define_singleton_method(gCButton, "new", cbtn_s_new, -1); - - /* RadioButton */ - rb_define_singleton_method(gCButton, "new", rbtn_s_new, -1); - rb_define_method(gCButton, "group", rbtn_group, 0); - - /* ButtonBox */ - rb_define_singleton_method(gBBox, "get_child_size_default", - bbox_get_child_size_default, 0); - rb_define_singleton_method(gBBox, "get_child_ipadding_default", - bbox_get_child_ipadding_default, 0); - rb_define_singleton_method(gBBox, "set_child_size_default", - bbox_set_child_size_default, 2); - rb_define_singleton_method(gBBox, "set_child_ipadding_default", - bbox_set_child_ipadding_default, 2); - rb_define_method(gBBox, "get_spacing", bbox_get_spacing, 0); - rb_define_method(gBBox, "get_layout", bbox_get_layout, 0); - rb_define_method(gBBox, "get_child_size", bbox_get_child_size, 0); - rb_define_method(gBBox, "get_child_ipadding", bbox_get_child_ipadding, 0); - rb_define_method(gBBox, "set_spacing", bbox_set_spacing, 1); - rb_define_method(gBBox, "set_layout", bbox_set_layout, 1); - rb_define_method(gBBox, "set_child_size", bbox_set_child_size, 2); - rb_define_method(gBBox, "set_child_ipadding", bbox_set_child_ipadding, 2); - - /* CList */ - rb_define_singleton_method(gCList, "new", clist_s_new, 1); - rb_define_method(gCList, "set_border", clist_set_border, 1); - rb_define_method(gCList, "set_selection_mode", clist_set_sel_mode, 1); - rb_define_method(gCList, "set_policy", clist_set_policy, 2); - rb_define_method(gCList, "freeze", clist_freeze, 0); - rb_define_method(gCList, "thaw", clist_thaw, 0); - rb_define_method(gCList, "set_column_title", clist_set_col_title, 2); - rb_define_method(gCList, "set_column_widget", clist_set_col_wigdet, 2); - rb_define_method(gCList, "set_column_justification", clist_set_col_just, 2); - rb_define_method(gCList, "set_column_width", clist_set_col_width, 2); - rb_define_method(gCList, "set_row_height", clist_set_row_height, 1); - rb_define_method(gCList, "moveto", clist_moveto, 4); - rb_define_method(gCList, "set_text", clist_set_text, 3); - rb_define_method(gCList, "set_pixmap", clist_set_text, 4); - rb_define_method(gCList, "set_pixtext", clist_set_pixtext, 6); - rb_define_method(gCList, "set_foreground", clist_set_foreground, 2); - rb_define_method(gCList, "set_background", clist_set_background, 2); - rb_define_method(gCList, "set_shift", clist_set_shift, 4); - rb_define_method(gCList, "append", clist_append, 1); - rb_define_method(gCList, "insert", clist_insert, 2); - rb_define_method(gCList, "remove", clist_remove, 1); - rb_define_method(gCList, "set_row_data", clist_set_row_data, 2); - rb_define_method(gCList, "get_row_data", clist_set_row_data, 1); - rb_define_method(gCList, "select_row", clist_select_row, 2); - rb_define_method(gCList, "unselect_row", clist_unselect_row, 2); - rb_define_method(gCList, "clear", clist_clear, 0); - - /* Window */ - rb_define_singleton_method(gWindow, "new", gwin_s_new, 1); - rb_define_method(gWindow, "set_title", gwin_set_title, 1); - rb_define_method(gWindow, "set_policy", gwin_set_policy, 3); - rb_define_method(gWindow, "set_wmclass", gwin_set_wmclass, 1); - rb_define_method(gWindow, "set_focus", gwin_set_focus, 1); - rb_define_method(gWindow, "set_default", gwin_set_focus, 1); - rb_define_method(gWindow, "add_accelerator_table", gwin_add_accel, 1); - rb_define_method(gWindow, "remove_accelerator_table", gwin_rm_accel, 1); - rb_define_method(gWindow, "position", gwin_position, 1); - - /* Dialog */ - rb_define_singleton_method(gDialog, "new", dialog_s_new, 0); - - /* FileSelection */ - rb_define_singleton_method(gFileSel, "new", fsel_s_new, 1); - rb_define_method(gFileSel, "set_filename", fsel_set_fname, 1); - rb_define_method(gFileSel, "get_filename", fsel_get_fname, 0); - rb_define_method(gFileSel, "ok_button", fsel_ok_button, 0); - rb_define_method(gFileSel, "cancel_button", fsel_cancel_button, 0); - rb_define_method(gFileSel, "help_button", fsel_help_button, 0); - - /* VBox */ - rb_define_singleton_method(gVBox, "new", vbox_s_new, -1); - - /* ColorSelection */ - rb_define_singleton_method(gColorSel, "new", colorsel_s_new, 0); - rb_define_method(gColorSel, "set_update_policy", colorsel_set_update_policy, 1); - rb_define_method(gColorSel, "set_opacity", colorsel_set_opacity, 1); - rb_define_method(gColorSel, "set_color", colorsel_set_color, 1); - rb_define_method(gColorSel, "get_color", colorsel_get_color, 0); - - /* ColorSelectionDialog */ - rb_define_singleton_method(gColorSelDialog, "new", cdialog_s_new, 1); - - /* Image */ - rb_define_singleton_method(gImage, "new", image_s_new, 2); - rb_define_method(gImage, "set", image_set, 2); - rb_define_method(gImage, "get", image_get, 0); - - /* DrawingArea */ - rb_define_singleton_method(gDrawArea, "new", darea_s_new, 0); - rb_define_method(gDrawArea, "size", darea_size, 2); - - /* Entry */ - rb_define_singleton_method(gEntry, "new", entry_s_new, 0); - rb_define_method(gEntry, "set_text", entry_set_text, 1); - - /* EventBox */ - rb_define_singleton_method(gEventBox, "new", eventbox_s_new, 0); - - /* Fixed */ - rb_define_singleton_method(gFixed, "new", fixed_s_new, 0); - rb_define_method(gFixed, "put", fixed_put, 3); - rb_define_method(gFixed, "move", fixed_move, 3); - - /* GammaCurve */ - rb_define_singleton_method(gGamma, "new", gamma_s_new, 0); - rb_define_method(gGamma, "gamma", gamma_gamma, 0); - - /* HButtonBox */ - rb_define_singleton_method(gHBBox, "new", hbbox_s_new, 0); - rb_define_singleton_method(gHBBox, "get_spacing_default", - hbbox_get_spacing_default, 0); - rb_define_singleton_method(gHBBox, "get_layout_default", - hbbox_get_spacing_default, 0); - rb_define_singleton_method(gHBBox, "set_spacing_default", - hbbox_set_spacing_default, 1); - rb_define_singleton_method(gHBBox, "set_layout_default", - hbbox_set_layout_default, 1); - - /* VButtonBox */ - rb_define_singleton_method(gVBBox, "new", vbbox_s_new, 0); - rb_define_singleton_method(gVBBox, "get_spacing_default", - vbbox_get_spacing_default, 0); - rb_define_singleton_method(gVBBox, "get_layout_default", - vbbox_get_spacing_default, 0); - rb_define_singleton_method(gVBBox, "set_spacing_default", - vbbox_set_spacing_default, 1); - rb_define_singleton_method(gVBBox, "set_layout_default", - vbbox_set_layout_default, 1); - - /* HBox */ - rb_define_singleton_method(gHBox, "new", hbox_s_new, -1); - - /* Paned */ - rb_define_method(gPaned, "add1", paned_add1, 1); - rb_define_method(gPaned, "add2", paned_add1, 1); - rb_define_method(gPaned, "handle_size", paned_handle_size, 1); - rb_define_method(gPaned, "gutter_size", paned_gutter_size, 1); - - /* HPaned */ - rb_define_singleton_method(gHPaned, "new", hpaned_s_new, 0); - - /* VPaned */ - rb_define_singleton_method(gVPaned, "new", vpaned_s_new, 0); - - /* Ruler */ - rb_define_method(gRuler, "set_metric", ruler_set_metric, 1); - rb_define_method(gRuler, "set_range", ruler_set_range, 4); - rb_define_method(gRuler, "draw_ticks", ruler_draw_ticks, 0); - rb_define_method(gRuler, "draw_pos", ruler_draw_pos, 0); - - /* HRuler */ - rb_define_singleton_method(gHRuler, "new", hruler_s_new, 0); - - /* VRuler */ - rb_define_singleton_method(gVRuler, "new", vruler_s_new, 0); - - /* Range */ - rb_define_method(gRange, "get_adjustment", range_get_adj, 0); - rb_define_method(gRange, "set_update_policy", range_set_update_policy, 1); - rb_define_method(gRange, "set_adjustment", range_set_adj, 1); - rb_define_method(gRange, "draw_background", range_draw_bg, 0); - rb_define_method(gRange, "draw_trough", range_draw_trough, 0); - rb_define_method(gRange, "draw_slider", range_draw_slider, 0); - rb_define_method(gRange, "draw_step_forw", range_draw_step_forw, 0); - rb_define_method(gRange, "draw_step_back", range_draw_step_back, 0); - rb_define_method(gRange, "slider_update", range_slider_update, 0); - rb_define_method(gRange, "trough_click", range_trough_click, 2); - rb_define_method(gRange, "draw_background", range_draw_bg, 2); - rb_define_method(gRange, "default_hslider_update", range_default_hslider_update, 0); - rb_define_method(gRange, "default_vslider_update", range_default_vslider_update, 0); - rb_define_method(gRange, "default_htrough_click", range_default_htrough_click, 2); - rb_define_method(gRange, "default_vtrough_click", range_default_vtrough_click, 2); - rb_define_method(gRange, "default_hmotion", range_default_hmotion, 2); - rb_define_method(gRange, "default_vmotion", range_default_vmotion, 2); - rb_define_method(gRange, "calc_value", range_calc_value, 1); - - /* Scale */ - rb_define_method(gScale, "set_digits", scale_set_digits, 1); - rb_define_method(gScale, "set_draw_value", scale_set_draw_value, 1); - rb_define_method(gScale, "set_value_pos", scale_set_value_pos, 1); - rb_define_method(gScale, "value_width", scale_value_width, 0); - rb_define_method(gScale, "draw_value", scale_draw_value, 0); - - /* HScale */ - rb_define_singleton_method(gHScale, "new", hscale_s_new, -1); - - /* VScale */ - rb_define_singleton_method(gVScale, "new", vscale_s_new, -1); - - /* Scrollbar */ - /* -- */ - - /* HScrollbar */ - rb_define_singleton_method(gHScrollbar, "new", hscrollbar_s_new, -1); - - /* VScrollbar */ - rb_define_singleton_method(gVScrollbar, "new", vscrollbar_s_new, -1); - - /* Separator */ - /* -- */ - - /* HSeparator */ - rb_define_singleton_method(gHSeparator, "new", hsep_s_new, 0); - - /* VSeparator */ - rb_define_singleton_method(gVSeparator, "new", vsep_s_new, 0); - - /* InputDialog */ - rb_define_singleton_method(gInputDialog, "new", idiag_s_new, 0); - - /* Label */ - rb_define_singleton_method(gLabel, "new", label_s_new, 1); - - /* List */ - rb_define_singleton_method(gList, "new", list_s_new, 0); - rb_define_method(gList, "set_selection_mode", list_set_sel_mode, 1); - rb_define_method(gList, "selection_mode", list_sel_mode, 1); - rb_define_method(gList, "selection", list_selection, 0); - rb_define_method(gList, "insert_items", list_insert_items, 2); - rb_define_method(gList, "append_items", list_append_items, 1); - rb_define_method(gList, "prepend_items", list_prepend_items, 1); - rb_define_method(gList, "remove_items", list_remove_items, 1); - rb_define_method(gList, "clear_items", list_clear_items, 2); - rb_define_method(gList, "select_item", list_select_item, 1); - rb_define_method(gList, "unselect_item", list_unselect_item, 1); - rb_define_method(gList, "select_child", list_select_child, 1); - rb_define_method(gList, "unselect_child", list_unselect_child, 1); - rb_define_method(gList, "child_position", list_child_position, 1); - - /* Item */ - rb_define_method(gItem, "select", item_select, 0); - rb_define_method(gItem, "deselect", item_deselect, 0); - rb_define_method(gItem, "toggle", item_toggle, 0); - - /* ListItem */ - rb_define_singleton_method(gListItem, "new", litem_s_new, -1); - - /* MenuShell */ - rb_define_method(gMenuShell, "append", mshell_append, 1); - rb_define_method(gMenuShell, "prepend", mshell_prepend, 1); - rb_define_method(gMenuShell, "insert", mshell_insert, 2); - rb_define_method(gMenuShell, "deactivate", mshell_deactivate, 0); - - /* Menu */ - rb_define_singleton_method(gMenu, "new", menu_s_new, 0); - rb_define_method(gMenu, "append", menu_append, 1); - rb_define_method(gMenu, "prepend", menu_prepend, 1); - rb_define_method(gMenu, "insert", menu_insert, 2); - rb_define_method(gMenu, "popup", menu_popup, 6); - rb_define_method(gMenu, "popdown", menu_popup, 0); - rb_define_method(gMenu, "get_active", menu_get_active, 0); - rb_define_method(gMenu, "set_active", menu_set_active, 1); - rb_define_method(gMenu, "set_accelerator_table", menu_set_acceltbl, 1); - - /* MenuBar */ - rb_define_singleton_method(gMenuBar, "new", mbar_s_new, 0); - rb_define_method(gMenuBar, "append", mbar_append, 1); - rb_define_method(gMenuBar, "prepend", mbar_prepend, 1); - rb_define_method(gMenuBar, "insert", mbar_insert, 2); - - /* MenuItem */ - rb_define_singleton_method(gMenuItem, "new", mitem_s_new, -1); - rb_define_method(gMenuItem, "set_submenu", mitem_set_submenu, 1); - rb_define_method(gMenuItem, "set_placement", mitem_set_placement, 1); - rb_define_method(gMenuItem, "accelerator_size", mitem_accelerator_size, 0); - rb_define_method(gMenuItem, "accelerator_text", mitem_accelerator_text, 0); - rb_define_method(gMenuItem, "configure", mitem_configure, 2); - rb_define_method(gMenuItem, "select", mitem_select, 0); - rb_define_method(gMenuItem, "deselect", mitem_deselect, 0); - rb_define_method(gMenuItem, "activate", mitem_activate, 0); - rb_define_method(gMenuItem, "right_justify", mitem_right_justify, 0); - - /* CheckMenuItem */ - rb_define_singleton_method(gCMenuItem, "new", cmitem_s_new, -1); - rb_define_method(gCMenuItem, "set_state", cmitem_set_state, 1); - rb_define_method(gCMenuItem, "set_show_toggle", cmitem_set_show_toggle, 1); - rb_define_method(gCMenuItem, "toggled", cmitem_toggled, 0); - - /* RadioMenuItem */ - rb_define_singleton_method(gRMenuItem, "new", rmitem_s_new, -1); - rb_define_method(gRMenuItem, "group", rmitem_group, 0); - - /* NoteBook */ - rb_define_singleton_method(gNotebook, "new", note_s_new, 0); - rb_define_method(gNotebook, "append_page", note_append_page, 2); - rb_define_method(gNotebook, "prepend_page", note_prepend_page, 2); - rb_define_method(gNotebook, "insert_page", note_insert_page, 3); - rb_define_method(gNotebook, "remove_page", note_remove_page, 1); - rb_define_method(gNotebook, "set_page", note_set_page, 1); - rb_define_method(gNotebook, "cur_page", note_cur_page, 0); - rb_define_method(gNotebook, "page", note_cur_page, 0); - rb_define_method(gNotebook, "next_page", note_next_page, 0); - rb_define_method(gNotebook, "prev_page", note_prev_page, 0); - rb_define_method(gNotebook, "set_tab_pos", note_set_tab_pos, 1); - rb_define_method(gNotebook, "tab_pos", note_tab_pos, 0); - rb_define_method(gNotebook, "set_show_tabs", note_set_show_tabs, 1); - rb_define_method(gNotebook, "show_tabs", note_show_tabs, 0); - rb_define_method(gNotebook, "set_show_border", note_set_show_border, 1); - rb_define_method(gNotebook, "show_border", note_show_border, 0); - - /* OptionMenu */ - rb_define_singleton_method(gOptionMenu, "new", omenu_s_new, 0); - rb_define_method(gOptionMenu, "get_menu", omenu_get_menu, 0); - rb_define_method(gOptionMenu, "set_menu", omenu_set_menu, 1); - rb_define_method(gOptionMenu, "remove_menu", omenu_set_menu, 0); - rb_define_method(gOptionMenu, "set_history", omenu_set_history, 1); - - /* Pixmap */ - rb_define_singleton_method(gPixmap, "new", pixmap_s_new, 2); - rb_define_method(gPixmap, "set", pixmap_set, 2); - rb_define_method(gPixmap, "get", pixmap_get, 0); - - /* Preview */ - rb_define_singleton_method(gPreview, "new", preview_s_new, 1); - rb_define_method(gPreview, "size", preview_size, 2); - rb_define_method(gPreview, "put", preview_size, 8); - rb_define_method(gPreview, "put_row", preview_size, 5); - rb_define_method(gPreview, "draw_row", preview_size, 4); - rb_define_method(gPreview, "set_expand", preview_set_expand, 1); - rb_define_singleton_method(gPreview, "set_gamma", preview_set_gamma, 1); - rb_define_singleton_method(gPreview, "set_color_cube", - preview_set_color_cube, 4); - rb_define_singleton_method(gPreview, "set_install_cmap", - preview_set_install_cmap, 1); - rb_define_singleton_method(gPreview, "set_reserved", - preview_set_reserved, 1); - rb_define_singleton_method(gPreview, "get_visual", preview_get_visual, 0); - rb_define_singleton_method(gPreview, "get_cmap", preview_get_cmap, 0); - rb_define_singleton_method(gPreview, "get_info", preview_get_info, 0); - - /* ProgressBar */ - rb_define_singleton_method(gProgressBar, "new", pbar_s_new, 0); - rb_define_method(gProgressBar, "update", pbar_update, 1); - - /* ScrolledWindow */ - rb_define_singleton_method(gScrolledWin, "new", scwin_s_new, -1); - rb_define_method(gScrolledWin, "set_policy", scwin_set_policy, 2); - - /* Table */ - rb_define_singleton_method(gTable, "new", tbl_s_new, -1); - rb_define_method(gTable, "attach", tbl_attach, -1); - rb_define_method(gTable, "set_row_spacing", tbl_set_row_spacing, 2); - rb_define_method(gTable, "set_col_spacing", tbl_set_col_spacing, 2); - rb_define_method(gTable, "set_row_spacings", tbl_set_row_spacings, 1); - rb_define_method(gTable, "set_col_spacings", tbl_set_col_spacings, 1); - - /* Text */ - rb_define_singleton_method(gText, "new", txt_s_new, -1); - rb_define_method(gText, "set_editable", txt_set_editable, 1); - rb_define_method(gText, "set_adjustment", txt_set_adjustment, 2); - rb_define_method(gText, "set_point", txt_set_point, 1); - rb_define_method(gText, "get_point", txt_get_point, 0); - rb_define_method(gText, "get_length", txt_get_length, 0); - rb_define_method(gText, "freeze", txt_freeze, 0); - rb_define_method(gText, "thaw", txt_thaw, 0); - rb_define_method(gText, "insert", txt_insert, 4); - rb_define_method(gText, "backward_delete", txt_backward_delete, 1); - rb_define_method(gText, "forward_delete", txt_forward_delete, 1); - - /* Toolbar */ - rb_define_singleton_method(gToolbar, "new", tbar_s_new, -1); - rb_define_method(gToolbar, "append_item", tbar_append_item, 4); - rb_define_method(gToolbar, "prepend_item", tbar_prepend_item, 4); - rb_define_method(gToolbar, "insert_item", tbar_append_item, 5); - rb_define_method(gToolbar, "append_space", tbar_append_space, 0); - rb_define_method(gToolbar, "prepend_space", tbar_prepend_space, 0); - rb_define_method(gToolbar, "insert_space", tbar_append_space, 1); - rb_define_method(gToolbar, "set_orientation", tbar_set_orientation, 1); - rb_define_method(gToolbar, "set_style", tbar_set_style, 1); - rb_define_method(gToolbar, "set_space_size", tbar_set_space_size, 1); - rb_define_method(gToolbar, "set_tooltips", tbar_set_tooltips, 1); - - /* Tooltips */ - rb_define_singleton_method(gTooltips, "new", ttips_s_new, 0); - rb_define_method(gTooltips, "set_tips", ttips_set_tips, 2); - rb_define_method(gTooltips, "set_delay", ttips_set_delay, 1); - rb_define_method(gTooltips, "enable", ttips_enable, 0); - rb_define_method(gTooltips, "disable", ttips_disable, 0); - - /* Tree */ - rb_define_singleton_method(gTree, "new", tree_s_new, 0); - rb_define_method(gTree, "append", tree_append, 1); - rb_define_method(gTree, "prepend", tree_prepend, 1); - rb_define_method(gTree, "insert", tree_insert, 2); - - /* TreeItem */ - rb_define_singleton_method(gTreeItem, "new", titem_s_new, -1); - rb_define_method(gTreeItem, "set_subtree", titem_set_subtree, 1); - rb_define_method(gTreeItem, "select", titem_select, 0); - rb_define_method(gTreeItem, "deselect", titem_deselect, 0); - rb_define_method(gTreeItem, "expand", titem_expand, 0); - rb_define_method(gTreeItem, "collapse", titem_collapse, 0); - - /* ViewPort */ - rb_define_singleton_method(gViewPort, "new", vport_s_new, -1); - rb_define_method(gViewPort, "get_hadjustment", vport_get_hadj, 0); - rb_define_method(gViewPort, "get_vadjustment", vport_get_vadj, 0); - rb_define_method(gViewPort, "set_hadjustment", vport_set_hadj, 1); - rb_define_method(gViewPort, "set_vadjustment", vport_set_vadj, 1); - rb_define_method(gViewPort, "set_shadow_type", vport_set_shadow, 1); - - /* AcceleratorTable */ - /* Style */ - - /* Gtk module */ - rb_define_module_function(mGtk, "main", gtk_m_main, 0); - rb_define_module_function(mGtk, "timeout_add", timeout_add, -1); - rb_define_module_function(mGtk, "timeout_remove", timeout_remove, 1); - rb_define_module_function(mGtk, "idle_add", idle_add, -1); - rb_define_module_function(mGtk, "idle_remove", idle_remove, 1); - - rb_define_module_function(mGtk, "set_warning_handler", - set_warning_handler, -1); - rb_define_module_function(mGtk, "set_message_handler", - set_message_handler, -1); - rb_define_module_function(mGtk, "set_print_handler", - set_print_handler, -1); - - /* Gdk module */ - /* GdkFont */ - rb_define_method(gdkFont, "==", gdkfnt_equal, 1); - - /* GdkBitmap */ - rb_define_singleton_method(gdkBitmap, "new", gdkbmap_s_new, 3); - rb_define_singleton_method(gdkBitmap, "create_from_data", - gdkbmap_create_from_data, 4); - - /* GdkPixmap */ - rb_define_singleton_method(gdkPixmap, "new", gdkpmap_s_new, 4); - rb_define_singleton_method(gdkPixmap, "create_from_xpm", - gdkpmap_create_from_xpm, 3); - rb_define_singleton_method(gdkPixmap, "create_from_xpm_d", - gdkpmap_create_from_xpm, 3); - - /* GdkWindow */ - - /* GdkImage */ - - rb_define_const(mGtk, "VISIBLE", INT2FIX(GTK_VISIBLE)); - rb_define_const(mGtk, "MAPPED", INT2FIX(GTK_MAPPED)); - rb_define_const(mGtk, "UNMAPPED", INT2FIX(GTK_UNMAPPED)); - rb_define_const(mGtk, "REALIZED", INT2FIX(GTK_REALIZED)); - rb_define_const(mGtk, "SENSITIVE", INT2FIX(GTK_SENSITIVE)); - rb_define_const(mGtk, "PARENT_SENSITIVE", INT2FIX(GTK_PARENT_SENSITIVE)); - rb_define_const(mGtk, "NO_WINDOW", INT2FIX(GTK_NO_WINDOW)); - rb_define_const(mGtk, "HAS_FOCUS", INT2FIX(GTK_HAS_FOCUS)); - rb_define_const(mGtk, "CAN_FOCUS", INT2FIX(GTK_CAN_FOCUS)); - rb_define_const(mGtk, "HAS_DEFAULT", INT2FIX(GTK_HAS_DEFAULT)); - rb_define_const(mGtk, "CAN_DEFAULT", INT2FIX(GTK_CAN_DEFAULT)); - rb_define_const(mGtk, "PROPAGATE_STATE", INT2FIX(GTK_PROPAGATE_STATE)); - rb_define_const(mGtk, "ANCHORED", INT2FIX(GTK_ANCHORED)); - rb_define_const(mGtk, "BASIC", INT2FIX(GTK_BASIC)); - rb_define_const(mGtk, "USER_STYLE", INT2FIX(GTK_USER_STYLE)); - rb_define_const(mGtk, "GRAB_ALL", INT2FIX(GTK_GRAB_ALL)); - rb_define_const(mGtk, "REDRAW_PENDING", INT2FIX(GTK_REDRAW_PENDING)); - rb_define_const(mGtk, "RESIZE_PENDING", INT2FIX(GTK_RESIZE_PENDING)); - rb_define_const(mGtk, "RESIZE_NEEDED", INT2FIX(GTK_RESIZE_NEEDED)); - rb_define_const(mGtk, "HAS_SHAPE_MASK", INT2FIX(GTK_HAS_SHAPE_MASK)); - - /* GtkWindowType */ - rb_define_const(mGtk, "WINDOW_TOPLEVEL", INT2FIX(GTK_WINDOW_TOPLEVEL)); - rb_define_const(mGtk, "WINDOW_DIALOG", INT2FIX(GTK_WINDOW_DIALOG)); - rb_define_const(mGtk, "WIN_POS_NONE", INT2FIX(GTK_WIN_POS_NONE)); - rb_define_const(mGtk, "WIN_POS_CENTER", INT2FIX(GTK_WIN_POS_CENTER)); - rb_define_const(mGtk, "WIN_POS_MOUSE", INT2FIX(GTK_WIN_POS_MOUSE)); - - /* GtkDirectionType */ - rb_define_const(mGtk, "DIR_TAB_FORWARD", INT2FIX(GTK_DIR_TAB_FORWARD)); - rb_define_const(mGtk, "DIR_TAB_BACKWARD", INT2FIX(GTK_DIR_TAB_BACKWARD)); - rb_define_const(mGtk, "DIR_UP", INT2FIX(GTK_DIR_UP)); - rb_define_const(mGtk, "DIR_DOWN", INT2FIX(GTK_DIR_DOWN)); - rb_define_const(mGtk, "DIR_LEFT", INT2FIX(GTK_DIR_LEFT)); - rb_define_const(mGtk, "DIR_RIGHT", INT2FIX(GTK_DIR_RIGHT)); - - /* GtkPolicyType */ - rb_define_const(mGtk, "POLICY_ALWAYS", INT2FIX(GTK_POLICY_ALWAYS)); - rb_define_const(mGtk, "POLICY_AUTOMATIC", INT2FIX(GTK_POLICY_AUTOMATIC)); - - /* GtkSelectionMode */ - rb_define_const(mGtk, "SELECTION_SINGLE", INT2FIX(GTK_SELECTION_SINGLE)); - rb_define_const(mGtk, "SELECTION_BROWSE", INT2FIX(GTK_SELECTION_BROWSE)); - rb_define_const(mGtk, "SELECTION_MULTIPLE", INT2FIX(GTK_SELECTION_MULTIPLE)); - rb_define_const(mGtk, "SELECTION_EXTENDED", INT2FIX(GTK_SELECTION_EXTENDED)); - /* GtkPositionType */ - rb_define_const(mGtk, "POS_LEFT", INT2FIX(GTK_POS_LEFT)); - rb_define_const(mGtk, "POS_RIGHT", INT2FIX(GTK_POS_RIGHT)); - rb_define_const(mGtk, "POS_TOP", INT2FIX(GTK_POS_TOP)); - rb_define_const(mGtk, "POS_BOTTOM", INT2FIX(GTK_POS_BOTTOM)); - - /* GtkShadowType */ - rb_define_const(mGtk, "SHADOW_NONE", INT2FIX(GTK_SHADOW_NONE)); - rb_define_const(mGtk, "SHADOW_IN", INT2FIX(GTK_SHADOW_IN)); - rb_define_const(mGtk, "SHADOW_OUT", INT2FIX(GTK_SHADOW_OUT)); - rb_define_const(mGtk, "SHADOW_ETCHED_IN", INT2FIX(GTK_SHADOW_ETCHED_IN)); - rb_define_const(mGtk, "SHADOW_ETCHED_OUT", INT2FIX(GTK_SHADOW_ETCHED_OUT)); - /* GtkStateType */ - rb_define_const(mGtk, "STATE_NORMAL", INT2FIX(GTK_STATE_NORMAL)); - rb_define_const(mGtk, "STATE_ACTIVE", INT2FIX(GTK_STATE_ACTIVE)); - rb_define_const(mGtk, "STATE_PRELIGHT", INT2FIX(GTK_STATE_PRELIGHT)); - rb_define_const(mGtk, "STATE_SELECTED", INT2FIX(GTK_STATE_SELECTED)); - rb_define_const(mGtk, "STATE_INSENSITIVE", INT2FIX(GTK_STATE_INSENSITIVE)); - /* GtkAttachOptions */ - rb_define_const(mGtk, "EXPAND", INT2FIX(GTK_EXPAND)); - rb_define_const(mGtk, "SHRINK", INT2FIX(GTK_SHRINK)); - rb_define_const(mGtk, "FILL", INT2FIX(GTK_FILL)); - /* GtkSubmenuDirection */ - rb_define_const(mGtk, "DIRECTION_LEFT", INT2FIX(GTK_DIRECTION_LEFT)); - rb_define_const(mGtk, "DIRECTION_RIGHT", INT2FIX(GTK_DIRECTION_RIGHT)); - /* GtkSubmenuPlacement */ - rb_define_const(mGtk, "TOP_BOTTOM", INT2FIX(GTK_TOP_BOTTOM)); - rb_define_const(mGtk, "LEFT_RIGHT", INT2FIX(GTK_LEFT_RIGHT)); - /* GtkMetricType */ - rb_define_const(mGtk, "PIXELS", INT2FIX(GTK_PIXELS)); - rb_define_const(mGtk, "INCHES", INT2FIX(GTK_INCHES)); - rb_define_const(mGtk, "CENTIMETERS", INT2FIX(GTK_CENTIMETERS)); - - /* GtkArrowType */ - rb_define_const(mGtk, "ARROW_UP", INT2FIX(GTK_ARROW_UP)); - rb_define_const(mGtk, "ARROW_DOWN", INT2FIX(GTK_ARROW_DOWN)); - rb_define_const(mGtk, "ARROW_LEFT", INT2FIX(GTK_ARROW_LEFT)); - rb_define_const(mGtk, "ARROW_RIGHT", INT2FIX(GTK_ARROW_RIGHT)); - - /* GtkPreviewType */ - rb_define_const(mGtk, "PREVIEW_COLOR", INT2FIX(GTK_PREVIEW_COLOR)); - rb_define_const(mGtk, "PREVIEW_GRAYSCALE", INT2FIX(GTK_PREVIEW_GRAYSCALE)); - - rb_define_const(mGtk, "BUTTONBOX_DEFAULT", INT2FIX(GTK_BUTTONBOX_DEFAULT)); - rb_define_const(mGtk, "BUTTONBOX_SPREAD", INT2FIX(GTK_BUTTONBOX_SPREAD)); - rb_define_const(mGtk, "BUTTONBOX_EDGE", INT2FIX(GTK_BUTTONBOX_EDGE)); - rb_define_const(mGtk, "BUTTONBOX_START", INT2FIX(GTK_BUTTONBOX_START)); - rb_define_const(mGtk, "BUTTONBOX_END", INT2FIX(GTK_BUTTONBOX_END)); - - /* GtkToolbarStyle */ - rb_define_const(mGtk, "TOOLBAR_ICONS", INT2FIX(GTK_TOOLBAR_ICONS)); - rb_define_const(mGtk, "TOOLBAR_TEXT", INT2FIX(GTK_TOOLBAR_TEXT)); - rb_define_const(mGtk, "TOOLBAR_BOTH", INT2FIX(GTK_TOOLBAR_BOTH)); - - /* GtkOrientation */ - rb_define_const(mGtk, "ORIENTATION_HORIZONTAL", INT2FIX(GTK_ORIENTATION_HORIZONTAL)); - rb_define_const(mGtk, "ORIENTATION_VERTICAL", INT2FIX(GTK_ORIENTATION_VERTICAL)); - - /* GdkExtensionMode */ - rb_define_const(mGdk, "EXTENSION_EVENTS_NONE", INT2FIX(GDK_EXTENSION_EVENTS_NONE)); - rb_define_const(mGdk, "EXTENSION_EVENTS_ALL", INT2FIX(GDK_EXTENSION_EVENTS_ALL)); - rb_define_const(mGdk, "EXTENSION_EVENTS_CURSOR", INT2FIX(GDK_EXTENSION_EVENTS_CURSOR)); - - argc = RARRAY(rb_argv)->len; - argv = ALLOCA_N(char*,argc+1); - argv[0] = RSTRING(rb_argv0)->ptr; - for (i=0;iptr[i]) == T_STRING) { - argv[i+1] = RSTRING(RARRAY(rb_argv)->ptr[i])->ptr; - } - else { - argv[i+1] = ""; - } - } - argc++; - { - /* Gdk modifies sighandlers, sigh */ - RETSIGTYPE (*sigfunc[7])(); - - sigfunc[0] = signal(SIGHUP, SIG_IGN); - sigfunc[1] = signal(SIGINT, SIG_IGN); - sigfunc[2] = signal(SIGQUIT, SIG_IGN); - sigfunc[3] = signal(SIGBUS, SIG_IGN); - sigfunc[4] = signal(SIGSEGV, SIG_IGN); - sigfunc[5] = signal(SIGPIPE, SIG_IGN); - sigfunc[6] = signal(SIGTERM, SIG_IGN); - - gdk_init(&argc, &argv); - - signal(SIGHUP, sigfunc[0]); - signal(SIGINT, sigfunc[1]); - signal(SIGQUIT, sigfunc[2]); - signal(SIGBUS, sigfunc[3]); - signal(SIGSEGV, sigfunc[4]); - signal(SIGPIPE, sigfunc[5]); - signal(SIGTERM, sigfunc[6]); - } - - for (i=1;iptr[i] = str_taint(str_new2(argv[i])); - } - RARRAY(rb_argv)->len = argc-1; - - id_gtkdata = rb_intern("gtkdata"); - id_relatives = rb_intern("relatives"); - id_call = rb_intern("call"); - gtk_idle_add((GtkFunction)idle, 0); - - g_set_error_handler(gtkerr); - g_set_warning_handler(gtkerr); - rb_global_variable(&warn_handler); - rb_global_variable(&mesg_handler); - rb_global_variable(&print_handler); -} diff --git a/ext/gtk/test.rb b/ext/gtk/test.rb deleted file mode 100644 index 52ce5db7e0..0000000000 --- a/ext/gtk/test.rb +++ /dev/null @@ -1,96 +0,0 @@ -require 'gtk' - -def create_menu(depth) - return nil if depth < 1 - - menu = Gtk::Menu::new() - group = nil - submenu = nil - - for i in 0..4 - buf = sprintf("item %2d - %d", depth, i+1) -# menuitem = Gtk::MenuItem::new(buf) - menuitem = Gtk::RadioMenuItem.new(group, buf) - group = menuitem.group - if depth % 2 - menuitem.set_show_toggle TRUE - end - menu.append menuitem - menuitem.show - if depth > 0 - unless submenu - submenu = create_menu(depth - 1) - end - menuitem.set_submenu submenu - end - end - return menu -end - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.signal_connect("destroy") do - exit -end -window.signal_connect("delete_event") do - exit -end -window.set_title("menus") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add box1 -box1.show - -menubar = Gtk::MenuBar::new() -box1.pack_start menubar, FALSE, TRUE, 0 -menubar.show - -menu = create_menu(2) -menuitem = Gtk::MenuItem::new("test\nline2") -menuitem.set_submenu menu -menubar.append menuitem -menuitem.show - -menuitem = Gtk::MenuItem::new("foo") -menuitem.set_submenu menu -menubar.append menuitem -menuitem.show - -menuitem = Gtk::MenuItem::new("bar") -menuitem.set_submenu menu -menubar.append menuitem -menuitem.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width 10 -box1.pack_start box2, TRUE, TRUE, 0 -box2.show - -optionmenu = Gtk::OptionMenu::new() -optionmenu.set_menu create_menu(1) -optionmenu.set_history 4 -box2.pack_start optionmenu, TRUE, TRUE, 0 -optionmenu.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::HBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test.xpm b/ext/gtk/test.xpm deleted file mode 100644 index 9b0d2efdb2..0000000000 --- a/ext/gtk/test.xpm +++ /dev/null @@ -1,92 +0,0 @@ -/* XPM */ -static char *openfile[] = { -/* width height num_colors chars_per_pixel */ -" 20 19 66 2", -/* colors */ -".. c None", -".# c #000000", -".a c #dfdfdf", -".b c #7f7f7f", -".c c #006f6f", -".d c #00efef", -".e c #009f9f", -".f c #004040", -".g c #00bfbf", -".h c #ff0000", -".i c #ffffff", -".j c #7f0000", -".k c #007070", -".l c #00ffff", -".m c #00a0a0", -".n c #004f4f", -".o c #00cfcf", -".p c #8f8f8f", -".q c #6f6f6f", -".r c #a0a0a0", -".s c #7f7f00", -".t c #007f7f", -".u c #5f5f5f", -".v c #707070", -".w c #00f0f0", -".x c #009090", -".y c #ffff00", -".z c #0000ff", -".A c #00afaf", -".B c #00d0d0", -".C c #00dfdf", -".D c #005f5f", -".E c #00b0b0", -".F c #001010", -".G c #00c0c0", -".H c #000f0f", -".I c #00007f", -".J c #005050", -".K c #002f2f", -".L c #dfcfcf", -".M c #dfd0d0", -".N c #006060", -".O c #00e0e0", -".P c #00ff00", -".Q c #002020", -".R c #dfc0c0", -".S c #008080", -".T c #001f1f", -".U c #003f3f", -".V c #007f00", -".W c #00000f", -".X c #000010", -".Y c #00001f", -".Z c #000020", -".0 c #00002f", -".1 c #000030", -".2 c #00003f", -".3 c #000040", -".4 c #00004f", -".5 c #000050", -".6 c #00005f", -".7 c #000060", -".8 c #00006f", -".9 c #000070", -"#. c #7f7f80", -"## c #9f9f9f", -/* pixels */ -"........................................", -"........................................", -"........................................", -".......................#.#.#............", -".....................#.......#...#......", -"...............................#.#......", -".......#.#.#.................#.#.#......", -".....#.y.i.y.#.#.#.#.#.#.#..............", -".....#.i.y.i.y.i.y.i.y.i.#..............", -".....#.y.i.y.i.y.i.y.i.y.#..............", -".....#.i.y.i.y.#.#.#.#.#.#.#.#.#.#.#....", -".....#.y.i.y.#.s.s.s.s.s.s.s.s.s.#......", -".....#.i.y.#.s.s.s.s.s.s.s.s.s.#........", -".....#.y.#.s.s.s.s.s.s.s.s.s.#..........", -".....#.#.s.s.s.s.s.s.s.s.s.#............", -".....#.#.#.#.#.#.#.#.#.#.#..............", -"........................................", -"........................................", -"........................................" -}; diff --git a/ext/gtk/test0.rb b/ext/gtk/test0.rb deleted file mode 100644 index 4ff802d6ca..0000000000 --- a/ext/gtk/test0.rb +++ /dev/null @@ -1,13 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.border_width(10) -button = Gtk::Button::new("Hello World") -button.signal_connect("clicked") do - print "hello world\n" - exit -end -window.add(button) -button.show -window.show -Gtk::main() diff --git a/ext/gtk/test1.rb b/ext/gtk/test1.rb deleted file mode 100644 index 7d24199580..0000000000 --- a/ext/gtk/test1.rb +++ /dev/null @@ -1,41 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("entry") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -entry = Gtk::Entry::new() -entry.set_text("hello world") -box2.pack_start(entry, TRUE, TRUE, 0) -entry.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show -window.show - -Gtk::main() diff --git a/ext/gtk/test2.rb b/ext/gtk/test2.rb deleted file mode 100644 index 170de96185..0000000000 --- a/ext/gtk/test2.rb +++ /dev/null @@ -1,89 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("list") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -scrolled_win = Gtk::ScrolledWindow::new() -scrolled_win.set_policy(Gtk::POLICY_AUTOMATIC,Gtk::POLICY_AUTOMATIC) -box2.pack_start(scrolled_win, TRUE, TRUE, 0) -scrolled_win.show - -list = Gtk::List::new() -list.set_selection_mode(Gtk::SELECTION_MULTIPLE) -list.set_selection_mode(Gtk::SELECTION_BROWSE) -scrolled_win.add(list) -list.show - -for i in [ - "hello", - "world", - "blah", - "foo", - "bar", - "argh", - "spencer", - "is a", - "wussy", - "programmer", - ] - list_item = Gtk::ListItem::new(i) - list.add(list_item) - list_item.show -end - -button = Gtk::Button::new("add") -button.set_flags(Gtk::CAN_FOCUS); -i = 1 -button.signal_connect("clicked") do - list_item = Gtk::ListItem::new(format("added item %d", i)) - list.add(list_item) - list_item.show - i += 1 -end -box2.pack_start(button, FALSE, TRUE, 0) -button.show - -button = Gtk::Button::new("remove") -button.set_flags(Gtk::CAN_FOCUS); -button.signal_connect("clicked") do - tmp_list = list.selection - list.remove_items(tmp_list) - for i in tmp_list - i.destroy - end -end -box2.pack_start(button, FALSE, TRUE, 0) -button.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test3.rb b/ext/gtk/test3.rb deleted file mode 100644 index d73f72f9fa..0000000000 --- a/ext/gtk/test3.rb +++ /dev/null @@ -1,16 +0,0 @@ -require 'gtk' - -window = Gtk::FileSelection::new("file selection dialog") -window.position(Gtk::WIN_POS_MOUSE) -window.border_width(0) - -window.ok_button.signal_connect("clicked") do - print window.get_filename, "\n" -end -window.cancel_button.signal_connect("clicked") do - window.destroy - exit -end -window.show - -Gtk::main() diff --git a/ext/gtk/test4.rb b/ext/gtk/test4.rb deleted file mode 100644 index da0000c420..0000000000 --- a/ext/gtk/test4.rb +++ /dev/null @@ -1,77 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("notebook") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -notebook = Gtk::Notebook::new() -notebook.set_tab_pos(Gtk::POS_TOP) -box2.pack_start(notebook, TRUE, TRUE, 0) -notebook.show - -for i in 1..5 - frame = Gtk::Frame::new(format("Page %d", i)) - frame.border_width(10) - frame.set_usize(200, 150) - frame.show - - label = Gtk::Label::new(format("Box %d", i)) - frame.add label - label.show - - label = Gtk::Label::new(format("Tab %d", i)) - notebook.append_page frame, label -end - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::HBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show - -button = Gtk::Button::new("next") -button.signal_connect("clicked") do - notebook.next_page -end -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::Button::new("prev") -button.signal_connect("clicked") do - notebook.prev_page -end -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::Button::new("rotate") -button.signal_connect("clicked") do - notebook.set_tab_pos((notebook.tab_pos+1)%4) -end -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test5.rb b/ext/gtk/test5.rb deleted file mode 100644 index 714232079b..0000000000 --- a/ext/gtk/test5.rb +++ /dev/null @@ -1,63 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("buttons") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -table = Gtk::Table::new(3, 3, FALSE) -table.set_row_spacings(5) -table.set_col_spacings(5) -table.border_width(10) -box1.pack_start(table, TRUE, TRUE, 0) -table.show - -button = [] -0.upto(8) do |i| - button.push Gtk::Button::new("button"+(i+1)) -end -0.upto(8) do |i| - button[i].signal_connect("clicked") do |w| - if button[i+1].visible? - button[i+1].hide - else - button[i+1].show - end - end - button[i].show -end -table.attach(button[0], 0, 1, 0, 1, nil, nil, 0, 0) -table.attach(button[1], 1, 2, 1, 2, nil, nil, 0, 0) -table.attach(button[2], 2, 3, 2, 3, nil, nil, 0, 0) -table.attach(button[3], 0, 1, 2, 3, nil, nil, 0, 0) -table.attach(button[4], 2, 3, 0, 1, nil, nil, 0, 0) -table.attach(button[5], 1, 2, 2, 3, nil, nil, 0, 0) -table.attach(button[6], 1, 2, 0, 1, nil, nil, 0, 0) -table.attach(button[7], 2, 3, 1, 2, nil, nil, 0, 0) -table.attach(button[8], 0, 1, 1, 2, nil, nil, 0, 0) - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -close = Gtk::Button::new("close") -close.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(close, TRUE, TRUE, 0) -close.set_flags(Gtk::CAN_DEFAULT); -close.grab_default -close.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test6.rb b/ext/gtk/test6.rb deleted file mode 100644 index a589530ab0..0000000000 --- a/ext/gtk/test6.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("toggle buttons") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -button = Gtk::ToggleButton::new("button1") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::ToggleButton::new("button2") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::ToggleButton::new("button3") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -close = Gtk::Button::new("close") -close.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(close, TRUE, TRUE, 0) -close.set_flags(Gtk::CAN_DEFAULT); -close.grab_default -close.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test7.rb b/ext/gtk/test7.rb deleted file mode 100644 index 4d78648a3c..0000000000 --- a/ext/gtk/test7.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("check buttons") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -button = Gtk::CheckButton::new("button1") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::CheckButton::new("button2") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::CheckButton::new("button3") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -close = Gtk::Button::new("close") -close.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(close, TRUE, TRUE, 0) -close.set_flags(Gtk::CAN_DEFAULT); -close.grab_default -close.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test8.rb b/ext/gtk/test8.rb deleted file mode 100644 index 4ac4b0b8ad..0000000000 --- a/ext/gtk/test8.rb +++ /dev/null @@ -1,49 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("radio buttons") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add(box1) -box1.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width 10 -box1.pack_start(box2, TRUE, TRUE, 0) -box2.show - -button = Gtk::RadioButton::new("button1") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::RadioButton::new(button, "button2") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -button = Gtk::RadioButton::new(button, "button3") -box2.pack_start(button, TRUE, TRUE, 0) -button.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::VBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -close = Gtk::Button::new("close") -close.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(close, TRUE, TRUE, 0) -close.set_flags(Gtk::CAN_DEFAULT); -close.grab_default -close.show - -window.show - -Gtk::main() diff --git a/ext/gtk/test9.rb b/ext/gtk/test9.rb deleted file mode 100644 index 7bb3bf305e..0000000000 --- a/ext/gtk/test9.rb +++ /dev/null @@ -1,98 +0,0 @@ -require 'gtk' - -def create_bbox_window(horizontal, title, pos, spacing, cw, ch, layout) - window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) - window.set_title(title) - window.signal_connect("destroy") do - window.destroy - end - window.signal_connect("delete_event") do - window.hide - window.destroy - end - if horizontal - window.set_usize(550, 60) - window.set_uposition(150, pos) - else - window.set_usize(150, 400) - window.set_uposition(pos, 200) - end - box1 = Gtk::VBox::new(FALSE, 0) - window.add box1 - box1.show - if horizontal - bbox = Gtk::HButtonBox::new() - else - bbox = Gtk::VButtonBox::new() - end - bbox.set_layout layout - bbox.set_spacing spacing - bbox.set_child_size cw, ch - bbox.show - box1.border_width 25 - box1.pack_start(bbox, TRUE, TRUE, 0) - button = Gtk::Button::new("OK") - bbox.add button - button.signal_connect("clicked") do - window.hide - window.destroy - end - button.show - - button = Gtk::Button::new("Cancel") - bbox.add button - button.signal_connect("clicked") do - window.hide - window.destroy - end - button.show - - button = Gtk::Button::new("Help") - bbox.add button - button.show - - window.show -end - -def test_hbbox - create_bbox_window(TRUE, "Spread", 50, 40, 85, 25, Gtk::BUTTONBOX_SPREAD); - create_bbox_window(TRUE, "Edge", 250, 40, 85, 28, Gtk::BUTTONBOX_EDGE); - create_bbox_window(TRUE, "Start", 450, 40, 85, 25, Gtk::BUTTONBOX_START); - create_bbox_window(TRUE, "End", 650, 15, 30, 25, Gtk::BUTTONBOX_END); -end - -def test_vbbox - create_bbox_window(FALSE, "Spread", 50, 40, 85, 25, Gtk::BUTTONBOX_SPREAD); - create_bbox_window(FALSE, "Edge", 250, 40, 85, 28, Gtk::BUTTONBOX_EDGE); - create_bbox_window(FALSE, "Start", 450, 40, 85, 25, Gtk::BUTTONBOX_START); - create_bbox_window(FALSE, "End", 650, 15, 30, 25, Gtk::BUTTONBOX_END); -end - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.signal_connect("delete_event") do - window.destroy - exit -end -window.set_title("button box") -window.border_width(20) - -bbox = Gtk::HButtonBox::new() -window.add(bbox) -bbox.show - -button = Gtk::Button::new("Horizontal") -def button.clicked(*args) - test_hbbox -end -bbox.add button -button.show - -button = Gtk::Button::new("Vertical") -def button.clicked(*args) - test_vbbox -end -bbox.add button -button.show -window.show - -Gtk::main() diff --git a/ext/gtk/testa.rb b/ext/gtk/testa.rb deleted file mode 100644 index 00a6603dfd..0000000000 --- a/ext/gtk/testa.rb +++ /dev/null @@ -1,78 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.set_title("toolbar test") -window.set_policy(TRUE, TRUE, TRUE) -window.signal_connect("destroy") do - exit -end -window.signal_connect("delete_event") do - exit -end -window.border_width(0) -window.realize - -toolbar = Gtk::Toolbar::new(Gtk::ORIENTATION_HORIZONTAL, Gtk::TOOLBAR_BOTH) -toolbar.append_item "Horizontal", "Horizontal toolbar layout", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil, - #window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_orientation Gtk::ORIENTATION_HORIZONTAL -end -toolbar.append_item "Vertival", "Vertical toolbar layout", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil, #window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_orientation Gtk::ORIENTATION_VERTICAL -end -toolbar.append_space -toolbar.append_item "Icons", "Only show toolbar icons", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil, #window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_style Gtk::TOOLBAR_ICONS -end -toolbar.append_item "Text", "Only show toolbar text", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil,#window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_style Gtk::TOOLBAR_TEXT -end -toolbar.append_item "Both", "Show toolbar icons and text", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil, #window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_style Gtk::TOOLBAR_BOTH -end -toolbar.append_space -toolbar.append_item "Small", "User small spaces", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil,#window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_space_size 5 -end -toolbar.append_item "Big", "User big spaces", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil,#window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_space_size 10 -end -toolbar.append_space -toolbar.append_item "Enable", "Enable tooltips", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil,#window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_tooltips TRUE -end -toolbar.append_item "Disable", "Disable tooltips", - Gtk::Pixmap::new(*Gdk::Pixmap::create_from_xpm(window.window, - nil,#window.style.bg[Gtk::STATE_NORMAL], - "test.xpm")), nil do - toolbar.set_tooltips FALSE -end -window.add toolbar -toolbar.show -window.show - -Gtk::main() diff --git a/ext/gtk/testb.rb b/ext/gtk/testb.rb deleted file mode 100644 index 4e707bcf87..0000000000 --- a/ext/gtk/testb.rb +++ /dev/null @@ -1,78 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.signal_connect("destroy") do - exit -end -window.signal_connect("delete_event") do - exit -end -window.set_title("buttons") -window.border_width(0) - -box1 = Gtk::VBox::new(FALSE, 0) -window.add box1 -box1.show - -box2 = Gtk::HBox::new(FALSE, 5) -box2.border_width 10 -box1.pack_start box2, TRUE, TRUE, 0 -box2.show - -label = Gtk::Label::new("Hello World") -frame = Gtk::Frame::new("Frame 1") -box2.pack_start frame, TRUE, TRUE, 0 -frame.show - -box3 = Gtk::VBox::new(FALSE, 5) -box3.border_width 5 -frame.add box3 -box3.show - -button = Gtk::Button::new("switch") -button.signal_connect("clicked") do - label.reparent box3 -end -box3.pack_start button, FALSE, TRUE, 0 -button.show -box3.pack_start label, FALSE, TRUE, 0 -label.show - -frame = Gtk::Frame::new("Frame 2") -box2.pack_start frame, TRUE, TRUE, 0 -frame.show - -box4 = Gtk::VBox::new(FALSE, 5) -box4.border_width 5 -frame.add box4 -box4.show - -button = Gtk::Button::new("switch") -button.signal_connect("clicked") do - label.reparent box4 -end -box4.pack_start button, FALSE, TRUE, 0 -button.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::HBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show - -window.show - -Gtk::main() diff --git a/ext/gtk/testc.rb b/ext/gtk/testc.rb deleted file mode 100644 index 98c6466beb..0000000000 --- a/ext/gtk/testc.rb +++ /dev/null @@ -1,64 +0,0 @@ -require 'gtk' - -window = Gtk::Window::new(Gtk::WINDOW_TOPLEVEL) -window.signal_connect("destroy") do - exit -end -window.signal_connect("delete_event") do - exit -end -window.set_title("pixmap") -window.border_width(0) -window.realize - -box1 = Gtk::VBox::new(FALSE, 0) -window.add box1 -box1.show - -box2 = Gtk::HBox::new(FALSE, 10) -box2.border_width 10 -box1.pack_start box2, TRUE, TRUE, 0 -box2.show - -button = Gtk::Button::new() -box2.pack_start button, FALSE, FALSE, 0 -button.show - -style = button.style -pixmap, mask = Gdk::Pixmap::create_from_xpm(window.window, - nil, - #style.bg[Gtk::STATE_NORMAL], - "test.xpm") -pixmapwid = Gtk::Pixmap::new(pixmap, mask) -label = Gtk::Label::new("Pixmap\ntest") -box3 = Gtk::HBox::new(FALSE, 0) -box3.border_width 2 -box3.add pixmapwid -box3.add label -button.add box3 -pixmapwid.show -label.show -box3.show - -separator = Gtk::HSeparator::new() -box1.pack_start(separator, FALSE, TRUE, 0) -separator.show - -box2 = Gtk::HBox::new(FALSE, 10) -box2.border_width(10) -box1.pack_start(box2, FALSE, TRUE, 0) -box2.show - -button = Gtk::Button::new("close") -button.signal_connect("clicked") do - window.destroy - exit -end -box2.pack_start(button, TRUE, TRUE, 0) -button.set_flags(Gtk::CAN_DEFAULT); -button.grab_default -button.show - -window.show - -Gtk::main() diff --git a/ext/marshal/MANIFEST b/ext/marshal/MANIFEST deleted file mode 100644 index 54870ec71f..0000000000 --- a/ext/marshal/MANIFEST +++ /dev/null @@ -1,5 +0,0 @@ -MANIFEST -depend -extconf.rb -marshal.c -marshal.doc diff --git a/ext/marshal/depend b/ext/marshal/depend deleted file mode 100644 index c955eb2d59..0000000000 --- a/ext/marshal/depend +++ /dev/null @@ -1,2 +0,0 @@ -marshal.o: marshal.c ../../ruby.h ../../config.h ../../defines.h ../../io.h \ - ../../st.h diff --git a/ext/marshal/extconf.rb b/ext/marshal/extconf.rb deleted file mode 100644 index ab30bd117b..0000000000 --- a/ext/marshal/extconf.rb +++ /dev/null @@ -1 +0,0 @@ -create_makefile("marshal") diff --git a/ext/marshal/marshal.c b/ext/marshal/marshal.c deleted file mode 100644 index 99e87d0b5f..0000000000 --- a/ext/marshal/marshal.c +++ /dev/null @@ -1,850 +0,0 @@ -/************************************************ - - marshal.c - - - $Author$ - $Revision$ - $Date$ - created at: Thu Apr 27 16:30:01 JST 1995 - -************************************************/ - -#include "ruby.h" -#include "io.h" -#include "st.h" - -#define MARSHAL_MAJOR 4 -#define MARSHAL_MINOR 0 - -#define TYPE_NIL '0' -#define TYPE_TRUE 'T' -#define TYPE_FALSE 'F' -#define TYPE_FIXNUM 'i' - -#define TYPE_UCLASS 'C' -#define TYPE_OBJECT 'o' -#define TYPE_USERDEF 'u' -#define TYPE_FLOAT 'f' -#define TYPE_BIGNUM 'l' -#define TYPE_STRING '"' -#define TYPE_REGEXP '/' -#define TYPE_ARRAY '[' -#define TYPE_HASH '{' -#define TYPE_STRUCT 'S' -#define TYPE_MODULE 'M' - -#define TYPE_SYMBOL ':' -#define TYPE_SYMLINK ';' - -#define TYPE_LINK '@' - -extern VALUE cString; -extern VALUE cRegexp; -extern VALUE cArray; -extern VALUE cHash; - -VALUE rb_path2class(); - -static ID s_dump, s_load; - -struct dump_arg { - VALUE obj; - FILE *fp; - VALUE str; - st_table *symbol; - st_table *data; -}; - -struct dump_call_arg { - VALUE obj; - struct dump_arg *arg; - int limit; -}; - -static void w_long _((long, struct dump_arg*)); - -static void -w_byte(c, arg) - char c; - struct dump_arg *arg; -{ - if (arg->fp) putc(c, arg->fp); - else str_cat(arg->str, (UCHAR*)&c, 1); -} - -static void -w_bytes(s, n, arg) - char *s; - int n; - struct dump_arg *arg; -{ - w_long(n, arg); - if (arg->fp) { - fwrite(s, 1, n, arg->fp); - } - else { - str_cat(arg->str, s, n); - } -} - -static void -w_short(x, arg) - int x; - struct dump_arg *arg; -{ - int i; - - for (i=0; i> (i*8)) & 0xff, arg); - } -} - -static void -w_long(x, arg) - long x; - struct dump_arg *arg; -{ - char buf[sizeof(long)+1]; - int i, len = 0; - - if (x == 0) { - w_byte(0, arg); - return; - } - for (i=1;isymbol, id, &num)) { - w_byte(TYPE_SYMLINK, arg); - w_long(num, arg); - } - else { - w_byte(TYPE_SYMBOL, arg); - w_bytes(sym, strlen(sym), arg); - st_insert(arg->symbol, id, arg->symbol->num_entries); - } -} - -static void -w_unique(s, arg) - char *s; - struct dump_arg *arg; -{ - w_symbol(rb_intern(s), arg); -} - -static void w_object _((VALUE,struct dump_arg*,int)); -extern VALUE cIO, cBignum, cStruct; - -static int -hash_each(key, value, arg) - VALUE key, value; - struct dump_call_arg *arg; -{ - w_object(key, arg->arg, arg->limit); - w_object(value, arg->arg, arg->limit); - return ST_CONTINUE; -} - -static int -obj_each(id, value, arg) - ID id; - VALUE value; - struct dump_call_arg *arg; -{ - w_symbol(id, arg->arg); - w_object(value, arg->arg, arg->limit); - return ST_CONTINUE; -} - -static void -w_uclass(obj, class, arg) - VALUE obj, class; - struct dump_arg *arg; -{ - if (CLASS_OF(obj) != class) { - w_byte(TYPE_UCLASS, arg); - w_unique(rb_class2name(CLASS_OF(obj)), arg); - } -} - -static void -w_object(obj, arg, limit) - VALUE obj; - struct dump_arg *arg; - int limit; -{ - int n; - struct dump_call_arg c_arg; - - if (limit == 0) { - Fail("exceed depth limit"); - } - limit--; - c_arg.limit = limit; - c_arg.arg = arg; - - if (obj == Qnil) { - w_byte(TYPE_NIL, arg); - } - else if (obj == TRUE) { - w_byte(TYPE_TRUE, arg); - } - else if (obj == FALSE) { - w_byte(TYPE_FALSE, arg); - } - else if (FIXNUM_P(obj)) { -#if SIZEOF_LONG <= 4 - w_byte(TYPE_FIXNUM, arg); - w_long(FIX2INT(obj), arg); -#else - if (RSHIFT(obj, 32) == 0 || RSHIFT(obj, 32) == -1) { - w_byte(TYPE_FIXNUM, arg); - w_long(FIX2INT(obj), arg); - } - else { - obj = int2big(FIX2INT(obj)); - goto write_bignum; - } -#endif - } - else { - int num; - - if (st_lookup(arg->data, obj, &num)) { - w_byte(TYPE_LINK, arg); - w_long(num, arg); - return; - } - st_insert(arg->data, obj, arg->data->num_entries); - if (rb_respond_to(obj, s_dump)) { - VALUE v; - - w_byte(TYPE_USERDEF, arg); - w_unique(rb_class2name(CLASS_OF(obj)), arg); - v = rb_funcall(obj, s_dump, 1, limit); - if (TYPE(v) != T_STRING) { - TypeError("_dump_to must return String"); - } - w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, arg); - return; - } - - switch (BUILTIN_TYPE(obj)) { - case T_MODULE: - case T_CLASS: - w_byte(TYPE_MODULE, arg); - { - VALUE path = rb_class_path(obj); - w_bytes(RSTRING(path)->ptr, RSTRING(path)->len, arg); - } - return; - - case T_FLOAT: - w_byte(TYPE_FLOAT, arg); - w_float(RFLOAT(obj)->value, arg); - return; - - case T_BIGNUM: - write_bignum: - w_byte(TYPE_BIGNUM, arg); - { - char sign = RBIGNUM(obj)->sign?'+':'-'; - int len = RBIGNUM(obj)->len; - USHORT *d = RBIGNUM(obj)->digits; - - w_byte(sign, arg); - w_long(len, arg); - while (len--) { - w_short(*d, arg); - d++; - } - } - return; - - case T_STRING: - w_uclass(obj, cString, arg); - w_byte(TYPE_STRING, arg); - w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg); - return; - - case T_REGEXP: - w_uclass(obj, cRegexp, arg); - w_byte(TYPE_REGEXP, arg); - w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, arg); - w_byte(FL_TEST(obj, FL_USER1), arg); - return; - - case T_ARRAY: - w_uclass(obj, cArray, arg); - w_byte(TYPE_ARRAY, arg); - { - int len = RARRAY(obj)->len; - VALUE *ptr = RARRAY(obj)->ptr; - - w_long(len, arg); - while (len--) { - w_object(*ptr, arg, limit); - ptr++; - } - } - break; - - case T_HASH: - w_uclass(obj, cHash, arg); - w_byte(TYPE_HASH, arg); - w_long(RHASH(obj)->tbl->num_entries, arg); - st_foreach(RHASH(obj)->tbl, hash_each, &c_arg); - break; - - case T_STRUCT: - w_byte(TYPE_STRUCT, arg); - { - int len = RSTRUCT(obj)->len; - char *path = rb_class2name(CLASS_OF(obj)); - VALUE mem; - int i; - - w_unique(path, arg); - w_long(len, arg); - mem = rb_ivar_get(CLASS_OF(obj), rb_intern("__member__")); - if (mem == Qnil) { - Fatal("non-initialized struct"); - } - for (i=0; iptr[i]), arg); - w_object(RSTRUCT(obj)->ptr[i], arg, limit); - } - } - break; - - case T_OBJECT: - w_byte(TYPE_OBJECT, arg); - { - VALUE class = CLASS_OF(obj); - char *path; - - if (FL_TEST(class, FL_SINGLETON)) { - TypeError("singleton can't be dumped"); - } - path = rb_class2name(class); - w_unique(path, arg); - if (ROBJECT(obj)->iv_tbl) { - w_long(ROBJECT(obj)->iv_tbl->num_entries, arg); - st_foreach(ROBJECT(obj)->iv_tbl, obj_each, &c_arg); - } - else { - w_long(0, arg); - } - } - break; - - default: - TypeError("can't dump %s", rb_class2name(CLASS_OF(obj))); - break; - } - } -} - -static VALUE -dump(arg) - struct dump_call_arg *arg; -{ - w_object(arg->obj, arg->arg, arg->limit); -} - -static VALUE -dump_ensure(arg) - struct dump_arg *arg; -{ - st_free_table(arg->symbol); - st_free_table(arg->data); -} - -static VALUE -marshal_dump(argc, argv) - int argc; - VALUE argv; -{ - VALUE obj, port, a1, a2; - int limit = -1; - extern VALUE cIO; - struct dump_arg arg; - struct dump_call_arg c_arg; - - port = 0; - rb_scan_args(argc, argv, "12", &obj, &a1, &a2); - if (argc == 3) { - limit = NUM2INT(a2); - port = a1; - } - else if (argc == 2) { - if (FIXNUM_P(a1)) limit = FIX2INT(a1); - else port = a1; - } - if (port) { - if (obj_is_kind_of(port, cIO)) { - OpenFile *fptr; - - io_binmode(port); - GetOpenFile(port, fptr); - io_writable(fptr); - arg.fp = (fptr->f2) ? fptr->f2 : fptr->f; - } - else { - TypeError("instance of IO needed"); - } - } - else { - arg.fp = 0; - port = str_new(0, 0); - arg.str = port; - } - - arg.symbol = st_init_numtable(); - arg.data = st_init_numtable(); - c_arg.obj = obj; - c_arg.arg = &arg; - c_arg.limit = limit; - - w_byte(MARSHAL_MAJOR, &arg); - w_byte(MARSHAL_MINOR, &arg); - - rb_ensure(dump, &c_arg, dump_ensure, &arg); - - return port; -} - -struct load_arg { - FILE *fp; - UCHAR *ptr, *end; - st_table *symbol; - st_table *data; -}; - -static int -r_byte(arg) - struct load_arg *arg; -{ - if (arg->fp) return getc(arg->fp); - if (arg->ptr < arg->end) return *arg->ptr++; - return EOF; -} - -static USHORT -r_short(arg) - struct load_arg *arg; -{ - USHORT x; - int i; - - x = 0; - for (i=0; i 0) { - if (c > sizeof(long)) long_toobig((int)c); - x = 0; - for (i=0;i sizeof(long)) long_toobig((int)c); - x = -1; - for (i=0;ifp) { - len = fread(s, 1, len, arg->fp); - } - else { - if (arg->ptr + len > arg->end) { - len = arg->end - arg->ptr; - } - memcpy(s, arg->ptr, len); - arg->ptr += len; - } - - (s)[len] = '\0'; - *sp = s; - - return len; -} - -static ID -r_symbol(arg) - struct load_arg *arg; -{ - char *buf; - ID id; - char type; - - if (r_byte(arg) == TYPE_SYMLINK) { - int num = r_long(arg); - - if (st_lookup(arg->symbol, num, &id)) { - return id; - } - TypeError("bad symbol"); - } - r_bytes(buf, arg); - id = rb_intern(buf); - st_insert(arg->symbol, arg->symbol->num_entries, id); - - return id; -} - -static char* -r_unique(arg) - struct load_arg *arg; -{ - return rb_id2name(r_symbol(arg)); -} - -static VALUE -r_string(arg) - struct load_arg *arg; -{ - char *buf; - int len = r_bytes(buf, arg); - - return str_taint(str_new(buf, len)); -} - -static VALUE -r_regist(v, arg) - VALUE v; - struct load_arg *arg; -{ - st_insert(arg->data, arg->data->num_entries, v); - return v; -} - -static VALUE -r_object(arg) - struct load_arg *arg; -{ - VALUE v; - int type = r_byte(arg); - - switch (type) { - case EOF: - eof_error(); - return Qnil; - - case TYPE_LINK: - if (st_lookup(arg->data, r_long(arg), &v)) { - return v; - } - ArgError("dump format error (unlinked)"); - break; - - case TYPE_UCLASS: - { - VALUE c = rb_path2class(r_unique(arg)); - v = r_object(arg); - if (rb_special_const_p(v)) { - ArgError("dump format error (user class)"); - } - RBASIC(v)->class = c; - return v; - } - - case TYPE_NIL: - return Qnil; - - case TYPE_TRUE: - return TRUE; - - case TYPE_FALSE: - return FALSE; - - case TYPE_FIXNUM: - { - int i = r_long(arg); - return INT2FIX(i); - } - - case TYPE_FLOAT: - { -#ifndef atof - double atof(); -#endif - char *buf; - - r_bytes(buf, arg); - v = float_new(atof(buf)); - return r_regist(v, arg); - } - - case TYPE_BIGNUM: - { - int len; - USHORT *digits; - - NEWOBJ(big, struct RBignum); - OBJSETUP(big, cBignum, T_BIGNUM); - big->sign = (r_byte(arg) == '+'); - big->len = len = r_long(arg); - big->digits = digits = ALLOC_N(USHORT, len); - while (len--) { - *digits++ = r_short(arg); - } - big = RBIGNUM(big_norm((VALUE)big)); - if (TYPE(big) == T_BIGNUM) { - r_regist(big, arg); - } - return (VALUE)big; - } - - case TYPE_STRING: - return r_regist(r_string(arg), arg); - - case TYPE_REGEXP: - { - char *buf; - int len = r_bytes(buf, arg); - int ci = r_byte(arg); - return r_regist(reg_new(buf, len, ci), arg); - } - - case TYPE_ARRAY: - { - volatile int len = r_long(arg); - v = ary_new2(len); - r_regist(v, arg); - while (len--) { - ary_push(v, r_object(arg)); - } - return v; - } - - case TYPE_HASH: - { - int len = r_long(arg); - - v = hash_new(); - r_regist(v, arg); - while (len--) { - VALUE key = r_object(arg); - VALUE value = r_object(arg); - hash_aset(v, key, value); - } - return v; - } - - case TYPE_STRUCT: - { - VALUE class, mem, values; - int i, len; - int num = arg->data->num_entries; - - class = rb_path2class(r_unique(arg)); - mem = rb_ivar_get(class, rb_intern("__member__")); - if (mem == Qnil) { - Fatal("non-initialized struct"); - } - len = r_long(arg); - - values = ary_new2(len); - for (i=0; iptr[i] != INT2FIX(slot)) - TypeError("struct not compatible"); - struct_aset(v, INT2FIX(i), r_object(arg)); - } - return v; - } - break; - - case TYPE_USERDEF: - { - VALUE class; - int len; - - class = rb_path2class(r_unique(arg)); - if (rb_respond_to(class, s_load)) { - v = rb_funcall(class, s_load, 1, r_string(arg)); - return r_regist(v, arg); - } - TypeError("class %s needs to have method `_load_from'", - rb_class2name(class)); - } - break; - - case TYPE_OBJECT: - { - VALUE class; - int len; - - class = rb_path2class(r_unique(arg)); - len = r_long(arg); - v = obj_alloc(class); - r_regist(v, arg); - if (len > 0) { - while (len--) { - ID id = r_symbol(arg); - VALUE val = r_object(arg); - rb_ivar_set(v, id, val); - } - } - return v; - } - break; - - case TYPE_MODULE: - { - char *buf; - r_bytes(buf, arg); - return rb_path2class(buf); - } - - default: - ArgError("dump format error(0x%x)", type); - break; - } -} - -static VALUE -load(arg) - struct load_arg *arg; -{ - return r_object(arg); -} - -static VALUE -load_ensure(arg) - struct load_arg *arg; -{ - st_free_table(arg->symbol); - st_free_table(arg->data); -} - -static VALUE -marshal_load(self, port) - VALUE self, port; -{ - FILE *fp; - int major; - VALUE v; - OpenFile *fptr; - struct load_arg arg; - - if (TYPE(port) == T_STRING) { - arg.fp = 0; - arg.ptr = RSTRING(port)->ptr; - arg.end = arg.ptr + RSTRING(port)->len; - } - else { - if (obj_is_kind_of(port, cIO)) { - io_binmode(port); - GetOpenFile(port, fptr); - io_readable(fptr); - arg.fp = fptr->f; - } - else { - TypeError("instance of IO needed"); - } - } - - major = r_byte(&arg); - if (major == MARSHAL_MAJOR) { - if (r_byte(&arg) != MARSHAL_MINOR) { - Warning("Old marshal file format (can be read)"); - } - arg.symbol = st_init_numtable(); - arg.data = st_init_numtable(); - v = rb_ensure(load, &arg, load_ensure, &arg); - } - else { - TypeError("Old marshal file format (can't read)"); - } - - return v; -} - -Init_marshal() -{ - VALUE mMarshal = rb_define_module("Marshal"); - - s_dump = rb_intern("_dump_to"); - s_load = rb_intern("_load_from"); - rb_define_module_function(mMarshal, "dump", marshal_dump, -1); - rb_define_module_function(mMarshal, "load", marshal_load, 1); - rb_define_module_function(mMarshal, "restore", marshal_load, 1); -} diff --git a/ext/marshal/marshal.doc b/ext/marshal/marshal.doc deleted file mode 100644 index 7529e7942f..0000000000 --- a/ext/marshal/marshal.doc +++ /dev/null @@ -1,48 +0,0 @@ -.\" marshal.doc - -*- Indented-Text -*- created at: Tue May 16 12:18:08 JST 1995 - -** Marshal(モジュール) - -rubyオブジェクトをファイルに書き出したり,読みも度したりする機能を提供 -するモジュール.大部分のクラスのインスタンスを書き出す事ができるが,ファ -イルへの不可能なクラスも存在し(例:IO),そのようなクラスを書き出そうと -すると例外を発生させる. - -Methods: -Single Methods: - - dump(obj, port[, limit]) - - objを再帰的にファイルに書き出す.ファイルに書き出せないクラスのイ - ンスタンスをファイルに書き出そうとすると例外を発生させる.ファイル - に書き出せないクラスは以下の通り. - - Class, Module, Data - - また,これらのクラスを間接的に指すクラス(例えばIOのサブクラス)など - も書き出せない.portはIO(またはそのサブクラス)のインスタンスを指定 - する. - - 出力するオブジェクトがメソッド`_dump_to'を定義している場合には,ファ - イル出力はそのメソッドを使って行われる.メソッド`_dump_to'は引数と - して出力先のファイルオブジェクトを受け取る.インスタンスがメソッド - `_dump_to'を持つクラスは必ず同じフォーマットを読み戻す特異メソッド - `_load_from'を定義する必要がある. - - limitを指定した場合,limit段以上深くリンクしたオブジェクトをダンプ - できない(デフォルトは100レベル)。負のlimitを指定すると深さチェック - を行わない。 - - dumps(obj) - - dump()がファイルに書き出すのと同じ内容を含む文字列を返す. - - load(port) - - portからオブジェクトを読み込んで来て,元のオブジェクトと同じ状態を - もつオブジェクトを生成する.portは文字列かIO(またはそのサブクラス) - のインスタンスである. - -------------------------------------------------------- -Local variables: -fill-column: 70 -end: diff --git a/ext/md5/MANIFEST b/ext/md5/MANIFEST index e4f0004b4a..8057ebb06c 100644 --- a/ext/md5/MANIFEST +++ b/ext/md5/MANIFEST @@ -1,6 +1,7 @@ MANIFEST depend -md5.doc +md5.txt +md5.txt.jp md5.h md5c.c md5init.c diff --git a/ext/md5/md5init.c b/ext/md5/md5init.c index a825f96d47..e95e135812 100644 --- a/ext/md5/md5init.c +++ b/ext/md5/md5init.c @@ -77,7 +77,7 @@ md5_new(argc, argv, class) if (!NIL_P(arg)) { md5_update(obj, arg); } - rb_obj_call_init(obj); + rb_obj_call_init(obj, argc, argv); return obj; } 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= 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..5a350ae666 --- /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#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 +#endif + +#if defined(MSDOS) || defined(__OS2__) +#include +#include +#include +#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 +#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 + +static 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= *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; +} + + + +static 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> 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 || 0x7e0x80 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. +*/ + +static 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 */ + } +} + +static 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' ';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 */ + 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> 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 + +static 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); +} + +static 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 + ** ohta@src.ricoh.co.jp (Junn Ohta) + ** inouet@strl.nhk.or.jp (Tomoyuki Inoue) + ** kiri@pulser.win.or.jp (Tetsuaki Kiriyama) + ** Kimihiko Sato + ** 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] +M1FERED"6GIAR(%-E8V]N9"!3=&%G92"8I9=Y($AI +M#28./ +>@Y*#DR!+:6=O=2"!18&'@D^"8(._@]:$081@A+X* +eofeof +#' + +example['euc'] = <<'eofeof'.unpack('u')[0] +M1FERI?*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 +MHCK>.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.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.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 +M5)!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(&-A5)!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(&-AB1./RD;*$)H5)! +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(&-AB1./RD;*$)HB1./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(&-AB1./RD;*$)HB1./RD[=ALH0@H;)$(T +603MZ)$XE1ALH0EM+4U9)1WEH2S\]"@`* +eofeof +#" + +example['mime.base64'] = <<'eofeof'.unpack('u')[0] +M9W-M5"])3&YG$I+-&=Q=4,S24LS9W%Q0E%:3TUI-39,,S0Q-&=S5T)1 +M43!+9VUA1%9O3T@*9S)+1%1O3'=K8C)1;$E+;V=Q2T-X24MG9W5M0W%*3EEG +<$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)$2P@1$5.34%22R`@7"`B36EN(&OF<&AEX0208 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/socket/socket.c b/ext/socket/socket.c index e9bdbc9e8c..66bf56a251 100644 --- a/ext/socket/socket.c +++ b/ext/socket/socket.c @@ -96,11 +96,13 @@ sock_new(class, fd) fp->f = rb_fdopen(fd, "r"); #ifdef NT fp->finalize = sock_finalize; +#else + fd = dup(fd); #endif fp->f2 = rb_fdopen(fd, "w"); fp->mode = FMODE_READWRITE; rb_io_unbuffered(fp); - rb_obj_call_init((VALUE)sock); + rb_obj_call_init((VALUE)sock, 0, 0); return (VALUE)sock; } @@ -140,11 +142,13 @@ bsock_close_read(sock) rb_secure(4); GetOpenFile(sock, fptr); + shutdown(fileno(fptr->f), 0); if (fptr->f2 == 0) { return rb_io_close(sock); } - if (shutdown(fileno(fptr->f), 0) == -1) - rb_sys_fail(0); +#ifdef USE_THREAD + rb_thread_fd_close(fileno(fptr->f)); +#endif fptr->mode &= ~FMODE_READABLE; #ifdef NT free(fptr->f); @@ -168,8 +172,7 @@ bsock_close_write(sock) if (fptr->f2 == 0) { return rb_io_close(sock); } - if (shutdown(fileno(fptr->f), 1) == -1) - rb_sys_fail(0); + shutdown(fileno(fptr->f2), 1); fptr->mode &= ~FMODE_WRITABLE; #ifdef NT free(fptr->f2); diff --git a/ext/tcltklib/tcltklib.c b/ext/tcltklib/tcltklib.c index 625fe61ccc..11eb977861 100644 --- a/ext/tcltklib/tcltklib.c +++ b/ext/tcltklib/tcltklib.c @@ -16,10 +16,10 @@ # include #endif -/* for rb_debug */ +/* for ruby_debug */ -#define DUMP1(ARG1) if (rb_debug) { fprintf(stderr, "tcltklib: %s\n", ARG1);} -#define DUMP2(ARG1, ARG2) if (rb_debug) { fprintf(stderr, "tcltklib: ");\ +#define DUMP1(ARG1) if (ruby_debug) { fprintf(stderr, "tcltklib: %s\n", ARG1);} +#define DUMP2(ARG1, ARG2) if (ruby_debug) { fprintf(stderr, "tcltklib: ");\ fprintf(stderr, ARG1, ARG2); fprintf(stderr, "\n"); } /* #define DUMP1(ARG1) diff --git a/ext/tk/lib/tk.rb b/ext/tk/lib/tk.rb index e32723be96..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 @@ -2412,6 +2413,9 @@ class TkMenubutton +# by Yukihiro Matsumoto require 'tk.rb' class TkScrollbox #ifdef HAVE_SYS_TIME_H # include #else @@ -39,6 +40,8 @@ struct timeval { #endif /* NT */ #endif +VALUE rb_time_new _((time_t, time_t)); + #ifdef HAVE_UTIME_H #include #endif @@ -58,107 +61,13 @@ char *strrchr _((char*,char)); #include "macruby_missing.h" extern int fileno(FILE *stream); extern int utimes(); + char* strdup(char*); #endif VALUE rb_cFile; VALUE rb_mFileTest; static VALUE sStat; -VALUE -rb_file_open(fname, mode) - char *fname, *mode; -{ - OpenFile *fptr; - NEWOBJ(port, struct RFile); - OBJSETUP(port, rb_cFile, T_FILE); - MakeOpenFile(port, fptr); - - fptr->mode = rb_io_mode_flags(mode); - fptr->f = rb_fopen(fname, mode); - fptr->path = strdup(fname); - rb_obj_call_init((VALUE)port); - - return (VALUE)port; -} - -static VALUE -rb_file_s_open(argc, argv, klass) - int argc; - VALUE *argv; - VALUE klass; -{ - VALUE fname, vmode, file; - char *mode; - - rb_scan_args(argc, argv, "11", &fname, &vmode); - Check_SafeStr(fname); - if (!NIL_P(vmode)) { - mode = STR2CSTR(vmode); - } - else { - mode = "r"; - } - file = rb_file_open(RSTRING(fname)->ptr, mode); - - RBASIC(file)->klass = klass; - rb_obj_call_init(file); - if (rb_iterator_p()) { - return rb_ensure(rb_yield, file, rb_io_close, file); - } - - return file; -} - -static VALUE -rb_file_reopen(argc, argv, file) - int argc; - VALUE *argv; - VALUE file; -{ - VALUE fname, nmode; - char *mode; - OpenFile *fptr; - - rb_secure(4); - if (rb_scan_args(argc, argv, "11", &fname, &nmode) == 1) { - if (TYPE(fname) == T_FILE) { /* fname must be IO */ - return rb_io_reopen(file, fname); - } - } - - Check_SafeStr(fname); - if (!NIL_P(nmode)) { - mode = STR2CSTR(nmode); - } - else { - mode = "r"; - } - - GetOpenFile(file, fptr); - if (fptr->path) free(fptr->path); - fptr->path = strdup(RSTRING(fname)->ptr); - fptr->mode = rb_io_mode_flags(mode); - if (!fptr->f) { - fptr->f = rb_fopen(RSTRING(fname)->ptr, mode); - if (fptr->f2) { - fclose(fptr->f2); - fptr->f2 = NULL; - } - return file; - } - - if (freopen(RSTRING(fname)->ptr, mode, fptr->f) == NULL) { - rb_sys_fail(fptr->path); - } - if (fptr->f2) { - if (freopen(RSTRING(fname)->ptr, "w", fptr->f2) == NULL) { - rb_sys_fail(fptr->path); - } - } - - return file; -} - static int apply2files(func, vargs, arg) int (*func)(); @@ -1396,8 +1305,9 @@ rb_file_truncate(obj, len) #if defined(USE_THREAD) && defined(EWOULDBLOCK) static int -rb_thread_flock(fd, op) +rb_thread_flock(fd, op, fptr) int fd, op; + OpenFile *fptr; { if (rb_thread_alone() || (op & LOCK_NB)) { return flock(fd, op); @@ -1408,6 +1318,7 @@ rb_thread_flock(fd, op) case EINTR: /* can be happen? */ case EWOULDBLOCK: rb_thread_schedule(); /* busy wait */ + rb_io_check_closed(fptr); break; default: return -1; @@ -1415,7 +1326,7 @@ rb_thread_flock(fd, op) } return 0; } -#define flock rb_thread_flock +#define flock(fd, op) rb_thread_flock(fd, op, fptr) #endif static VALUE @@ -1452,7 +1363,7 @@ test_check(n, argc, argv) int i; n+=1; - if (n < argc) rb_raise(rb_eArgError, "Wrong # of arguments(%d for %d)", argc, n); + if (n < argc) rb_raise(rb_eArgError, "wrong # of arguments(%d for %d)", argc, n); for (i=1; i -#include "fnmatch.h" - -#ifdef USE_CWGUSI -#include -#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/gc.c b/gc.c index 31ed11196a..215479e0f6 100644 --- a/gc.c +++ b/gc.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Oct 5 09:44:46 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -42,10 +42,10 @@ static void run_final(); #if defined(MSDOS) || defined(__human68k__) #define GC_MALLOC_LIMIT 100000 #else -#define GC_MALLOC_LIMIT 200000 +#define GC_MALLOC_LIMIT 400000 #endif #endif -#define GC_NEWOBJ_LIMIT 1000 +#define GC_NEWOBJ_LIMIT 10000 static unsigned long malloc_memories = 0; static unsigned long alloc_objects = 0; @@ -389,10 +389,10 @@ rb_gc_mark(ptr) register RVALUE *obj = RANY(ptr); Top: - if (FIXNUM_P(obj)) return; /* fixnum not marked */ + if (FIXNUM_P(obj)) return; /* fixnum not marked */ if (rb_special_const_p((VALUE)obj)) return; /* special const not marked */ - if (obj->as.basic.flags == 0) return; /* free cell */ - if (obj->as.basic.flags & FL_MARK) return; /* already marked */ + if (obj->as.basic.flags == 0) return; /* free cell */ + if (obj->as.basic.flags & FL_MARK) return; /* already marked */ obj->as.basic.flags |= FL_MARK; @@ -598,7 +598,8 @@ rb_gc_mark(ptr) break; case T_SCOPE: - if (obj->as.scope.local_vars) { + if (obj->as.scope.local_vars && + obj->as.scope.flag != SCOPE_ALLOCA) { int n = obj->as.scope.local_tbl[0]+1; VALUE *vars = &obj->as.scope.local_vars[-1]; @@ -769,10 +770,10 @@ obj_free(obj) } break; case T_MATCH: - if (RANY(obj)->as.match.regs) + if (RANY(obj)->as.match.regs) { re_free_registers(RANY(obj)->as.match.regs); - if (RANY(obj)->as.match.regs) free(RANY(obj)->as.match.regs); + } break; case T_FILE: if (RANY(obj)->as.file.fptr) { @@ -807,7 +808,8 @@ obj_free(obj) return; /* no need to free iv_tbl */ case T_SCOPE: - if (RANY(obj)->as.scope.local_vars) { + if (RANY(obj)->as.scope.local_vars && + RANY(obj)->as.scope.flag != SCOPE_ALLOCA) { VALUE *vars = RANY(obj)->as.scope.local_vars-1; if (vars[0] == 0) free(RANY(obj)->as.scope.local_tbl); diff --git a/glob.c b/glob.c index 09a47e0aa4..57723d8fc7 100644 --- a/glob.c +++ b/glob.c @@ -95,7 +95,11 @@ # endif /* !SHELL */ #endif /* OPENDIR_NOT_ROBUST */ -#include "fnmatch.h" +#ifdef HAVE_FNMATCH_H +#include +#else +#include "missing/fnmatch.h" +#endif extern void *xmalloc (), *xrealloc (); #if !defined (HAVE_STDLIB_H) diff --git a/hash.c b/hash.c index 9141406410..34e7213856 100644 --- a/hash.c +++ b/hash.c @@ -6,12 +6,13 @@ $Date$ created at: Mon Nov 22 18:51:18 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ #include "ruby.h" #include "st.h" +#include "util.h" #include "rubysig.h" #include @@ -21,6 +22,10 @@ char *strchr _((char*,char)); #endif +#ifdef USE_CWGUSI +char* strdup(const char*); +#endif + #define HASH_FREEZE FL_USER1 #define HASH_DELETED FL_USER2 @@ -30,7 +35,7 @@ rb_hash_modify(hash) { if (FL_TEST(hash, HASH_FREEZE)) rb_raise(rb_eTypeError, "can't modify frozen hash"); - if (rb_safe_level() >= 4 && !FL_TEST(hash, FL_TAINT)) + if (!FL_TEST(hash, FL_TAINT) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't modify hash"); } @@ -127,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"); @@ -187,7 +192,7 @@ rb_hash_s_new(argc, argv, klass) VALUE *argv; VALUE klass; { - VALUE sz, ifnone; + VALUE ifnone; int size; NEWOBJ(hash, struct RHash); @@ -197,15 +202,11 @@ rb_hash_s_new(argc, argv, klass) hash->ifnone = Qnil; hash->tbl = 0; /* avoid GC crashing */ - rb_scan_args(argc, argv, "02", &ifnone, &sz); - if (NIL_P(sz)) { - size = 0; - } - else size = NUM2INT(sz); + rb_scan_args(argc, argv, "01", &ifnone); hash->ifnone = ifnone; - hash->tbl = st_init_table_with_size(&objhash, size); - rb_obj_call_init((VALUE)hash); + hash->tbl = st_init_table(&objhash); + rb_obj_call_init((VALUE)hash, argc, argv); return (VALUE)hash; } @@ -241,18 +242,16 @@ rb_hash_s_create(argc, argv, klass) int i; if (argc == 1 && TYPE(argv[0]) == T_HASH) { - if (klass == CLASS_OF(argv[0])) return argv[0]; - else { - NEWOBJ(hash, struct RHash); - OBJSETUP(hash, klass, T_HASH); + NEWOBJ(hash, struct RHash); + OBJSETUP(hash, klass, T_HASH); - hash->iter_lev = 0; - hash->ifnone = Qnil; - hash->tbl = 0; /* avoid GC crashing */ - hash->tbl = (st_table*)st_copy(RHASH(argv[0])->tbl); - rb_obj_call_init((VALUE)hash); - return (VALUE)hash; - } + hash->iter_lev = 0; + hash->ifnone = Qnil; + hash->tbl = 0; /* avoid GC crashing */ + hash->tbl = (st_table*)st_copy(RHASH(argv[0])->tbl); + rb_obj_call_init((VALUE)hash, argc, argv); + + return (VALUE)hash; } if (argc % 2 != 0) { @@ -263,7 +262,7 @@ rb_hash_s_create(argc, argv, klass) for (i=0; itbl, argv[i], argv[i+1]); } - rb_obj_call_init(hash); + rb_obj_call_init(hash, argc, argv); return hash; } @@ -428,7 +427,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; @@ -454,8 +453,8 @@ static int delete_if_i(key, value) VALUE key, value; { - if (key == Qnil) return ST_CONTINUE; - if (rb_yield(rb_assoc_new(key, value))) + if (value == Qnil) return ST_CONTINUE; + if (RTEST(rb_yield(rb_assoc_new(key, value)))) return ST_DELETE; return ST_CONTINUE; } @@ -500,7 +499,7 @@ rb_hash_aset(hash, key, val) st_insert(RHASH(hash)->tbl, key, val); } else { - st_add_direct(RHASH(hash)->tbl, rb_str_dup_frozen(key), val); + st_add_direct(RHASH(hash)->tbl, rb_str_new4(key), val); } return val; } @@ -544,7 +543,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; } @@ -561,7 +560,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; } @@ -578,7 +577,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; } @@ -595,7 +594,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; } @@ -625,7 +624,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); } @@ -687,7 +686,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; } @@ -708,7 +707,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; } @@ -740,7 +739,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; @@ -773,7 +772,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; @@ -807,7 +806,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; } @@ -827,7 +826,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; } @@ -841,7 +840,6 @@ rb_hash_update(hash1, hash2) return hash1; } -#ifndef __MACOS__ /* no environment variables on MacOS. */ static int path_tainted = -1; #ifndef NT @@ -849,6 +847,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; @@ -858,7 +874,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] == '=') { @@ -894,7 +912,7 @@ rb_f_getenv(obj, name) nam = str2cstr(name, &len); if (strlen(nam) != len) { - rb_raise(rb_eArgError, "Bad environment variable name"); + rb_raise(rb_eArgError, "bad environment variable name"); } env = getenv(nam); if (env) { @@ -988,8 +1006,8 @@ char *nam; return i; } -static void -my_setenv(name, value) +void +ruby_setenv(name, value) char *name; char *value; { @@ -1112,13 +1130,13 @@ rb_f_setenv(obj, nm, val) } name = str2cstr(nm, &nlen); - value = STR2CSTR(val &vlen); + value = str2cstr(val, &vlen); if (strlen(name) != nlen) - rb_raise(rb_eArgError, "Bad environment name"); + rb_raise(rb_eArgError, "bad environment variable name"); if (strlen(value) != vlen) - rb_raise(rb_eArgError, "Bad environment value"); + rb_raise(rb_eArgError, "bad environment variable value"); - my_setenv(name, value); + ruby_setenv(name, value); if (strcmp(name, "PATH") == 0) { if (OBJ_TAINTED(val)) { /* already tainted, no check */ @@ -1363,8 +1381,6 @@ env_to_hash(obj) return hash; } -#endif /* ifndef __MACOS__ no environment variables on MacOS. */ - void Init_Hash() { @@ -1414,6 +1430,7 @@ Init_Hash() rb_define_method(rb_cHash,"shift", rb_hash_shift, 0); rb_define_method(rb_cHash,"delete", rb_hash_delete, 1); rb_define_method(rb_cHash,"delete_if", rb_hash_delete_if, 0); + rb_define_method(rb_cHash,"reject!", rb_hash_delete_if, 0); rb_define_method(rb_cHash,"clear", rb_hash_clear, 0); rb_define_method(rb_cHash,"invert", rb_hash_invert, 0); rb_define_method(rb_cHash,"update", rb_hash_update, 1); @@ -1438,6 +1455,7 @@ Init_Hash() rb_define_singleton_method(envtbl,"each_value", env_each_value, 0); rb_define_singleton_method(envtbl,"delete", env_delete_method, 1); rb_define_singleton_method(envtbl,"delete_if", env_delete_if, 0); + rb_define_singleton_method(envtbl,"reject!", env_delete_if, 0); rb_define_singleton_method(envtbl,"to_s", env_to_s, 0); rb_define_singleton_method(envtbl,"rehash", env_none, 0); rb_define_singleton_method(envtbl,"to_a", env_to_a, 0); diff --git a/inits.c b/inits.c index 3708edc03a..170912d443 100644 --- a/inits.c +++ b/inits.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Dec 28 16:01:58 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -31,6 +31,7 @@ void Init_marshal _((void)); void Init_Numeric _((void)); void Init_Object _((void)); void Init_pack _((void)); +void Init_Precision _((void)); void Init_sym _((void)); void Init_process _((void)); void Init_Random _((void)); @@ -51,6 +52,7 @@ rb_call_inits() Init_Object(); Init_Comparable(); Init_Enumerable(); + Init_Precision(); Init_eval(); Init_String(); Init_Exception(); diff --git a/instruby.rb b/instruby.rb index d489e0f838..6f46f86ee2 100644 --- a/instruby.rb +++ b/instruby.rb @@ -15,43 +15,54 @@ else prefix = CONFIG["prefix"] end ruby_install_name = CONFIG["ruby_install_name"] -bindir = CONFIG["bindir"] -libdir = CONFIG["libdir"] -pkglibdir = libdir + "/" + ruby_install_name +bindir = destdir+CONFIG["bindir"] +libdir = destdir+CONFIG["libdir"] +#pkglibdir = libdir + "/" + ruby_install_name+"/"+CONFIG["MAJOR"]+"."+CONFIG["MINOR"] +pkglibdir = libdir + "/ruby/"+CONFIG["MAJOR"]+"."+CONFIG["MINOR"] archdir = pkglibdir + "/" + CONFIG["arch"] -mandir = CONFIG["mandir"] + "/man1" +mandir = destdir+CONFIG["mandir"] + "/man1" wdir = Dir.getwd -File.makedirs "#{destdir}#{bindir}", true -File.install "ruby#{binsuffix}", - "#{destdir}#{bindir}/#{ruby_install_name}#{binsuffix}", 0755, true +File.makedirs bindir, true +File.install ruby_install_name+binsuffix, + "#{bindir}/#{ruby_install_name}#{binsuffix}", 0755, true for dll in Dir['*.dll'] - File.install dll, "#{destdir}#{bindir}/#{dll}", 0755, true + File.install dll, "#{bindir}/#{dll}", 0755, true end -File.makedirs "#{destdir}#{libdir}", true -for lib in ["libruby.so", "libruby.so.LIB"] +File.makedirs libdir, true +for lib in ["libruby.so.LIB", CONFIG["LIBRUBY_SO"]] if File.exist? lib - File.install lib, "#{destdir}#{libdir}", 0644, true + File.install lib, libdir, 0644, true end end -File.makedirs "#{destdir}#{pkglibdir}", true -File.makedirs "#{destdir}#{archdir}", true +Dir.chdir libdir +if File.exist? CONFIG["LIBRUBY_SO"] + for link in CONFIG["LIBRUBY_ALIASES"].split + if File.exist? link + File.delete link + end + File.symlink CONFIG["LIBRUBY_SO"], link + print "link #{CONFIG['LIBRUBY_SO']} -> #{link}\n" + end +end +Dir.chdir wdir +File.makedirs pkglibdir, true +File.makedirs archdir, true Dir.chdir "ext" system "../miniruby#{binsuffix} extmk.rb install #{destdir}" Dir.chdir CONFIG["srcdir"] for f in Dir["lib/*.rb"] - File.install f, "#{destdir}#{pkglibdir}", 0644, true + File.install f, pkglibdir, 0644, true end -File.makedirs(archdir,true) for f in Dir["*.h"] - File.install f, "#{destdir}#{archdir}", 0644, true + File.install f, archdir, 0644, true end -File.install "libruby.a", "#{destdir}#{archdir}", 0644, true +File.install wdir+'/'+CONFIG['LIBRUBY_A'], archdir, 0644, true -File.makedirs "#{destdir}#{mandir}", true -File.install "ruby.1", "#{destdir}#{mandir}", 0644, true +File.makedirs mandir, true +File.install "ruby.1", mandir, 0644, true Dir.chdir wdir -File.install "config.h", "#{destdir}#{archdir}", 0644, true -File.install "rbconfig.rb", "#{destdir}#{archdir}", 0644, true +File.install "config.h", archdir, 0644, true +File.install "rbconfig.rb", archdir, 0644, true # vi:set sw=2: diff --git a/intern.h b/intern.h index 8b88751469..9c72f72db1 100644 --- a/intern.h +++ b/intern.h @@ -6,18 +6,18 @@ void rb_mem_clear _((register VALUE*, register size_t)); VALUE rb_assoc_new _((VALUE, VALUE)); VALUE rb_ary_new _((void)); -VALUE rb_ary_new2 _((size_t)); -VALUE rb_ary_new3 __((size_t,...)); -VALUE rb_ary_new4 _((size_t, VALUE *)); +VALUE rb_ary_new2 _((int)); +VALUE rb_ary_new3 __((int,...)); +VALUE rb_ary_new4 _((int, VALUE *)); VALUE rb_ary_freeze _((VALUE)); VALUE rb_ary_aref _((int, VALUE*, VALUE)); -void rb_ary_store _((VALUE, size_t, VALUE)); +void rb_ary_store _((VALUE, int, VALUE)); VALUE rb_ary_to_s _((VALUE)); VALUE rb_ary_push _((VALUE, VALUE)); VALUE rb_ary_pop _((VALUE)); VALUE rb_ary_shift _((VALUE)); VALUE rb_ary_unshift _((VALUE, VALUE)); -VALUE rb_ary_entry _((VALUE, size_t)); +VALUE rb_ary_entry _((VALUE, int)); VALUE rb_ary_each _((VALUE)); VALUE rb_ary_join _((VALUE, VALUE)); VALUE rb_ary_print_on _((VALUE, VALUE)); @@ -117,7 +117,7 @@ void rb_load_protect _((VALUE, int, int*)); 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_init _((VALUE, int, VALUE*)); VALUE rb_class_new_instance _((int, VALUE*, VALUE)); VALUE rb_f_lambda _((void)); VALUE rb_protect _((VALUE (*)(), VALUE, int*)); @@ -127,7 +127,7 @@ void rb_thread_start_timer _((void)); void rb_thread_stop_timer _((void)); void rb_thread_schedule _((void)); void rb_thread_wait_fd _((int)); -void rb_thread_fd_writable _((int)); +int rb_thread_fd_writable _((int)); int rb_thread_alone _((void)); void rb_thread_sleep _((int)); void rb_thread_sleep_forever _((void)); @@ -142,9 +142,9 @@ VALUE rb_thread_main _((void)); VALUE rb_thread_local_aref _((VALUE, ID)); VALUE rb_thread_local_aset _((VALUE, ID, VALUE)); /* file.c */ -VALUE rb_file_open _((char*, char*)); int eaccess _((char*, int)); VALUE rb_file_s_expand_path _((int, VALUE *)); +void rb_file_const _((char*, VALUE)); /* gc.c */ void rb_global_variable _((VALUE*)); void rb_gc_mark_locations _((VALUE*, VALUE*)); @@ -176,8 +176,7 @@ VALUE rb_io_ungetc _((VALUE, VALUE)); VALUE rb_io_close _((VALUE)); VALUE rb_io_eof _((VALUE)); VALUE rb_io_binmode _((VALUE)); -int rb_io_mode_flags _((char*)); -VALUE rb_io_reopen _((VALUE, VALUE)); +VALUE rb_file_open _((char*, char*)); VALUE rb_gets _((void)); void rb_str_setter _((VALUE, ID, VALUE*)); /* numeric.c */ @@ -230,7 +229,7 @@ VALUE rb_reg_last_match _((VALUE)); VALUE rb_reg_match_pre _((VALUE)); VALUE rb_reg_match_post _((VALUE)); VALUE rb_reg_match_last _((VALUE)); -VALUE rb_reg_new _((char*, size_t, int)); +VALUE rb_reg_new _((char*, int, int)); VALUE rb_reg_match _((VALUE, VALUE)); VALUE rb_reg_match2 _((VALUE)); int rb_reg_options _((VALUE)); @@ -238,6 +237,7 @@ char*rb_get_kcode _((void)); void rb_set_kcode _((char*)); int rb_ignorecase_p _((void)); /* ruby.c */ +extern VALUE rb_argv0; void rb_load_file _((char*)); void ruby_script _((char*)); void ruby_prog_init _((void)); @@ -257,23 +257,22 @@ void rb_trap_exec _((void)); /* sprintf.c */ VALUE rb_f_sprintf _((int, VALUE*)); /* string.c */ -VALUE rb_str_new _((char*, size_t)); +VALUE rb_str_new _((char*, int)); VALUE rb_str_new2 _((char*)); VALUE rb_str_new3 _((VALUE)); VALUE rb_str_new4 _((VALUE)); -VALUE rb_tainted_str_new _((char*, size_t)); +VALUE rb_tainted_str_new _((char*, int)); VALUE rb_tainted_str_new2 _((char*)); VALUE rb_obj_as_string _((VALUE)); VALUE rb_str_to_str _((VALUE)); VALUE rb_str_dup _((VALUE)); VALUE rb_str_plus _((VALUE, VALUE)); VALUE rb_str_times _((VALUE, VALUE)); -VALUE rb_str_substr _((VALUE, size_t, size_t)); +VALUE rb_str_substr _((VALUE, int, int)); void rb_str_modify _((VALUE)); VALUE rb_str_freeze _((VALUE)); -VALUE rb_str_dup_frozen _((VALUE)); -VALUE rb_str_resize _((VALUE, size_t)); -VALUE rb_str_cat _((VALUE, char*, size_t)); +VALUE rb_str_resize _((VALUE, int)); +VALUE rb_str_cat _((VALUE, char*, int)); VALUE rb_str_concat _((VALUE, VALUE)); int rb_str_hash _((VALUE)); int rb_str_cmp _((VALUE, VALUE)); @@ -287,8 +286,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 5573e76a64..01c509c5ec 100644 --- a/io.c +++ b/io.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Oct 15 18:08:59 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -20,7 +20,7 @@ #if !defined(DJGPP) && !defined(NT) && !defined(__human68k__) #include #endif -#if defined(HAVE_FCNTL) +#if defined(HAVE_FCNTL) || defined(NT) #include #endif @@ -54,10 +54,14 @@ struct timeval { #include #include #include + extern char* strdup(const char*); #endif extern void Init_File _((void)); #ifdef __BEOS__ +# ifdef _X86_ +# define NOFILE (OPEN_MAX) +# endif #include #endif @@ -99,7 +103,7 @@ static VALUE lineno; #elif defined(__BEOS__) # define ReadDataPending(fp) (fp->_state._eof == 0) #elif defined(USE_CWGUSI) -# define ReadDataPending(fp) (fp->state.eof == 0) +# define READ_DATA_PENDING(fp) (fp->state.eof == 0) #else /* requires systems own version of the ReadDataPending() */ extern int ReadDataPending(); @@ -110,7 +114,10 @@ extern int ReadDataPending(); # define READ_CHECK(fp) 0 #else # define READ_CHECK(fp) do {\ - if (!READ_DATA_PENDING(fp)) rb_thread_wait_fd(fileno(fp));\ + if (!READ_DATA_PENDING(fp)) {\ + rb_thread_wait_fd(fileno(fp));\ + rb_io_check_closed(fptr);\ + }\ } while(0) #endif @@ -840,8 +847,14 @@ static void rb_io_fptr_close(fptr) OpenFile *fptr; { + int fd; + if (fptr->f == NULL && fptr->f2 == NULL) return; +#ifdef USE_THREAD + rb_thread_fd_close(fileno(fptr->f)); +#endif + if (fptr->finalize) { (*fptr->finalize)(fptr); } @@ -953,7 +966,9 @@ rb_io_syswrite(io, str) f = GetWriteFile(fptr); #ifdef USE_THREAD - rb_thread_fd_writable(fileno(f)); + if (!rb_thread_fd_writable(fileno(f))) { + rb_io_check_closed(fptr); + } #endif n = write(fileno(f), RSTRING(str)->ptr, RSTRING(str)->len); @@ -1014,9 +1029,9 @@ rb_io_binmode(io) rb_sys_fail(fptr->path); # else /* USE_CWGUSI */ if (fptr->f) - fptr->f->mode.binrb_ary_io = 1; + fptr->f->mode.binary_io = 1; if (fptr->f2) - fptr->f2->mode.binrb_ary_io = 1; + fptr->f2->mode.binary_io = 1; # endif /* USE_CWGUSI */ #endif @@ -1025,7 +1040,7 @@ rb_io_binmode(io) return io; } -int +static int rb_io_mode_flags(mode) char *mode; { @@ -1042,7 +1057,8 @@ rb_io_mode_flags(mode) flags |= FMODE_WRITABLE; break; default: - rb_raise(rb_eArgError, "illegal access mode"); + error: + rb_raise(rb_eArgError, "illegal access mode %s", mode); } if (mode[1] == 'b') { @@ -1052,29 +1068,112 @@ rb_io_mode_flags(mode) if (mode[1] == '+') { flags |= FMODE_READWRITE; + if (mode[2] != 0) goto error; } + else if (mode[1] != 0) goto error; return flags; } +static int +rb_io_mode_flags2(mode) + int mode; +{ + int flags; + + switch (mode & (O_RDONLY|O_WRONLY|O_RDWR)) { + case O_RDONLY: + flags = FMODE_READABLE; + break; + case O_WRONLY: + flags = FMODE_WRITABLE; + break; + case O_RDWR: + flags = FMODE_WRITABLE|FMODE_READABLE; + break; + } + +#ifdef O_BINARY + if (mode & O_BINARY) { + flags |= FMODE_BINMODE; + } +#endif + + return flags; +} + +static char* +rb_io_flags_mode(flags) + int flags; +{ + static char mode[4]; + char *p = mode; + + switch (flags & (O_RDONLY|O_WRONLY|O_RDWR)) { + case O_RDONLY: + *p++ = 'r'; + break; + case O_WRONLY: + *p++ = 'w'; + break; + case O_RDWR: + *p++ = 'w'; + *p++ = '+'; + break; + } + *p++ = '\0'; +#ifdef O_BINARY + if (flags & O_BINARY) { + if (mode[1] == '+') { + mode[1] = 'b'; mode[2] = '+'; mode[3] = '\0'; + } + else { + mode[1] = 'b'; mode[2] = '\0'; + } + } +#endif + return mode; +} + +static int +rb_open(fname, flag, mode) + char *fname; + int flag; + unsigned int mode; +{ + int fd; + + fd = open(fname, flag, mode); + if (fd < 0) { + if (errno == EMFILE || errno == ENFILE) { + rb_gc(); + fd = open(fname, flag, mode); + } + if (fd < 0) { + rb_sys_fail(fname); + } + } + return fd; +} + FILE * rb_fopen(fname, mode) char *fname; char *mode; { - FILE *f; + FILE *file; - f = fopen(fname, mode); - if (f == NULL) { + file = fopen(fname, mode); + if (file == NULL) { if (errno == EMFILE || errno == ENFILE) { rb_gc(); - f = fopen(fname, mode); + file = fopen(fname, mode); } - if (f == NULL) { + if (file == NULL) { rb_sys_fail(fname); } } - return f; + return file; } FILE * @@ -1082,18 +1181,65 @@ rb_fdopen(fd, mode) int fd; char *mode; { - FILE *f; + FILE *file; - f = fdopen(fd, mode); - if (f == NULL) { - if (errno == EMFILE) { - f = fdopen(fd, mode); + file = fdopen(fd, mode); + if (file == NULL) { + if (errno == EMFILE || errno == ENFILE) { + rb_gc(); + file = fdopen(fd, mode); } - if (f == NULL) { + if (file == NULL) { rb_sys_fail(0); } } - return f; + return file; +} + +VALUE +rb_file_open(fname, mode) + char *fname, *mode; +{ + OpenFile *fptr; + NEWOBJ(port, struct RFile); + OBJSETUP(port, rb_cFile, T_FILE); + MakeOpenFile(port, fptr); + + fptr->mode = rb_io_mode_flags(mode); + fptr->f = rb_fopen(fname, mode); + fptr->path = strdup(fname); + rb_obj_call_init((VALUE)port, 0, 0); + + return (VALUE)port; +} + +VALUE +rb_file_sysopen(fname, flags, mode) + char *fname; + int flags, mode; +{ +#ifdef USE_CWGUSI + if (mode != 0666) { + rb_warn("can't specify file mode on this platform"); + } + return rb_file_open(fname, rb_io_flags_mode(flags)); +#else + OpenFile *fptr; + int fd; + char *m; + NEWOBJ(port, struct RFile); + OBJSETUP(port, rb_cFile, T_FILE); + 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); + rb_obj_call_init((VALUE)port, 0, 0); + + return (VALUE)port; +#endif } #if defined (NT) || defined(DJGPP) || defined(__CYGWIN32__) || defined(__human68k__) @@ -1205,7 +1351,7 @@ pipe_open(pname, mode) fptr->f2 = f; rb_io_unbuffered(fptr); } - rb_obj_call_init((VALUE)port); + rb_obj_call_init((VALUE)port, 0, 0); return (VALUE)port; } #else @@ -1293,7 +1439,7 @@ pipe_open(pname, mode) fptr->finalize = pipe_finalize; pipe_add_fptr(fptr); #endif - rb_obj_call_init((VALUE)port); + rb_obj_call_init((VALUE)port, 0, 0); return (VALUE)port; } } @@ -1329,15 +1475,41 @@ rb_io_s_popen(argc, argv, self) } static VALUE -rb_io_open(fname, mode) - char *fname, *mode; +rb_file_s_open(argc, argv, klass) + int argc; + VALUE *argv; + VALUE klass; { - if (fname[0] == '|') { - return pipe_open(fname+1, mode); + VALUE fname, vmode, file, perm; + char *path, *mode; + + rb_scan_args(argc, argv, "12", &fname, &vmode, &perm); + Check_SafeStr(fname); + path = RSTRING(fname)->ptr; + + if (FIXNUM_P(vmode)) { + int flags = FIX2INT(vmode); + int fmode = NIL_P(perm) ? 0666 : FIX2INT(perm); + + file = rb_file_sysopen(path, flags, fmode); } else { - return rb_file_open(fname, mode); + if (!NIL_P(vmode)) { + mode = STR2CSTR(vmode); + } + else { + mode = "r"; + } + file = rb_file_open(RSTRING(fname)->ptr, mode); } + + RBASIC(file)->klass = klass; + rb_obj_call_init(file, 0, 0); + if (rb_iterator_p()) { + return rb_ensure(rb_yield, file, rb_io_close, file); + } + + return file; } static VALUE @@ -1346,24 +1518,31 @@ rb_f_open(argc, argv) VALUE *argv; { char *mode; - VALUE pname, pmode; + VALUE pname, pmode, perm; VALUE port; - rb_scan_args(argc, argv, "11", &pname, &pmode); + rb_scan_args(argc, argv, "12", &pname, &pmode, &perm); Check_SafeStr(pname); + if (RSTRING(pname)->ptr[0] != '|') /* open file */ + return rb_file_s_open(argc, argv, rb_cFile); + + /* open pipe */ if (NIL_P(pmode)) { mode = "r"; } + else if (FIXNUM_P(pmode)) { + mode = rb_io_flags_mode(FIX2INT(pmode)); + } else { int len; mode = STR2CSTR(pmode); len = strlen(mode); if (len == 0 || len > 3) - rb_raise(rb_eArgError, "illegal access mode"); + rb_raise(rb_eArgError, "illegal access mode %s", mode); } - port = rb_io_open(RSTRING(pname)->ptr, mode); + port = pipe_open(RSTRING(pname)->ptr+1, mode); if (rb_iterator_p()) { return rb_ensure(rb_yield, port, rb_io_close, port); } @@ -1371,6 +1550,18 @@ rb_f_open(argc, argv) return port; } +static VALUE +rb_io_open(fname, mode) + char *fname, *mode; +{ + if (fname[0] == '|') { + return pipe_open(fname+1, mode); + } + else { + return rb_file_open(fname, mode); + } +} + static VALUE rb_io_get_io(io) VALUE io; @@ -1393,7 +1584,7 @@ rb_io_mode_string(fptr) } } -VALUE +static VALUE rb_io_reopen(io, nfile) VALUE io, nfile; { @@ -1412,6 +1603,9 @@ rb_io_reopen(io, nfile) else if (orig->mode & FMODE_WRITABLE) { fflush(orig->f); } +#ifdef USE_THREAD + rb_thread_fd_close(fileno(fptr->f)); +#endif /* copy OpenFile structure */ fptr->mode = orig->mode; @@ -1457,6 +1651,56 @@ rb_io_reopen(io, nfile) return io; } +static VALUE +rb_file_reopen(argc, argv, file) + int argc; + VALUE *argv; + VALUE file; +{ + VALUE fname, nmode; + char *mode; + OpenFile *fptr; + + rb_secure(4); + if (rb_scan_args(argc, argv, "11", &fname, &nmode) == 1) { + if (TYPE(fname) == T_FILE) { /* fname must be IO */ + return rb_io_reopen(file, fname); + } + } + + Check_SafeStr(fname); + if (!NIL_P(nmode)) { + mode = STR2CSTR(nmode); + } + else { + mode = "r"; + } + + GetOpenFile(file, fptr); + if (fptr->path) free(fptr->path); + fptr->path = strdup(RSTRING(fname)->ptr); + fptr->mode = rb_io_mode_flags(mode); + if (!fptr->f) { + fptr->f = rb_fopen(RSTRING(fname)->ptr, mode); + if (fptr->f2) { + fclose(fptr->f2); + fptr->f2 = NULL; + } + return file; + } + + if (freopen(RSTRING(fname)->ptr, mode, fptr->f) == NULL) { + rb_sys_fail(fptr->path); + } + if (fptr->f2) { + if (freopen(RSTRING(fname)->ptr, "w", fptr->f2) == NULL) { + rb_sys_fail(fptr->path); + } + } + + return file; +} + static VALUE rb_io_clone(io) VALUE io; @@ -1772,7 +2016,7 @@ prep_stdio(f, mode, klass) MakeOpenFile(io, fp); fp->f = f; fp->mode = mode; - rb_obj_call_init((VALUE)io); + rb_obj_call_init((VALUE)io, 0, 0); return (VALUE)io; } @@ -1870,8 +2114,7 @@ next_argv() #endif } fw = rb_fopen(fn, "w"); -#if !defined(MSDOS) && !defined(__CYGWIN32__) && !(NT) && !defined(__human68k__)\ - && !defined(USE_CWGUSI) && !defined(__BEOS__) +#if !defined(MSDOS) && !defined(__CYGWIN32__) && !(NT) && !defined(__human68k__) && !defined(USE_CWGUSI) && !defined(__BEOS__) fstat(fileno(fw), &st2); fchmod(fileno(fw), st.st_mode); if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) { @@ -1900,7 +2143,12 @@ rb_f_gets_internal(argc, argv) retry: if (!next_argv()) return Qnil; - line = rb_io_gets_internal(argc, argv, file); + if (rb_rs == rb_default_rs) { + line = rb_io_gets(file); + } + else { + line = rb_io_gets_internal(argc, argv, file); + } if (NIL_P(line) && next_p != -1) { rb_io_close(file); next_p = 1; @@ -1928,6 +2176,10 @@ rb_gets() { VALUE line; + if (rb_rs != rb_default_rs) { + return rb_f_gets(0, 0); + } + retry: if (!next_argv()) return Qnil; line = rb_io_gets(file); @@ -1959,76 +2211,13 @@ rb_f_readline(argc, argv) return line; } -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; @@ -2452,8 +2641,8 @@ rb_io_s_pipe() #endif rb_sys_fail(0); - r = prep_stdio(fdopen(pipes[0], "r"), FMODE_READABLE, rb_cIO); - w = prep_stdio(fdopen(pipes[1], "w"), FMODE_WRITABLE, rb_cIO); + r = prep_stdio(rb_fdopen(pipes[0], "r"), FMODE_READABLE, rb_cIO); + w = prep_stdio(rb_fdopen(pipes[1], "w"), FMODE_WRITABLE, rb_cIO); ary = rb_ary_new2(2); rb_ary_push(ary, r); @@ -2466,6 +2655,13 @@ rb_io_s_pipe() #endif } +static VALUE +rb_f_pipe() +{ + rb_warn("pipe is obsolete; use IO::pipe instead"); + return rb_io_s_pipe(); +} + struct foreach_arg { int argc; VALUE sep; @@ -2532,6 +2728,40 @@ rb_io_s_readlines(argc, argv, io) return rb_ensure(rb_io_readline_line, (VALUE)&arg, rb_io_close, arg.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() { @@ -2550,7 +2780,7 @@ arg_read(argc, argv) VALUE *argv; { VALUE tmp, str; - size_t len; + int len; if (argc == 1) len = NUM2INT(argv[0]); str = Qnil; @@ -2606,6 +2836,25 @@ arg_readchar() return c; } +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; @@ -2704,20 +2953,15 @@ 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); rb_define_global_function("`", rb_f_backquote, 1); - rb_define_global_function("pipe", rb_io_s_pipe, 0); + rb_define_global_function("pipe", rb_f_pipe, 0); rb_define_global_function("p", rb_f_p, -1); rb_define_method(rb_mKernel, "display", rb_obj_display, -1); @@ -2838,14 +3082,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); @@ -2866,4 +3109,30 @@ Init_IO() #endif Init_File(); + + rb_define_method(rb_cFile, "reopen", rb_file_reopen, -1); + + rb_define_singleton_method(rb_cFile, "new", rb_file_s_open, -1); + rb_define_singleton_method(rb_cFile, "open", rb_file_s_open, -1); + + rb_file_const("RDONLY", INT2FIX(O_RDONLY)); + rb_file_const("WRONLY", INT2FIX(O_WRONLY)); + rb_file_const("RDWR", INT2FIX(O_RDWR)); + rb_file_const("APPEND", INT2FIX(O_APPEND)); + rb_file_const("CREAT", INT2FIX(O_CREAT)); + rb_file_const("EXCL", INT2FIX(O_EXCL)); +#if defined(O_NDELAY) || defined(O_NONBLOCK) +# ifdef O_NONBLOCK + rb_file_const("NONBLOCK", INT2FIX(O_NONBLOCK)); +# else + rb_file_const("NONBLOCK", INT2FIX(O_NDELAY)); +# endif +#endif + rb_file_const("TRUNC", INT2FIX(O_TRUNC)); +#ifdef O_NOCTTY + rb_file_const("NOCTTY", INT2FIX(O_NOCTTY)); +#endif +#ifdef O_BINARY + rb_file_const("BINARY", INT2FIX(O_BINARY)); +#endif } diff --git a/io.h b/io.h deleted file mode 100644 index c671fca8ed..0000000000 --- a/io.h +++ /dev/null @@ -1,58 +0,0 @@ -/************************************************ - - io.h - - - $Author$ - $Revision$ - $Date$ - created at: Fri Nov 12 16:47:09 JST 1993 - - Copyright (C) 1993-1996 Yukihiro Matsumoto - -************************************************/ - -#ifndef IO_H -#define IO_H - -#include "sig.h" -#include -#include - -typedef struct OpenFile { - FILE *f; /* stdio ptr for read/write */ - FILE *f2; /* additional ptr for rw pipes */ - int mode; /* mode flags */ - int pid; /* child's pid (for pipes) */ - int lineno; /* number of lines read */ - char *path; /* pathname for file */ - void (*finalize)(); /* finalize proc */ -} OpenFile; - -#define FMODE_READABLE 1 -#define FMODE_WRITABLE 2 -#define FMODE_READWRITE 3 -#define FMODE_BINMODE 4 -#define FMODE_SYNC 8 - -#define GetOpenFile(obj,fp) ((fp) = RFILE(obj)->fptr) - -#define MakeOpenFile(obj, fp) do {\ - fp = RFILE(obj)->fptr = ALLOC(OpenFile);\ - fp->f = fp->f2 = NULL;\ - fp->mode = 0;\ - fp->pid = 0;\ - fp->lineno = 0;\ - fp->path = NULL;\ - fp->finalize = 0;\ -} while (0) - -#define GetWriteFile(fptr) (((fptr)->f2) ? (fptr)->f2 : (fptr)->f) - -FILE *rb_fopen _((char *, char *)); -FILE *rb_fdopen _((int, char *)); -void io_writable _((OpenFile *)); -void io_readable _((OpenFile *)); -void io_fptr_finalize _((OpenFile *)); -void io_unbuffered _((OpenFile *)); - -#endif diff --git a/lib/README b/lib/README index 09e5946ccb..765c380f7d 100644 --- a/lib/README +++ b/lib/README @@ -1,11 +1,11 @@ English.rb access global variables by english names Env.rb access environment variables as globals README this file -base64.rb encode/decode base64 (bit obsolete) +base64.rb encode/decode base64 (obsolete) cgi-lib.rb decode CGI data complex.rb complex number suppor date.rb date object (compatible) -date2.rb date object based on Julian date +date2.rb yet another (better) date object debug.rb ruby debugger delegate.rb delegate messages to other object e2mmap.rb exception utilities @@ -15,6 +15,7 @@ finalize.rb add finalizer to the object find.rb traverse directory tree ftools.rb file tools ftplib.rb ftp access library +getoptlong.rb GNU getoptlong compatible getopts.rb parse command line options importenv.rb access environment variables as globals jcode.rb japanese text handling (replace String methods) @@ -29,12 +30,12 @@ open3.rb open subprocess connection stdin/stdout/stderr ostruct.rb python style object parsearg.rb argument parser using getopts parsedate.rb parse date string -ping.rb +ping.rb check whether host is up, using TCP echo. profile.rb ruby profiler pstore.rb persistent object strage using marshal rational.rb rational number support readbytes.rb define IO#readbytes -shell.rb shell like operation under Ruby (imcomlete) +shell.rb shell like operation under Ruby (imcomplete) shellwords.rb split into words like shell singleton.rb singleton design pattern library sync.rb 2 phase lock @@ -43,19 +44,5 @@ tempfile.rb temporary file that automatically removed thread.rb thread support thwait.rb thread syncronization class timeout.rb provids timeout -tk.rb Tk interface -tkafter.rb -tkbgerror.rb Tk error module -tkcanvas.rb Tk canvas interface -tkclass.rb provides generic names for Tk classes -tkdialog.rb Tk dialog class -tkentry.rb Tk entry class -tkfont.rb Tk font support -tkmenubar.rb TK menubar utility -tkmngfocus.rb focus manager -tkpalette.rb pallete support -tkscrollbox.rb scroll box, also example of compound widget -tktext.rb text classes -tkvirtevent.rb virtual event support tracer.rb execution tracer weakref.rb weak reference class diff --git a/lib/cgi-lib.rb b/lib/cgi-lib.rb index 7033f0f8c1..12c850240b 100644 --- a/lib/cgi-lib.rb +++ b/lib/cgi-lib.rb @@ -1,62 +1,171 @@ -# -# Get CGI String -# -# EXAMPLE: -# require "cgi-lib.rb" -# foo = CGI.new -# foo['field'] <== value of 'field' -# foo.keys <== array of fields -# and foo has Hash class methods - -# if running on Windows(IIS or PWS) then change cwd. -if ENV['SERVER_SOFTWARE'] =~ /^Microsoft-/ then - Dir.chdir ENV['PATH_TRANSLATED'].sub(/[^\\]+$/, '') -end +=begin + += simple CGI support library + += example + +== get form values + + require "cgi-lib.rb" + query = CGI.new + query['field'] # <== value of 'field' + query.keys # <== array of fields + +and query has Hash class methods + + +== get cookie values + + require "cgi-lib.rb" + query = CGI.new + query.cookie['name'] # <== cookie value of 'name' + query.cookie.keys # <== all cookie names + +and query.cookie has Hash class methods + + +== print HTTP header and HTML string to $> + + require "cgi-lib.rb" + CGI.print{ + CGI.tag("HTML"){ + CGI.tag("HEAD"){ CGI.tag("TITLE"){"TITLE"} } + + CGI.tag("BODY"){ + CGI.tag("FORM", {"ACTION"=>"test.rb", "METHOD"=>"POST"}){ + CGI.tag("INPUT", {"TYPE"=>"submit", "VALUE"=>"submit"}) + } + + CGI.tag("HR") + } + } + } + + +== make raw cookie string + + require "cgi-lib.rb" + cookie1 = CGI.cookie({'name' => 'name', + 'value' => 'value', + 'path' => 'path', # optional + 'domain' => 'domain', # optional + 'expires' => Time.now, # optional + 'secure' => true # optional + }) + + CGI.print("Content-Type: text/html", cookie1, cookie2){ "string" } + + +== print HTTP header and string to $> + + require "cgi-lib.rb" + CGI.print{ "string" } + # == CGI.print("Content-Type: text/html"){ "string" } + CGI.print("Content-Type: text/html", cookie1, cookie2){ "string" } + + +=== NPH (no-parse-header) mode + + require "cgi-lib.rb" + CGI.print("nph"){ "string" } + # == CGI.print("nph", "Content-Type: text/html"){ "string" } + CGI.print("nph", "Content-Type: text/html", cookie1, cookie2){ "string" } + + +== make HTML tag string + + require "cgi-lib.rb" + CGI.tag("element", {"attribute_name"=>"attribute_value"}){"content"} + + +== make HTTP header string + + require "cgi-lib.rb" + CGI.header # == CGI.header("Content-Type: text/html") + CGI.header("Content-Type: text/html", cookie1, cookie2) + + +=== NPH (no-parse-header) mode + + CGI.header("nph") # == CGI.header("nph", "Content-Type: text/html") + CGI.header("nph", "Content-Type: text/html", cookie1, cookie2) + + +== escape url encode + + require "cgi-lib.rb" + url_encoded_string = CGI.escape("string") + + +== unescape url encoded + + require "cgi-lib.rb" + string = CGI.unescape("url encoded string") + + +== escape HTML &"<> + + require "cgi-lib.rb" + CGI.escapeHTML("string") + + +=end require "delegate" class CGI < SimpleDelegator - attr("inputs") + CR = "\015" + LF = "\012" + EOL = CR + LF - # original is CGI.pm - def read_from_cmdline - require "shellwords.rb" - words = Shellwords.shellwords(if not ARGV.empty? then - ARGV.join(' ') - else - STDERR.print "(offline mode: enter name=value pairs on standard input)\n" if STDIN.tty? - readlines.join(' ').gsub(/\n/, '') - end.gsub(/\\=/, '%3D').gsub(/\\&/, '%26')) - - if words.find{|x| x =~ /=/} then words.join('&') else words.join('+') end + # if running on Windows(IIS or PWS) then change cwd. + if ENV['SERVER_SOFTWARE'] =~ /^Microsoft-/ + Dir.chdir(ENV['PATH_TRANSLATED'].sub(/[^\\]+$/, '')) end - + # escape url encode def escape(str) - str.gsub!(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) } - str + str.gsub(/[^a-zA-Z0-9_\-.]/n){ sprintf("%%%02X", $&.unpack("C")[0]) } end # unescape url encoded def unescape(str) - str.gsub! /\+/, ' ' - str.gsub!(/%([0-9a-fA-F]{2})/){ [$1.hex].pack("c") } - str + str.gsub(/\+/, ' ').gsub(/%([0-9a-fA-F]{2})/){ [$1.hex].pack("c") } + end + + # escape HTML + def escapeHTML(str) + str.gsub(/&/, "&").gsub(/\"/, """).gsub(/>/, ">").gsub(/) ENV['QUERY_STRING'] or "" when "POST" # exception messages should be printed to stdout. - STDERR.reopen(STDOUT) + STDERR.reopen($>) input.read Integer(ENV['CONTENT_LENGTH']) else read_from_cmdline @@ -70,27 +179,93 @@ class CGI < SimpleDelegator end super(@inputs) + + if ENV.has_key?('HTTP_COOKIE') or ENV.has_key?('COOKIE') + (ENV['HTTP_COOKIE'] or ENV['COOKIE']).split("; ").each do |x| + key, val = x.split(/=/,2) + key = unescape(key) + val = val.split(/&/).collect{|x|unescape(x)}.join("\0") + if @cookie.include?(key) + @cookie[key] += "\0" + val + else + @cookie[key] = val + end + end + end end - def CGI.message(msg, title = "") - print "Content-type: text/html\n\n" - print "" - print title - print "\n" - print msg - print "\n" + attr("inputs") + attr("cookie") + + # make HTML tag string + def CGI.tag(element, attributes = {}) + "<" + escapeHTML(element) + attributes.collect{|name, value| + " " + escapeHTML(name) + '="' + escapeHTML(value) + '"' + }.to_s + ">" + + (iterator? ? yield.to_s + "" : "") + end + + # make raw cookie string + def CGI.cookie(options) + "Set-Cookie: " + options['name'] + '=' + escape(options['value']) + + (options['domain'] ? '; domain=' + options['domain'] : '') + + (options['path'] ? '; path=' + options['path'] : '') + + (options['expires'] ? '; expires=' + options['expires'].strftime("%a, %d %b %Y %X %Z") : '') + + (options['secure'] ? '; secure' : '') + end + + # make HTTP header string + def CGI.header(*options) + if ENV['MOD_RUBY'] + options.each{|option| + option.sub(/(.*?): (.*)/){ + Apache::request[$1] = $2 + } + } + Apache::request.send_http_header + '' + else + if options.delete("nph") or (ENV['SERVER_SOFTWARE'] =~ /IIS/) + [(ENV['SERVER_PROTOCOL'] or "HTTP/1.0") + " 200 OK", + "Date: " + Time.now.gmtime.strftime("%a, %d %b %Y %X %Z"), + "Server: " + (ENV['SERVER_SOFTWARE'] or ""), + "Connection: close"] + + (options.empty? ? ["Content-Type: text/html"] : options) + else + options.empty? ? ["Content-Type: text/html"] : options + end.join(EOL) + EOL + EOL + end + end + + # print HTTP header and string to $> + def CGI.print(*options) + $>.print CGI.header(*options) + yield.to_s + end + + # print message to $> + def CGI.message(message, title = "", header = ["Content-Type: text/html"]) + if message.kind_of?(Hash) + title = message['title'] + header = message['header'] + message = message['body'] + end + CGI.print(*header){ + CGI.tag("HTML"){ + CGI.tag("HEAD"){ CGI.tag("TITLE"){ title } } + + CGI.tag("BODY"){ message } + } + } TRUE end + # print error message to $> and exit def CGI.error - m = $!.to_s.dup - m.gsub!(/&/, '&') - m.gsub!(//, '>') - msgs = ["
ERROR: #{m}"]
-    msgs << $@
-    msgs << "
" - CGI.message(msgs.join("\n"), "ERROR") + CGI.message({'title'=>'ERROR', 'body'=> + CGI.tag("PRE"){ + "ERROR: " + CGI.tag("STRONG"){ escapeHTML($!.to_s) } + "\n" + + escapeHTML($@.join("\n")) + } + }) exit end end diff --git a/lib/complex.rb b/lib/complex.rb index 59caad6ebc..0af8c20b89 100644 --- a/lib/complex.rb +++ b/lib/complex.rb @@ -72,6 +72,8 @@ class Complex < Numeric end def initialize(a, b = 0) + raise "non numeric 1st arg `#{a.inspect}'" if !a.kind_of? Numeric + raise "non numeric 2nd arg `#{b.inspect}'" if !b.kind_of? Numeric @real = a @image = b end @@ -84,7 +86,7 @@ class Complex < Numeric elsif Complex.generic?(other) Complex(@real + other, @image) else - x , y = a.coerce(self) + x , y = other.coerce(self) x + y end end @@ -97,7 +99,7 @@ class Complex < Numeric elsif Complex.generic?(other) Complex(@real - other, @image) else - x , y = a.coerce(self) + x , y = other.coerce(self) x - y end end @@ -110,7 +112,7 @@ class Complex < Numeric elsif Complex.generic?(other) Complex(@real * other, @image * other) else - x , y = a.coerce(self) + x , y = other.coerce(self) x * y end end @@ -121,7 +123,7 @@ class Complex < Numeric elsif Complex.generic?(other) Complex(@real / other, @image / other) else - x , y = a.coerce(self) + x , y = other.coerce(self) x / y end end @@ -163,7 +165,7 @@ class Complex < Numeric r, theta = polar Complex.polar(r.power!(other), theta * other) else - x , y = a.coerce(self) + x , y = other.coerce(self) x / y end end @@ -174,7 +176,7 @@ class Complex < Numeric elsif Complex.generic?(other) Complex(@real % other, @image % other) else - x , y = a.coerce(self) + x , y = other.coerce(self) x % y end end @@ -187,7 +189,7 @@ class Complex < Numeric elsif Complex.generic?(other) Complex(@real.divmod(other), @image.divmod(other)) else - x , y = a.coerce(self) + x , y = other.coerce(self) x.divmod(y) end end @@ -222,7 +224,7 @@ class Complex < Numeric elsif Complex.generic?(other) @real == other and @image == 0 else - x , y = a.coerce(self) + x , y = other.coerce(self) x == y end end diff --git a/lib/date2.rb b/lib/date2.rb index 50c2ccfbd9..6e87824b38 100644 --- a/lib/date2.rb +++ b/lib/date2.rb @@ -1,11 +1,11 @@ -# date.rb: Written by Tadayoshi Funaba 1998 -# $Id: date.rb,v 1.4 1998/06/01 12:52:33 tadf Exp $ +# date.rb: Written by Tadayoshi Funaba 1998, 1999 +# $Id: date.rb,v 1.5 1999/02/06 08:51:56 tadf Exp $ class Date include Comparable - MONTHNAMES = [ '', 'January', 'February', 'March', 'April', 'May', 'June', + MONTHNAMES = [ nil, 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ] DAYNAMES = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', @@ -162,26 +162,24 @@ class Date end def + (other) - if other.kind_of? Numeric then - return Date.new(@jd + other, @gs) + case other + when Numeric; return Date.new(@jd + other, @gs) end fail TypeError, 'expected numeric' end def - (other) - if other.kind_of? Numeric then - return Date.new(@jd - other, @gs) - elsif other.kind_of? Date then - return @jd - other.jd + case other + when Numeric; return Date.new(@jd - other, @gs) + when Date; return @jd - other.jd end fail TypeError, 'expected numeric or date' end def <=> (other) - if other.kind_of? Numeric then - return @jd <=> other - elsif other.kind_of? Date then - return @jd <=> other.jd + case other + when Numeric; return @jd <=> other + when Date; return @jd <=> other.jd end fail TypeError, 'expected numeric or date' end diff --git a/lib/e2mmap.rb b/lib/e2mmap.rb index bf860dc5c1..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 - # 過去の互換性のため - 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 < 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/mkmf.rb b/lib/mkmf.rb index 7e131fe890..52b4ed20a9 100644 --- a/lib/mkmf.rb +++ b/lib/mkmf.rb @@ -31,7 +31,9 @@ if File.exist?($config_cache) then end $srcdir = CONFIG["srcdir"] -$libdir = CONFIG["libdir"]+"/"+CONFIG["ruby_install_name"] +#$libdir = CONFIG["libdir"]+"/"+CONFIG["ruby_install_name"] +$libdir = CONFIG["libdir"]+"/ruby" +$libdir += "/"+CONFIG["MAJOR"]+"."+CONFIG["MINOR"] $archdir = $libdir+"/"+CONFIG["arch"] $install = CONFIG["INSTALL_PROGRAM"] $install_data = CONFIG["INSTALL_DATA"] diff --git a/lib/mutex_m.rb b/lib/mutex_m.rb index 4b8d64438e..dd92ff9883 100644 --- a/lib/mutex_m.rb +++ b/lib/mutex_m.rb @@ -12,7 +12,7 @@ # obj = Object.new # obj.extend Mutex_m # ... -# 後はMutexと同じ使い方 +# extended object can be handled like Mutex # require "finalize" @@ -36,7 +36,7 @@ module Mutex_m dummy = cl.new Mutex_m.extendable_module(dummy) rescue NameError - # newが定義されていない時は, DATAとみなす. + # if new is not defined, cl must be Data. For_primitive_object end end @@ -44,8 +44,8 @@ module Mutex_m def Mutex_m.extend_class(cl) return super if cl.instance_of?(Module) - # モジュールの時は何もしない. クラスの場合, 適切なモジュールの決定 - # とaliasを行う. + # do nothing for Modules + # make aliases and include the proper module. real = includable_module(cl) cl.module_eval %q{ include real @@ -162,7 +162,6 @@ module Mutex_m def For_primitive_object.mu_finalize(id) Thread.critical = TRUE if wait = Mu_Locked.delete(id) - # wait == [] ときだけ GCされるので, for w in wait は意味なし. Thread.critical = FALSE for w in wait w.run diff --git a/lib/parsedate.rb b/lib/parsedate.rb index 68550c6505..e27735b755 100644 --- a/lib/parsedate.rb +++ b/lib/parsedate.rb @@ -8,8 +8,8 @@ module ParseDate 'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3, 'thu' => 4, 'fri' => 5, 'sat' => 6 } DAYPAT = DAYS.keys.join('|') - - def parsedate(date) + + def parsedate(date, guess=false) # part of ISO 8601 # yyyy-mm-dd | yyyy-mm | yyyy # date hh:mm:ss | date Thh:mm:ss @@ -58,6 +58,23 @@ module ParseDate if $3 year = $3.to_i end + elsif date.sub!(/(\d+)-(#{MONTHPAT})-(\d+)/i, ' ') + mday = $1.to_i + mon = MONTHS[$2.downcase] + year = $3.to_i + end + if guess + if year < 100 + if year >= 69 + year += 1900 + else + year += 2000 + end + end + elsif date.sub!(/(\d+)-(#{MONTHPAT})-(\d+)/i, ' ') + mday = $1.to_i + mon = MONTHS[$2.downcase] + year = $3.to_i end return year, mon, mday, hour, min, sec, zone, wday end diff --git a/lib/profile.rb b/lib/profile.rb index 3abcc37662..3634b5bdc2 100644 --- a/lib/profile.rb +++ b/lib/profile.rb @@ -16,6 +16,7 @@ module Profiler__ data = MAP[id] unless data name = klass.to_s + if name.nil? then name = '' end if klass.kind_of? Class name += "#" else @@ -34,6 +35,7 @@ module Profiler__ END { set_trace_func nil total = Float(Time.times[0]) - Start + if total == 0 then total = 0.01 end MAP[:toplevel][1] = total # f = open("./rmon.out", "w") f = STDERR diff --git a/lib/sync.rb b/lib/sync.rb index 9f9706d9ee..dc54626b4f 100644 --- a/lib/sync.rb +++ b/lib/sync.rb @@ -1,5 +1,5 @@ # -# sync.rb - カウント付2-フェーズロッククラス +# sync.rb - 2 phase lock with counter # $Release Version: 0.2$ # $Revision$ # $Date$ @@ -54,7 +54,7 @@ module Sync_m SH = :SH EX = :EX - # 例外定義 + # exceptions class Err < StandardError def Err.Fail(*opt) fail self, sprintf(self::Message, *opt) @@ -97,7 +97,7 @@ module Sync_m dummy = cl.new Sync_m.extendable_module(dummy) rescue NameError - # newが定義されていない時は, DATAとみなす. + # if new is not defined, cl must be Data. For_primitive_object end end @@ -105,8 +105,8 @@ module Sync_m def Sync_m.extend_class(cl) return super if cl.instance_of?(Module) - # モジュールの時は何もしない. クラスの場合, 適切なモジュールの決定 - # とaliasを行う. + # do nothing for Modules + # make aliases and include the proper module. real = includable_module(cl) cl.module_eval %q{ include real @@ -267,7 +267,7 @@ module Sync_m sync_sh_locker[Thread.current] = count + 1 ret = TRUE when EX - # 既に, モードがEXである時は, 必ずEXロックとなる. + # in EX mode, lock will upgrade to EX lock if sync_ex_locker == Thread.current self.sync_ex_count = sync_ex_count + 1 ret = TRUE @@ -342,7 +342,7 @@ module Sync_m def For_primitive_object.sync_finalize(id) wait = Sync_Locked.delete(id) - # waiting == [] ときだけ GCされるので, 待ち行列の解放は意味がない. + # need not to free waiting end def sync_mode diff --git a/lib/telnet.rb b/lib/telnet.rb index e3c590c35d..10a528ed43 100644 --- a/lib/telnet.rb +++ b/lib/telnet.rb @@ -1,134 +1,139 @@ -# -# telnet.rb -# ver0.16 1998/10/09 -# Wakou Aoyama -# -# ver0.16 1998/10/09 -# preprocess method change for the better -# add binmode method. -# change default Binmode -# TRUE --> FALSE -# -# ver0.15 1998/10/04 -# add telnetmode method. -# -# ver0.141 1998/09/22 -# change default prompt -# /[$%#>] $/ --> /[$%#>] \Z/ -# -# ver0.14 1998/09/01 -# IAC WILL SGA send EOL --> CR+NULL -# IAC WILL SGA IAC DO BIN send EOL --> CR -# NONE send EOL --> LF -# add Dump_log option. -# -# ver0.13 1998/08/25 -# add print method. -# -# ver0.122 1998/08/05 -# support for HP-UX 10.20 thanks to WATANABE Tetsuya -# socket.<< --> socket.write -# -# ver0.121 1998/07/15 -# string.+= --> string.concat -# -# ver0.12 1998/06/01 -# add timeout, waittime. -# -# ver0.11 1998/04/21 -# add realtime output. -# -# ver0.10 1998/04/13 -# first release. -# -# == make new Telnet object -# host = Telnet.new({"Binmode" => FALSE, default: FALSE -# "Host" => "localhost", default: "localhost" -# "Output_log" => "output_log", default: not output -# "Dump_log" => "dump_log", default: not output -# "Port" => 23, default: 23 -# "Prompt" => /[$%#>] \Z/, default: /[$%#>] \Z/ -# "Telnetmode" => TRUE, default: TRUE -# "Timeout" => 10, default: 10 -# "Waittime" => 0}) default: 0 -# -# if set "Telnetmode" option FALSE. not TELNET command interpretation. -# "Waittime" is time to confirm "Prompt". There is a possibility that -# the same character as "Prompt" is included in the data, and, when -# the network or the host is very heavy, the value is enlarged. -# -# == wait for match -# line = host.waitfor(/match/) -# line = host.waitfor({"Match" => /match/, -# "String" => "string", -# "Timeout" => secs}) -# if set "String" option. Match = Regexp.new(quote(string)) -# -# realtime output. of cource, set sync=TRUE or flush is necessary. -# host.waitfor(/match/){|c| print c } -# host.waitfor({"Match" => /match/, -# "String" => "string", -# "Timeout" => secs}){|c| print c} -# -# == send string and wait prompt -# line = host.cmd("string") -# line = host.cmd({"String" => "string", -# "Prompt" => /[$%#>] \Z/, -# "Timeout" => 10}) -# -# realtime output. of cource, set sync=TRUE or flush is necessary. -# host.cmd("string"){|c| print c } -# host.cmd({"String" => "string", -# "Prompt" => /[$%#>] \Z/, -# "Timeout" => 10}){|c| print c } -# -# == send string -# host.print("string") -# -# == turn telnet command interpretation -# host.telnetmode # turn on/off -# host.telnetmode(TRUE) # on -# host.telnetmode(FALSE) # off -# -# == toggle newline translation -# host.binmode # turn TRUE/FALSE -# host.binmode(TRUE) # no translate newline -# host.binmode(FALSE) # translate newline -# -# == login -# host.login("username", "password") -# host.login({"Name" => "username", -# "Password" => "password", -# "Prompt" => /[$%#>] \Z/, -# "Timeout" => 10}) -# -# realtime output. of cource, set sync=TRUE or flush is necessary. -# host.login("username", "password"){|c| print c } -# host.login({"Name" => "username", -# "Password" => "password", -# "Prompt" => /[$%#>] \Z/, -# "Timeout" => 10}){|c| print c } -# -# and Telnet object has socket class methods -# -# == sample -# localhost = Telnet.new({"Host" => "localhost", -# "Timeout" => 10, -# "Prompt" => /[$%#>] \Z/}) -# localhost.login("username", "password"){|c| print c } -# localhost.cmd("command"){|c| print c } -# localhost.close -# -# == sample 2 -# checks a POP server to see if you have mail. -# -# pop = Telnet.new({"Host" => "your_destination_host_here", -# "Port" => 110, -# "Telnetmode" => FALSE, -# "Prompt" => /^\+OK/}) -# pop.cmd("user " + "your_username_here"){|c| print c} -# pop.cmd("pass " + "your_password_here"){|c| print c} -# pop.cmd("list"){|c| print c} +=begin + +telnet.rb ver0.161 1999/02/03 +Wakou Aoyama + +ver0.161 1999/02/03 +select --> IO::select + +ver0.16 1998/10/09 +preprocess method change for the better +add binmode method. +change default Binmode +TRUE --> FALSE + +ver0.15 1998/10/04 +add telnetmode method. + +ver0.141 1998/09/22 +change default prompt +/[$%#>] $/ --> /[$%#>] \Z/ + +ver0.14 1998/09/01 +IAC WILL SGA send EOL --> CR+NULL +IAC WILL SGA IAC DO BIN send EOL --> CR +NONE send EOL --> LF +add Dump_log option. + +ver0.13 1998/08/25 +add print method. + +ver0.122 1998/08/05 +support for HP-UX 10.20 thanks to WATANABE Tetsuya +socket.<< --> socket.write + +ver0.121 1998/07/15 +string.+= --> string.concat + +ver0.12 1998/06/01 +add timeout, waittime. + +ver0.11 1998/04/21 +add realtime output. + +ver0.10 1998/04/13 +first release. + +== make new Telnet object +host = Telnet.new({"Binmode" => FALSE, default: FALSE + "Host" => "localhost", default: "localhost" + "Output_log" => "output_log", default: not output + "Dump_log" => "dump_log", default: not output + "Port" => 23, default: 23 + "Prompt" => /[$%#>] \Z/, default: /[$%#>] \Z/ + "Telnetmode" => TRUE, default: TRUE + "Timeout" => 10, default: 10 + "Waittime" => 0}) default: 0 + +if set "Telnetmode" option FALSE. not TELNET command interpretation. +"Waittime" is time to confirm "Prompt". There is a possibility that +the same character as "Prompt" is included in the data, and, when +the network or the host is very heavy, the value is enlarged. + +== wait for match +line = host.waitfor(/match/) +line = host.waitfor({"Match" => /match/, + "String" => "string", + "Timeout" => secs}) +if set "String" option. Match = Regexp.new(quote(string)) + +realtime output. of cource, set sync=TRUE or flush is necessary. +host.waitfor(/match/){|c| print c } +host.waitfor({"Match" => /match/, + "String" => "string", + "Timeout" => secs}){|c| print c} + +== send string and wait prompt +line = host.cmd("string") +line = host.cmd({"String" => "string", + "Prompt" => /[$%#>] \Z/, + "Timeout" => 10}) + +realtime output. of cource, set sync=TRUE or flush is necessary. +host.cmd("string"){|c| print c } +host.cmd({"String" => "string", + "Prompt" => /[$%#>] \Z/, + "Timeout" => 10}){|c| print c } + +== send string +host.print("string") + +== turn telnet command interpretation +host.telnetmode # turn on/off +host.telnetmode(TRUE) # on +host.telnetmode(FALSE) # off + +== toggle newline translation +host.binmode # turn TRUE/FALSE +host.binmode(TRUE) # no translate newline +host.binmode(FALSE) # translate newline + +== login +host.login("username", "password") +host.login({"Name" => "username", + "Password" => "password", + "Prompt" => /[$%#>] \Z/, + "Timeout" => 10}) + +realtime output. of cource, set sync=TRUE or flush is necessary. +host.login("username", "password"){|c| print c } +host.login({"Name" => "username", + "Password" => "password", + "Prompt" => /[$%#>] \Z/, + "Timeout" => 10}){|c| print c } + +and Telnet object has socket class methods + +== sample +localhost = Telnet.new({"Host" => "localhost", + "Timeout" => 10, + "Prompt" => /[$%#>] \Z/}) +localhost.login("username", "password"){|c| print c } +localhost.cmd("command"){|c| print c } +localhost.close + +== sample 2 +checks a POP server to see if you have mail. + +pop = Telnet.new({"Host" => "your_destination_host_here", + "Port" => 110, + "Telnetmode" => FALSE, + "Prompt" => /^\+OK/}) +pop.cmd("user " + "your_username_here"){|c| print c} +pop.cmd("pass " + "your_password_here"){|c| print c} +pop.cmd("list"){|c| print c} + +=end require "socket" require "delegate" @@ -356,9 +361,9 @@ class Telnet < SimpleDelegator end line = '' - until(not select([@sock], nil, nil, waittime) and prompt === line) + until(not IO::select([@sock], nil, nil, waittime) and prompt === line) raise TimeOut, "timed-out; wait for the next data" if - not select([@sock], nil, nil, timeout) + not IO::select([@sock], nil, nil, timeout) buf = '' begin buf = @sock.sysread(1024 * 1024) @@ -405,7 +410,7 @@ class Telnet < SimpleDelegator string = options end - select(nil, [@sock]) + IO::select(nil, [@sock]) print(string) if iterator? waitfor({"Prompt" => match, "Timeout" => timeout}){|c| yield c } 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/lib/tk.rb b/lib/tk.rb deleted file mode 100644 index 2cbbec02a8..0000000000 --- a/lib/tk.rb +++ /dev/null @@ -1,1254 +0,0 @@ -# -# tk.rb - Tk interface modue using tcltklib -# $Date$ -# by Yukihiro Matsumoto - -# use Shigehiro's tcltklib -require "tcltklib" -require "tkutil" - -module TkComm - None = Object.new - def None.to_s - 'None' - end - - Tk_CMDTBL = {} - Tk_WINDOWS = {} - - def error_at - frames = caller(1) - frames.delete_if do |c| - c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+! - end - frames - end - private :error_at - - def tk_tcl2ruby(val) - case val - when /^-?\d+$/ - val.to_i - when /^\./ - Tk_WINDOWS[val] - when /^rb_out (c\d+)/ - Tk_CMDTBL[$1] - when / / - val.split.collect{|elt| - tk_tcl2ruby(elt) - } - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - - def tk_split_list(str) - idx = str.index('{') - return tk_tcl2ruby(str) if not idx - - list = tk_tcl2ruby(str[0,idx]) - str = str[idx+1..-1] - i = -1 - brace = 1 - str.each_byte {|c| - i += 1 - brace += 1 if c == ?{ - brace -= 1 if c == ?} - break if brace == 0 - } - if str[0, i] == ' ' - list.push ' ' - else - list.push tk_split_list(str[0, i]) - end - list += tk_split_list(str[i+1..-1]) - list - end - private :tk_tcl2ruby, :tk_split_list - - def hash_kv(keys) - conf = [] - if keys and keys != None - for k, v in keys - conf.push("-#{k}") - v = install_cmd(v) if v.kind_of? Proc - conf.push(v) - end - end - conf - end - private :hash_kv - - def bool(val) - case val - when "1", 1, 'yes', 'true' - TRUE - else - FALSE - end - end - def number(val) - case val - when /^-?\d+$/ - val.to_i - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - def string(val) - if val == "{}" - '' - elsif val[0] == ?{ - val[1..-2] - else - val - end - end - def list(val) - tk_split_list(val) - end - def window(val) - Tk_WINDOWS[val] - end - def procedure(val) - if val =~ /^rb_out (c\d+)/ - Tk_CMDTBL[$1] - else - nil - end - end - private :bool, :number, :string, :list, :window, :procedure - - Tk_IDs = [0] # [0]-cmdid, [1]-winid - def _curr_cmd_id - id = format("c%.4d", Tk_IDs[0]) - end - def _next_cmd_id - id = _curr_cmd_id - Tk_IDs[0] += 1 - end - def install_cmd(cmd) - return '' if cmd == '' - id = _next_cmd_id - Tk_CMDTBL[id] = cmd - @cmdtbl = [] if not @cmdtbl - @cmdtbl.push id - return format("rb_out %s", id); - end - def uninstall_cmd(id) - Tk_CMDTBL[id] = nil - end - private :install_cmd, :uninstall_cmd - - def install_win(ppath) - id = format("w%.4d", Tk_IDs[0]) - Tk_IDs[0] += 1 - if !ppath or ppath == "." - @path = format(".%s", id); - else - @path = format("%s.%s", ppath, id) - end - Tk_WINDOWS[@path] = self - end - - def uninstall_win() - Tk_WINDOWS[@path] = nil - end - - class Event - def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy) - @serial = seq - @num = b - @focus = (f == 1) - @height = h - @keycode = k - @state = s - @time = t - @width = w - @x = x - @y = y - @char = aa - @send_event = (ee == 1) - @keysym = kk - @keysym_num = nn - @type = tt - @widget = ww - @x_root = xx - @y_root = yy - end - attr :serial - attr :num - attr :focus - attr :height - attr :keycode - attr :state - attr :time - attr :width - attr :x - attr :y - attr :char - attr :send_event - attr :keysym - attr :keysym_num - attr :type - attr :widget - attr :x_root - attr :y_root - end - - def install_bind(cmd, args=nil) - if args - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, *arg - }) - id + " " + args - else - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, Event.new(*arg) - }) - id + ' %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y' - end - end - - def _bind(path, context, cmd, args=nil) - begin - id = install_bind(cmd, args) - tk_call 'bind', path, "<#{context}>", id - rescue - uninstall_cmd(id) - fail - end - end - private :install_bind, :_bind - - def bind_all(context, cmd=Proc.new, args=nil) - _bind 'all', context, cmd, args - end - - def pack(*args) - TkPack.configure *args - end - - def after(ms, cmd=Proc.new) - myid = _curr_cmd_id - tk_call 'after', ms, - install_cmd(proc{ - TkUtil.eval_cmd cmd - uninstall_cmd myid - }) - end -end - -module TkCore - include TkComm - extend TkComm - - INTERP = TclTkIp.new - INTERP._eval("proc rb_out {args} { ruby [format \"TkCore.callback %%Q!%s!\" $args] }") - - def TkCore.callback(arg) - arg = Array(tk_split_list(arg)) - TkUtil.eval_cmd Tk_CMDTBL[arg.shift], *arg - end - - def mainloop - TclTkLib.mainloop - end - - def _get_eval_string(*args) - argstr = "" - args.each{|arg| - next if arg == None - if arg.kind_of?(Hash) - str = hash_kv(arg).join(" ") - elsif arg == nil - str = "" - elsif arg == false - str = "0" - elsif arg == true - str = "1" - elsif (arg.respond_to?(:to_eval)) - str = arg.to_eval() - else - str = arg.to_s() - end - argstr += " " if argstr != "" - argstr += '"' + str.gsub(/[][$"]/, '\\\\\&') + '"' - } - return argstr - end - - def tk_call(*args) - argstr = _get_eval_string(*args) - - res = INTERP._eval(argstr) - if INTERP._return_value() != 0 - fail RuntimeError, res, error_at - end - return res - end -end - -module Tk - include TkCore - extend Tk - - def root - TkRoot.new - end - - def bell - tk_call 'bell' - end - - def mainloop - TclTkLib.mainloop - end - - module Scrollable - def xscrollcommand(cmd=Proc.new) - configure_cmd 'xscrollcommand', cmd - end - def yscrollcommand(cmd=Proc.new) - configure_cmd 'yscrollcommand', cmd - end - end - - module Wm - def aspect(*args) - w = window(tk_call('wm', 'grid', path, *args)) - w.split.collect{|s|s.to_i} if args.length == 0 - end - def client(name=None) - tk_call 'wm', 'client', path, name - end - def colormapwindows(*args) - list(tk_call('wm', 'colormapwindows', path, *args)) - end - def wm_command(value=None) - string(tk_call('wm', 'command', path, value)) - end - def deiconify - tk_call 'wm', 'deiconify', path - end - def focusmodel(*args) - tk_call 'wm', 'focusmodel', path, *args - end - def frame - tk_call 'wm', 'frame', path - end - def geometry(*args) - list(tk_call('wm', 'geometry', path, *args)) - end - def grid(*args) - w = tk_call('wm', 'grid', path, *args) - list(w) if args.size == 0 - end - def group(*args) - tk_call 'wm', 'path', path, *args - end - def iconbitmap(*args) - tk_call 'wm', 'bitmap', path, *args - end - def iconify - tk_call 'wm', 'iconify' - end - def iconmask(*args) - tk_call 'wm', 'iconmask', path, *args - end - def iconname(*args) - tk_call 'wm', 'iconname', path, *args - end - def iconposition(*args) - w = tk_call('wm', 'iconposition', path, *args) - list(w) if args.size == 0 - end - def iconwindow(*args) - tk_call 'wm', 'iconwindow', path, *args - end - def maxsize(*args) - w = tk_call('wm', 'maxsize', path, *args) - list(w) if not args.size == 0 - end - def minsize(*args) - w = tk_call('wm', 'minsize', path, *args) - list(w) if args.size == 0 - end - def overrideredirect(bool=None) - if bool == None - bool(tk_call('wm', 'overrideredirect', path)) - else - tk_call 'wm', 'overrideredirect', path, bool - end - end - def positionfrom(*args) - tk_call 'wm', 'positionfrom', path, *args - end - def protocol(name, func=None) - func = install_cmd(func) if not func == None - tk_call 'wm', 'command', path, name, func - end - def resizable(*args) - w = tk_call('wm', 'resizable', path, *args) - if args.length == 0 - list(w).collect{|e| bool(e)} - end - end - def sizefrom(*args) - list(tk_call('wm', 'sizefrom', path, *args)) - end - def state - tk_call 'wm', 'state', path - end - def title(*args) - tk_call 'wm', 'title', path, *args - end - def transient(*args) - tk_call 'wm', 'transient', path, *args - end - def withdraw - tk_call 'wm', 'withdraw', path - end - end -end - -class TkVariable - include Tk - - Tk_VARIABLE_ID = ["v00000"] - def initialize(val="") - @id = Tk_VARIABLE_ID[0] - Tk_VARIABLE_ID[0] = Tk_VARIABLE_ID[0].succ - INTERP._eval(format('global %s; set %s %s', @id, @id, _get_eval_string(val))) - end - - def id - @id - end - - def value - INTERP._eval(format('global %s; set %s', @id, @id)) - end - - def value=(val) - INTERP._eval(format('global %s; set %s %s', @id, @id, _get_eval_string(val))) - end - - def to_i - Integer(number(value)) - end - - def to_f - Float(number(value)) - end - - def to_s - String(string(value)) - end - - def inspect - format "", @id - end - - def ==(other) - case other - when TkVariable - self.equal(self) - when String - self.to_s == other - when Integer - self.to_i == other - when Float - self.to_f == other - when Array - self.to_a == other - else - false - end - end - - def to_a - list(value) - end - - def to_eval - @id - end -end - -module TkSelection - include Tk - extend Tk - def clear(win=Tk.root) - tk_call 'selection', 'clear', win.path - end - def get(type=None) - tk_call 'selection', 'get', type - end - def TkSelection.handle(win, func, type=None, format=None) - id = install_cmd(func) - tk_call 'selection', 'handle', win.path, id, type, format - end - def handle(func, type=None, format=None) - TkSelection.handle self, func, type, format - end - def TkSelection.own(win, func=None) - id = install_cmd(func) - tk_call 'selection', 'own', win.path, id - end - def own(func=None) - TkSelection.own self, func - end - - module_function :clear, :get -end - -module TkWinfo - include Tk - extend Tk - def TkWinfo.atom(name) - tk_call 'winfo', name - end - def winfo_atom(name) - TkWinfo.atom name - end - def TkWinfo.atomname(id) - tk_call 'winfo', id - end - def winfo_atomname(id) - TkWinfo.atomname id - end - def TkWinfo.cells(window) - number(tk_call('winfo', window.path)) - end - def winfo_cells - TkWinfo.cells self - end - def TkWinfo.children(window) - c = tk_call('winfo', 'children', window.path) - list(c) - end - def winfo_children - TkWinfo.children self - end - def TkWinfo.classname(window) - tk_call 'winfo', 'class', window.path - end - def winfo_classname - TkWinfo.classname self - end - def TkWinfo.containing(rootX, rootY) - path = tk_call('winfo', 'class', window.path) - window(path) - end - def winfo_containing(x, y) - TkWinfo.containing x, y - end - def TkWinfo.depth(window) - number(tk_call('winfo', 'depth', window.path)) - end - def winfo_depth(window) - TkWinfo.depth self - end - def TkWinfo.exist?(window) - bool(tk_call('winfo', 'exists', window.path)) - end - def winfo_exist?(window) - TkWinfo.exist? self - end - def TkWinfo.fpixels(window, number) - number(tk_call('winfo', 'fpixels', window.path, number)) - end - def winfo_fpixels(window, number) - TkWinfo.fpixels self - end - def TkWinfo.geometry(window) - list(tk_call('winfo', 'geometry', window.path)) - end - def winfo_geometry(window) - TkWinfo.geometry self - end - def TkWinfo.height(window) - number(tk_call('winfo', 'height', window.path)) - end - def winfo_height(window) - TkWinfo.height self - end - def TkWinfo.id(window) - number(tk_call('winfo', 'id', window.path)) - end - def winfo_id(window) - TkWinfo.id self - end - def TkWinfo.mapped?(window) - bool(tk_call('winfo', 'ismapped', window.path)) - end - def winfo_mapped?(window) - TkWinfo.mapped? self - end - def TkWinfo.parent(window) - window(tk_call('winfo', 'parent', window.path)) - end - def winfo_parent(window) - TkWinfo.parent self - end - def TkWinfo.widget(id) - window(tk_call('winfo', 'pathname', id)) - end - def winfo_widget(id) - TkWinfo.widget id - end - def TkWinfo.pixels(window, number) - number(tk_call('winfo', 'pixels', window.path, number)) - end - def winfo_pixels(window, number) - TkWinfo.pixels self, number - end - def TkWinfo.reqheight(window) - number(tk_call('winfo', 'reqheight', window.path)) - end - def winfo_reqheight(window) - TkWinfo.reqheight self - end - def TkWinfo.reqwidth(window) - number(tk_call('winfo', 'reqwidth', window.path)) - end - def winfo_reqwidth(window) - TkWinfo.reqwidth self - end - def TkWinfo.rgb(window, color) - list(tk_call('winfo', 'rgb', window.path, color)) - end - def winfo_rgb(window, color) - TkWinfo.rgb self, color - end - def TkWinfo.rootx(window) - number(tk_call('winfo', 'rootx', window.path)) - end - def winfo_rootx(window) - TkWinfo.rootx self - end - def TkWinfo.rooty(window) - number(tk_call('winfo', 'rooty', window.path)) - end - def winfo_rooty(window) - TkWinfo.rooty self - end - def TkWinfo.screen(window) - tk_call 'winfo', 'screen', window.path - end - def winfo_screen(window) - TkWinfo.screen self - end - def TkWinfo.screencells(window) - number(tk_call('winfo', 'screencells', window.path)) - end - def winfo_screencells(window) - TkWinfo.screencells self - end - def TkWinfo.screendepth(window) - number(tk_call('winfo', 'screendepth', window.path)) - end - def winfo_screendepth(window) - TkWinfo.screendepth self - end - def TkWinfo.screenheight (window) - number(tk_call('winfo', 'screenheight', window.path)) - end - def winfo_screenheight(window) - TkWinfo.screenheight self - end - def TkWinfo.screenmmheight(window) - number(tk_call('winfo', 'screenmmheight', window.path)) - end - def winfo_screenmmheight(window) - TkWinfo.screenmmheight self - end - def TkWinfo.screenmmwidth(window) - number(tk_call('winfo', 'screenmmwidth', window.path)) - end - def winfo_screenmmwidth(window) - TkWinfo.screenmmwidth self - end - def TkWinfo.screenvisual(window) - tk_call 'winfo', 'screenvisual', window.path - end - def winfo_screenvisual(window) - TkWinfo.screenvisual self - end - def TkWinfo.screenwidth(window) - number(tk_call('winfo', 'screenwidth', window.path)) - end - def winfo_screenwidth(window) - TkWinfo.screenwidth self - end - def TkWinfo.toplevel(window) - window(tk_call('winfo', 'toplevel', window.path)) - end - def winfo_toplevel(window) - TkWinfo.toplevel self - end - def TkWinfo.visual(window) - tk_call 'winfo', 'visual', window.path - end - def winfo_visual(window) - TkWinfo.visual self - end - def TkWinfo.vrootheigh(window) - number(tk_call('winfo', 'vrootheight', window.path)) - end - def winfo_vrootheight(window) - TkWinfo.vrootheight self - end - def TkWinfo.vrootwidth(window) - number(tk_call('winfo', 'vrootwidth', window.path)) - end - def winfo_vrootwidth(window) - TkWinfo.vrootwidth self - end - def TkWinfo.vrootx(window) - number(tk_call('winfo', 'vrootx', window.path)) - end - def winfo_vrootx(window) - TkWinfo.vrootx self - end - def TkWinfo.vrooty(window) - number(tk_call('winfo', 'vrooty', window.path)) - end - def winfo_vrooty(window) - TkWinfo.vrooty self - end - def TkWinfo.width(window) - number(tk_call('winfo', 'width', window.path)) - end - def winfo_width(window) - TkWinfo.width self - end - def TkWinfo.x(window) - number(tk_call('winfo', 'x', window.path)) - end - def winfo_x(window) - TkWinfo.x self - end - def TkWinfo.y(window) - number(tk_call('winfo', 'y', window.path)) - end - def winfo_y(window) - TkWinfo.y self - end -end - -module TkPack - include Tk - extend Tk - def configure(win, *args) - if args[-1].kind_of?(Hash) - keys = args.pop - end - wins = [win.epath] - for i in args - wins.push i.epath - end - tk_call "pack", 'configure', *(wins+hash_kv(keys)) - end - - def forget(*args) - tk_call 'pack', 'forget' *args - end - - def propagate(master, bool=None) - bool(tk_call('pack', 'propagate', master.epath, bool)) - end - module_function :configure, :forget, :propagate -end - -module TkOption - include Tk - extend Tk - def add pat, value, pri=None - tk_call 'option', 'add', pat, value, pri - end - def clear - tk_call 'option', 'clear' - end - def get win, classname, name - tk_call 'option', 'get', classname, name - end - def readfile file, pri=None - tk_call 'option', 'readfile', file, pri - end - module_function :add, :clear, :get, :readfile -end - -class TkObject - -require "tk" - -class TkCanvas", id - @cmdtbl.push id - end - def canvasx(x, *args) - tk_send 'canvasx', x, *args - end - def canvasy(y, *args) - tk_send 'canvasy', y, *args - end - def coords(tag, *args) - tk_send 'coords', tagid(tag), *args - end - def dchars(tag, first, last=None) - tk_send 'dchars', tagid(tag), first, last - end - def delete(*args) - tk_send 'delete', *args - end - alias remove delete - def dtag(tag, tag_to_del=None) - tk_send 'dtag', tagid(tag), tag_to_del - end - def find(*args) - tk_send 'find', *args - end - def itemfocus(tag) - tk_send 'find', tagid(tag) - end - def gettags(tag) - tk_send 'gettags', tagid(tag) - end - def icursor(tag, index) - tk_send 'icursor', tagid(tag), index - end - def index(tag) - tk_send 'index', tagid(tag), index - end - def lower(tag, below=None) - tk_send 'lower', tagid(tag), below - end - def move(tag, x, y) - tk_send 'move', tagid(tag), x, y - end - def itemtype(tag) - tk_send 'type', tagid(tag) - end - def postscript(keys) - tk_send "postscript", *hash_kv(keys) - end - def raise(tag, above=None) - tk_send 'raise', tagid(tag), above - end - def scale(tag, x, y, xs, ys) - tk_send 'scale', tagid(tag), x, y, xs, ys - end - def scan_mark(x, y) - tk_send 'scan', 'mark', x, y - end - def scan_dragto(x, y) - tk_send 'scan', 'dragto', x, y - end - def select(*args) - tk_send 'select', *args - end - def xview(*index) - tk_send 'xview', *index - end - def yview(*index) - tk_send 'yview', *index - end -end - -class TkcItem - -require "tk" - -TopLevel = TkToplevel -Frame = TkFrame -Label = TkLabel -Button = TkButton -Radiobutton = TkRadioButton -Checkbutton = TkCheckButton -Message = TkMessage -Entry = TkEntry -Text = TkText -Scale = TkScale -Scrollbar = TkScrollbar -Listbox = TkListbox -Menu = TkMenu -Menubutton = TkMenubutton -Canvas = TkCanvas -Arc = TkcArc -Bitmap = TkcBitmap -Line = TkcLine -Oval = TkcOval -Polygon = TkcPolygon -Rectangle = TkcRectangle -TextItem = TkcText -WindowItem = TkcWindow -Selection = TkSelection -Winfo = TkWinfo -Pack = TkPack -Variable = TkVariable - -def Mainloop - Tk.mainloop -end diff --git a/lib/tkcore.rb b/lib/tkcore.rb deleted file mode 100644 index c151b0af9e..0000000000 --- a/lib/tkcore.rb +++ /dev/null @@ -1,528 +0,0 @@ -# -# tkcore.rb - Tk interface modue without thread -# $Date$ -# by Yukihiro Matsumoto - -require "tkutil" -if defined? Thread - require "thread" -end - -module Tk - include TkUtil - extend Tk - - wish_path = nil - ENV['PATH'].split(":").each {|path| - for wish in ['wish4.2', 'wish4.1', 'wish4.0', 'wish'] - if File.exist? path+'/'+wish - wish_path = path+'/'+wish - break - end - break if wish_path - end - } - fail 'can\'t find wish' if not wish_path #' - - def Tk.tk_exit - if not PORT.closed? - PORT.print "exit\n" - PORT.close - end - end - -# PORT = open(format("|%s -n %s", wish_path, File.basename($0)), "w+"); - PORT = open(format("|%s", wish_path), "w+"); - trap "EXIT", proc{Tk.tk_exit} - trap "PIPE", "" - - def tk_write(*args) - printf PORT, *args; - PORT.print "\n" - PORT.flush - end - tk_write '\ -wm withdraw . -proc rb_out args { - puts [format %%s $args] - flush stdout -} -proc rb_ans arg { - if [catch $arg var] {puts "!$var"} {puts "=$var@@"} - flush stdout -} -proc tkerror args { exit } -proc keepalive {} { rb_out alive; after 120000 keepalive} -after 120000 keepalive' - - READABLE = [] - READ_CMD = {} - - def file_readable(port, cmd) - if cmd == nil - READABLE.delete port - else - READABLE.push port - end - READ_CMD[port] = cmd - end - - WRITABLE = [] - WRITE_CMD = {} - def file_writable(port, cmd) - if cmd == nil - WRITABLE.delete port - else - WRITABLE.push port - end - WRITE_CMD[port] = cmd - end - module_function :file_readable, :file_writable - - file_readable PORT, proc { - line = PORT.gets - exit if not line - Tk.dispatch(line.chop!) - } - - def error_at - frames = caller(1) - frames.delete_if do |c| - c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+! - end - frames - end - - def tk_tcl2ruby(val) - case val - when /^-?\d+$/ - val.to_i - when /^\./ - $tk_window_list[val] - when /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - when / / - val.split.collect{|elt| - tk_tcl2ruby(elt) - } - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - - def tk_split_list(str) - idx = str.index('{') - return tk_tcl2ruby(str) if not idx - - list = tk_tcl2ruby(str[0,idx]) - str = str[idx+1..-1] - i = -1 - brace = 1 - str.each_byte {|c| - i += 1 - brace += 1 if c == ?{ - brace -= 1 if c == ?} - break if brace == 0 - } - if str[0, i] == ' ' - list.push ' ' - else - list.push tk_split_list(str[0, i]) - end - list += tk_split_list(str[i+1..-1]) - list - end - private :tk_tcl2ruby, :tk_split_list - - def bool(val) - case bool - when "1", 1, 'yes', 'true' - TRUE - else - FALSE - end - end - def number(val) - case val - when /^-?\d+$/ - val.to_i - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - def string(val) - if val == "{}" - '' - elsif val[0] == ?{ - val[1..-2] - else - val - end - end - def list(val) - tk_split_list(val) - end - def window(val) - $tk_window_list[val] - end - def procedure(val) - if val =~ /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - else - nil - end - end - private :bool, :number, :string, :list, :window, :procedure - - # mark for non-given arguments - None = Object.new - def None.to_s - 'None' - end - - $tk_event_queue = [] - def tk_call(str, *args) - args = args.collect{|s| - next if s == None - if s.kind_of?(Hash) - s = hash_kv(s).join(" ") - else - if not s - s = "0" - elsif s == TRUE - s = "1" - elsif s.kind_of?(TkObject) - s = s.path - elsif s.kind_of?(TkVariable) - s = s.id - else - s = s.to_s - s.gsub!(/["\\\$\[\]]/, '\\\\\0') #" - s.gsub!(/\{/, '\\\\173') - s.gsub!(/\}/, '\\\\175') - end - "\"#{s}\"" - end - } - str += " " - str += args.join(" ") - print str, "\n" if $DEBUG - tk_write 'rb_ans {%s}', str - while PORT.gets - print $_ if $DEBUG - $_.chop! - if /^=(.*)@@$/ - val = $1 - break - elsif /^=/ - val = $' + "\n" - while TRUE - PORT.readline - if ~/@@$/ - val += $' - return val - else - val += $_ - end - end - elsif /^!/ - $@ = error_at - msg = $' - if msg =~ /unknown option "-(.*)"/ - $! = NameError.new(format("undefined method `%s' for %s(%s)", - $1, self, self.type)) #`' - else - $! = RuntimeError.new(format("%s - %s", self.type, msg)) - end - fail - end - $tk_event_queue.push $_ - end - - while ev = $tk_event_queue.shift - Tk.dispatch ev - end - fail 'wish closed' if PORT.closed? -# tk_split_list(val) - val - end - - def hash_kv(keys) - conf = [] - if keys - for k, v in keys - conf.push("-#{k}") - v = install_cmd(v) if v.kind_of? Proc - conf.push(v) - end - end - conf - end - private :tk_call, :error_at, :hash_kv - - $tk_cmdid = 0 - def install_cmd(cmd) - return '' if cmd == '' # uninstall cmd - id = format("c%.4d", $tk_cmdid) - $tk_cmdid += 1 - $tk_cmdtbl[id] = cmd - @cmdtbl = [] if not @cmdtbl - @cmdtbl.push id - return format('rb_out %s', id) - end - def uninstall_cmd(id) - $tk_cmdtbl[id] = nil - end - private :install_cmd, :uninstall_cmd - - $tk_window_list = {} - class Event - def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy) - @serial = seq - @num = b - @focus = (f == 1) - @height = h - @keycode = k - @state = s - @time = t - @width = w - @x = x - @y = y - @char = aa - @send_event = (ee == 1) - @keysym = kk - @keysym_num = nn - @type = tt - @widget = ww - @x_root = xx - @y_root = yy - end - attr :serial - attr :num - attr :focus - attr :height - attr :keycode - attr :state - attr :time - attr :width - attr :x - attr :y - attr :char - attr :send_event - attr :keysym - attr :keysym_num - attr :type - attr :widget - attr :x_root - attr :y_root - end - - def install_bind(cmd, args=nil) - if args - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, *arg - }) - id + " " + args - else - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, Event.new(*arg) - }) - id + " %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y" - end - end - - def _bind(path, context, cmd, args=nil) - begin - id = install_bind(cmd, args) - tk_call 'bind', path, "<#{context}>", id - rescue - $tk_cmdtbl[id] = nil - fail - end - end - private :install_bind, :_bind - - def bind_all(context, cmd=Proc.new, args=nil) - _bind 'all', context, cmd, args - end - - def pack(*args) - TkPack.configure *args - end - - $tk_cmdtbl = {} - - def after(ms, cmd=Proc.new) - myid = format("c%.4d", $tk_cmdid) - tk_call 'after', ms, - install_cmd(proc{ - TkUtil.eval_cmd cmd - uninstall_cmd myid - }) - end - - def update(idle=nil) - if idle - tk_call 'update', 'idletasks' - else - tk_call 'update' - end - end - - def dispatch(line) - if line =~ /^c\d+/ - cmd = $& - fail "no command `#{cmd}'" if not $tk_cmdtbl[cmd] - args = tk_split_list($') - TkUtil.eval_cmd $tk_cmdtbl[cmd], *args - elsif line =~ /^alive$/ - # keep alive, do nothing - else - fail "malformed line <#{line}>" - end - end - - def mainloop - begin - tk_write 'after idle {wm deiconify .}' - while TRUE - rf, wf = select(READABLE, WRITABLE) - for f in rf - READ_CMD[f].call(f) if READ_CMD[f] - if f.closed? - READABLE.delete f - READ_CMD[f] = nil - end - end - for f in wf - WRITE_CMD[f].call(f) if WRITE_CMD[f] - if f.closed? - WRITABLE.delete f - WRITE_CMD[f] = nil - end - end - end - ensure - Tk.tk_exit - end - end - - def root - $tk_root - end - - def bell - tk_call 'bell' - end - module_function :after, :update, :dispatch, :mainloop, :root, :bell - - module Scrollable - def xscrollcommand(cmd=Proc.new) - configure_cmd 'xscrollcommand', cmd - end - def yscrollcommand(cmd=Proc.new) - configure_cmd 'yscrollcommand', cmd - end - end - - module Wm - def aspect(*args) - w = window(tk_call('wm', 'grid', path, *args)) - w.split.collect{|s|s.to_i} if args.length == 0 - end - def client(name=None) - tk_call 'wm', 'client', path, name - end - def colormapwindows(*args) - list(tk_call('wm', 'colormapwindows', path, *args)) - end - def wm_command(value=None) - string(tk_call('wm', 'command', path, value)) - end - def deiconify - tk_call 'wm', 'deiconify', path - end - def focusmodel(*args) - tk_call 'wm', 'focusmodel', path, *args - end - def frame - tk_call 'wm', 'frame', path - end - def geometry(*args) - list(tk_call('wm', 'geometry', path, *args)) - end - def grid(*args) - w = tk_call('wm', 'grid', path, *args) - list(w) if args.size == 0 - end - def group(*args) - tk_call 'wm', 'path', path, *args - end - def iconbitmap(*args) - tk_call 'wm', 'bitmap', path, *args - end - def iconify - tk_call 'wm', 'iconify' - end - def iconmask(*args) - tk_call 'wm', 'iconmask', path, *args - end - def iconname(*args) - tk_call 'wm', 'iconname', path, *args - end - def iconposition(*args) - w = tk_call('wm', 'iconposition', path, *args) - list(w) if args.size == 0 - end - def iconwindow(*args) - tk_call 'wm', 'iconwindow', path, *args - end - def maxsize(*args) - w = tk_call('wm', 'maxsize', path, *args) - list(w) if not args.size == 0 - end - def minsize(*args) - w = tk_call('wm', 'minsize', path, *args) - list(w) if args.size == 0 - end - def overrideredirect(bool=None) - if bool == None - bool(tk_call('wm', 'overrideredirect', path)) - else - tk_call 'wm', 'overrideredirect', path, bool - end - end - def positionfrom(*args) - tk_call 'wm', 'positionfrom', path, *args - end - def protocol(name, func=None) - func = install_cmd(func) if not func == None - tk_call 'wm', 'command', path, name, func - end - def resizable(*args) - w = tk_call('wm', 'resizable', path, *args) - if args.length == 0 - list(w).collect{|e| bool(e)} - end - end - def sizefrom(*args) - list(tk_call('wm', 'sizefrom', path, *args)) - end - def state - tk_call 'wm', 'state', path - end - def title(*args) - tk_call 'wm', 'title', path, *args - end - def transient(*args) - tk_call 'wm', 'transient', path, *args - end - def withdraw - tk_call 'wm', 'withdraw', path - end - end -end diff --git a/lib/tkdialog.rb b/lib/tkdialog.rb deleted file mode 100644 index e8f2142e07..0000000000 --- a/lib/tkdialog.rb +++ /dev/null @@ -1,62 +0,0 @@ -require "tk" - -class TkDialog < TkWindow - # initialize tk_dialog - def initialize - super - @var = TkVariable.new - id = @var.id - INTERP._eval('eval {global '+id+';'+ - 'set '+id+' [tk_dialog '+ - @path+" "+title+" \"#{message}\" "+bitmap+" "+ - default_button+" "+buttons+']}') - end - def value - return @var.value.to_i - end - ###################################################### - # # - # these methods must be overridden for each dialog # - # # - ###################################################### - def title - return "DIALOG" - end - def message - return "MESSAGE" - end - def bitmap - return "info" - end - def default_button - return 0 - end - def buttons - return "BUTTON1 BUTTON2" - end -end - -# -# dialog for warning -# -class TkWarning < TkDialog - def initialize(mes) - @mes = mes - super() - end - def message - return @mes - end - def title - return "WARNING"; - end - def bitmap - return "warning"; - end - def default_button - return 0; - end - def buttons - return "OK"; - end -end diff --git a/lib/tkentry.rb b/lib/tkentry.rb deleted file mode 100644 index bcf092a15c..0000000000 --- a/lib/tkentry.rb +++ /dev/null @@ -1,67 +0,0 @@ -# -# tkentry.rb - Tk entry classes -# $Date$ -# by Yukihiro Matsumoto - -require 'tk.rb' - -class TkEntry - -require 'tk.rb' - -class TkScrollbox'left','fill'=>'both','expand'=>'yes' - scroll.configure 'command', list.path+" yview" - scroll.pack 'side'=>'right','fill'=>'y' - - delegate('DEFAULT', list) - delegate('foreground', list) - delegate('background', list, scroll) - delegate('borderwidth', @frame) - delegate('relief', @frame) - end -end diff --git a/lib/tktext.rb b/lib/tktext.rb deleted file mode 100644 index 47e11f2c85..0000000000 --- a/lib/tktext.rb +++ /dev/null @@ -1,164 +0,0 @@ -# -# tktext.rb - Tk text classes -# $Date$ -# by Yukihiro Matsumoto - -require 'tk.rb' - -class TkText", id - @t._addcmd cmd - end - - def lower(below=None) - tk_call @t.path, 'tag', 'lower', below - end - - def destroy - tk_call @t.path, 'tag', 'delete', @id - end -end - -class TkTextMark - -require "tkutil" -require "thread" - -module Tk - include TkUtil - extend Tk - - def Tk.tk_exit - if not PORT.closed? - tk_write "exit" - PORT.close - end - end - - trap "EXIT", proc{Tk.tk_exit} - trap "PIPE", '' - - wish_path = nil - ENV['PATH'].split(":").each {|path| - for wish in ['wish4.2', 'wish4.1', 'wish4.0', 'wish'] - if File.exist? path+'/'+wish - wish_path = path+'/'+wish - break - end - break if wish_path - end - } - fail 'can\'t find wish' if not wish_path #' - - # mark for non-given arguments - None = Object.new - def None.to_s - 'None' - end - - Qin = Queue.new - Qout = Queue.new - Qwish = Queue.new - Qcmd = Queue.new - PORT = open(format("|%s -n %s", wish_path, File.basename($0)), "w+"); - - $tk_not_init = TRUE - - def Tk.init - $tk_not_init = FALSE - Thread.start do - loop do - while line = PORT.gets - line.chop! - if line =~ /^[=!]/ - Qwish.push line - else - Qcmd.push line - end - end - exit - end - end - - Thread.start do - ary = [PORT] - loop do - str = Qin.pop - print "Qin: ", str, "\n" if $DEBUG - tk_write 'if [catch {%s} var] {puts "!$var"} {puts "=$var@@"};flush stdout', str - line = tk_recv - Qout.push(line) - end - end - end - - $tk_event_queue = [] - def tk_recv() - val = nil - $_ = Qwish.pop - loop do - if /^=(.*)@@$/ - val = $1 - break - elsif /^=/ - val = $' + "\n" - while TRUE - PORT.readline - if ~/@@$/ - val += $' - return val - else - val += $_ - end - end - elsif /^!/ - $@ = error_at - msg = $' - if msg =~ /unknown option "-(.*)"/ - fail NameError, format("undefined method `%s' for %s(%s)", $1, self, self.type) #`' - else - fail format("%s - %s", self.type, msg) - end - end - end - - fail 'wish closed' if PORT.closed? -# tk_split_list(val) - val - end - - def tk_call(str, *args) - Tk.init if $tk_not_init - args = args.collect{|s| - next if s == None - if s.kind_of?(Hash) - s = hash_kv(s).join(" ") - else - if not s - s = "0" - elsif s == TRUE - s = "1" - elsif s.kind_of?(TkObject) - s = s.path - elsif s.kind_of?(TkVariable) - s = s.id - else - s = s.to_s - s.gsub!(/["\\\$\[\]]/, '\\\\\0') #" - s.gsub!(/\{/, '\\\\173') - s.gsub!(/\}/, '\\\\175') - end - "\"#{s}\"" - end - } - str += " " - str += args.join(" ") - Qin.push str - return Qout.pop - end - - def tk_write(*args) - PORT.printf *args; PORT.print "\n" - PORT.flush - end - module_function :tk_write, :tk_recv - tk_write '\ -wm withdraw . -proc rb_out args { - puts [format %%s $args] - flush stdout -} -proc tkerror args { exit } -proc keepalive {} { rb_out alive; after 120000 keepalive} -after 120000 keepalive' - - READ_TH = {} - def file_readable(port, cmd) - if cmd == nil - if READ_TH[port].has_key? - READ_TH[port].exit - READ_TH[port] = nil - end - else - READ_TH[port] = Thread.start{ - loop do - TkUtil.eval_cmd cmd - end - } - end - end - - WRITE_TH = {} - def file_writable(port, cmd) - if cmd == nil - if WRITE_TH[port].has_key? - WRITE_TH[port].exit - end - else - WRITE_TH[port] = Thread.start{ - loop do - TkUtil.eval_cmd cmd - end - } - end - end - module_function :file_readable, :file_writable - - def tk_tcl2ruby(val) - case val - when /^-?\d+$/ - val.to_i - when /^\./ - $tk_window_list[val] - when /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - when / / - val.split.collect{|elt| - tk_tcl2ruby(elt) - } - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - - def tk_split_list(str) - idx = str.index('{') - return tk_tcl2ruby(str) if not idx - - list = tk_tcl2ruby(str[0,idx]) - str = str[idx+1..-1] - i = -1 - brace = 1 - str.each_byte {|c| - i += 1 - brace += 1 if c == ?{ - brace -= 1 if c == ?} - break if brace == 0 - } - if str[0, i] == ' ' - list.push ' ' - else - list.push tk_split_list(str[0, i]) - end - list += tk_split_list(str[i+1..-1]) - list - end - private :tk_tcl2ruby, :tk_split_list - - def dispatch(line) - if line =~ /^c\d+/ - cmd = $& - fail "no command `#{cmd}'" if not $tk_cmdtbl[cmd] - args = tk_split_list($') - TkUtil.eval_cmd $tk_cmdtbl[cmd], *args - elsif line =~ /^alive$/ - # keep alive, do nothing - else - fail "malformed line <#{line}>" - end - end - module_function :dispatch - - def error_at - frames = caller(1) - frames.delete_if do |c| - c =~ %r!/tk(|core|thcore|canvas|text|entry|scrollbox)\.rb:\d+! - end - frames - end - - def bool(val) - case bool - when "1", 1, 'yes', 'true' - TRUE - else - FALSE - end - end - def number(val) - case val - when /^-?\d+$/ - val.to_i - when /^-?\d+\.\d*$/ - val.to_f - else - val - end - end - def string(val) - if val == "{}" - '' - elsif val[0] == ?{ - val[1..-2] - else - val - end - end - def list(val) - tk_split_list(val) - end - def window(val) - $tk_window_list[val] - end - def procedure(val) - if val =~ /^rb_out (c\d+)/ - $tk_cmdtbl[$1] - else - nil - end - end - private :bool, :number, :string, :list, :window, :procedure - - def hash_kv(keys) - conf = [] - if keys - for k, v in keys - conf.push("-#{k}") - v = install_cmd(v) if v.kind_of? Proc - conf.push(v) - end - end - conf - end - private :tk_call, :error_at, :hash_kv - - $tk_cmdid = 0 - def install_cmd(cmd) - return '' if cmd == '' # uninstall cmd - id = format("c%.4d", $tk_cmdid) - $tk_cmdid += 1 - $tk_cmdtbl[id] = cmd - @cmdtbl = [] if not @cmdtbl - @cmdtbl.push id - return format('rb_out %s', id) - end - def uninstall_cmd(id) - $tk_cmdtbl[id] = nil - end - private :install_cmd, :uninstall_cmd - - $tk_window_list = {} - class Event - def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy) - @serial = seq - @num = b - @focus = (f == 1) - @height = h - @keycode = k - @state = s - @time = t - @width = w - @x = x - @y = y - @char = aa - @send_event = (ee == 1) - @keysym = kk - @keysym_num = nn - @type = tt - @widget = ww - @x_root = xx - @y_root = yy - end - attr :serial - attr :num - attr :focus - attr :height - attr :keycode - attr :state - attr :time - attr :width - attr :x - attr :y - attr :char - attr :send_event - attr :keysym - attr :keysym_num - attr :type - attr :widget - attr :x_root - attr :y_root - end - - def install_bind(cmd, args=nil) - if args - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, *arg - }) - id + " " + args - else - id = install_cmd(proc{|arg| - TkUtil.eval_cmd cmd, Event.new(*arg) - }) - id + " %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y" - end - end - - def _bind(path, context, cmd, args=nil) - begin - id = install_bind(cmd, args) - tk_call 'bind', path, "<#{context}>", id - rescue - $tk_cmdtbl[id] = nil - fail - end - end - private :install_bind, :_bind - - def bind_all(context, cmd=Proc.new, args=nil) - _bind 'all', context, cmd, args - end - - def pack(*args) - TkPack.configure *args - end - - $tk_cmdtbl = {} - - Qafter = Queue.new - def after(ms, cmd=Proc.new) - unless $tk_after_thread - $tk_after_thread = Thread.start{ - loop do - cmd = Qafter.pop - TkUtil.eval_cmd cmd - end - } - end - Thread.start do - sleep Float(ms)/1000 - Qafter.push cmd - end - end - - def update(idle=nil) - if idle - tk_call 'update', 'idletasks' - else - tk_call 'update' - end - end - - def root - $tk_root - end - - def bell - tk_call 'bell' - end - - def mainloop - begin - tk_call 'after', 'idle', 'wm deiconify .' - loop do - dispatch Qcmd.pop - end - ensure - Tk.tk_exit - end - end - module_function :after, :update, :dispatch, :mainloop, :root, :bell - - module Scrollable - def xscrollcommand(cmd=Proc.new) - configure_cmd 'xscrollcommand', cmd - end - def yscrollcommand(cmd=Proc.new) - configure_cmd 'yscrollcommand', cmd - end - end - - module Wm - def aspect(*args) - w = window(tk_call('wm', 'grid', path, *args)) - w.split.collect{|s|s.to_i} if args.length == 0 - end - def client(name=None) - tk_call 'wm', 'client', path, name - end - def colormapwindows(*args) - list(tk_call('wm', 'colormapwindows', path, *args)) - end - def wm_command(value=None) - string(tk_call('wm', 'command', path, value)) - end - def deiconify - tk_call 'wm', 'deiconify', path - end - def focusmodel(*args) - tk_call 'wm', 'focusmodel', path, *args - end - def frame - tk_call 'wm', 'frame', path - end - def geometry(*args) - list(tk_call('wm', 'geometry', path, *args)) - end - def grid(*args) - w = tk_call('wm', 'grid', path, *args) - list(w) if args.size == 0 - end - def group(*args) - tk_call 'wm', 'path', path, *args - end - def iconbitmap(*args) - tk_call 'wm', 'bitmap', path, *args - end - def iconify - tk_call 'wm', 'iconify' - end - def iconmask(*args) - tk_call 'wm', 'iconmask', path, *args - end - def iconname(*args) - tk_call 'wm', 'iconname', path, *args - end - def iconposition(*args) - w = tk_call('wm', 'iconposition', path, *args) - list(w) if args.size == 0 - end - def iconwindow(*args) - tk_call 'wm', 'iconwindow', path, *args - end - def maxsize(*args) - w = tk_call('wm', 'maxsize', path, *args) - list(w) if not args.size == 0 - end - def minsize(*args) - w = tk_call('wm', 'minsize', path, *args) - list(w) if args.size == 0 - end - def overrideredirect(bool=None) - if bool == None - bool(tk_call('wm', 'overrideredirect', path)) - else - tk_call 'wm', 'overrideredirect', path, bool - end - end - def positionfrom(*args) - tk_call 'wm', 'positionfrom', path, *args - end - def protocol(name, func=None) - func = install_cmd(func) if not func == None - tk_call 'wm', 'command', path, name, func - end - def resizable(*args) - w = tk_call('wm', 'resizable', path, *args) - if args.length == 0 - list(w).collect{|e| bool(e)} - end - end - def sizefrom(*args) - list(tk_call('wm', 'sizefrom', path, *args)) - end - def state - tk_call 'wm', 'state', path - end - def title(*args) - tk_call 'wm', 'title', path, *args - end - def transient(*args) - tk_call 'wm', 'transient', path, *args - end - def withdraw - tk_call 'wm', 'withdraw', path - end - end -end diff --git a/lib/weakref.rb b/lib/weakref.rb index c31e959e74..d53aa15c71 100644 --- a/lib/weakref.rb +++ b/lib/weakref.rb @@ -60,10 +60,11 @@ class WeakRef +#endif + int main(argc, argv, envp) int argc; @@ -26,6 +30,9 @@ main(argc, argv, envp) #if defined(NT) NtInitialize(&argc, &argv); #endif +#if defined(__MACOS__) && defined(__MWERKS__) + argc = ccommand(&argv); +#endif ruby_init(); ruby_options(argc, argv); diff --git a/marshal.c b/marshal.c index 6a68b04352..7374fadcdd 100644 --- a/marshal.c +++ b/marshal.c @@ -12,8 +12,12 @@ #include "rubyio.h" #include "st.h" +#ifndef atof +double strtod(); +#endif + #define MARSHAL_MAJOR 4 -#define MARSHAL_MINOR 0 +#define MARSHAL_MINOR 1 #define TYPE_NIL '0' #define TYPE_TRUE 'T' @@ -164,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; { @@ -174,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; @@ -249,7 +253,7 @@ w_object(obj, arg, limit) w_byte(TYPE_USERDEF, arg); w_unique(rb_class2name(CLASS_OF(obj)), arg); - v = rb_funcall(obj, s_dump, 1, limit); + v = rb_funcall(obj, s_dump, 1, INT2NUM(limit)); if (TYPE(v) != T_STRING) { rb_raise(rb_eTypeError, "_dump_to must return String"); } @@ -320,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: @@ -357,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); @@ -641,13 +645,10 @@ r_object(arg) case TYPE_FLOAT: { -#ifndef atof - double atof(); -#endif char *buf; r_bytes(buf, arg); - v = rb_float_new(atof(buf)); + v = rb_float_new(strtod(buf, 0)); return r_regist(v, arg); } @@ -754,7 +755,7 @@ r_object(arg) v = rb_funcall(klass, s_load, 1, r_string(arg)); return r_regist(v, arg); } - rb_raise(rb_eTypeError, "class %s needs to have method `_load_from'", + rb_raise(rb_eTypeError, "class %s needs to have method `_load'", rb_class2name(klass)); } break; @@ -850,7 +851,7 @@ marshal_load(argc, argv) v = rb_ensure(load, (VALUE)&arg, load_ensure, (VALUE)&arg); } else { - rb_raise(rb_eTypeError, "Old marshal file format (can't read)"); + rb_raise(rb_eTypeError, "old marshal file format (can't read)"); } return v; diff --git a/math.c b/math.c index 3ea30bdbba..978a23c73c 100644 --- a/math.c +++ b/math.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Jan 25 14:12:56 JST 1994 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ diff --git a/misc/ruby-mode.el b/misc/ruby-mode.el index cf53574481..e27102f212 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) @@ -684,16 +685,15 @@ An end of a defun is found by moving forward from the beginning of one." '("^\\s *def\\s *\\<\\(\\(\\w\\|\\s_\\)+\\.\\)?\\(\\(\\w\\|\\s_\\)+\\)\\>" 3 font-lock-function-name-face t)) "*Additional expressions to highlight in ruby mode.") - (if (and (>= (string-to-int emacs-version) 19) - (not (featurep 'xemacs))) - (add-hook - 'ruby-mode-hook - (lambda () - (make-local-variable 'font-lock-defaults) - (setq font-lock-defaults - '((ruby-font-lock-keywords) nil nil ((?\_ . "w")))))) - (add-hook 'ruby-mode-hook - (lambda () - (setq font-lock-keywords ruby-font-lock-keywords)))))) + (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)) + (setq font-lock-keywords ruby-font-lock-keywords))))) (provide 'ruby-mode) diff --git a/missing/fnmatch.c b/missing/fnmatch.c new file mode 100644 index 0000000000..09f474b0ec --- /dev/null +++ b/missing/fnmatch.c @@ -0,0 +1,199 @@ +/* + * 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 + +#define EOS '\0' + +static char *rangematch(const char *, int, int); + +int +fnmatch(pattern, string, flags) + char *pattern; + char *string; + int flags; +{ + 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 char* +rangematch(pattern, test, flags) + char *pattern; + int test, 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..773851625a --- /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(); + +#ifdef __cplusplus +} +#endif + +#endif /* !_FNMATCH_H_ */ diff --git a/missing/nt.c b/missing/nt.c deleted file mode 100644 index 703556cad7..0000000000 --- a/missing/nt.c +++ /dev/null @@ -1,2194 +0,0 @@ -/* - * Copyright (c) 1993, Intergraph Corporation - * - * You may distribute under the terms of either the GNU General Public - * License or the Artistic License, as specified in the perl README file. - * - * Various Unix compatibility functions and NT specific functions. - * - * Some of this code was derived from the MSDOS port(s) and the OS/2 port. - * - */ - -#include "ruby.h" -#include -#include -#include -/* #include */ -#include -#include -#include -#include - -#include -#include -#include -#include "nt.h" -#include "dir.h" -#ifndef index -#define index(x, y) strchr((x), (y)) -#endif - -#ifndef bool -#define bool int -#endif - -bool NtSyncProcess = TRUE; -#if 0 // declared in header file -extern char **environ; -#define environ _environ -#endif - -static bool NtHasRedirection (char *); -static int valid_filename(char *s); -static void StartSockets (); -static char *str_grow(struct RString *str, size_t new_size); - -char *NTLoginName; - -DWORD Win32System = (DWORD)-1; - -static DWORD -IdOS(void) -{ - static OSVERSIONINFO osver; - - if (osver.dwPlatformId != Win32System) { - memset(&osver, 0, sizeof(OSVERSIONINFO)); - osver.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); - GetVersionEx(&osver); - Win32System = osver.dwPlatformId; - } - return (Win32System); -} - -static int -IsWin95(void) { - return (IdOS() == VER_PLATFORM_WIN32_WINDOWS); -} - -static int -IsWinNT(void) { - return (IdOS() == VER_PLATFORM_WIN32_NT); -} - - -/* simulate flock by locking a range on the file */ - - -#define LK_ERR(f,i) ((f) ? (i = 0) : (errno = GetLastError())) -#define LK_LEN 0xffff0000 - -int -flock(int fd, int oper) -{ - OVERLAPPED o; - int i = -1; - HANDLE fh; - - fh = (HANDLE)_get_osfhandle(fd); - memset(&o, 0, sizeof(o)); - - if(IsWinNT()) { - switch(oper) { - case LOCK_SH: /* shared lock */ - LK_ERR(LockFileEx(fh, 0, 0, LK_LEN, 0, &o),i); - break; - case LOCK_EX: /* exclusive lock */ - LK_ERR(LockFileEx(fh, LOCKFILE_EXCLUSIVE_LOCK, 0, LK_LEN, 0, &o),i); - break; - case LOCK_SH|LOCK_NB: /* non-blocking shared lock */ - LK_ERR(LockFileEx(fh, LOCKFILE_FAIL_IMMEDIATELY, 0, LK_LEN, 0, &o),i); - break; - case LOCK_EX|LOCK_NB: /* non-blocking exclusive lock */ - LK_ERR(LockFileEx(fh, - LOCKFILE_EXCLUSIVE_LOCK|LOCKFILE_FAIL_IMMEDIATELY, - 0, LK_LEN, 0, &o),i); - if(errno == EDOM) errno = EWOULDBLOCK; - break; - case LOCK_UN: /* unlock lock */ - if (UnlockFileEx(fh, 0, LK_LEN, 0, &o)) { - i = 0; - } - else { - /* GetLastError() must returns `ERROR_NOT_LOCKED' */ - errno = EWOULDBLOCK; - } - if(errno == EDOM) errno = EWOULDBLOCK; - break; - default: /* unknown */ - errno = EINVAL; - break; - } - } - else if(IsWin95()) { - switch(oper) { - case LOCK_EX: - while(i == -1) { - LK_ERR(LockFile(fh, 0, 0, LK_LEN, 0), i); - if(errno != EDOM && i == -1) break; - } - break; - case LOCK_EX | LOCK_NB: - LK_ERR(LockFile(fh, 0, 0, LK_LEN, 0), i); - if(errno == EDOM) errno = EWOULDBLOCK; - break; - case LOCK_UN: - LK_ERR(UnlockFile(fh, 0, 0, LK_LEN, 0), i); - if(errno == EDOM) errno = EWOULDBLOCK; - break; - default: - errno = EINVAL; - break; - } - } - return i; -} - -#undef LK_ERR -#undef LK_LEN - - -//#undef const -//FILE *fdopen(int, const char *); - -#if 0 -void -sleep(unsigned int len) -{ - time_t end; - - end = time((time_t *)0) + len; - while (time((time_t *)0) < end) - ; -} -#endif - -// -// Initialization stuff -// -void -NtInitialize(int *argc, char ***argv) { - - WORD version; - int ret; - - // - // subvert cmd.exe\'s feeble attempt at command line parsing - // - *argc = NtMakeCmdVector((char *)GetCommandLine(), argv, TRUE); - - // - // Now set up the correct time stuff - // - - tzset(); - - // Initialize Winsock - StartSockets(); -} - - -char *getlogin() -{ - char buffer[200]; - int len = 200; - extern char *NTLoginName; - - if (NTLoginName == NULL) { - if (GetUserName(buffer, &len)) { - NTLoginName = ALLOC_N(char, len+1); - strncpy(NTLoginName, buffer, len); - NTLoginName[len] = '\0'; - } - else { - NTLoginName = ""; - } - } - return NTLoginName; -} - - - -#if 1 -// popen stuff - -// -// use these so I can remember which index is which -// - -#define NtPipeRead 0 // index of pipe read descriptor -#define NtPipeWrite 1 // index of pipe write descriptor - -#define NtPipeSize 1024 // size of pipe buffer - -#define MYPOPENSIZE 256 // size of book keeping structure - -struct { - int inuse; - int pid; - HANDLE oshandle; - FILE *pipe; -} MyPopenRecord[MYPOPENSIZE]; - -int SafeFree(char **vec, int vecc) -{ - // vec - // | - // V ^---------------------V - // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - // | | | .... | NULL | | ..... |\0 | | ..... |\0 |... - // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - // |- elements+1 -| ^ 1st element ^ 2nd element - - char *p; - - p = (char *)(vec - (vecc * sizeof (char *) + 1)); - free(p); - - return 0; -} - - -static char *szInternalCmds[] = { - "cd", - "chdir", - "cls", - "copy", - "date", - "del", - "dir", - "echo", - "erase", - "label", - "md", - "mkdir", - "path", - "rd", - "rem", - "ren", - "rename", - "rmdir", - "set", - "start", - "time", - "type", - "ver", - "vol", -}; - -int -isInternalCmd(char *cmd) -{ - int fRet; - char **vec; - int vecc = NtMakeCmdVector(cmd, &vec, FALSE); - - SafeFree (vec, vecc); - - return 0; -} - - -FILE * -mypopen (char *cmd, char *mode) -{ - FILE *fp; - int saved, reading; - int pipemode; - int pipes[2]; - int pid; - int slot; - static initialized = 0; - - // - // if first time through, intialize our book keeping structure - // - - if (!initialized++) { - for (slot = 0; slot < MYPOPENSIZE; slot++) - MyPopenRecord[slot].inuse = FALSE; - } - - //printf("mypopen %s\n", cmd); - - // - // find a free popen slot - // - - for (slot = 0; slot < MYPOPENSIZE && MyPopenRecord[slot].inuse; slot++) - ; - - if (slot > MYPOPENSIZE) { - return NULL; - } - - // - // Figure out what we\'re doing... - // - - reading = (*mode == 'r') ? TRUE : FALSE; - pipemode = (*(mode+1) == 'b') ? O_BINARY : O_TEXT; - - // - // Now get a pipe - // - -#if 0 - if (_pipe(pipes, NtPipeSize, pipemode) == -1) { - return NULL; - } - - if (reading) { - - // - // we\'re reading from the pipe, so we must hook up the - // write end of the pipe to the new processes stdout. - // To do this we must save our file handle from stdout - // by _dup\'ing it, then setting our stdout to be the pipe\'s - // write descriptor. We must also make the write handle - // inheritable so the new process can use it. - - if ((saved = _dup(fileno(stdout))) == -1) { - _close(pipes[NtPipeRead]); - _close(pipes[NtPipeWrite]); - return NULL; - } - if (_dup2 (pipes[NtPipeWrite], fileno(stdout)) == -1) { - _close(pipes[NtPipeRead]); - _close(pipes[NtPipeWrite]); - return NULL; - } - } - else { - // - // must be writing to the new process. Do the opposite of - // the above, i.e. hook up the processes stdin to the read - // end of the pipe. - // - - if ((saved = _dup(fileno(stdin))) == -1) { - _close(pipes[NtPipeRead]); - _close(pipes[NtPipeWrite]); - return NULL; - } - if (_dup2(pipes[NtPipeRead], fileno(stdin)) == -1) { - _close(pipes[NtPipeRead]); - _close(pipes[NtPipeWrite]); - return NULL; - } - } - - // - // Start the new process. Must set _fileinfo to non-zero value - // for file descriptors to be inherited. Reset after the process - // is started. - // - - if (NtHasRedirection(cmd)) { - docmd: - pid = spawnlpe(_P_NOWAIT, "cmd.exe", "/c", cmd, 0, environ); - if (pid == -1) { - _close(pipes[NtPipeRead]); - _close(pipes[NtPipeWrite]); - return NULL; - } - } - else { - char **vec; - int vecc = NtMakeCmdVector(cmd, &vec, FALSE); - - //pid = spawnvpe (_P_NOWAIT, vec[0], vec, environ); - pid = spawnvpe (_P_WAIT, vec[0], vec, environ); - if (pid == -1) { - goto docmd; - } - Safefree (vec, vecc); - } - - if (reading) { - - // - // We need to close our instance of the inherited pipe write - // handle now that it's been inherited so that it will actually close - // when the child process ends. - // - - if (_close(pipes[NtPipeWrite]) == -1) { - _close(pipes[NtPipeRead]); - return NULL; - } - if (_dup2 (saved, fileno(stdout)) == -1) { - _close(pipes[NtPipeRead]); - return NULL; - } - _close(saved); - - // - // Now get a stream pointer to return to the calling program. - // - - if ((fp = (FILE *) fdopen(pipes[NtPipeRead], mode)) == NULL) { - return NULL; - } - } - else { - - // - // need to close our read end of the pipe so that it will go - // away when the write end is closed. - // - - if (_close(pipes[NtPipeRead]) == -1) { - _close(pipes[NtPipeWrite]); - return NULL; - } - if (_dup2 (saved, fileno(stdin)) == -1) { - _close(pipes[NtPipeWrite]); - return NULL; - } - _close(saved); - - // - // Now get a stream pointer to return to the calling program. - // - - if ((fp = (FILE *) fdopen(pipes[NtPipeWrite], mode)) == NULL) { - _close(pipes[NtPipeWrite]); - return NULL; - } - } - - // - // do the book keeping - // - - MyPopenRecord[slot].inuse = TRUE; - MyPopenRecord[slot].pipe = fp; - MyPopenRecord[slot].pid = pid; - - return fp; -#else - { - int p[2]; - - BOOL fRet; - HANDLE hInFile, hOutFile, hStdin, hStdout; - LPCSTR lpApplicationName = NULL; - LPTSTR lpCommandLine; - LPTSTR lpCmd2 = NULL; - DWORD dwCreationFlags; - STARTUPINFO aStartupInfo; - PROCESS_INFORMATION aProcessInformation; - SECURITY_ATTRIBUTES sa; - int fd; - - sa.nLength = sizeof (SECURITY_ATTRIBUTES); - sa.lpSecurityDescriptor = NULL; - sa.bInheritHandle = TRUE; - - if (!reading) { - FILE *fp; - - fp = (_popen)(cmd, mode); - - MyPopenRecord[slot].inuse = TRUE; - MyPopenRecord[slot].pipe = fp; - MyPopenRecord[slot].pid = -1; - - if (!fp) - Fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno)); - return fp; - } - - fRet = CreatePipe(&hInFile, &hOutFile, &sa, 2048L); - if (!fRet) - Fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno)); - - memset(&aStartupInfo, 0, sizeof (STARTUPINFO)); - memset(&aProcessInformation, 0, sizeof (PROCESS_INFORMATION)); - aStartupInfo.cb = sizeof (STARTUPINFO); - aStartupInfo.dwFlags = STARTF_USESTDHANDLES; - - if (reading) { - aStartupInfo.hStdInput = GetStdHandle(STD_OUTPUT_HANDLE);//hStdin; - aStartupInfo.hStdError = INVALID_HANDLE_VALUE; - //for save - DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE), - GetCurrentProcess(), &hStdout, - 0, FALSE, DUPLICATE_SAME_ACCESS - ); - //for redirect - DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), - GetCurrentProcess(), &hStdin, - 0, TRUE, DUPLICATE_SAME_ACCESS - ); - aStartupInfo.hStdOutput = hOutFile; - } - else { - aStartupInfo.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE); //hStdout; - aStartupInfo.hStdError = INVALID_HANDLE_VALUE; - // for save - DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_INPUT_HANDLE), - GetCurrentProcess(), &hStdin, - 0, FALSE, DUPLICATE_SAME_ACCESS - ); - //for redirect - DuplicateHandle(GetCurrentProcess(), GetStdHandle(STD_OUTPUT_HANDLE), - GetCurrentProcess(), &hStdout, - 0, TRUE, DUPLICATE_SAME_ACCESS - ); - aStartupInfo.hStdInput = hInFile; - } - - dwCreationFlags = (NORMAL_PRIORITY_CLASS); - - lpCommandLine = cmd; - if (NtHasRedirection(cmd) || isInternalCmd(cmd)) { - lpApplicationName = getenv("COMSPEC"); - lpCmd2 = malloc(strlen(lpApplicationName) + 1 + strlen(cmd) + sizeof (" /c ")); - if (lpCmd2 == NULL) - Fatal("Mypopen: malloc failed"); - sprintf(lpCmd2, "%s %s%s", lpApplicationName, " /c ", cmd); - lpCommandLine = lpCmd2; - } - - fRet = CreateProcess(lpApplicationName, lpCommandLine, &sa, &sa, - sa.bInheritHandle, dwCreationFlags, NULL, NULL, &aStartupInfo, &aProcessInformation); - - if (!fRet) { - CloseHandle(hInFile); - CloseHandle(hOutFile); - Fatal("cannot fork for \"%s\" (%s)", cmd, strerror(errno)); - } - - CloseHandle(aProcessInformation.hThread); - - if (reading) { - HANDLE hDummy; - - fd = _open_osfhandle((long)hInFile, (_O_RDONLY | pipemode)); - CloseHandle(hOutFile); - DuplicateHandle(GetCurrentProcess(), hStdout, - GetCurrentProcess(), &hDummy, - 0, TRUE, (DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE) - ); - } - else { - HANDLE hDummy; - - fd = _open_osfhandle((long)hOutFile, (_O_WRONLY | pipemode)); - CloseHandle(hInFile); - DuplicateHandle(GetCurrentProcess(), hStdin, - GetCurrentProcess(), &hDummy, - 0, TRUE, (DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE) - ); - } - - if (fd == -1) - Fatal("cannot open pipe \"%s\" (%s)", cmd, strerror(errno)); - - - if ((fp = (FILE *) fdopen(fd, mode)) == NULL) - return NULL; - - if (lpCmd2) - free(lpCmd2); - - MyPopenRecord[slot].inuse = TRUE; - MyPopenRecord[slot].pipe = fp; - MyPopenRecord[slot].oshandle = (reading ? hInFile : hOutFile); - MyPopenRecord[slot].pid = (int)aProcessInformation.hProcess; - return fp; - } -#endif -} - -int -mypclose(FILE *fp) -{ - int i; - int exitcode; - - Sleep(100); - for (i = 0; i < MYPOPENSIZE; i++) { - if (MyPopenRecord[i].inuse && MyPopenRecord[i].pipe == fp) - break; - } - if (i >= MYPOPENSIZE) { - Fatal("Invalid file pointer passed to mypclose!\n"); - } - - // - // get the return status of the process - // - -#if 0 - if (_cwait(&exitcode, MyPopenRecord[i].pid, WAIT_CHILD) == -1) { - if (errno == ECHILD) { - fprintf(stderr, "mypclose: nosuch child as pid %x\n", - MyPopenRecord[i].pid); - } - } -#else - for (;;) { - if (GetExitCodeProcess((HANDLE)MyPopenRecord[i].pid, &exitcode)) { - if (exitcode == STILL_ACTIVE) { - //printf("Process is Active.\n"); - Sleep(100); - TerminateProcess((HANDLE)MyPopenRecord[i].pid, 0); // ugly... - continue; - } - else if (exitcode == 0) { - //printf("done.\n"); - break; - } - else { - //printf("never.\n"); - break; - } - } - } -#endif - - - // - // close the pipe - // - CloseHandle(MyPopenRecord[i].oshandle); - fflush(fp); - fclose(fp); - - // - // free this slot - // - - MyPopenRecord[i].inuse = FALSE; - MyPopenRecord[i].pipe = NULL; - MyPopenRecord[i].pid = 0; - - return exitcode; -} -#endif - -#if 1 - - -typedef char* CHARP; -/* - * The following code is based on the do_exec and do_aexec functions - * in file doio.c - */ - -int -do_spawn(cmd) -char *cmd; -{ - register char **a; - register char *s; - char **argv; - int status; - char *shell, *cmd2; - int mode = NtSyncProcess ? P_WAIT : P_NOWAIT; - - /* save an extra exec if possible */ - if ((shell = getenv("RUBYSHELL")) != 0) { - if (NtHasRedirection(cmd)) { - int i; - char *p; - char *argv[4]; - char *cmdline = ALLOC_N(char, (strlen(cmd) * 2 + 1)); - - p=cmdline; - *p++ = '"'; - for (s=cmd; *s;) { - if (*s == '"') - *p++ = '\\'; /* Escape d-quote */ - *p++ = *s++; - } - *p++ = '"'; - *p = '\0'; - - /* fprintf(stderr, "do_spawn: %s %s\n", shell, cmdline); */ - argv[0] = shell; - argv[1] = "-c"; - argv[2] = cmdline; - argv[4] = NULL; - status = spawnvpe(mode, argv[0], argv, environ); - /* return spawnle(mode, shell, shell, "-c", cmd, (char*)0, environ); */ - free(cmdline); - return status; - } - } - else if ((shell = getenv("COMSPEC")) != 0) { - if (NtHasRedirection(cmd) /* || isInternalCmd(cmd) */) { - do_comspec_shell: - return spawnle(mode, shell, shell, "/c", cmd, (char*)0, environ); - } - } - - argv = ALLOC_N(CHARP, (strlen(cmd) / 2 + 2)); - cmd2 = ALLOC_N(char, (strlen(cmd) + 1)); - strcpy(cmd2, cmd); - a = argv; - for (s = cmd2; *s;) { - while (*s && isspace(*s)) s++; - if (*s) - *(a++) = s; - while (*s && !isspace(*s)) s++; - if (*s) - *s++ = '\0'; - } - *a = NULL; - if (argv[0]) { - if ((status = spawnvpe(mode, argv[0], argv, environ)) == -1) { - free(argv); - free(cmd2); - return -1; - } - } - free(cmd2); - free(argv); - return status; -} - -#endif - -typedef struct _NtCmdLineElement { - struct _NtCmdLineElement *next, *prev; - char *str; - int len; - int flags; -} NtCmdLineElement; - -// -// Possible values for flags -// - -#define NTGLOB 0x1 // element contains a wildcard -#define NTMALLOC 0x2 // string in element was malloc'ed -#define NTSTRING 0x4 // element contains a quoted string - -NtCmdLineElement *NtCmdHead = NULL, *NtCmdTail = NULL; - -void -NtFreeCmdLine(void) -{ - NtCmdLineElement *ptr; - - while(NtCmdHead) { - ptr = NtCmdHead; - NtCmdHead = NtCmdHead->next; - free(ptr); - } - NtCmdHead = NtCmdTail = NULL; -} - -// -// This function expands wild card characters that were spotted -// during the parse phase. The idea here is to call FindFirstFile and -// FindNextFile with the wildcard pattern specified, and splice in the -// resulting list of new names. If the wildcard pattern doesn\'t match -// any existing files, just leave it in the list. -// - -void -NtCmdGlob (NtCmdLineElement *patt) -{ - WIN32_FIND_DATA fd; - HANDLE fh; - char buffer[512]; - NtCmdLineElement *tmphead, *tmptail, *tmpcurr; - - strncpy(buffer, patt->str, patt->len); - buffer[patt->len] = '\0'; - if ((fh = FindFirstFile (buffer, &fd)) == INVALID_HANDLE_VALUE) { - return; - } - tmphead = tmptail = NULL; - do { - tmpcurr = ALLOC(NtCmdLineElement); - if (tmpcurr == NULL) { - fprintf(stderr, "Out of Memory in globbing!\n"); - while (tmphead) { - tmpcurr = tmphead; - tmphead = tmphead->next; - free(tmpcurr->str); - free(tmpcurr); - } - return; - } - memset (tmpcurr, 0, sizeof(*tmpcurr)); - tmpcurr->len = strlen(fd.cFileName); - tmpcurr->str = ALLOC_N(char, tmpcurr->len+1); - if (tmpcurr->str == NULL) { - fprintf(stderr, "Out of Memory in globbing!\n"); - while (tmphead) { - tmpcurr = tmphead; - tmphead = tmphead->next; - free(tmpcurr->str); - free(tmpcurr); - } - return; - } - strcpy(tmpcurr->str, fd.cFileName); - tmpcurr->flags |= NTMALLOC; - if (tmptail) { - tmptail->next = tmpcurr; - tmpcurr->prev = tmptail; - tmptail = tmpcurr; - } - else { - tmptail = tmphead = tmpcurr; - } - } while(FindNextFile(fh, &fd)); - - // - // ok, now we\'ve got a list of files that matched the wildcard - // specification. Put it in place of the pattern structure. - // - - tmphead->prev = patt->prev; - tmptail->next = patt->next; - - if (tmphead->prev) - tmphead->prev->next = tmphead; - - if (tmptail->next) - tmptail->next->prev = tmptail; - - // - // Now get rid of the pattern structure - // - - if (patt->flags & NTMALLOC) - free(patt->str); - // free(patt); //TODO: memory leak occures here. we have to fix it. -} - -// -// Check a command string to determine if it has I/O redirection -// characters that require it to be executed by a command interpreter -// - -static bool -NtHasRedirection (char *cmd) -{ - int inquote = 0; - char quote = '\0'; - char *ptr ; - - // - // Scan the string, looking for redirection (< or >) or pipe - // characters (|) that are not in a quoted string - // - - for (ptr = cmd; *ptr; ptr++) { - - switch (*ptr) { - - case '\'': - case '\"': - if (inquote) { - if (quote == *ptr) { - inquote = 0; - quote = '\0'; - } - } - else { - quote = *ptr; - inquote++; - } - break; - - case '>': - case '<': - - if (!inquote) - return TRUE; - } - } - return FALSE; -} - - -int -NtMakeCmdVector (char *cmdline, char ***vec, int InputCmd) -{ - int cmdlen = strlen(cmdline); - int done, instring, globbing, quoted, len; - int newline, need_free = 0, i; - int elements, strsz; - int slashes = 0; - char *ptr, *base, *buffer; - char **vptr; - char quote; - NtCmdLineElement *curr; - - // - // just return if we don\'t have a command line - // - - if (cmdlen == 0) { - *vec = NULL; - return 0; - } - - // - // strip trailing white space - // - - ptr = cmdline+(cmdlen - 1); - while(ptr >= cmdline && isspace(*ptr)) - --ptr; - *++ptr = '\0'; - - // - // check for newlines and formfeeds. If we find any, make a new - // command string that replaces them with escaped sequences (\n or \f) - // - - for (ptr = cmdline, newline = 0; *ptr; ptr++) { - if (*ptr == '\n' || *ptr == '\f') - newline++; - } - - if (newline) { - base = ALLOC_N(char, strlen(cmdline) + 1 + newline + slashes); - if (base == NULL) { - fprintf(stderr, "malloc failed!\n"); - return 0; - } - for (i = 0, ptr = base; (unsigned) i < strlen(cmdline); i++) { - switch (cmdline[i]) { - case '\n': - *ptr++ = '\\'; - *ptr++ = 'n'; - break; - default: - *ptr++ = cmdline[i]; - } - } - *ptr = '\0'; - cmdline = base; - need_free++; - } - - // - // Ok, parse the command line, building a list of CmdLineElements. - // When we\'ve finished, and it\'s an input command (meaning that it\'s - // the processes argv), we\'ll do globing and then build the argument - // vector. - // The outer loop does one interation for each element seen. - // The inner loop does one interation for each character in the element. - // - - for (done = 0, ptr = cmdline; *ptr;) { - - // - // zap any leading whitespace - // - - while(isspace(*ptr)) - ptr++; - base = ptr; - - for (done = newline = globbing = instring = quoted = 0; - *ptr && !done; ptr++) { - - // - // Switch on the current character. We only care about the - // white-space characters, the wild-card characters, and the - // quote characters. - // - - switch (*ptr) { - case ' ': - case '\t': -#if 0 - case '/': // have to do this for NT/DOS option strings - - // - // check to see if we\'re parsing an option switch - // - - if (*ptr == '/' && base == ptr) - continue; -#endif - // - // if we\'re not in a string, then we\'re finished with this - // element - // - - if (!instring) - done++; - break; - - case '*': - case '?': - - // - // record the fact that this element has a wildcard character - // N.B. Don\'t glob if inside a single quoted string - // - - if (!(instring && quote == '\'')) - globbing++; - break; - - case '\n': - - // - // If this string contains a newline, mark it as such so - // we can replace it with the two character sequence "\n" - // (cmd.exe doesn\'t like raw newlines in strings...sigh). - // - - newline++; - break; - - case '\'': - case '\"': - - // - // if we\'re already in a string, see if this is the - // terminating close-quote. If it is, we\'re finished with - // the string, but not neccessarily with the element. - // If we\'re not already in a string, start one. - // - - if (instring) { - if (quote == *ptr) { - instring = 0; - quote = '\0'; - } - } - else { - instring++; - quote = *ptr; - quoted++; - } - break; - } - } - - // - // need to back up ptr by one due to last increment of for loop - // (if we got out by seeing white space) - // - - if (*ptr) - ptr--; - - // - // when we get here, we\'ve got a pair of pointers to the element, - // base and ptr. Base points to the start of the element while ptr - // points to the character following the element. - // - - curr = ALLOC(NtCmdLineElement); - if (curr == NULL) { - NtFreeCmdLine(); - fprintf(stderr, "Out of memory!!\n"); - *vec = NULL; - return 0; - } - memset (curr, 0, sizeof(*curr)); - - len = ptr - base; - - // - // if it\'s an input vector element and it\'s enclosed by quotes, - // we can remove them. - // - - if (InputCmd && - ((base[0] == '\"' && base[len-1] == '\"') || - (base[0] == '\'' && base[len-1] == '\''))) { - base++; - len -= 2; - } - - curr->str = base; - curr->len = len; - curr->flags |= (globbing ? NTGLOB : 0); - - // - // Now put it in the list of elements - // - if (NtCmdTail) { - NtCmdTail->next = curr; - curr->prev = NtCmdTail; - NtCmdTail = curr; - } - else { - NtCmdHead = NtCmdTail = curr; - } - } - - if (InputCmd) { - - // - // When we get here we\'ve finished parsing the command line. Now - // we need to run the list, expanding any globbing patterns. - // - - for(curr = NtCmdHead; curr; curr = curr->next) { - if (curr->flags & NTGLOB) { - NtCmdGlob(curr); - } - } - } - - // - // Almost done! - // Count up the elements, then allocate space for a vector of pointers - // (argv) and a string table for the elements. - // - - for (elements = 0, strsz = 0, curr = NtCmdHead; curr; curr = curr->next) { - elements++; - strsz += (curr->len + 1); - } - - len = (elements+1)*sizeof(char *) + strsz; - buffer = ALLOC_N(char, len); - if (buffer == NULL) { - fprintf(stderr, "Out of memory!!\n"); - NtFreeCmdLine(); - *vec = NULL; - return 0; - } - - memset (buffer, 0, len); - - // - // make vptr point to the start of the buffer - // and ptr point to the area we\'ll consider the string table. - // - // buffer (*vec) - // | - // V ^---------------------V - // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - // | | | .... | NULL | | ..... |\0 | | ..... |\0 |... - // +---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+ - // |- elements+1 -| ^ 1st element ^ 2nd element - - vptr = (char **) buffer; - - ptr = buffer + (elements+1) * sizeof(char *); - - for (curr = NtCmdHead; curr; curr = curr->next) { - strncpy (ptr, curr->str, curr->len); - ptr[curr->len] = '\0'; - *vptr++ = ptr; - ptr += curr->len + 1; - } - NtFreeCmdLine(); - *vec = (char **) buffer; - return elements; -} - - -#if 1 -// -// UNIX compatible directory access functions for NT -// - -// -// File names are converted to lowercase if the -// CONVERT_TO_LOWER_CASE variable is defined. -// - -#define CONVERT_TO_LOWER_CASE -#define PATHLEN 1024 - -// -// The idea here is to read all the directory names into a string table -// (separated by nulls) and when one of the other dir functions is called -// return the pointer to the current file name. -// - -DIR * -opendir(char *filename) -{ - DIR *p; - long len; - long idx; - char scannamespc[PATHLEN]; - char *scanname = scannamespc; - struct stat sbuf; - WIN32_FIND_DATA FindData; - HANDLE fh; - char root[PATHLEN]; - char volname[PATHLEN]; - DWORD serial, maxname, flags; - BOOL downcase; - char *dummy; - - // - // check to see if we\'ve got a directory - // - - if (stat (filename, &sbuf) < 0 || - sbuf.st_mode & _S_IFDIR == 0) { - return NULL; - } - - // - // check out the file system characteristics - // - if (GetFullPathName(filename, PATHLEN, root, &dummy)) { - if (dummy = strchr(root, '\\')) - *++dummy = '\0'; - if (GetVolumeInformation(root, volname, PATHLEN, - &serial, &maxname, &flags, 0, 0)) { - downcase = !(flags & FS_CASE_SENSITIVE); - } - } - else { - downcase = TRUE; - } - - // - // Get us a DIR structure - // - - p = xcalloc(sizeof(DIR), 1); - if (p == NULL) - return NULL; - - // - // Create the search pattern - // - - strcpy(scanname, filename); - - if (index("/\\", *(scanname + strlen(scanname) - 1)) == NULL) - strcat(scanname, "/*"); - else - strcat(scanname, "*"); - - // - // do the FindFirstFile call - // - - fh = FindFirstFile (scanname, &FindData); - if (fh == INVALID_HANDLE_VALUE) { - return NULL; - } - - // - // now allocate the first part of the string table for the - // filenames that we find. - // - - idx = strlen(FindData.cFileName)+1; - p->start = ALLOC_N(char, idx); - strcpy (p->start, FindData.cFileName); - if (downcase) - strlwr(p->start); - p->nfiles++; - - // - // loop finding all the files that match the wildcard - // (which should be all of them in this directory!). - // the variable idx should point one past the null terminator - // of the previous string found. - // - while (FindNextFile(fh, &FindData)) { - len = strlen (FindData.cFileName); - - // - // bump the string table size by enough for the - // new name and it's null terminator - // - - #define Renew(x, y, z) (x = (z *)realloc(x, y)) - - Renew (p->start, idx+len+1, char); - if (p->start == NULL) { - Fatal ("opendir: malloc failed!\n"); - } - strcpy(&p->start[idx], FindData.cFileName); - if (downcase) - strlwr(&p->start[idx]); - p->nfiles++; - idx += len+1; - } - FindClose(fh); - p->size = idx; - p->curr = p->start; - return p; -} - - -// -// Readdir just returns the current string pointer and bumps the -// string pointer to the next entry. -// - -struct direct * -readdir(DIR *dirp) -{ - int len; - static int dummy = 0; - - if (dirp->curr) { - - // - // first set up the structure to return - // - - len = strlen(dirp->curr); - strcpy(dirp->dirstr.d_name, dirp->curr); - dirp->dirstr.d_namlen = len; - - // - // Fake inode - // - dirp->dirstr.d_ino = dummy++; - - // - // Now set up for the next call to readdir - // - - dirp->curr += len + 1; - if (dirp->curr >= (dirp->start + dirp->size)) { - dirp->curr = NULL; - } - - return &(dirp->dirstr); - - } else - return NULL; -} - -// -// Telldir returns the current string pointer position -// - -long -telldir(DIR *dirp) -{ - return (long) dirp->curr; /* ouch! pointer to long cast */ -} - -// -// Seekdir moves the string pointer to a previously saved position -// (Saved by telldir). - -void -seekdir(DIR *dirp, long loc) -{ - dirp->curr = (char *) loc; /* ouch! long to pointer cast */ -} - -// -// Rewinddir resets the string pointer to the start -// - -void -rewinddir(DIR *dirp) -{ - dirp->curr = dirp->start; -} - -// -// This just free\'s the memory allocated by opendir -// - -void -closedir(DIR *dirp) -{ - free(dirp->start); - free(dirp); -} -#endif - - -// -// 98.2% of this code was lifted from the OS2 port. (JCW) -// - -#if 0 -// add_suffix is in util.c too. -/* - * Suffix appending for in-place editing under MS-DOS and OS/2 (and now NT!). - * - * Here are the rules: - * - * Style 0: Append the suffix exactly as standard perl would do it. - * If the filesystem groks it, use it. (HPFS will always - * grok it. So will NTFS. FAT will rarely accept it.) - * - * Style 1: The suffix begins with a '.'. The extension is replaced. - * If the name matches the original name, use the fallback method. - * - * Style 2: The suffix is a single character, not a '.'. Try to add the - * suffix to the following places, using the first one that works. - * [1] Append to extension. - * [2] Append to filename, - * [3] Replace end of extension, - * [4] Replace end of filename. - * If the name matches the original name, use the fallback method. - * - * Style 3: Any other case: Ignore the suffix completely and use the - * fallback method. - * - * Fallback method: Change the extension to ".$$$". If that matches the - * original name, then change the extension to ".~~~". - * - * If filename is more than 1000 characters long, we die a horrible - * death. Sorry. - * - * The filename restriction is a cheat so that we can use buf[] to store - * assorted temporary goo. - * - * Examples, assuming style 0 failed. - * - * suffix = ".bak" (style 1) - * foo.bar => foo.bak - * foo.bak => foo.$$$ (fallback) - * foo.$$$ => foo.~~~ (fallback) - * makefile => makefile.bak - * - * suffix = "~" (style 2) - * foo.c => foo.c~ - * foo.c~ => foo.c~~ - * foo.c~~ => foo~.c~~ - * foo~.c~~ => foo~~.c~~ - * foo~~~~~.c~~ => foo~~~~~.$$$ (fallback) - * - * foo.pas => foo~.pas - * makefile => makefile.~ - * longname.fil => longname.fi~ - * longname.fi~ => longnam~.fi~ - * longnam~.fi~ => longnam~.$$$ - * - */ - - -static char suffix1[] = ".$$$"; -static char suffix2[] = ".~~~"; - -#define ext (&buf[1000]) - -#define strEQ(s1,s2) (strcmp(s1,s2) == 0) - -void -add_suffix(struct RString *str, char *suffix) -{ - int baselen; - int extlen = strlen(suffix); - char *s, *t, *p; - int slen; - char buf[1024]; - - if (str->len > 1000) - Fatal("Cannot do inplace edit on long filename (%d characters)", str->len); - - /* Style 0 */ - slen = str->len; - str_cat(str, suffix, extlen); - if (valid_filename(str->ptr)) return; - - /* Fooey, style 0 failed. Fix str before continuing. */ - str->ptr[str->len = slen] = '\0'; - - slen = extlen; - t = buf; baselen = 0; s = str->ptr; - while ( (*t = *s) && *s != '.') { - baselen++; - if (*s == '\\' || *s == '/') baselen = 0; - s++; t++; - } - p = t; - - t = ext; extlen = 0; - while (*t++ = *s++) extlen++; - if (extlen == 0) { ext[0] = '.'; ext[1] = 0; extlen++; } - - if (*suffix == '.') { /* Style 1 */ - if (strEQ(ext, suffix)) goto fallback; - strcpy(p, suffix); - } else if (suffix[1] == '\0') { /* Style 2 */ - if (extlen < 4) { - ext[extlen] = *suffix; - ext[++extlen] = '\0'; - } else if (baselen < 8) { - *p++ = *suffix; - } else if (ext[3] != *suffix) { - ext[3] = *suffix; - } else if (buf[7] != *suffix) { - buf[7] = *suffix; - } else goto fallback; - strcpy(p, ext); - } else { /* Style 3: Panic */ -fallback: - (void)memcpy(p, strEQ(ext, suffix1) ? suffix2 : suffix1, 5); - } - str_grow(str, strlen(buf)); - memcpy(str->ptr, buf, str->len); -} -#endif - -static int -valid_filename(char *s) -{ - int fd; - - // - // if the file exists, then it\'s a valid filename! - // - - if (_access(s, 0) == 0) { - return 1; - } - - // - // It doesn\'t exist, so see if we can open it. - // - - if ((fd = _open(s, _O_CREAT, 0666)) >= 0) { - close(fd); - _unlink (s); // don\'t leave it laying around - return 1; - } - return 0; -} - - -// -// This is a clone of fdopen so that we can handle the -// brain damaged version of sockets that NT gets to use. -// -// The problem is that sockets are not real file handles and -// cannot be fdopen\'ed. This causes problems in the do_socket -// routine in doio.c, since it tries to create two file pointers -// for the socket just created. We\'ll fake out an fdopen and see -// if we can prevent perl from trying to do stdio on sockets. -// - -FILE * -myfdopen (int fd, const char *mode) -{ - FILE *fp; - char sockbuf[80]; - int optlen; - int retval; - extern int errno; - - //fprintf(stderr, "myfdopen()\n"); - - retval = getsockopt((SOCKET)fd, SOL_SOCKET, SO_TYPE, sockbuf, &optlen); - if (retval == SOCKET_ERROR) { - int iRet; - - iRet = WSAGetLastError(); - if (iRet == WSAENOTSOCK || iRet == WSANOTINITIALISED) - return (_fdopen(fd, mode)); - } - - // - // If we get here, then fd is actually a socket. - // - fp = xcalloc(sizeof(FILE), 1); -#if _MSC_VER < 800 - fileno(fp) = fd; -#else - fp->_file = fd; -#endif - if (*mode == 'r') - fp->_flag = _IOREAD; - else - fp->_flag = _IOWRT; - return fp; -} - - -// -// Since the errors returned by the socket error function -// WSAGetLastError() are not known by the library routine strerror -// we have to roll our own. -// - -#undef strerror - -char * -mystrerror(int e) -{ - static char buffer[512]; - extern int sys_nerr; - DWORD source = 0; - - if (e < 0 || e > sys_nerr) { - if (e < 0) - e = GetLastError(); - if (FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM, &source, e, 0, - buffer, 512, NULL) == 0) { - strcpy (buffer, "Unknown Error"); - } - return buffer; - } - return strerror(e); - -} - -// -// various stubs -// - - -// Ownership -// -// Just pretend that everyone is a superuser. NT will let us know if -// we don\'t really have permission to do something. -// - -#define ROOT_UID 0 -#define ROOT_GID 0 - -UIDTYPE -getuid(void) -{ - return ROOT_UID; -} - -UIDTYPE -geteuid(void) -{ - return ROOT_UID; -} - -GIDTYPE -getgid(void) -{ - return ROOT_GID; -} - -GIDTYPE -getegid(void) -{ - return ROOT_GID; -} - -int -setuid(int uid) -{ - return (uid == ROOT_UID ? 0 : -1); -} - -int -setgid(int gid) -{ - return (gid == ROOT_GID ? 0 : -1); -} - -// -// File system stuff -// - -int -/* ioctl(int i, unsigned int u, char *data) */ -ioctl(int i, unsigned int u, long data) -{ - return -1; -} - - -// -// Networking trampolines -// These are used to avoid socket startup/shutdown overhead in case -// the socket routines aren\'t used. -// - -#undef select - -static int NtSocketsInitialized = 0; - -long -myselect (int nfds, fd_set *rd, fd_set *wr, fd_set *ex, - struct timeval *timeout) -{ - long r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = select (nfds, rd, wr, ex, timeout)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -static void -StartSockets () { - WORD version; - WSADATA retdata; - int ret; - - // - // initalize the winsock interface and insure that it\'s - // cleaned up at exit. - // - version = MAKEWORD(1, 1); - if (ret = WSAStartup(version, &retdata)) - Fatal ("Unable to locate winsock library!\n"); - if (LOBYTE(retdata.wVersion) != 1) - Fatal("could not find version 1 of winsock dll\n"); - - if (HIBYTE(retdata.wVersion) != 1) - Fatal("could not find version 1 of winsock dll\n"); - - atexit((void (*)(void)) WSACleanup); -} - -#undef accept - -SOCKET -myaccept (SOCKET s, struct sockaddr *addr, int *addrlen) -{ - SOCKET r; - - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = accept (s, addr, addrlen)) == INVALID_SOCKET) - errno = WSAGetLastError(); - return r; -} - -#undef bind - -int -mybind (SOCKET s, struct sockaddr *addr, int addrlen) -{ - int r; - - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = bind (s, addr, addrlen)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef connect - -int -myconnect (SOCKET s, struct sockaddr *addr, int addrlen) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = connect (s, addr, addrlen)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - - -#undef getpeername - -int -mygetpeername (SOCKET s, struct sockaddr *addr, int *addrlen) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = getpeername (s, addr, addrlen)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef getsockname - -int -mygetsockname (SOCKET s, struct sockaddr *addr, int *addrlen) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = getsockname (s, addr, addrlen)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef getsockopt - -int -mygetsockopt (SOCKET s, int level, int optname, char *optval, int *optlen) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = getsockopt (s, level, optname, optval, optlen)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef ioctlsocket - -int -myioctlsocket (SOCKET s, long cmd, u_long *argp) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = ioctlsocket (s, cmd, argp)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef listen - -int -mylisten (SOCKET s, int backlog) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = listen (s, backlog)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef recv - -int -myrecv (SOCKET s, char *buf, int len, int flags) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = recv (s, buf, len, flags)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef recvfrom - -int -myrecvfrom (SOCKET s, char *buf, int len, int flags, - struct sockaddr *from, int *fromlen) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = recvfrom (s, buf, len, flags, from, fromlen)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef send - -int -mysend (SOCKET s, char *buf, int len, int flags) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = send (s, buf, len, flags)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef sendto - -int -mysendto (SOCKET s, char *buf, int len, int flags, - struct sockaddr *to, int tolen) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = sendto (s, buf, len, flags, to, tolen)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef setsockopt - -int -mysetsockopt (SOCKET s, int level, int optname, char *optval, int optlen) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = setsockopt (s, level, optname, optval, optlen)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef shutdown - -int -myshutdown (SOCKET s, int how) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = shutdown (s, how)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef socket - -SOCKET -mysocket (int af, int type, int protocol) -{ - SOCKET s; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((s = socket (af, type, protocol)) == INVALID_SOCKET) { - errno = WSAGetLastError(); - //fprintf(stderr, "socket fail (%d)", WSAGetLastError()); - } - return s; -} - -#undef gethostbyaddr - -struct hostent * -mygethostbyaddr (char *addr, int len, int type) -{ - struct hostent *r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = gethostbyaddr (addr, len, type)) == NULL) - errno = WSAGetLastError(); - return r; -} - -#undef gethostbyname - -struct hostent * -mygethostbyname (char *name) -{ - struct hostent *r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = gethostbyname (name)) == NULL) - errno = WSAGetLastError(); - return r; -} - -#undef gethostname - -int -mygethostname (char *name, int len) -{ - int r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = gethostname (name, len)) == SOCKET_ERROR) - errno = WSAGetLastError(); - return r; -} - -#undef getprotobyname - -struct protoent * -mygetprotobyname (char *name) -{ - struct protoent *r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = getprotobyname (name)) == NULL) - errno = WSAGetLastError(); - return r; -} - -#undef getprotobynumber - -struct protoent * -mygetprotobynumber (int num) -{ - struct protoent *r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = getprotobynumber (num)) == NULL) - errno = WSAGetLastError(); - return r; -} - -#undef getservbyname - -struct servent * -mygetservbyname (char *name, char *proto) -{ - struct servent *r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = getservbyname (name, proto)) == NULL) - errno = WSAGetLastError(); - return r; -} - -#undef getservbyport - -struct servent * -mygetservbyport (int port, char *proto) -{ - struct servent *r; - if (!NtSocketsInitialized++) { - StartSockets(); - } - if ((r = getservbyport (port, proto)) == NULL) - errno = WSAGetLastError(); - return r; -} - -// -// Networking stubs -// - -void endhostent() {} -void endnetent() {} -void endprotoent() {} -void endservent() {} - -struct netent *getnetent (void) {return (struct netent *) NULL;} - -struct netent *getnetbyaddr(char *name) {return (struct netent *)NULL;} - -struct netent *getnetbyname(long net, int type) {return (struct netent *)NULL;} - -struct protoent *getprotoent (void) {return (struct protoent *) NULL;} - -struct servent *getservent (void) {return (struct servent *) NULL;} - -void sethostent (int stayopen) {} - -void setnetent (int stayopen) {} - -void setprotoent (int stayopen) {} - -void setservent (int stayopen) {} - - -#ifndef WNOHANG -#define WNOHANG -1 -#endif - -pid_t -waitpid (pid_t pid, int *stat_loc, int options) -{ - DWORD timeout; - - if (options == WNOHANG) { - timeout = 0; - } else { - timeout = INFINITE; - } - if (WaitForSingleObject((HANDLE) pid, timeout) == WAIT_OBJECT_0) { - pid = _cwait(stat_loc, pid, 0); - return pid; - } - return 0; -} - -#include - -void _cdecl -gettimeofday(struct timeval *tv, struct timezone *tz) -{ - struct timeb tb; - - ftime(&tb); - tv->tv_sec = tb.time; - tv->tv_usec = tb.millitm * 1000; -} - -char * -getcwd(buffer, size) - char *buffer; - int size; -{ - int length; - char *bp; - - if (_getcwd(buffer, size) == NULL) { - return NULL; - } - length = strlen(buffer); - if (length >= size) { - return NULL; - } - - for (bp = buffer; *bp != '\0'; bp++) { - if (*bp == '\\') { - *bp = '/'; - } - } - return buffer; -} - -static char * -str_grow(struct RString *str, size_t new_size) -{ - char *p; - - p = realloc(str->ptr, new_size); - if (p == NULL) - Fatal("cannot grow string\n"); - - str->len = new_size; - str->ptr = p; - - return p; -} - -int -chown(char *path, int owner, int group) -{ - return 0; -} - -int -kill(int pid, int sig) -{ -#if 1 - if (pid == GetCurrentProcessId()) - return raise(sig); - - if (sig == 2 && pid > 0) - if (GenerateConsoleCtrlEvent(CTRL_C_EVENT, (DWORD)pid)) - return 0; - - return -1; -#else - return 0; -#endif -} - -int -link(char *from, char *to) -{ - return -1; -} - -int -wait() -{ - return 0; -} - diff --git a/missing/nt.h b/missing/nt.h deleted file mode 100644 index 830b9edf13..0000000000 --- a/missing/nt.h +++ /dev/null @@ -1,362 +0,0 @@ -#ifndef EXT_NT_H -#define EXT_NT_H - -/* - * Copyright (c) 1993, Intergraph Corporation - * - * You may distribute under the terms of either the GNU General Public - * License or the Artistic License, as specified in the perl README file. - * - */ - -// -// Definitions for NT port of Perl -// - -// -// GRRRR!!!! Windows Nonsense. -// Define the following so we don't get tons of extra stuff -// when we include windows.h -// -#if 0 -#define NOGDICAPMASKS -#define NOVIRTUALKEYCODES -#define NOWINMESSAGES -#define NOWINSTYLES -#define NOSYSMETRICS -#define NOMENUS -#define NOICONS -#define NOKEYSTATES -#define NOSYSCOMMANDS -#define NORASTEROPS -#define NOSHOWWINDOW -#define OEMRESOURCE -#define NOATOM -#define NOCLIPBOARD -#define NOCOLOR -#define NOCTLMGR -#define NODRAWTEXT -#define NOGDI -//#define NOKERNEL -//#define NOUSER -#define NONLS -#define NOMB -#define NOMEMMGR -#define NOMETAFILE -#define NOMINMAX -#define NOMSG -#define NOOPENFILE -#define NOSCROLL -#define NOSERVICE -#define NOSOUND -#define NOTEXTMETRIC -#define NOWH -#define NOWINOFFSETS -#define NOCOMM -#define NOKANJI -#define NOHELP -#define NOPROFILER -#define NODEFERWINDOWPOS -#endif - -// -// Ok now we can include the normal include files. -// - -// #include conflict with varargs.h? -// There is function-name conflitct, so we rename it -#if !defined(IN) && !defined(FLOAT) -#define OpenFile WINAPI_OpenFile -#include -#include -#undef OpenFile -#endif -// -// We\'re not using Microsoft\'s "extensions" to C for -// Structured Exception Handling (SEH) so we can nuke these -// -#undef try -#undef except -#undef finally -#undef leave -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// -// Grrr... -// - -#define access _access -#define chmod _chmod -#define chsize _chsize -#define close _close -#define creat _creat -#define dup _dup -#define dup2 _dup2 -#define eof _eof -#define filelength _filelength -#define isatty _isatty -#define locking _locking -#define lseek _lseek -#define mktemp _mktemp -#define open _open -#define read _read -#define setmode _setmode -#define sopen _sopen -#define tell _tell -#define umask _umask -#define unlink _unlink -#define write _write -#define execl _execl -#define execle _execle -#define execlp _execlp -#define execlpe _execlpe -#define execv _execv -#define execve _execve -#define execvp _execvp -#define execvpe _execvpe -#define getpid _getpid -#define spawnl _spawnl -#define spawnle _spawnle -#define spawnlp _spawnlp -#define spawnlpe _spawnlpe -#define spawnv _spawnv -#define spawnve _spawnve -#define spawnvp _spawnvp -#define spawnvpe _spawnvpe -#if _MSC_VER < 800 -#define fileno _fileno -#endif -#define utime _utime -//#define pipe _pipe -#define perror _perror - - -/* these are defined in nt.c */ - -extern int NtMakeCmdVector(char *, char ***, int); -/* extern void NtInitialize(int *, char ***); */ -extern char *NtGetLib(void); -extern char *NtGetBin(void); -extern FILE *mypopen(char *, char *); -extern int flock(int fd, int oper); -extern FILE * myfdopen(int, char*); -extern SOCKET myaccept(SOCKET, struct sockaddr *, int *); -extern int mybind(SOCKET, struct sockaddr *, int); -extern int myconnect(SOCKET, struct sockaddr *, int); -extern int mygetpeername(SOCKET, struct sockaddr *, int *); -extern int mygetsockname(SOCKET, struct sockaddr *, int *); -extern int mygetsockopt(SOCKET, int, int, char *, int *); -extern int myioctlsocket(SOCKET, long, u_long *); -extern int mylisten(SOCKET, int); -extern int myrecv(SOCKET, char *, int, int); -extern int myrecvfrom(SOCKET, char *, int, int, struct sockaddr *, int *); -extern int mysend(SOCKET, char *, int, int); -extern int mysendto(SOCKET, char *, int, int, struct sockaddr *, int); -extern int mysetsockopt(SOCKET, int, int, char *, int); -extern int myshutdown(SOCKET, int); -extern SOCKET mysocket(int, int, int); -extern struct hostent * mygethostbyaddr(char *, int, int); -extern struct hostent * mygethostbyname(char *); -extern int mygethostname(char *, int); -extern struct protoent * mygetprotobyname(char *); -extern struct protoent * mygetprotobynumber(int); -extern struct servent * mygetservbyname(char *, char *); -extern struct servent * mygetservbyport(int, char *); - -// -// define this so we can do inplace editing -// - -#define SUFFIX - -// -// stubs -// -// extern int ioctl (int, unsigned int, char *); -extern int ioctl (int, unsigned int, long); -#if 0 -extern void sleep (unsigned int); -#else -#define sleep(x) Sleep(x*1000) -#endif - -extern UIDTYPE getuid (void); -extern UIDTYPE geteuid (void); -extern GIDTYPE getgid (void); -extern GIDTYPE getegid (void); -extern int setuid (int); -extern int setgid (int); - - -#undef IN /* confict in parse.c */ - -#if 0 -extern int sys_nerr; -extern char *sys_errlist[]; -#endif -extern char *mystrerror(int); - -#define strerror(e) mystrerror(e) - -#define PIPE_BUF 1024 - -#define HAVE_STDLIB_H 1 -#define HAVE_GETLOGIN 1 -#define HAVE_WAITPID 1 -#define HAVE_GETCWD 1 - -#define LOCK_SH 1 -#define LOCK_EX 2 -#define LOCK_NB 4 -#define LOCK_UN 8 -#ifndef EWOULDBLOCK -#define EWOULDBLOCK 10035 /* EBASEERR + 35 (winsock.h) */ -#endif - -#ifdef popen -#undef popen -#define popen mypopen -#endif -#ifdef pclose -#undef pclose -#define pclose mypclose -#endif - -#undef va_start -#undef va_end - -#ifdef popen -#undef popen -#define popen mypopen -#endif -#ifdef pclose -#undef pclose -#define pclose mypclose -#endif - -#undef va_start -#undef va_end - -#ifdef fdopen -#undef fdopen -#endif -#define fdopen myfdopen - -#ifdef accept -#undef accept -#endif -#define accept myaccept - -#ifdef bind -#undef bind -#endif -#define bind mybind - -#ifdef connect -#undef connect -#endif -#define connect myconnect - -#ifdef getpeername -#undef getpeername -#endif -#define getpeername mygetpeername - -#ifdef getsockname -#undef getsockname -#endif -#define getsockname mygetsockname - -#ifdef getsockopt -#undef getsockopt -#endif -#define getsockopt mygetsockopt - -#ifdef ioctlsocket -#undef ioctlsocket -#endif -#define ioctlsocket myioctlsocket - -#ifdef listen -#undef listen -#endif -#define listen mylisten - -#ifdef recv -#undef recv -#endif -#define recv myrecv - -#ifdef recvfrom -#undef recvfrom -#endif -#define recvfrom myrecvfrom - -#ifdef send -#undef send -#endif -#define send mysend - -#ifdef sendto -#undef sendto -#endif -#define sendto mysendto - -#ifdef setsockopt -#undef setsockopt -#endif -#define setsockopt mysetsockopt - -#ifdef shutdown -#undef shutdown -#endif -#define shutdown myshutdown - -#ifdef socket -#undef socket -#endif -#define socket mysocket - -#ifdef gethostbyaddr -#undef gethostbyaddr -#endif -#define gethostbyaddr mygethostbyaddr - -#ifdef gethostbyname -#undef gethostbyname -#endif -#define gethostbyname mygethostbyname - -#ifdef gethostname -#undef gethostname -#endif -#define gethostname mygethostname - -#ifdef getprotobyname -#undef getprotobyname -#endif -#define getprotobyname mygetprotobyname - -#ifdef getprotobynumber -#undef getprotobynumber -#endif -#define getprotobynumber mygetprotobynumber - -#ifdef getservbyname -#undef getservbyname -#endif -#define getservbyname mygetservbyname - -#ifdef getservbyport -#undef getservbyport -#endif -#define getservbyport mygetservbyport -#endif diff --git a/missing/setenv.c b/missing/setenv.c deleted file mode 100644 index c9cb4b20e0..0000000000 --- a/missing/setenv.c +++ /dev/null @@ -1,149 +0,0 @@ -/* - * Copyright (c) 1991, Larry Wall - * - * You may distribute under the terms of either the GNU General Public - * License or the Artistic License, as specified in the README file. - */ - -#include "ruby.h" - -#ifndef NT -extern char **environ; -#endif -extern char **origenviron; - -#ifndef NT -char *strdup(); -#endif - -#ifdef USE_WIN32_RTL_ENV -#include -#endif - -static int -envix(nam) -char *nam; -{ - register int i, len = strlen(nam); - - for (i = 0; environ[i]; i++) { - if (memcmp(environ[i],nam,len) == 0 && environ[i][len] == '=') - break; /* memcmp must come first to avoid */ - } /* potential SEGV's */ - return i; -} - -#ifndef WIN32 -void -setenv(nam,val, n) -char *nam, *val; -int n; -{ - register int i=envix(nam); /* where does it go? */ - - if (environ == origenviron) { /* need we copy environment? */ - int j; - int max; - char **tmpenv; - - /*SUPPRESS 530*/ - for (max = i; environ[max]; max++) ; - tmpenv = ALLOC_N(char*, max+2); - for (j=0; j +#include +#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/missing/strtod.c b/missing/strtod.c new file mode 100644 index 0000000000..e052cbc067 --- /dev/null +++ b/missing/strtod.c @@ -0,0 +1,266 @@ +/* + * strtod.c -- + * + * Source code for the "strtod" library procedure. + * + * Copyright (c) 1988-1993 The Regents of the University of California. + * Copyright (c) 1994 Sun Microsystems, Inc. + * + * See the file "license.terms" for information on usage and redistribution + * of this file, and for a DISCLAIMER OF ALL WARRANTIES. + * + * RCS: @(#) $Id$ + */ + +#include "config.h" +#ifdef HAVE_STDLIB_H +# include +#endif +#include +#include +extern int errno; + +#ifndef __STDC__ +# ifdef __GNUC__ +# define const __const__ +# else +# define const +# endif +#endif + +#ifndef TRUE +#define TRUE 1 +#define FALSE 0 +#endif +#ifndef NULL +#define NULL 0 +#endif + +static int maxExponent = 511; /* Largest possible base 10 exponent. Any + * exponent larger than this will already + * produce underflow or overflow, so there's + * no need to worry about additional digits. + */ +static double powersOf10[] = { /* Table giving binary powers of 10. Entry */ + 10., /* is 10^2^i. Used to convert decimal */ + 100., /* exponents into floating-point numbers. */ + 1.0e4, + 1.0e8, + 1.0e16, + 1.0e32, + 1.0e64, + 1.0e128, + 1.0e256 +}; + +/* + *---------------------------------------------------------------------- + * + * strtod -- + * + * This procedure converts a floating-point number from an ASCII + * decimal representation to internal double-precision format. + * + * Results: + * The return value is the double-precision floating-point + * representation of the characters in string. If endPtr isn't + * NULL, then *endPtr is filled in with the address of the + * next character after the last one that was part of the + * floating-point number. + * + * Side effects: + * None. + * + *---------------------------------------------------------------------- + */ + +double +strtod(string, endPtr) + const char *string; /* A decimal ASCII floating-point number, + * optionally preceded by white space. + * Must have form "-I.FE-X", where I is the + * integer part of the mantissa, F is the + * fractional part of the mantissa, and X + * is the exponent. Either of the signs + * may be "+", "-", or omitted. Either I + * or F may be omitted, or both. The decimal + * point isn't necessary unless F is present. + * The "E" may actually be an "e". E and X + * may both be omitted (but not just one). + */ + char **endPtr; /* If non-NULL, store terminating character's + * address here. */ +{ + int sign, expSign = FALSE; + double fraction, dblExp, *d; + register const char *p; + register int c; + int exp = 0; /* Exponent read from "EX" field. */ + int fracExp = 0; /* Exponent that derives from the fractional + * part. Under normal circumstatnces, it is + * the negative of the number of digits in F. + * However, if I is very long, the last digits + * of I get dropped (otherwise a long I with a + * large negative exponent could cause an + * unnecessary overflow on I alone). In this + * case, fracExp is incremented one for each + * dropped digit. */ + int mantSize; /* Number of digits in mantissa. */ + int decPt; /* Number of mantissa digits BEFORE decimal + * point. */ + const char *pExp; /* Temporarily holds location of exponent + * in string. */ + + /* + * Strip off leading blanks and check for a sign. + */ + + p = string; + while (isspace(*p)) { + p += 1; + } + if (*p == '-') { + sign = TRUE; + p += 1; + } else { + if (*p == '+') { + p += 1; + } + sign = FALSE; + } + + /* + * Count the number of digits in the mantissa (including the decimal + * point), and also locate the decimal point. + */ + + decPt = -1; + for (mantSize = 0; ; mantSize += 1) + { + c = *p; + if (!isdigit(c)) { + if ((c != '.') || (decPt >= 0)) { + break; + } + decPt = mantSize; + } + p += 1; + } + + /* + * Now suck up the digits in the mantissa. Use two integers to + * collect 9 digits each (this is faster than using floating-point). + * If the mantissa has more than 18 digits, ignore the extras, since + * they can't affect the value anyway. + */ + + pExp = p; + p -= mantSize; + if (decPt < 0) { + decPt = mantSize; + } else { + mantSize -= 1; /* One of the digits was the point. */ + } + if (mantSize > 18) { + fracExp = decPt - 18; + mantSize = 18; + } else { + fracExp = decPt - mantSize; + } + if (mantSize == 0) { + fraction = 0.0; + p = string; + goto done; + } else { + int frac1, frac2; + frac1 = 0; + for ( ; mantSize > 9; mantSize -= 1) + { + c = *p; + p += 1; + if (c == '.') { + c = *p; + p += 1; + } + frac1 = 10*frac1 + (c - '0'); + } + frac2 = 0; + for (; mantSize > 0; mantSize -= 1) + { + c = *p; + p += 1; + if (c == '.') { + c = *p; + p += 1; + } + frac2 = 10*frac2 + (c - '0'); + } + fraction = (1.0e9 * frac1) + frac2; + } + + /* + * Skim off the exponent. + */ + + p = pExp; + if ((*p == 'E') || (*p == 'e')) { + p += 1; + if (*p == '-') { + expSign = TRUE; + p += 1; + } else { + if (*p == '+') { + p += 1; + } + expSign = FALSE; + } + while (isdigit(*p)) { + exp = exp * 10 + (*p - '0'); + p += 1; + } + } + if (expSign) { + exp = fracExp - exp; + } else { + exp = fracExp + exp; + } + + /* + * Generate a floating-point number that represents the exponent. + * Do this by processing the exponent one bit at a time to combine + * many powers of 2 of 10. Then combine the exponent with the + * fraction. + */ + + if (exp < 0) { + expSign = TRUE; + exp = -exp; + } else { + expSign = FALSE; + } + if (exp > maxExponent) { + exp = maxExponent; + errno = ERANGE; + } + dblExp = 1.0; + for (d = powersOf10; exp != 0; exp >>= 1, d += 1) { + if (exp & 01) { + dblExp *= *d; + } + } + if (expSign) { + fraction /= dblExp; + } else { + fraction *= dblExp; + } + +done: + if (endPtr != NULL) { + *endPtr = (char *) p; + } + + if (sign) { + return -fraction; + } + return fraction; +} diff --git a/missing/vsnprintf.c b/missing/vsnprintf.c index f0e9e8c672..8b190b1450 100644 --- a/missing/vsnprintf.c +++ b/missing/vsnprintf.c @@ -58,9 +58,6 @@ */ #include -#ifdef NT -typedef unsigned int size_t; -#endif #define u_long unsigned long #define u_short unsigned short #define u_int unsigned int @@ -104,6 +101,9 @@ typedef unsigned int size_t; #define __const #endif /* People who don't like const sys_error */ +#ifdef NT +typedef long size_t; +#endif #ifndef NULL #define NULL 0 @@ -179,32 +179,6 @@ typedef struct __sFILE { #define EOF (-1) -/* - * The __sfoo macros are here so that we can - * define function versions in the C library. - */ -#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) -#if defined(__GNUC__) && defined(__STDC__) -static __inline int __sputc(int _c, FILE *_p) { - if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) - return (*_p->_p++ = _c); - else - return (__swbuf(_c, _p)); -} -#else -/* - * This has been tuned to generate reasonable code on the vax using pcc. - */ -#define __sputc(c, p) \ - (--(p)->_w < 0 ? \ - (p)->_w >= (p)->_lbfsize ? \ - (*(p)->_p = (c)), *(p)->_p != '\n' ? \ - (int)*(p)->_p++ : \ - __swbuf('\n', p) : \ - __swbuf((int)(c), p) : \ - (*(p)->_p = (c), (int)*(p)->_p++)) -#endif - #define __sfeof(p) (((p)->_flags & __SEOF) != 0) #define __sferror(p) (((p)->_flags & __SERR) != 0) #define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) @@ -218,11 +192,6 @@ static __inline int __sputc(int _c, FILE *_p) { #define fileno(p) __sfileno(p) #endif -#ifndef lint -#define getc(fp) __sgetc(fp) -#define putc(x, fp) __sputc(x, fp) -#endif /* lint */ - #if defined(__hpux) && !defined(__GNUC__) #include @@ -447,7 +416,15 @@ BSD__ultoa(val, endp, base, octzero, xdigs) #ifdef FLOATING_POINT #include -#include "floatio.h" +/* #include "floatio.h" */ + +#ifndef MAXEXP +# define MAXEXP 1024 +#endif + +#ifndef MAXFRACT +# define MAXFRACT 64 +#endif #define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ #define DEFPREC 6 diff --git a/node.h b/node.h index c1923fba75..a9b5c92e25 100644 --- a/node.h +++ b/node.h @@ -6,7 +6,7 @@ $Date$ created at: Fri May 28 15:14:02 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ diff --git a/numeric.c b/numeric.c index e8ea6075a9..65e27c0bd2 100644 --- a/numeric.c +++ b/numeric.c @@ -6,13 +6,16 @@ $Date$ created at: Fri Aug 13 18:33:09 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ #include "ruby.h" #include #include +#ifdef __FreeBSD__ +#include +#endif static ID coerce; static ID to_i; @@ -22,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(); @@ -31,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 @@ -183,10 +187,19 @@ static VALUE flo_to_s(flt) VALUE flt; { - char buf[32]; - - sprintf(buf, "%g", RFLOAT(flt)->value); - if (strchr(buf, '.') == 0) { + char buf[24]; + char *s; + 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) { int len = strlen(buf); char *ind = strchr(buf, 'e'); @@ -274,14 +287,11 @@ flo_div(x, y) switch (TYPE(y)) { case T_FIXNUM: f_y = FIX2LONG(y); - if (f_y == 0) rb_num_zerodiv(); return rb_float_new(RFLOAT(x)->value / (double)f_y); case T_BIGNUM: d = rb_big2dbl(y); - if (d == 0.0) rb_num_zerodiv(); return rb_float_new(RFLOAT(x)->value / d); case T_FLOAT: - if (RFLOAT(y)->value == 0.0) rb_num_zerodiv(); return rb_float_new(RFLOAT(x)->value / RFLOAT(y)->value); default: return rb_num_coerce_bin(x, y); @@ -666,8 +676,12 @@ rb_num2long(val) return (long)(RFLOAT(val)->value); } else { - rb_raise(rb_eTypeError, "float %g out of rang of integer", - RFLOAT(val)->value); + char buf[24]; + char *s; + + sprintf(buf, "%-.10g", RFLOAT(val)->value); + if (s = strchr(buf, ' ')) *s = '\0'; + rb_raise(rb_eTypeError, "float %s out of rang of integer", buf); } case T_BIGNUM: @@ -677,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)) { @@ -704,7 +723,7 @@ rb_num2int(val) long num = rb_num2long(val); if (num < INT_MIN || INT_MAX < num) { - rb_raise(rb_eArgError, "integer %d too big to convert to `int'.", num); + rb_raise(rb_eArgError, "integer %d too big to convert to `int'", num); } return (int)num; } @@ -716,7 +735,7 @@ rb_fix2int(val) long num = FIXNUM_P(val)?FIX2LONG(val):rb_num2long(val); if (num < INT_MIN || INT_MAX < num) { - rb_raise(rb_eArgError, "integer %d too big to convert to `int'.", num); + rb_raise(rb_eArgError, "integer %d too big to convert to `int'", num); } return (int)num; } @@ -777,6 +796,45 @@ int_chr(num) return rb_str_new(&c, 1); } +static VALUE +rb_fix_induced_from(klass, x) + VALUE klass, x; +{ + return rb_num2fix(x); +} + +static VALUE +rb_int_induced_from(klass, x) + VALUE klass, x; +{ + switch (TYPE(x)) { + case T_FIXNUM: + case T_BIGNUM: + return x; + case T_FLOAT: + return rb_funcall(x, rb_intern("to_i"), 0); + default: + rb_raise(rb_eTypeError, "failed to convert %s into Integer", + rb_class2name(CLASS_OF(x))); + } +} + +static VALUE +rb_flo_induced_from(klass, x) + VALUE klass, x; +{ + switch (TYPE(x)) { + case T_FIXNUM: + case T_BIGNUM: + return rb_funcall(x, rb_intern("to_f"), 0); + case T_FLOAT: + return x; + default: + rb_raise(rb_eTypeError, "failed to convert %s into Float", + rb_class2name(CLASS_OF(x))); + } +} + static VALUE fix_uminus(num) VALUE num; @@ -797,7 +855,7 @@ rb_fix2str(x, base) else if (base == 8) fmt[2] = 'o'; else rb_fatal("fixnum cannot treat base %d", base); - sprintf(buf, fmt, FIX2LONG(x)); + snprintf(buf, 22, fmt, FIX2LONG(x)); return rb_str_new2(buf); } @@ -940,15 +998,13 @@ fix_pow(x, y) b = FIX2LONG(y); if (b == 0) return INT2FIX(1); + if (b == 1) return x; a = FIX2LONG(x); if (b > 0) { return rb_big_pow(rb_int2big(a), y); } return rb_float_new(pow((double)a, (double)b)); } - else if (NIL_P(y)) { - return INT2FIX(1); - } return rb_num_coerce_bin(x, y); } @@ -1309,20 +1365,23 @@ fix_step(from, to, step) if (!FIXNUM_P(to) || !FIXNUM_P(step)) return int_step(from, to, step); + i = FIX2LONG(from); end = FIX2LONG(to); diff = FIX2LONG(step); if (diff == 0) { rb_raise(rb_eArgError, "step cannot be 0"); } - else if (diff > 0) { - for (i=FIX2LONG(from); i <= end; i+=diff) { + if (diff > 0) { + while (i <= end) { rb_yield(INT2FIX(i)); + i += diff; } } else { - for (i=FIX2LONG(from); i >= end; i+=diff) { + while (i >= end) { rb_yield(INT2FIX(i)); + i += diff; } } return from; @@ -1354,10 +1413,15 @@ fix_zero_p(num) void Init_Numeric() { +#ifdef __FreeBSD__ + /* allow divide by zero -- Inf */ + 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); @@ -1380,11 +1444,15 @@ Init_Numeric() rb_define_method(rb_cInteger, "downto", int_downto, 1); rb_define_method(rb_cInteger, "step", int_step, 2); rb_define_method(rb_cInteger, "times", int_dotimes, 0); + rb_include_module(rb_cInteger, rb_mPrecision); rb_define_method(rb_cInteger, "succ", int_succ, 0); rb_define_method(rb_cInteger, "next", int_succ, 0); rb_define_method(rb_cInteger, "chr", int_chr, 0); rb_cFixnum = rb_define_class("Fixnum", rb_cInteger); + rb_include_module(rb_cFixnum, rb_mPrecision); + rb_define_singleton_method(rb_cFixnum, "induced_from", rb_fix_induced_from, 1); + rb_define_singleton_method(rb_cInteger, "induced_from", rb_int_induced_from, 1); rb_undef_method(CLASS_OF(rb_cFixnum), "new"); @@ -1437,6 +1505,9 @@ Init_Numeric() rb_undef_method(CLASS_OF(rb_cFloat), "new"); + rb_define_singleton_method(rb_cFloat, "induced_from", rb_flo_induced_from, 1); + rb_include_module(rb_cFloat, rb_mPrecision); + rb_define_method(rb_cFloat, "to_s", flo_to_s, 0); rb_define_method(rb_cFloat, "coerce", flo_coerce, 1); rb_define_method(rb_cFloat, "-@", flo_uminus, 0); diff --git a/object.c b/object.c index 15e757d054..733f2accd2 100644 --- a/object.c +++ b/object.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Jul 15 12:01:24 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -47,7 +47,7 @@ int rb_eql(obj1, obj2) VALUE obj1, obj2; { - return rb_funcall(obj1, eql, 1, obj2); + return rb_funcall(obj1, eql, 1, obj2) == Qtrue; } static VALUE @@ -367,13 +367,6 @@ true_to_s(obj) return rb_str_new2("true"); } -static VALUE -true_to_i(obj) - VALUE obj; -{ - return INT2FIX(1); -} - static VALUE true_type(obj) VALUE obj; @@ -409,13 +402,6 @@ false_to_s(obj) return rb_str_new2("false"); } -static VALUE -false_to_i(obj) - VALUE obj; -{ - return INT2FIX(0); -} - static VALUE false_type(obj) VALUE obj; @@ -579,12 +565,10 @@ rb_module_s_new(klass) VALUE mod = rb_module_new(); RBASIC(mod)->klass = klass; - rb_obj_call_init(mod); + rb_obj_call_init(mod, 0, 0); return mod; } -VALUE rb_class_new_instance(); - static VALUE rb_class_s_new(argc, argv) int argc; @@ -603,7 +587,7 @@ rb_class_s_new(argc, argv) /* make metaclass */ RBASIC(klass)->klass = rb_singleton_class_new(RBASIC(super)->klass); rb_singleton_class_attached(RBASIC(klass)->klass, klass); - rb_obj_call_init(klass); + rb_obj_call_init(klass, argc, argv); return klass; } @@ -754,43 +738,6 @@ rb_obj_private_methods(obj) return rb_class_private_instance_methods(1, argv, CLASS_OF(obj)); } -VALUE -rb_Integer(val) - VALUE val; -{ - long i; - - switch (TYPE(val)) { - case T_FLOAT: - if (RFLOAT(val)->value <= (double)FIXNUM_MAX - && RFLOAT(val)->value >= (double)FIXNUM_MIN) { - i = (long)RFLOAT(val)->value; - break; - } - return rb_dbl2big(RFLOAT(val)->value); - - case T_BIGNUM: - return val; - - case T_STRING: - return rb_str2inum(RSTRING(val)->ptr, 0); - - case T_NIL: - return INT2FIX(0); - - default: - i = NUM2LONG(val); - } - return INT2NUM(i); -} - -static VALUE -rb_f_integer(obj, arg) - VALUE obj, arg; -{ - return rb_Integer(arg); -} - struct arg_to { VALUE val; char *s; @@ -832,6 +779,50 @@ rb_convert_type(val, type, tname, method) return val; } +VALUE +rb_Integer(val) + VALUE val; +{ + struct arg_to arg1, arg2; + + switch (TYPE(val)) { + case T_FLOAT: + if (RFLOAT(val)->value <= (double)FIXNUM_MAX + && RFLOAT(val)->value >= (double)FIXNUM_MIN) { + break; + } + return rb_dbl2big(RFLOAT(val)->value); + + case T_BIGNUM: + return val; + + case T_STRING: + return rb_str2inum(RSTRING(val)->ptr, 0); + + case T_NIL: + return INT2FIX(0); + + default: + break; + } + + arg1.val = arg2.val = val; + arg1.s = "to_i"; + arg2.s = "Integer"; + val = rb_rescue(to_type, (VALUE)&arg1, fail_to_type, (VALUE)&arg2); + if (!rb_obj_is_kind_of(val, rb_cInteger)) { + rb_raise(rb_eTypeError, "to_i should return Integer"); + } + return val; +} + +static VALUE +rb_f_integer(obj, arg) + VALUE obj, arg; +{ + return rb_Integer(arg); +} + double rb_big2dbl _((VALUE)); VALUE @@ -848,6 +839,9 @@ rb_Float(val) case T_BIGNUM: return rb_float_new(rb_big2dbl(val)); + case T_NIL: + return rb_float_new(0.0); + default: return rb_convert_type(val, T_FLOAT, "Float", "to_f"); } @@ -864,8 +858,23 @@ double rb_num2dbl(val) VALUE val; { - VALUE v = rb_Float(val); - return RFLOAT(v)->value; + switch (TYPE(val)) { + case T_FLOAT: + return RFLOAT(val)->value; + + case T_STRING: + rb_raise(rb_eTypeError, "no implicit conversion from String"); + break; + + case T_NIL: + rb_raise(rb_eTypeError, "no implicit conversion from nil"); + break; + + default: + break; + } + + return RFLOAT(rb_Float(val))->value; } char* @@ -1083,7 +1092,6 @@ Init_Object() rb_cTrueClass = rb_define_class("TrueClass", rb_cObject); rb_define_method(rb_cTrueClass, "to_s", true_to_s, 0); - rb_define_method(rb_cTrueClass, "to_i", true_to_i, 0); rb_define_method(rb_cTrueClass, "type", true_type, 0); rb_define_method(rb_cTrueClass, "&", true_and, 1); rb_define_method(rb_cTrueClass, "|", true_or, 1); @@ -1093,7 +1101,6 @@ Init_Object() rb_cFalseClass = rb_define_class("FalseClass", rb_cObject); rb_define_method(rb_cFalseClass, "to_s", false_to_s, 0); - rb_define_method(rb_cFalseClass, "to_i", false_to_i, 0); rb_define_method(rb_cFalseClass, "type", false_type, 0); rb_define_method(rb_cFalseClass, "&", false_and, 1); rb_define_method(rb_cFalseClass, "|", false_or, 1); diff --git a/pack.c b/pack.c index dc393b83fe..f064cc4be6 100644 --- a/pack.c +++ b/pack.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Feb 10 15:17:05 JST 1994 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -14,11 +14,132 @@ #include #include +#ifndef atof +double strtod(); +#endif + +#define define_swapx(x, xtype) \ +static xtype \ +TOKEN_PASTE(swap,x)(z) \ + xtype z; \ +{ \ + xtype r; \ + xtype *zp; \ + unsigned char *s, *t; \ + int i; \ + \ + zp = (xtype *)malloc(sizeof(xtype));\ + *zp = z; \ + s = (char *)zp; \ + t = (char *)malloc(sizeof(xtype)); \ + for (i=0 ; i>8)&0xFF)) +#else +#if SIZEOF_SHORT == 4 +#define swaps(x) ((((x)&0xFF)<<24) \ + +(((x)>>24)&0xFF) \ + +(((x)&0x0000FF00)<<8) \ + +(((x)&0x00FF0000)>>8) ) +#else +define_swapx(s,short); +#endif +#endif + +#if SIZEOF_LONG == 4 #define swapl(x) ((((x)&0xFF)<<24) \ +(((x)>>24)&0xFF) \ +(((x)&0x0000FF00)<<8) \ +(((x)&0x00FF0000)>>8) ) +#else +#if SIZEOF_LONG == 8 +#define swapl(x) ((((x)&0x00000000000000FF)<<56) \ + +(((x)&0xFF00000000000000)>>56) \ + +(((x)&0x000000000000FF00)<<40) \ + +(((x)&0x00FF000000000000)>>40) \ + +(((x)&0x0000000000FF0000)<<24) \ + +(((x)&0x0000FF0000000000)>>24) \ + +(((x)&0x00000000FF000000)<<8) \ + +(((x)&0x000000FF00000000)>>8) ) +#else +define_swapx(l,long); +#endif +#endif + +#if SIZEOF_FLOAT == 4 +#if SIZEOF_LONG == 4 /* SIZEOF_FLOAT == 4 == SIZEOF_LONG */ +#define swapf(x) swapl(x) +#define FLOAT_SWAPPER unsigned long +#else +#if SIZEOF_SHORT == 4 /* SIZEOF_FLOAT == 4 == SIZEOF_SHORT */ +#define swapf(x) swaps(x) +#define FLOAT_SWAPPER unsigned short +#else /* SIZEOF_FLOAT == 4 but undivide by known size of int */ +define_swapx(f,float); +#endif /* #if SIZEOF_SHORT == 4 */ +#endif /* #if SIZEOF_LONG == 4 */ +#else /* SIZEOF_FLOAT != 4 */ +define_swapx(f,float); +#endif /* #if SIZEOF_FLOAT == 4 */ + +#if SIZEOF_DOUBLE == 8 +#if SIZEOF_LONG == 8 /* SIZEOF_DOUBLE == 8 == SIZEOF_LONG */ +#define swapd(x) swapl(x) +#define DOUBLE_SWAPPER unsigned long +#else +#if SIZEOF_LONG == 4 /* SIZEOF_DOUBLE == 8 && 4 == SIZEOF_LONG */ +static double +swapd(d) + const double d; +{ + double dtmp = d; + unsigned long utmp[2]; + unsigned long utmp0; + + utmp[0] = 0; utmp[1] = 0; + memcpy(utmp,&dtmp,sizeof(double)); + utmp0 = utmp[0]; + utmp[0] = swapl(utmp[1]); + utmp[1] = swapl(utmp0); + memcpy(&dtmp,utmp,sizeof(double)); + return dtmp; +} +#else +#if SIZEOF_SHORT == 4 /* SIZEOF_DOUBLE == 8 && 4 == SIZEOF_SHORT */ +static double +swapd(d) + const double d; +{ + double dtmp = d; + unsigned short utmp[2]; + unsigned short utmp0; + + utmp[0] = 0; utmp[1] = 0; + memcpy(utmp,&dtmp,sizeof(double)); + utmp0 = utmp[0]; + utmp[0] = swaps(utmp[1]); + utmp[1] = swaps(utmp0); + memcpy(&dtmp,utmp,sizeof(double)); + return dtmp; +} +#else /* SIZEOF_DOUBLE == 8 but undivied by known size of int */ +define_swapx(d, double); +#endif /* #if SIZEOF_SHORT == 4 */ +#endif /* #if SIZEOF_LONG == 4 */ +#endif /* #if SIZEOF_LONG == 8 */ +#else /* SIZEOF_DOUBLE != 8 */ +define_swapx(d, double); +#endif /* #if SIZEOF_DPOUBLE == 8 */ + +#undef define_swapx #ifdef DYNAMIC_ENDIAN #ifdef ntohs @@ -42,12 +163,20 @@ endian() #define ntohs(x) (endian()?(x):swaps(x)) #define ntohl(x) (endian()?(x):swapl(x)) +#define ntohf(x) (endian()?(x):swapf(x)) +#define ntohd(x) (endian()?(x):swapd(x)) #define htons(x) (endian()?(x):swaps(x)) #define htonl(x) (endian()?(x):swapl(x)) +#define htonf(x) (endian()?(x):swapf(x)) +#define htond(x) (endian()?(x):swapd(x)) #define htovs(x) (endian()?swaps(x):(x)) #define htovl(x) (endian()?swapl(x):(x)) +#define htovf(x) (endian()?swapf(x):(x)) +#define htovd(x) (endian()?swapd(x):(x)) #define vtohs(x) (endian()?swaps(x):(x)) #define vtohl(x) (endian()?swapl(x):(x)) +#define vtohf(x) (endian()?swapf(x):(x)) +#define vtohd(x) (endian()?swapd(x):(x)) #else #ifdef WORDS_BIGENDIAN #ifndef ntohs @@ -56,22 +185,94 @@ endian() #define htons(x) (x) #define htonl(x) (x) #endif +#define ntohf(x) (x) +#define ntohd(x) (x) +#define htonf(x) (x) +#define htond(x) (x) #define htovs(x) swaps(x) #define htovl(x) swapl(x) +#define htovf(x) swapf(x) +#define htovd(x) swapd(x) #define vtohs(x) swaps(x) #define vtohl(x) swapl(x) +#define vtohf(x) swapf(x) +#define vtohd(x) swapd(x) #else /* LITTLE ENDIAN */ #ifndef ntohs +#undef ntohs +#undef ntohl +#undef htons +#undef htonl #define ntohs(x) swaps(x) #define ntohl(x) swapl(x) #define htons(x) swaps(x) #define htonl(x) swapl(x) #endif +#define ntohf(x) swapf(x) +#define ntohd(x) swapd(x) +#define htonf(x) swapf(x) +#define htond(x) swapd(x) #define htovs(x) (x) #define htovl(x) (x) +#define htovf(x) (x) +#define htovd(x) (x) #define vtohs(x) (x) #define vtohl(x) (x) +#define vtohf(x) (x) +#define vtohd(x) (x) +#endif #endif + +#ifdef FLOAT_SWAPPER +#define FLOAT_CONVWITH(y) FLOAT_SWAPPER y; +#define HTONF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = htonf((FLOAT_SWAPPER)y), \ + memcpy(&x,&y,sizeof(float)), \ + x) +#define HTOVF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = htovf((FLOAT_SWAPPER)y), \ + memcpy(&x,&y,sizeof(float)), \ + x) +#define NTOHF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = ntohf((FLOAT_SWAPPER)y), \ + memcpy(&x,&y,sizeof(float)), \ + x) +#define VTOHF(x,y) (memcpy(&y,&x,sizeof(float)), \ + y = vtohf((FLOAT_SWAPPER)y), \ + memcpy(&x,&y,sizeof(float)), \ + x) +#else +#define FLOAT_CONVWITH(y) +#define HTONF(x,y) htonf(x) +#define HTOVF(x,y) htovf(x) +#define NTOHF(x,y) ntohf(x) +#define VTOHF(x,y) vtohf(x) +#endif + +#ifdef DOUBLE_SWAPPER +#define DOUBLE_CONVWITH(y) DOUBLE_SWAPPER y; +#define HTOND(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = htond((DOUBLE_SWAPPER)y), \ + memcpy(&x,&y,sizeof(double)), \ + x) +#define HTOVD(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = htovd((DOUBLE_SWAPPER)y), \ + memcpy(&x,&y,sizeof(double)), \ + x) +#define NTOHD(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = ntohd((DOUBLE_SWAPPER)y), \ + memcpy(&x,&y,sizeof(double)), \ + x) +#define VTOHD(x,y) (memcpy(&y,&x,sizeof(double)), \ + y = vtohd((DOUBLE_SWAPPER)y), \ + memcpy(&x,&y,sizeof(double)), \ + x) +#else +#define DOUBLE_CONVWITH(y) +#define HTOND(x,y) htond(x) +#define HTOVD(x,y) htovd(x) +#define NTOHD(x,y) ntohd(x) +#define VTOHD(x,y) vtohd(x) #endif static char *toofew = "too few arguments"; @@ -390,7 +591,7 @@ pack_pack(ary, fmt) f = RFLOAT(from)->value; break; case T_STRING: - f = atof(RSTRING(from)->ptr); + f = strtod(RSTRING(from)->ptr, 0); default: f = (float)NUM2INT(from); break; @@ -399,6 +600,48 @@ pack_pack(ary, fmt) } break; + case 'e': + while (len-- > 0) { + float f; + FLOAT_CONVWITH(ftmp); + + from = NEXTFROM; + switch (TYPE(from)) { + case T_FLOAT: + f = RFLOAT(from)->value; + break; + case T_STRING: + f = strtod(RSTRING(from)->ptr, 0); + default: + f = (float)NUM2INT(from); + break; + } + f = HTOVF(f,ftmp); + rb_str_cat(res, (char*)&f, sizeof(float)); + } + break; + + case 'E': + while (len-- > 0) { + double d; + DOUBLE_CONVWITH(dtmp); + + from = NEXTFROM; + switch (TYPE(from)) { + case T_FLOAT: + d = RFLOAT(from)->value; + break; + case T_STRING: + d = strtod(RSTRING(from)->ptr, 0); + default: + d = (double)NUM2INT(from); + break; + } + d = HTOVD(d,dtmp); + rb_str_cat(res, (char*)&d, sizeof(double)); + } + break; + case 'd': case 'D': while (len-- > 0) { @@ -410,7 +653,7 @@ pack_pack(ary, fmt) d = RFLOAT(from)->value; break; case T_STRING: - d = atof(RSTRING(from)->ptr); + d = strtod(RSTRING(from)->ptr, 0); default: d = (double)NUM2INT(from); break; @@ -419,6 +662,48 @@ pack_pack(ary, fmt) } break; + case 'g': + while (len-- > 0) { + float f; + FLOAT_CONVWITH(ftmp); + + from = NEXTFROM; + switch (TYPE(from)) { + case T_FLOAT: + f = RFLOAT(from)->value; + break; + case T_STRING: + f = strtod(RSTRING(from)->ptr, 0); + default: + f = (float)NUM2INT(from); + break; + } + f = HTONF(f,ftmp); + rb_str_cat(res, (char*)&f, sizeof(float)); + } + break; + + case 'G': + while (len-- > 0) { + double d; + DOUBLE_CONVWITH(dtmp); + + from = NEXTFROM; + switch (TYPE(from)) { + case T_FLOAT: + d = RFLOAT(from)->value; + break; + case T_STRING: + d = strtod(RSTRING(from)->ptr, 0); + default: + d = (double)NUM2INT(from); + break; + } + d = HTOND(d,dtmp); + rb_str_cat(res, (char*)&d, sizeof(double)); + } + break; + case 'x': grow: while (len >= 10) { @@ -558,7 +843,7 @@ qpencode(str, from, len) { char buff[1024]; int i = 0, n = 0, prev = EOF; - unsigned char *s = RSTRING(from)->ptr; + unsigned char *s = (unsigned char*)RSTRING(from)->ptr; unsigned char *send = s + RSTRING(from)->len; while (s < send) { @@ -911,6 +1196,34 @@ pack_unpack(str, fmt) } break; + case 'e': + if (len >= (send - s) / sizeof(float)) + len = (send - s) / sizeof(float); + while (len-- > 0) { + float tmp; + FLOAT_CONVWITH(ftmp); + + memcpy(&tmp, s, sizeof(float)); + s += sizeof(float); + tmp = VTOHF(tmp,ftmp); + rb_ary_push(ary, rb_float_new((double)tmp)); + } + break; + + case 'E': + if (len >= (send - s) / sizeof(double)) + len = (send - s) / sizeof(double); + while (len-- > 0) { + double tmp; + DOUBLE_CONVWITH(dtmp); + + memcpy(&tmp, s, sizeof(double)); + s += sizeof(double); + tmp = VTOHD(tmp,dtmp); + rb_ary_push(ary, rb_float_new(tmp)); + } + break; + case 'D': case 'd': if (len >= (send - s) / sizeof(double)) @@ -923,6 +1236,34 @@ pack_unpack(str, fmt) } break; + case 'g': + if (len >= (send - s) / sizeof(float)) + len = (send - s) / sizeof(float); + while (len-- > 0) { + float tmp; + FLOAT_CONVWITH(ftmp;) + + memcpy(&tmp, s, sizeof(float)); + s += sizeof(float); + tmp = NTOHF(tmp,ftmp); + rb_ary_push(ary, rb_float_new((double)tmp)); + } + break; + + case 'G': + if (len >= (send - s) / sizeof(double)) + len = (send - s) / sizeof(double); + while (len-- > 0) { + double tmp; + DOUBLE_CONVWITH(dtmp); + + memcpy(&tmp, s, sizeof(double)); + s += sizeof(double); + tmp = NTOHD(tmp,dtmp); + rb_ary_push(ary, rb_float_new(tmp)); + } + break; + case 'u': { VALUE str = rb_str_new(0, (send - s)*3/4); diff --git a/parse.c b/parse.c index 8c3bcc545a..996adf61bb 100644 --- a/parse.c +++ b/parse.c @@ -104,6 +104,8 @@ #include "node.h" #include "st.h" #include +#include +#include /* hack for bison */ #ifdef const @@ -191,7 +193,7 @@ static NODE *cur_cref; static void top_local_init(); static void top_local_setup(); -#line 109 "parse.y" +#line 111 "parse.y" typedef union { NODE *node; VALUE val; @@ -273,24 +275,25 @@ static const short yyprhs[] = { 0, 419, 422, 425, 429, 433, 437, 441, 445, 449, 453, 457, 461, 465, 469, 473, 477, 480, 483, 487, 491, 495, 499, 500, 505, 511, 513, 515, 516, 519, 521, - 524, 530, 533, 539, 544, 552, 556, 558, 561, 564, - 565, 567, 568, 570, 574, 576, 581, 584, 586, 587, - 590, 592, 596, 600, 603, 605, 607, 609, 611, 613, - 615, 617, 622, 626, 630, 635, 639, 641, 646, 650, - 652, 653, 660, 662, 665, 667, 670, 677, 684, 690, - 696, 701, 709, 716, 720, 721, 728, 729, 737, 738, - 744, 745, 752, 753, 754, 764, 766, 768, 770, 772, - 774, 776, 779, 781, 783, 785, 791, 792, 795, 797, - 799, 800, 803, 805, 809, 810, 816, 817, 823, 825, - 827, 829, 831, 833, 838, 845, 849, 856, 861, 863, - 869, 871, 876, 879, 881, 883, 889, 890, 891, 894, - 896, 899, 901, 903, 905, 907, 909, 911, 913, 915, - 917, 919, 921, 923, 925, 927, 929, 931, 933, 935, - 937, 939, 940, 945, 948, 953, 956, 963, 968, 973, - 976, 981, 984, 987, 989, 990, 992, 996, 1000, 1002, - 1006, 1009, 1012, 1015, 1016, 1018, 1023, 1024, 1027, 1030, - 1032, 1036, 1040, 1042, 1044, 1046, 1048, 1050, 1051, 1053, - 1054, 1056, 1057, 1059, 1061, 1063, 1065, 1067 + 524, 527, 533, 536, 539, 545, 550, 555, 563, 567, + 569, 572, 575, 576, 578, 579, 581, 585, 587, 592, + 595, 597, 598, 601, 603, 607, 611, 614, 616, 618, + 620, 622, 624, 626, 628, 633, 637, 641, 646, 650, + 652, 657, 661, 663, 664, 671, 673, 676, 678, 681, + 688, 695, 701, 707, 712, 720, 727, 731, 732, 739, + 740, 748, 749, 755, 756, 763, 764, 765, 775, 777, + 779, 781, 783, 785, 787, 790, 792, 794, 796, 802, + 803, 806, 808, 810, 811, 814, 816, 820, 821, 827, + 828, 834, 836, 838, 840, 842, 844, 849, 856, 860, + 867, 872, 874, 880, 882, 887, 890, 892, 894, 900, + 901, 902, 905, 907, 910, 912, 914, 916, 918, 920, + 922, 924, 926, 928, 930, 932, 934, 936, 938, 940, + 942, 944, 946, 948, 950, 951, 956, 959, 964, 967, + 974, 979, 984, 987, 992, 995, 998, 1000, 1001, 1003, + 1007, 1011, 1013, 1017, 1020, 1023, 1026, 1027, 1029, 1034, + 1035, 1038, 1041, 1043, 1047, 1051, 1053, 1055, 1057, 1059, + 1061, 1062, 1064, 1065, 1067, 1068, 1070, 1072, 1074, 1076, + 1078 }; static const short yyrhs[] = { -1, @@ -346,103 +349,105 @@ static const short yyrhs[] = { -1, 140, 71, 140, 0, 140, 72, 140, 0, 0, 42, 202, 143, 140, 0, 140, 92, 140, 93, 140, 0, 154, 0, 145, 0, 0, 146, 202, 0, 126, 0, - 150, 148, 0, 150, 111, 88, 140, 148, 0, 197, - 148, 0, 197, 111, 88, 140, 148, 0, 150, 111, - 197, 148, 0, 150, 111, 197, 111, 88, 140, 148, - 0, 88, 140, 148, 0, 147, 0, 89, 140, 0, - 111, 147, 0, 0, 150, 0, 0, 140, 0, 150, - 111, 140, 0, 150, 0, 150, 111, 88, 140, 0, - 88, 140, 0, 146, 0, 0, 150, 203, 0, 179, - 0, 154, 81, 51, 0, 154, 81, 47, 0, 82, - 134, 0, 54, 0, 57, 0, 55, 0, 58, 0, - 59, 0, 183, 0, 184, 0, 154, 112, 144, 113, - 0, 86, 153, 113, 0, 87, 196, 108, 0, 27, - 115, 152, 110, 0, 27, 115, 110, 0, 27, 0, - 28, 115, 152, 110, 0, 28, 115, 110, 0, 28, - 0, 0, 42, 202, 115, 155, 125, 110, 0, 48, - 0, 199, 170, 0, 173, 0, 173, 170, 0, 11, - 125, 162, 120, 164, 10, 0, 12, 125, 162, 120, - 165, 10, 0, 18, 125, 163, 120, 10, 0, 19, - 125, 163, 120, 10, 0, 16, 120, 174, 10, 0, - 20, 166, 25, 125, 163, 120, 10, 0, 7, 120, - 177, 165, 178, 10, 0, 85, 120, 110, 0, 0, - 3, 134, 185, 156, 120, 10, 0, 0, 3, 79, - 125, 204, 157, 120, 10, 0, 0, 4, 134, 158, - 120, 10, 0, 0, 5, 135, 159, 187, 120, 10, - 0, 0, 0, 5, 195, 200, 160, 135, 161, 187, - 120, 10, 0, 21, 0, 22, 0, 23, 0, 24, - 0, 204, 0, 13, 0, 204, 13, 0, 204, 0, - 26, 0, 165, 0, 14, 125, 162, 120, 164, 0, - 0, 15, 120, 0, 133, 0, 127, 0, 0, 96, - 96, 0, 72, 0, 96, 166, 96, 0, 0, 26, - 169, 167, 120, 10, 0, 0, 107, 171, 167, 120, - 108, 0, 47, 0, 51, 0, 48, 0, 173, 0, - 126, 0, 199, 115, 145, 110, 0, 154, 109, 199, - 115, 145, 110, 0, 154, 109, 199, 0, 154, 81, - 199, 115, 145, 110, 0, 29, 115, 145, 110, 0, - 29, 0, 17, 175, 162, 120, 176, 0, 150, 0, - 150, 111, 88, 140, 0, 88, 140, 0, 165, 0, - 174, 0, 8, 149, 163, 120, 177, 0, 0, 0, - 9, 120, 0, 181, 0, 90, 180, 0, 56, 0, - 135, 0, 50, 0, 49, 0, 52, 0, 53, 0, - 47, 0, 50, 0, 49, 0, 51, 0, 31, 0, - 30, 0, 32, 0, 33, 0, 46, 0, 45, 0, - 182, 0, 60, 0, 61, 0, 204, 0, 0, 95, - 186, 125, 204, 0, 1, 204, 0, 115, 188, 202, - 110, 0, 188, 204, 0, 189, 111, 191, 111, 192, - 194, 0, 189, 111, 191, 194, 0, 189, 111, 192, - 194, 0, 189, 194, 0, 191, 111, 192, 194, 0, - 191, 194, 0, 192, 194, 0, 193, 0, 0, 47, - 0, 189, 111, 47, 0, 47, 91, 140, 0, 190, - 0, 191, 111, 190, 0, 88, 47, 0, 89, 47, - 0, 111, 193, 0, 0, 183, 0, 85, 125, 202, - 110, 0, 0, 197, 203, 0, 150, 203, 0, 198, - 0, 197, 111, 198, 0, 140, 84, 140, 0, 47, - 0, 51, 0, 48, 0, 109, 0, 81, 0, 0, - 205, 0, 0, 116, 0, 0, 116, 0, 111, 0, - 117, 0, 116, 0, 204, 0, 205, 117, 0 + 150, 111, 0, 150, 148, 0, 150, 111, 88, 140, + 148, 0, 197, 111, 0, 197, 148, 0, 197, 111, + 88, 140, 148, 0, 150, 111, 197, 148, 0, 150, + 111, 197, 111, 0, 150, 111, 197, 111, 88, 140, + 148, 0, 88, 140, 148, 0, 147, 0, 89, 140, + 0, 111, 147, 0, 0, 150, 0, 0, 140, 0, + 150, 111, 140, 0, 150, 0, 150, 111, 88, 140, + 0, 88, 140, 0, 146, 0, 0, 150, 203, 0, + 179, 0, 154, 81, 51, 0, 154, 81, 47, 0, + 82, 134, 0, 54, 0, 57, 0, 55, 0, 58, + 0, 59, 0, 183, 0, 184, 0, 154, 112, 144, + 113, 0, 86, 153, 113, 0, 87, 196, 108, 0, + 27, 115, 152, 110, 0, 27, 115, 110, 0, 27, + 0, 28, 115, 152, 110, 0, 28, 115, 110, 0, + 28, 0, 0, 42, 202, 115, 155, 125, 110, 0, + 48, 0, 199, 170, 0, 173, 0, 173, 170, 0, + 11, 125, 162, 120, 164, 10, 0, 12, 125, 162, + 120, 165, 10, 0, 18, 125, 163, 120, 10, 0, + 19, 125, 163, 120, 10, 0, 16, 120, 174, 10, + 0, 20, 166, 25, 125, 163, 120, 10, 0, 7, + 120, 177, 165, 178, 10, 0, 85, 120, 110, 0, + 0, 3, 134, 185, 156, 120, 10, 0, 0, 3, + 79, 125, 204, 157, 120, 10, 0, 0, 4, 134, + 158, 120, 10, 0, 0, 5, 135, 159, 187, 120, + 10, 0, 0, 0, 5, 195, 200, 160, 135, 161, + 187, 120, 10, 0, 21, 0, 22, 0, 23, 0, + 24, 0, 204, 0, 13, 0, 204, 13, 0, 204, + 0, 26, 0, 165, 0, 14, 125, 162, 120, 164, + 0, 0, 15, 120, 0, 133, 0, 127, 0, 0, + 96, 96, 0, 72, 0, 96, 166, 96, 0, 0, + 26, 169, 167, 120, 10, 0, 0, 107, 171, 167, + 120, 108, 0, 47, 0, 51, 0, 48, 0, 173, + 0, 126, 0, 199, 115, 145, 110, 0, 154, 109, + 199, 115, 145, 110, 0, 154, 109, 199, 0, 154, + 81, 199, 115, 145, 110, 0, 29, 115, 145, 110, + 0, 29, 0, 17, 175, 162, 120, 176, 0, 150, + 0, 150, 111, 88, 140, 0, 88, 140, 0, 165, + 0, 174, 0, 8, 149, 163, 120, 177, 0, 0, + 0, 9, 120, 0, 181, 0, 90, 180, 0, 56, + 0, 135, 0, 50, 0, 49, 0, 52, 0, 53, + 0, 47, 0, 50, 0, 49, 0, 51, 0, 31, + 0, 30, 0, 32, 0, 33, 0, 46, 0, 45, + 0, 182, 0, 60, 0, 61, 0, 204, 0, 0, + 95, 186, 125, 204, 0, 1, 204, 0, 115, 188, + 202, 110, 0, 188, 204, 0, 189, 111, 191, 111, + 192, 194, 0, 189, 111, 191, 194, 0, 189, 111, + 192, 194, 0, 189, 194, 0, 191, 111, 192, 194, + 0, 191, 194, 0, 192, 194, 0, 193, 0, 0, + 47, 0, 189, 111, 47, 0, 47, 91, 140, 0, + 190, 0, 191, 111, 190, 0, 88, 47, 0, 89, + 47, 0, 111, 193, 0, 0, 183, 0, 115, 125, + 202, 110, 0, 0, 197, 203, 0, 150, 203, 0, + 198, 0, 197, 111, 198, 0, 140, 84, 140, 0, + 47, 0, 51, 0, 48, 0, 109, 0, 81, 0, + 0, 205, 0, 0, 116, 0, 0, 116, 0, 111, + 0, 117, 0, 116, 0, 204, 0, 205, 117, 0 }; #endif #if YYDEBUG != 0 static const short yyrline[] = { 0, - 231, 240, 248, 250, 254, 258, 262, 267, 276, 277, - 282, 288, 297, 302, 308, 314, 320, 330, 340, 348, - 355, 363, 365, 371, 378, 383, 384, 388, 392, 397, - 402, 404, 409, 415, 421, 429, 430, 435, 436, 441, - 445, 449, 453, 457, 462, 463, 468, 473, 477, 482, - 486, 490, 494, 500, 504, 506, 507, 508, 509, 514, - 520, 524, 525, 529, 530, 531, 532, 533, 534, 535, - 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, - 546, 547, 548, 549, 550, 551, 552, 553, 554, 555, - 557, 557, 557, 557, 558, 558, 558, 558, 558, 558, - 558, 559, 559, 559, 559, 559, 559, 559, 560, 560, - 560, 560, 560, 560, 560, 561, 561, 561, 561, 561, - 561, 561, 562, 562, 562, 562, 562, 562, 563, 563, - 565, 566, 573, 578, 583, 588, 594, 595, 610, 625, - 636, 647, 652, 656, 660, 664, 668, 672, 676, 680, - 684, 688, 692, 696, 700, 704, 708, 712, 716, 720, - 724, 728, 732, 736, 740, 744, 749, 753, 757, 761, - 765, 769, 770, 774, 780, 785, 793, 797, 799, 804, - 808, 813, 818, 823, 828, 833, 838, 840, 846, 850, - 855, 856, 861, 866, 872, 884, 889, 895, 909, 913, - 915, 919, 924, 929, 933, 937, 938, 942, 943, 944, - 945, 946, 951, 959, 963, 970, 976, 982, 987, 991, - 995, 995, 1000, 1004, 1009, 1010, 1019, 1028, 1037, 1045, - 1053, 1061, 1069, 1089, 1093, 1103, 1111, 1118, 1126, 1135, - 1143, 1151, 1160, 1161, 1168, 1176, 1180, 1184, 1188, 1193, - 1194, 1195, 1197, 1198, 1200, 1201, 1210, 1214, 1219, 1220, - 1222, 1226, 1230, 1234, 1239, 1244, 1252, 1257, 1264, 1268, - 1272, 1276, 1277, 1279, 1284, 1290, 1296, 1302, 1308, 1316, - 1323, 1324, 1329, 1335, 1336, 1338, 1345, 1350, 1354, 1359, - 1360, 1364, 1366, 1367, 1368, 1370, 1371, 1373, 1374, 1375, - 1376, 1377, 1378, 1379, 1380, 1381, 1382, 1384, 1389, 1390, - 1392, 1396, 1400, 1404, 1406, 1411, 1416, 1420, 1424, 1428, - 1432, 1436, 1440, 1444, 1448, 1453, 1460, 1468, 1475, 1480, - 1485, 1492, 1497, 1501, 1506, 1519, 1537, 1541, 1545, 1553, - 1554, 1559, 1564, 1565, 1566, 1568, 1569, 1571, 1572, 1574, - 1575, 1577, 1578, 1579, 1581, 1582, 1584, 1585 + 233, 242, 250, 252, 256, 260, 264, 269, 278, 279, + 284, 290, 299, 304, 310, 316, 322, 332, 342, 350, + 357, 365, 367, 373, 380, 385, 386, 390, 394, 399, + 404, 406, 411, 417, 423, 431, 432, 437, 438, 443, + 447, 451, 455, 459, 464, 465, 470, 475, 479, 484, + 488, 492, 496, 502, 506, 508, 509, 510, 511, 516, + 522, 526, 527, 531, 532, 533, 534, 535, 536, 537, + 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, + 548, 549, 550, 551, 552, 553, 554, 555, 556, 557, + 559, 559, 559, 559, 560, 560, 560, 560, 560, 560, + 560, 561, 561, 561, 561, 561, 561, 561, 562, 562, + 562, 562, 562, 562, 562, 563, 563, 563, 563, 563, + 563, 563, 564, 564, 564, 564, 564, 564, 565, 565, + 567, 568, 575, 580, 585, 590, 596, 597, 612, 627, + 638, 649, 654, 658, 662, 666, 670, 674, 678, 682, + 686, 690, 694, 698, 702, 706, 710, 714, 718, 722, + 726, 730, 734, 738, 742, 746, 751, 755, 759, 763, + 767, 771, 772, 776, 782, 787, 795, 799, 801, 806, + 810, 814, 819, 823, 828, 833, 838, 842, 847, 852, + 854, 860, 864, 869, 870, 875, 880, 886, 898, 903, + 909, 923, 927, 929, 933, 938, 943, 947, 951, 952, + 956, 957, 958, 959, 960, 965, 973, 977, 984, 990, + 996, 1001, 1005, 1009, 1009, 1014, 1018, 1023, 1024, 1033, + 1042, 1051, 1059, 1067, 1075, 1083, 1103, 1107, 1117, 1125, + 1132, 1140, 1149, 1157, 1165, 1174, 1175, 1182, 1190, 1194, + 1198, 1202, 1207, 1208, 1209, 1211, 1212, 1214, 1215, 1224, + 1228, 1233, 1234, 1236, 1240, 1244, 1248, 1253, 1258, 1266, + 1271, 1278, 1282, 1286, 1290, 1291, 1293, 1298, 1304, 1310, + 1316, 1322, 1330, 1337, 1338, 1343, 1349, 1350, 1352, 1359, + 1364, 1368, 1373, 1374, 1378, 1380, 1381, 1382, 1384, 1385, + 1387, 1388, 1389, 1390, 1391, 1392, 1393, 1394, 1395, 1396, + 1398, 1403, 1404, 1406, 1410, 1414, 1418, 1420, 1425, 1430, + 1434, 1438, 1442, 1446, 1450, 1454, 1458, 1462, 1467, 1474, + 1482, 1489, 1494, 1499, 1506, 1511, 1515, 1520, 1533, 1551, + 1555, 1559, 1567, 1568, 1573, 1578, 1579, 1580, 1582, 1583, + 1585, 1586, 1588, 1589, 1591, 1592, 1593, 1595, 1596, 1598, + 1599 }; #endif @@ -495,24 +500,25 @@ static const short yyr1[] = { 0, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 140, 143, 140, 140, 140, 144, 145, 145, 146, 146, - 146, 146, 146, 146, 146, 146, 146, 147, 148, 148, - 149, 149, 150, 150, 151, 151, 151, 152, 153, 153, + 146, 146, 146, 146, 146, 146, 146, 146, 146, 146, + 147, 148, 148, 149, 149, 150, 150, 151, 151, 151, + 152, 153, 153, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 155, 154, 154, 154, 154, 154, 154, 154, 154, 154, - 154, 154, 154, 154, 156, 154, 157, 154, 158, 154, - 159, 154, 160, 161, 154, 154, 154, 154, 154, 162, - 162, 162, 163, 163, 164, 164, 165, 165, 166, 166, - 167, 167, 167, 167, 169, 168, 171, 170, 172, 172, - 172, 172, 172, 173, 173, 173, 173, 173, 173, 174, - 175, 175, 175, 176, 176, 177, 177, 178, 178, 179, - 179, 179, 180, 180, 180, 181, 181, 182, 182, 182, - 182, 182, 182, 182, 182, 182, 182, 183, 184, 184, - 185, 186, 185, 185, 187, 187, 188, 188, 188, 188, - 188, 188, 188, 188, 188, 189, 189, 190, 191, 191, - 192, 193, 194, 194, 195, 195, 196, 196, 196, 197, - 197, 198, 199, 199, 199, 200, 200, 201, 201, 202, - 202, 203, 203, 203, 204, 204, 205, 205 + 154, 154, 154, 155, 154, 154, 154, 154, 154, 154, + 154, 154, 154, 154, 154, 154, 154, 156, 154, 157, + 154, 158, 154, 159, 154, 160, 161, 154, 154, 154, + 154, 154, 162, 162, 162, 163, 163, 164, 164, 165, + 165, 166, 166, 167, 167, 167, 167, 169, 168, 171, + 170, 172, 172, 172, 172, 172, 173, 173, 173, 173, + 173, 173, 174, 175, 175, 175, 176, 176, 177, 177, + 178, 178, 179, 179, 179, 180, 180, 180, 181, 181, + 182, 182, 182, 182, 182, 182, 182, 182, 182, 182, + 183, 184, 184, 185, 186, 185, 185, 187, 187, 188, + 188, 188, 188, 188, 188, 188, 188, 188, 189, 189, + 190, 191, 191, 192, 193, 194, 194, 195, 195, 196, + 196, 196, 197, 197, 198, 199, 199, 199, 200, 200, + 201, 201, 202, 202, 203, 203, 203, 204, 204, 205, + 205 }; static const short yyr2[] = { 0, @@ -534,89 +540,90 @@ static const short yyr2[] = { 0, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 3, 3, 0, 4, 5, 1, 1, 0, 2, 1, 2, - 5, 2, 5, 4, 7, 3, 1, 2, 2, 0, - 1, 0, 1, 3, 1, 4, 2, 1, 0, 2, - 1, 3, 3, 2, 1, 1, 1, 1, 1, 1, - 1, 4, 3, 3, 4, 3, 1, 4, 3, 1, - 0, 6, 1, 2, 1, 2, 6, 6, 5, 5, - 4, 7, 6, 3, 0, 6, 0, 7, 0, 5, - 0, 6, 0, 0, 9, 1, 1, 1, 1, 1, - 1, 2, 1, 1, 1, 5, 0, 2, 1, 1, - 0, 2, 1, 3, 0, 5, 0, 5, 1, 1, - 1, 1, 1, 4, 6, 3, 6, 4, 1, 5, - 1, 4, 2, 1, 1, 5, 0, 0, 2, 1, - 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 5, 2, 2, 5, 4, 4, 7, 3, 1, + 2, 2, 0, 1, 0, 1, 3, 1, 4, 2, + 1, 0, 2, 1, 3, 3, 2, 1, 1, 1, + 1, 1, 1, 1, 4, 3, 3, 4, 3, 1, + 4, 3, 1, 0, 6, 1, 2, 1, 2, 6, + 6, 5, 5, 4, 7, 6, 3, 0, 6, 0, + 7, 0, 5, 0, 6, 0, 0, 9, 1, 1, + 1, 1, 1, 1, 2, 1, 1, 1, 5, 0, + 2, 1, 1, 0, 2, 1, 3, 0, 5, 0, + 5, 1, 1, 1, 1, 1, 4, 6, 3, 6, + 4, 1, 5, 1, 4, 2, 1, 1, 5, 0, + 0, 2, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 0, 4, 2, 4, 2, 6, 4, 4, 2, - 4, 2, 2, 1, 0, 1, 3, 3, 1, 3, - 2, 2, 2, 0, 1, 4, 0, 2, 2, 1, - 3, 3, 1, 1, 1, 1, 1, 0, 1, 0, - 1, 0, 1, 1, 1, 1, 1, 2 + 1, 1, 1, 1, 0, 4, 2, 4, 2, 6, + 4, 4, 2, 4, 2, 2, 1, 0, 1, 3, + 3, 1, 3, 2, 2, 2, 0, 1, 4, 0, + 2, 2, 1, 3, 3, 1, 1, 1, 1, 1, + 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, + 2 }; static const short yydefact[] = { 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 246, 247, 248, 249, 217, 220, 279, - 303, 302, 304, 305, 0, 0, 350, 19, 0, 307, - 306, 343, 345, 300, 299, 344, 296, 297, 205, 207, - 292, 206, 208, 209, 309, 310, 0, 0, 0, 0, - 199, 337, 0, 0, 0, 0, 2, 348, 5, 22, - 26, 0, 36, 0, 40, 45, 31, 175, 0, 225, - 201, 290, 308, 210, 211, 0, 7, 54, 55, 0, - 0, 239, 100, 112, 101, 125, 97, 118, 107, 106, + 0, 0, 0, 249, 250, 251, 252, 220, 223, 282, + 306, 305, 307, 308, 0, 0, 353, 19, 0, 310, + 309, 346, 348, 303, 302, 347, 299, 300, 208, 210, + 295, 209, 211, 212, 312, 313, 0, 0, 0, 0, + 202, 340, 0, 0, 0, 0, 2, 351, 5, 22, + 26, 0, 36, 0, 40, 45, 31, 175, 0, 228, + 204, 293, 311, 213, 214, 0, 7, 54, 55, 0, + 0, 242, 100, 112, 101, 125, 97, 118, 107, 106, 123, 105, 104, 99, 128, 109, 98, 113, 117, 119, 111, 103, 120, 130, 122, 121, 114, 124, 108, 96, 116, 115, 110, 126, 129, 127, 95, 102, 93, 94, 91, 92, 56, 58, 57, 86, 87, 84, 68, 69, - 70, 73, 75, 71, 64, 88, 89, 76, 77, 0, - 81, 72, 74, 65, 66, 67, 78, 79, 80, 82, - 83, 85, 90, 241, 59, 60, 308, 335, 0, 121, - 114, 124, 108, 91, 92, 56, 57, 61, 14, 287, - 298, 223, 301, 0, 26, 225, 0, 0, 0, 0, - 217, 220, 279, 350, 260, 259, 0, 0, 50, 53, - 0, 0, 0, 0, 0, 0, 179, 193, 198, 187, - 190, 24, 175, 308, 211, 190, 340, 0, 25, 177, - 35, 29, 0, 9, 351, 172, 0, 0, 151, 175, - 152, 204, 0, 0, 0, 36, 193, 352, 0, 352, - 0, 352, 44, 295, 294, 293, 291, 30, 166, 167, - 356, 355, 3, 357, 349, 0, 0, 0, 0, 0, + 70, 73, 75, 71, 64, 88, 89, 76, 77, 81, + 72, 74, 65, 66, 67, 78, 79, 80, 82, 83, + 85, 90, 0, 244, 59, 60, 311, 338, 0, 121, + 114, 124, 108, 91, 92, 56, 57, 61, 14, 290, + 301, 226, 304, 0, 26, 228, 0, 0, 0, 0, + 220, 223, 282, 353, 263, 262, 0, 0, 50, 53, + 0, 0, 0, 0, 0, 0, 179, 196, 201, 190, + 193, 24, 175, 311, 214, 193, 343, 0, 25, 177, + 35, 29, 0, 9, 354, 172, 0, 0, 151, 175, + 152, 207, 0, 0, 0, 36, 196, 355, 0, 355, + 0, 355, 44, 298, 297, 296, 294, 30, 166, 167, + 359, 358, 3, 360, 352, 0, 0, 0, 0, 0, 0, 0, 47, 0, 0, 48, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 177, 265, 8, 267, 226, - 137, 131, 0, 0, 177, 32, 224, 0, 0, 312, - 235, 311, 0, 350, 325, 347, 346, 243, 62, 192, - 257, 251, 0, 250, 0, 0, 0, 254, 0, 253, - 0, 0, 0, 0, 177, 0, 190, 188, 216, 0, - 0, 0, 180, 0, 177, 0, 182, 219, 0, 0, - 350, 11, 13, 12, 0, 221, 0, 0, 0, 0, - 0, 234, 37, 354, 353, 200, 213, 339, 214, 354, - 338, 358, 6, 15, 16, 17, 18, 27, 28, 0, - 195, 23, 0, 41, 0, 150, 156, 161, 162, 163, + 0, 0, 0, 0, 0, 177, 268, 8, 270, 229, + 137, 131, 0, 0, 177, 32, 227, 0, 0, 315, + 238, 314, 0, 353, 328, 350, 349, 246, 62, 195, + 260, 254, 0, 253, 0, 0, 0, 257, 0, 256, + 0, 0, 0, 0, 177, 0, 193, 191, 219, 0, + 0, 180, 181, 0, 177, 183, 184, 222, 0, 0, + 353, 11, 13, 12, 0, 224, 0, 0, 0, 0, + 0, 237, 37, 357, 356, 203, 216, 342, 217, 357, + 341, 361, 6, 15, 16, 17, 18, 27, 28, 0, + 198, 23, 0, 41, 0, 150, 156, 161, 162, 163, 158, 160, 170, 171, 164, 165, 143, 144, 168, 169, 0, 157, 159, 153, 154, 155, 145, 146, 147, 148, - 149, 203, 345, 202, 0, 343, 344, 276, 0, 176, - 261, 261, 0, 0, 142, 136, 0, 237, 314, 0, - 0, 0, 0, 326, 0, 0, 325, 0, 0, 334, - 329, 334, 334, 324, 0, 0, 0, 191, 0, 288, - 257, 252, 257, 0, 281, 0, 231, 0, 0, 0, - 52, 344, 276, 0, 0, 0, 186, 215, 342, 0, - 194, 189, 190, 343, 0, 0, 0, 341, 218, 278, - 178, 10, 0, 173, 0, 21, 37, 194, 197, 0, + 149, 206, 348, 205, 0, 346, 347, 279, 0, 176, + 264, 264, 0, 0, 142, 136, 0, 240, 317, 0, + 0, 0, 0, 329, 0, 0, 328, 0, 0, 337, + 332, 337, 337, 327, 0, 0, 0, 194, 0, 291, + 260, 255, 260, 0, 284, 0, 234, 0, 0, 0, + 52, 347, 279, 0, 0, 0, 189, 218, 345, 0, + 197, 192, 193, 346, 0, 0, 0, 344, 221, 281, + 178, 10, 0, 173, 0, 21, 37, 197, 200, 0, 46, 0, 49, 0, 177, 34, 0, 0, 0, 0, - 177, 33, 212, 263, 0, 0, 0, 138, 132, 274, - 0, 0, 0, 240, 336, 0, 331, 332, 350, 0, - 316, 0, 320, 0, 322, 0, 323, 244, 63, 0, - 0, 258, 0, 0, 0, 0, 255, 0, 283, 0, - 0, 229, 230, 51, 0, 190, 0, 184, 212, 190, + 177, 33, 215, 266, 0, 0, 0, 138, 132, 277, + 0, 0, 0, 243, 339, 0, 334, 335, 353, 0, + 319, 0, 323, 0, 325, 0, 326, 247, 63, 0, + 0, 261, 0, 0, 0, 0, 258, 0, 286, 0, + 0, 232, 233, 51, 0, 193, 187, 186, 215, 193, 0, 20, 0, 43, 174, 0, 140, 134, 141, 135, - 0, 0, 0, 262, 0, 0, 0, 0, 313, 236, - 328, 0, 242, 327, 334, 334, 333, 0, 330, 334, - 325, 287, 289, 233, 0, 227, 228, 0, 257, 0, - 181, 0, 183, 222, 196, 277, 275, 139, 133, 264, - 266, 268, 238, 315, 0, 318, 319, 321, 0, 286, - 0, 282, 284, 285, 280, 232, 190, 334, 0, 257, - 185, 317, 245, 256, 0, 0, 0 + 0, 0, 0, 265, 0, 0, 0, 0, 316, 239, + 331, 0, 245, 330, 337, 337, 336, 0, 333, 337, + 328, 290, 292, 236, 0, 230, 231, 0, 260, 0, + 182, 0, 185, 225, 199, 280, 278, 139, 133, 267, + 269, 271, 241, 318, 0, 321, 322, 324, 0, 289, + 0, 285, 287, 288, 283, 235, 193, 337, 0, 260, + 188, 320, 248, 259, 0, 0, 0 }; static const short yydefgoto[] = { 615, @@ -632,311 +639,286 @@ static const short yydefgoto[] = { 615, }; static const short yypact[] = {-32768, - 1581, 4673, 29, 135, 4070, 4379, 2015, 4763, 4763, 2487, - 4763, 4763, 5841,-32768,-32768,-32768,-32768, 3427, 3517, 3607, --32768,-32768,-32768,-32768, 4763, 4276, -45,-32768, 39,-32768, --32768, 1679, 1898,-32768,-32768, 1793,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768, 5573, 5573, 135, 2578, - 5573, 5573, 6105, 4173, 5663, 5573,-32768, -25, 338, 93, - 136, 64,-32768, 59, 5929,-32768, 6104, 0, 147, 22, --32768,-32768, 122,-32768, 168, 3067, 338,-32768,-32768, 4763, - 41,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, + 1422, 4530, 39, 164, 2922, 4236, 1856, 4620, 4620, 2328, + 4620, 4620, 5698,-32768,-32768,-32768,-32768, 3387, 3477, 3567, +-32768,-32768,-32768,-32768, 4620, 4133, -53,-32768, -41,-32768, +-32768, 1520, 1739,-32768,-32768, 1634,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768,-32768, 5430, 5430, 164, 2419, + 5430, 5430, 5962, 4030, 5520, 5430,-32768, 158, 420, 322, + 88, 86,-32768, 82, 5786,-32768, 6041, -8, 160, 27, +-32768,-32768, 105,-32768, 168, 3027, 420,-32768,-32768, 4620, + 50,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, +-32768,-32768,-32768,-32768,-32768, 1, 94, 146, 182,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768, -9, 1, 2, 12,-32768, + 183, 196, 200,-32768, 201,-32768,-32768,-32768,-32768,-32768, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, - 79, 85, 125,-32768, 130,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 4763, -32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 175,-32768, --32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 74, 212, - 3157, 3247, 3337, 33,-32768, 118, 33, 221, 21, 21, - 155, 172, 177, -45,-32768, 192, 62, 285, 71, 78, - -17, 2686, 5573, 5573, 5573, 4483,-32768, 1089,-32768,-32768, - 205,-32768, 80, 210, 222, 211,-32768, 4578,-32768, 4853, --32768,-32768, 36,-32768,-32768, 215, 230, 2794, 284, 143, - 284,-32768, 2578, 251, 257, 258, 6104, -22, 243, -22, - 264, 92,-32768,-32768,-32768,-32768,-32768,-32768, 284, 284, --32768,-32768,-32768,-32768, 2976, 4763, 4763, 4763, 4763, 4763, - 4763, 5213,-32768, 2578, 6105,-32768, 268, 5573, 5573, 5573, - 5573, 5573, 5573, 5573, 5573, 5573, 5573, 5573, 5573, 5573, - 5573, 5573, 5573, 5573, 5573, 5573, 5573, 5573, 5573, 5573, - 5573, 5573, 5573, 235, 280, 4853,-32768,-32768,-32768,-32768, --32768,-32768, 5573, 5573, 4853,-32768,-32768, 31, -25,-32768, --32768,-32768, 2885, 28, -2,-32768,-32768,-32768,-32768, 5573, - 365,-32768, 2123, 382, 2305, 5303, 387,-32768, 2885,-32768, - 2885, 215, 235, 306, 4853, 4763, 749, 6104,-32768, 288, - 5573, 4943,-32768, 311, 4853, 5033,-32768,-32768, 290, 293, - -45,-32768,-32768,-32768, 4379,-32768, 5573, 2794, 297, 311, - 298,-32768, 299, 5573,-32768,-32768,-32768,-32768,-32768, 5573, --32768,-32768, 338, 93, 93, 93, 93,-32768,-32768, 5573, - 300,-32768, 302,-32768, 6017, 284, 670, 670, 670, 670, - 286, 286, 1385, 6184, 670, 670, 6144, 6144, 129, 129, - 1339, 286, 286, 99, 99, 291, 66, 66, 284, 284, - 284, 3697,-32768, 3787, 3877, 197, 226, 3967, 296,-32768, - 68, 68, 5573, 5573, 6104, 6104, 304,-32768,-32768, 4763, - 2885, 391, 305, 326, 375, 376, 13, 2885, -25, 313, --32768, 314, 315,-32768, 4379, 4379, 15, 318, 2396, 422, - 246,-32768, 365, 5573, 321, 25,-32768, 423, 425, 322, - 103,-32768, 324, 327, 21, 352,-32768,-32768, 6104, 5573, - 1089,-32768, 333, 232, 332, 5573, 1089,-32768,-32768,-32768, --32768,-32768, 4763, 6104, 339,-32768, 253, 6104, 6104, 5393, --32768, 6105,-32768, 5573, 4853,-32768, 5573, 5573, 5573, 5573, - 4853,-32768, 208,-32768, 5753, 2885, 2794, 6104, 6104,-32768, - 2885, 31, 439,-32768,-32768, 5573,-32768,-32768, -45, 440, --32768, 26,-32768, 30,-32768, 362,-32768,-32768,-32768, 2015, - 5573,-32768, 2885, 443, 4763, 444,-32768, 445, 6104, 5483, - 2214,-32768,-32768, 160, 2885, 749, 5123,-32768, 238, 749, - 23,-32768, 5573,-32768, 6104, 346, 6104, 6104, 6104, 6104, - 347, 5573, 5573,-32768, 363, 448, 353, 450,-32768,-32768, - 6104, 355,-32768, 326, 351, 315,-32768, 326,-32768, 315, - -2, 212,-32768,-32768, 33,-32768,-32768, 5573, 206, 457, --32768, 5573,-32768,-32768, 6104,-32768,-32768, 6104, 6104,-32768, --32768,-32768,-32768,-32768, 30,-32768,-32768,-32768, 2885,-32768, - 2123, 6104,-32768,-32768,-32768,-32768, 749, 315, 458, 246, --32768,-32768,-32768,-32768, 469, 470,-32768 +-32768,-32768, 4620,-32768,-32768,-32768,-32768,-32768, 235,-32768, +-32768,-32768,-32768,-32768,-32768,-32768,-32768,-32768, 127, 244, + 3117, 3207, 3297, 46,-32768, 149, 46, 273, 42, 42, + 198, 202, 206, -53,-32768, 150, 10, 286, 92, 93, + 74, 2527, 5430, 5430, 5430, 4340,-32768, 5961,-32768,-32768, + 204,-32768, 111, 37, 44, 218,-32768, 4435,-32768, 4710, +-32768,-32768, 270,-32768,-32768, 222, 242, 2635, 294, 116, + 294,-32768, 2419, 272, 275, 276, 6041, -27, 274, -27, + 282, 60,-32768,-32768,-32768,-32768,-32768,-32768, 294, 294, +-32768,-32768,-32768,-32768, 2817, 4620, 4620, 4620, 4620, 4620, + 4620, 5070,-32768, 2419, 5962,-32768, 280, 5430, 5430, 5430, + 5430, 5430, 5430, 5430, 5430, 5430, 5430, 5430, 5430, 5430, + 5430, 5430, 5430, 5430, 5430, 5430, 5430, 5430, 5430, 5430, + 5430, 5430, 5430, 249, 285, 4710,-32768,-32768,-32768,-32768, +-32768,-32768, 5430, 5430, 4710,-32768,-32768, 13, 158,-32768, +-32768,-32768, 2726, 35, 18,-32768,-32768,-32768,-32768, 5430, + 368,-32768, 1964, 380, 2146, 5160, 391,-32768, 2726,-32768, + 2726, 222, 249, 303, 4710, 4620, 1206, 6041,-32768, 292, + 5430, 4800,-32768, 320, 4710, 4890,-32768,-32768, 295, 298, + -53,-32768,-32768,-32768, 4236,-32768, 5430, 2635, 301, 320, + 300,-32768, 306, 5430,-32768,-32768,-32768,-32768,-32768, 5430, +-32768,-32768, 420, 322, 322, 322, 322,-32768,-32768, 5430, + 307,-32768, 312,-32768, 5874, 294, 6161, 6161, 6161, 6161, + 263, 263, 6201, 6121, 6161, 6161, 6081, 6081, -6, -6, + 6001, 263, 263, 134, 134, 475, 14, 14, 294, 294, + 294, 3657,-32768, 3747, 3837, 195, 117, 3927, 310,-32768, + 98, 98, 5430, 5430, 6041, 6041, 316,-32768,-32768, 4620, + 2726, 418, 324, 339, 388, 389, 20, 2726, 158, 330, +-32768, 331, 333,-32768, 4236, 4236, 48, 335, 2237, 438, + 355,-32768, 368, 5430, 337, 30,-32768, 440, 451, 347, + 75,-32768, 348, 353, 42, 379,-32768,-32768, 6041, 5430, + 5961,-32768, 358, 135, 357, 5430, 5961,-32768,-32768,-32768, +-32768,-32768, 4620, 6041, 363,-32768, 262, 6041, 6041, 5250, +-32768, 5962,-32768, 5430, 4710,-32768, 5430, 5430, 5430, 5430, + 4710,-32768, 197,-32768, 5610, 2726, 2635, 6041, 6041,-32768, + 2726, 13, 463,-32768,-32768, 5430,-32768,-32768, -53, 464, +-32768, 24,-32768, 36,-32768, 386,-32768,-32768,-32768, 1856, + 5430,-32768, 2726, 467, 4620, 469,-32768, 472, 6041, 5340, + 2055,-32768,-32768, 148, 2726, 1206, 4980,-32768, 216, 1206, + 26,-32768, 5430,-32768, 6041, 373, 6041, 6041, 6041, 6041, + 377, 5430, 5430,-32768, 392, 479, 383, 483,-32768,-32768, + 6041, 393,-32768, 339, 390, 333,-32768, 339,-32768, 333, + 18, 244,-32768,-32768, 46,-32768,-32768, 5430, 83, 487, +-32768, 5430,-32768,-32768, 6041,-32768,-32768, 6041, 6041,-32768, +-32768,-32768,-32768,-32768, 36,-32768,-32768,-32768, 2726,-32768, + 1964, 6041,-32768,-32768,-32768,-32768, 1206, 333, 489, 355, +-32768,-32768,-32768,-32768, 502, 506,-32768 }; static const short yypgoto[] = {-32768, --32768, 479,-32768, 32,-32768,-32768, 95, 1321, -10, -149, - -27, -49,-32768,-32768, 16, 46, 7,-32768,-32768,-32768, --32768, 1012,-32768,-32768,-32768, -247, -196, 8, -300, -201, --32768, -12,-32768, 18,-32768, -1,-32768,-32768,-32768,-32768, --32768,-32768,-32768, -173, -159, -139, -289, -20, 61,-32768, --32768, -46,-32768,-32768, 115, -103,-32768,-32768, -95,-32768, --32768,-32768,-32768, 616, 473, 698,-32768,-32768, -89, 56, --32768, -444, -24, -461, -274, -389,-32768,-32768, -32, -301, - 256,-32768,-32768, -169, 119, -56,-32768 +-32768, 345,-32768, 31,-32768,-32768, 19, 1162, -9, -151, + -24, -52,-32768,-32768, 3, 53, -4,-32768,-32768,-32768, +-32768, 853,-32768,-32768,-32768, -214, -190, 16, -295, -201, +-32768, -12,-32768, 23,-32768, -1,-32768,-32768,-32768,-32768, +-32768,-32768,-32768, -162, -166, -103, -286, 22, 96,-32768, +-32768, -47,-32768,-32768, 644, -70,-32768,-32768, -54,-32768, +-32768,-32768,-32768, 387, 515, 503,-32768,-32768, -50, 99, +-32768, -426, 15, -427, -284, -387,-32768,-32768, -29, -298, + 130,-32768,-32768, -181, 11, -26,-32768 }; -#define YYLAST 6287 +#define YYLAST 6304 static const short yytable[] = { 68, - 68, 244, 185, 315, 337, 68, 68, 68, 68, 68, - 68, 187, 168, 340, 322, 256, 203, 203, 203, 232, - 321, 440, 226, 68, 302, 199, 199, 211, 186, 297, - 434, 462, 214, 77, 468, 462, 209, 312, 228, 230, - 318, 299, 515, 517, 424, 312, 318, -272, 68, 82, - 566, 187, 570, 203, 250, 251, 250, 251, 468, 424, - 236, 250, 251, 187, 250, 251, 250, 251, 233, 569, - 215, -303, 564, 351, 203, 78, 568, 454, 68, 79, - 284, -302, -304, 296, 342, 425, 426, 465, 354, 289, - 241, 242, -305, 355, 222, 343, 344, 295, 417, -303, - 425, 426, 174, 177, 373, 179, 180, 80, 285, -302, - -304, 286, 427, 425, 426, 70, 70, 425, 426, 212, - -305, 70, 320, 320, 70, 457, 250, 251, 289, 258, - 241, 242, 584, 608, 423, 300, 241, 242, 68, 494, - 241, 242, 323, 215, 297, 218, 241, 242, 241, 242, - 569, -308, 434, 528, 252, 462, 241, 242, -211, -307, - 284, -273, 258, 495, 70, -306, 281, 282, 283, 253, - 324, 471, 287, 325, 298, 596, 597, 271, 272, -308, - 598, 78, -308, -343, 309, 79, -211, -307, 334, -211, - 68, 335, 258, -306, 203, 226, 278, 279, 280, 281, - 282, 283, 360, 199, 291, -298, 203, 355, 203, -343, - -301, -343, 292, 330, -343, 199, 68, -343, 612, 310, - 439, 68, 316, 323, 289, 339, 226, 279, 280, 281, - 282, 283, -50, -298, 304, 468, 462, 316, -301, 371, - -212, 418, 419, 68, 68, 68, 68, 68, 68, 68, - 293, 350, 68, 187, 335, 306, 76, 76, 294, 525, - 439, 538, 76, 76, 76, 76, 76, 76, -212, 196, - 374, -212, 531, 76, 76, 76, 363, 520, -53, 487, - 76, 402, 403, 307, 203, 404, 208, 488, 546, 603, - 552, 210, 291, 203, 551, 535, 434, 438, 553, 463, - 292, 68, -45, 445, 293, 76, 70, -52, 489, 326, - 76, 68, 294, 68, 487, 332, 490, 68, -51, 68, - 552, 336, 488, 203, 68, 483, 406, 403, 553, 346, - 407, 76, 70, 203, 581, 76, 348, 70, 583, 562, - 364, 365, 366, 367, 368, 369, 68, 258, 358, 258, - 361, 472, 451, 403, 258, 357, 452, 464, 403, 70, - 352, 407, -39, -46, 271, 272, 353, -38, 70, 271, - 272, 359, 511, 187, 246, 247, 248, 249, 375, 439, - 320, 276, 277, 278, 279, 280, 281, 282, 283, 279, - 280, 281, 282, 283, 442, 76, 447, 458, 320, 469, - 504, 601, 470, 203, 476, 611, 203, 477, 493, -46, - 480, 481, 486, 500, 505, 492, 506, 70, 68, 68, - 455, 507, 508, 512, 514, 516, 68, 70, 521, 70, - 523, 530, 532, 70, 533, 70, 485, 68, 491, 534, - 194, 518, 519, 537, 539, 559, 542, 76, 560, 563, - 426, 76, 574, 576, 577, 586, 587, 591, 590, 593, - 592, 595, 70, 76, 594, 76, 606, 613, 616, 617, - 614, 68, 497, 76, 555, 604, 600, 158, 76, 57, - 187, 599, 509, 203, 185, 170, 0, 565, 178, 203, - 0, 0, 0, 187, 68, 68, 0, 544, 0, 68, - 76, 76, 76, 76, 76, 76, 76, 0, 0, 76, - 186, 0, 0, 0, 502, 0, 0, 0, 68, 0, - 0, 68, 0, 68, 0, 0, 0, 0, 0, 68, - 0, 0, 0, 68, 0, 70, 0, 0, 0, 405, - 408, 76, 70, 0, 0, 0, 0, 0, 0, 0, - 76, 0, 0, 70, 0, 0, 0, 0, 76, 0, - 0, 0, 0, 0, 0, 0, 0, 541, 76, 0, - 76, 0, 0, 0, 76, 0, 76, 0, 450, 453, - 76, 76, 0, 0, 0, 0, 0, 0, 0, 408, - 76, 0, 0, 0, 0, 0, 0, 68, 0, 68, - 0, 0, 0, 76, 0, 453, 0, 0, 0, 0, - 70, 70, 0, 0, 0, 70, 73, 73, 0, 575, - 157, 0, 73, 73, 73, 73, 73, 73, 189, 0, - 0, 0, 0, 0, 70, 0, 0, 70, 0, 0, - 73, 0, 0, 0, 0, 70, 0, 0, 0, 70, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 76, 0, 0, 76, 0, 73, 0, 0, 189, 0, - 0, 0, 0, 0, 0, 76, 76, 0, 0, 0, - 189, 0, 0, 76, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 76, 73, 349, 0, 75, 75, - 0, 0, 0, 0, 75, 75, 75, 75, 75, 75, - 190, 0, 0, 70, 0, 70, 0, 0, 0, 0, - 0, 0, 75, 0, 0, 0, 0, 0, 76, 0, - 0, 0, 0, 258,-32768,-32768,-32768,-32768, 263, 264, - 76, 0,-32768,-32768, 0, 0, 76, 75, 271, 272, - 190, 76, 76, 0, 0, 73, 76, 0, 0, 0, - 0, 0, 190, 274, 275, 276, 277, 278, 279, 280, - 281, 282, 283, 0, 0, 76, 0, 75, 76, 0, - 76, 422, 0, 0, 0, 0, 76, 0, 0, 0, - 76, 441, 0, 443, 0, 0, 0, 448, 0, 449, - 0, 0, 0, 0, 0, 0, 0, 73, 0, 0, - 0, 0, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 0, 475, 271, 272, 0, - 0, 0, 0, 73, 0, 0, 0, 75, 73, 0, - 273, 0, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 0, 0, 76, 0, 76, 0, 0, 456, - 73, 73, 73, 73, 73, 73, 73, 0, 0, 73, - 189, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 503, - 0, 0, 0, 0, 0, 0, 510, 0, 0, 0, - 0, 0, 0, 0, 0, 75, 0, 522, 73, 0, - 75, 0, 0, 0, 0, 0, 0, 0, 73, 0, - 73, 0, 0, 0, 73, 0, 73, 0, 0, 0, - 0, 73, 75, 75, 75, 75, 75, 75, 75, 0, - 0, 75, 190, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 556, 557, 0, 0, 0, 558, + 68, 168, 322, 185, 337, 68, 68, 68, 68, 68, + 68, 187, 256, 321, 315, 186, 203, 203, 203, 340, + 434, 214, 232, 68, 440, 226, 174, 177, 297, 179, + 180, 244, 77, 199, 199, 211, 462, 468, 228, 230, + 462, 209, 312, 212, 515, 517, 250, 251, 68, 236, + 299, 187, -275, 203, 302, 233, 82, 258, 312, 250, + 251, 468, 215, 187, 424, 218, 424, 318, 250, 251, + 564, 351, 284, 318, 203, 250, 251, 258, 68, 250, + 251, -306, 568, 354, 566, 78, 570, 569, 355, 79, + 323, 296, 279, 280, 281, 282, 283, 439, 298, 316, + 285, 222, 373, 286, 417, 425, 426, 425, 426, -306, + 454, 425, 426, -276, 281, 282, 283, 80, 324, 291, + 465, 325, 423, 425, 426, 457, 293, 292, 241, 242, + 76, 76, 427, 289, 294, 584, 76, 76, 76, 76, + 76, 76, 434, 297, 300, 241, 242, 76, 76, 76, + 215, 68, 320, 320, 76, -346, 528, 241, 242, 471, + 462, 241, 242, 241, 242, 241, 242, 608, 569, 494, + 360, 304, -311, -214, -305, 355, 252, 596, 597, 76, + 289, -346, 598, -346, 76, 287, -346, 291, 295, -346, + 68, 284, 253, 495, 203, 292, 323, 258, 226, 489, + -311, -214, -305, -311, -214, 76, 203, 490, 203, 76, + 78, 199, 271, 272, 79, -50, 68, 487, 330, 334, + 612, 68, 335, 199, 350, 488, -307, 335, -215, 226, + 339, 278, 279, 280, 281, 282, 283, 309, 468, 371, + 358, 462, 361, 68, 68, 68, 68, 68, 68, 68, + 293, 310, 68, 187, -307, 289, -215, 374, 294, -215, + -45, 538, -308, -310, 364, 365, 366, 367, 368, 369, + 520, 418, 419, 241, 242, 363, -309, 487, -53, 552, + -301, -304, 76, 531, 203, 488, 434, 553, 535, 316, + -308, -310, 603, 203, 546, 402, 403, 438, 552, 404, + 551, 68, 463, 445, -309, -52, 553, -51, -301, -304, + 326, 68, 196, 68, 332, 306, 208, 68, 342, 68, + 210, 76, 483, 203, 68, 76, 258, 562, 336, 343, + 344, 406, 403, 203, 581, 407, 346, 76, 583, 76, + 472, 271, 272, 307, 455, 57, 68, 76, 348, 451, + 403, 170, 76, 452, 178, 250, 251, 258, 276, 277, + 278, 279, 280, 281, 282, 283, 464, 403, 525, 439, + 407, -39, -46, 187, 76, 76, 76, 76, 76, 76, + 76, 352, 439, 76, 353, -38, 357, 73, 73, 359, + 375, 157, 442, 73, 73, 73, 73, 73, 73, 189, + 447, 458, 511, 203, 469, 611, 203, 470, 476, 477, + 320, 73, 601, 405, 408, 76, -46, 480, 68, 68, + 486, 481, 493, 492, 76, 500, 68, 504, 320, 506, + 518, 519, 76, 505, 507, 508, 73, 68, 502, 189, + 512, 514, 76, 516, 76, 521, 523, 530, 76, 532, + 76, 189, 450, 453, 76, 76, 246, 247, 248, 249, + 533, 485, 491, 408, 76, 534, 73, 194, 537, 539, + 542, 68, 560, 563, 426, 559, 574, 76, 576, 453, + 187, 577, 586, 203, 544, 185, 587, 590, 591, 203, + 592, 541, 593, 187, 68, 68, 606, 186, 613, 68, + 595, 616, 594, 75, 75, 617, 614, 497, 604, 75, + 75, 75, 75, 75, 75, 190, 555, 600, 68, 158, + 599, 68, 0, 68, 0, 509, 565, 75, 0, 68, + 0, 0, 0, 68, 76, 0, 0, 76, 258, 73, + 0, 0, 0, 575, 0, 0, 0, 0, 0, 76, + 76, 0, 75, 271, 272, 190, 0, 76, 0, 0, + 0, 0, 349, 0, 0, 0, 0, 190, 76, 0, + 0, 0, 0, 279, 280, 281, 282, 283, 73, 0, + 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 68, 0, 68, + 0, 0, 76, 0, 73, 0, 0, 0, 0, 73, + 0, 0, 0, 0, 76, 0, 0, 0, 0, 0, + 76, 0, 0, 0, 0, 76, 76, 0, 0, 0, + 76, 73, 73, 73, 73, 73, 73, 73, 0, 0, + 73, 189, 0, 0, 70, 70, 0, 422, 0, 76, + 70, 0, 76, 70, 76, 75, 0, 441, 0, 443, + 76, 0, 0, 448, 76, 449, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 189, 0, 0, 0, 0, 0, 0, 0, 572, 0, - 75, 573, 0, 0, 0, 0, 0, 0, 0, 579, - 75, 0, 75, 580, 0, 0, 75, 0, 75, 0, - 0, 0, 0, 75, 0, 0, 0, 0, 0, 198, - 198, 198, 0, 0, 0, 73, 73, 0, 0, 0, - 0, 0, 0, 73, 0, 75, 0, 0, 0, 0, - 0, 0, 0, 0, 73, 0, 0, 0, 219, 221, - 0, 0, 227, 198, 0, 0, 239, 240, 0, 0, - 0, 0, 190, 0, 0, 0, 0, 609, 0, 610, - 0, 0, 0, 0, 0, 0, 0, 198, 73, 0, - 0, 0, 0, 0, 0, 0, 0, 189, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 73, + 0, 0, 475, 70, 75, 0, 0, 0, 0, 73, + 0, 73, 0, 0, 0, 73, 0, 73, 0, 0, + 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, + 75, 0, 0, 0, 0, 75, 0, 0, 76, 0, + 76, 0, 0, 0, 73, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 75, 75, 75, + 75, 75, 75, 75, 0, 0, 75, 190, 0, 0, + 0, 189, 0, 0, 0, 503, 0, 0, 0, 0, + 0, 0, 510, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 522, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 189, 73, 73, 0, 0, 0, 73, 75, 75, 0, + 0, 0, 0, 0, 0, 75, 73, 73, 0, 0, + 0, 0, 0, 0, 73, 75, 0, 75, 0, 0, + 0, 75, 0, 75, 0, 73, 0, 0, 75, 0, + 0, 0, 0, 0, 0, 70, 0, 0, 0, 0, + 556, 557, 0, 0, 0, 558, 0, 0, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 0, 0, 73, + 0, 70, 0, 0, 572, 0, 70, 573, 189, 0, + 198, 198, 198, 0, 0, 579, 0, 190, 0, 580, + 0, 189, 73, 73, 0, 0, 0, 73, 70, 0, + 0, 0, 0, 0, 0, 0, 0, 70, 0, 219, + 221, 0, 0, 227, 198, 0, 73, 239, 240, 73, + 0, 73, 0, 0, 0, 0, 0, 73, 0, 0, + 0, 73, 75, 75, 0, 0, 0, 0, 198, 0, + 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 75, 0, 609, 0, 610, 70, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 70, 0, 70, 0, + 0, 0, 70, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 73, 75, 0, 73, 0, - 73, 0, 0, 0, 0, 0, 73, 0, 0, 0, - 73, 0, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 0, 0, 271, 272, 0, - 75, 0, 331, 0, 0, 0, 0, 0, 0, 190, - 273, 0, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 190, 75, 75, 0, 0, 0, 75, 0, - 0, 0, 0, 0, 327, 328, 239, 198, 0, 0, - 0, 0, 0, 0, 73, 0, 73, 75, 0, 198, - 75, 198, 75, 0, 0, 0, 0, 0, 75, 0, - 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 190, 73, 0, 73, 0, 0, + 0, 70, 0, 0, 0, 0, 0, 190, 75, 75, + 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 75, 0, 0, 75, 0, 75, 0, 0, + 0, 0, 0, 75, 0, 0, 0, 75, 0, 0, + 0, 0, 0, 0, 0, 327, 328, 239, 198, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 227, 0, 0, 0, 0, 0, 376, - 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, - 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, - 397, 398, 399, 400, 401, 0, 75, 198, 75, 0, - 0, 0, 0, 0, 415, 416, 198, 0, 0, 0, + 198, 0, 198, 0, 70, 0, 0, 0, 0, 0, + 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 227, 0, 0, 0, 0, 0, 227, 175, 175, - 0, 175, 175, 0, 0, 0, 198, 0, 197, 197, - 197, 0, 459, 461, 0, 175, 198, 467, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 474, 0, - 0, 0, 0, 0, 0, 478, 0, 0, 0, 0, - 0, 467, 0, 0, 0, 238, 0, 0, 0, 0, - 0, 479, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, - 175, 0, 258, 259, 260, 261, 262, 263, 264, 265, - 266, 267, 268, 269, 270, 0, 198, 271, 272, 198, - 0, 0, 0, 0, 498, 499, 0, 0, 0, 0, - 273, 484, 274, 275, 276, 277, 278, 279, 280, 281, - 282, 283, 0, 0, 0, 0, 0, 0, 258, 259, - 260, 261, 262, 263, 264, 529, 0, 267, 268, 0, - 175, 0, 0, 271, 272, 0, 0, 0, 0, 0, - 0, 536, 0, 0, 0, 0, 0, 540, 274, 275, - 276, 277, 278, 279, 280, 281, 282, 283, 0, 0, - 0, 478, 0, 0, 0, 545, 198, 0, 547, 548, - 549, 550, 198, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 197, 561, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 197, 0, - 197, 0, 478, 0, 0, 0, 0, 0, 0, 0, - 0, 478, 0, 0, 0, 0, 0, 0, 467, 0, - 0, 0, 0, 0, 585, 0, 0, 0, 0, 0, - 0, 0, 0, 588, 589, 0, 175, 175, 175, 175, - 175, 175, 0, 0, 0, 0, 0, 0, 0, 0, - -4, 2, 0, 3, 4, 5, 6, 7, 0, 602, - 0, 8, 9, 607, 0, 0, 10, 0, 11, 12, - 13, 14, 15, 16, 17, 0, 197, 18, 19, 20, - 21, 22, 23, 24, 0, 197, 25, 0, 0, 0, - 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, - 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 0, 197, 175, 0, 0, 0, - 0, 0, 0, 0, 0, 197, 0, 0, 0, 0, - 0, 0, 49, 0, 0, 50, 51, 52, 53, 0, - 54, 0, 0, 0, 0, 0, 0, 0, -298, 0, - 0, 0, 0, 0, 55, 56, -298, -298, -298, 0, - 0, 0, -298, -298, 0, -298, -4, -4, 0, 0, - 0, 0, 0, 0, -269, 0, 0, 0, 0, 0, - 0, 0, -298, -298, 0, -298, -298, -298, -298, 0, - 0, 0, 0, 0, 0, 197, 0, 0, 197, 0, + 0, 75, 0, 75, 227, 0, 0, 0, 0, 0, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 0, 0, 198, 70, + 70, 0, 0, 0, 70, 415, 416, 198, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 227, 70, 0, 0, 70, 0, 227, 175, + 175, 0, 175, 175, 70, 0, 0, 198, 70, 197, + 197, 197, 0, 459, 461, 0, 175, 198, 467, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 474, + 0, 0, 0, 0, 0, 0, 478, 0, 0, 0, + 0, 0, 467, 0, 0, 0, 238, 0, 0, 0, + 0, 0, 479, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 197, 0, 0, + 0, 175, 70, 0, 70, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 198, 0, 0, + 198, 0, 0, 0, 0, 498, 499, 0, 0, 258, + 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, + 269, 270, 0, 0, 271, 272, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 529, 273, 0, 274, + 275, 276, 277, 278, 279, 280, 281, 282, 283, 0, + 0, 0, 536, 0, 175, 0, 456, 0, 540, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 175, 0, -298, -298, -298, -298, -298, -298, -298, -298, - -298, -298, -298, -298, -298, 0, 0, -298, -298, -298, - 0, -298, 0, 0, 0, 0, 0, 0, 0, -298, - -298, 0, -298, -298, -298, -298, -298, -298, -298, -298, - -298, -298, 0, 0, 0, 0, -298, -298, -298, -298, - -298, 0, -301, 175, -298, -298, 0, 0, 0, 0, - -301, -301, -301, 0, 0, 197, -301, -301, 0, -301, - 0, 197, 0, 0, 0, 0, 0, 0, -270, 0, - 0, 0, 0, 0, 0, 0, -301, -301, 0, -301, - -301, -301, -301, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 175, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, -301, -301, -301, -301, - -301, -301, -301, -301, -301, -301, -301, -301, -301, 0, - 0, -301, -301, -301, 0, -301, 0, 0, 0, 0, + 0, 0, 478, 0, 0, 0, 545, 198, 0, 547, + 548, 549, 550, 198, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 197, 561, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 197, + 0, 197, 0, 478, 0, 0, 0, 0, 0, 0, + 0, 0, 478, 0, 0, 0, 0, 0, 0, 467, + 0, 0, 0, 0, 0, 585, 0, 0, 0, 0, + 0, 0, 0, 0, 588, 589, 0, 175, 175, 175, + 175, 175, 175, 0, 0, 0, 0, 0, 0, 0, + 0, -4, 2, 0, 3, 4, 5, 6, 7, 0, + 602, 0, 8, 9, 607, 0, 0, 10, 0, 11, + 12, 13, 14, 15, 16, 17, 0, 197, 18, 19, + 20, 21, 22, 23, 24, 0, 197, 25, 0, 0, + 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 0, 197, 175, 0, 0, + 0, 0, 0, 0, 0, 0, 197, 0, 0, 0, + 0, 0, 0, 49, 0, 0, 50, 51, 52, 53, + 0, 54, 0, 0, 0, 0, 0, 0, 0, -301, + 0, 0, 0, 0, 0, 55, 56, -301, -301, -301, + 0, 0, 0, -301, -301, 0, -301, -4, -4, 0, + 0, 0, 0, 0, 0, -272, 0, 0, 0, 0, 0, 0, 0, -301, -301, 0, -301, -301, -301, -301, - -301, -301, -301, -301, -301, -301, 0, -223, 0, 0, - -301, -301, -301, -301, -301, -223, -223, -223, -301, -301, - 0, -223, -223, 0, -223, 0, 0, 0, 0, 0, - 0, 0, 0, -271, 0, 0, 0, 0, 0, 0, - 0, -223, -223, 0, -223, -223, -223, -223, 0, 0, + 0, 0, 0, 0, 0, 0, 197, 0, 0, 197, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 175, 0, -301, -301, -301, -301, -301, -301, -301, + -301, -301, -301, -301, -301, -301, 0, 0, -301, -301, + -301, 0, -301, 0, 0, 0, 0, 0, 0, 0, + -301, -301, 0, -301, -301, -301, -301, -301, -301, -301, + -301, -301, -301, 0, 0, 0, 0, -301, -301, -301, + -301, -301, 0, -304, 175, -301, -301, 0, 0, 0, + 0, -304, -304, -304, 0, 0, 197, -304, -304, 0, + -304, 0, 197, 0, 0, 0, 0, 0, 0, -273, + 0, 0, 0, 0, 0, 0, 0, -304, -304, 0, + -304, -304, -304, -304, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 175, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, -304, -304, -304, + -304, -304, -304, -304, -304, -304, -304, -304, -304, -304, + 0, 0, -304, -304, -304, 0, -304, 0, 0, 0, + 0, 0, 0, 0, -304, -304, 0, -304, -304, -304, + -304, -304, -304, -304, -304, -304, -304, 0, -226, 0, + 0, -304, -304, -304, -304, -304, -226, -226, -226, -304, + -304, 0, -226, -226, 0, -226, 0, 0, 0, 0, + 0, 0, 0, 0, -274, 0, 0, 0, 0, 0, + 0, 0, -226, -226, 0, -226, -226, -226, -226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, -223, -223, -223, -223, -223, -223, -223, -223, -223, - -223, -223, -223, -223, 0, 0, -223, -223, -223, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, -223, - 0, -223, -223, -223, -223, -223, -223, -223, -223, -223, - -223, 0, 0, 0, 0, -223, -223, -223, 0, -223, - 0, 0, 0, -223, -223, 2, 0, 3, 4, 5, - 6, 7, -4, -4, -4, 8, 9, 0, 0, -4, - 10, 0, 11, 12, 13, 14, 15, 16, 17, 0, - 0, 18, 19, 20, 21, 22, 23, 24, 0, 0, - 25, 0, 0, 0, 0, 26, 27, 28, 29, 30, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 49, 0, 0, 50, - 51, 52, 53, 0, 54, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 55, 56, - 0, 0, 0, 2, 0, 3, 4, 5, 6, 7, - -4, -4, -4, 8, 9, 0, -4, -4, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 18, - 19, 20, 21, 22, 23, 24, 0, 0, 25, 0, - 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 0, -226, -226, -226, -226, -226, -226, -226, -226, + -226, -226, -226, -226, -226, 0, 0, -226, -226, -226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 50, 51, 52, - 53, 0, 54, 0, 2, 0, 3, 4, 5, 6, - 7, 0, 0, -4, 8, 9, 55, 56, -4, 10, - -4, 11, 12, 13, 14, 15, 16, 17, -4, -4, + -226, 0, -226, -226, -226, -226, -226, -226, -226, -226, + -226, -226, 0, 0, 0, 0, -226, -226, -226, 0, + -226, 0, 0, 0, -226, -226, 2, 0, 3, 4, + 5, 6, 7, -4, -4, -4, 8, 9, 0, 0, + -4, 10, 0, 11, 12, 13, 14, 15, 16, 17, + 0, 0, 18, 19, 20, 21, 22, 23, 24, 0, + 0, 25, 0, 0, 0, 0, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, + 50, 51, 52, 53, 0, 54, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, + 56, 0, 0, 0, 2, 0, 3, 4, 5, 6, + 7, -4, -4, -4, 8, 9, 0, -4, -4, 10, + 0, 11, 12, 13, 14, 15, 16, 17, 0, 0, 18, 19, 20, 21, 22, 23, 24, 0, 0, 25, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, @@ -945,7 +927,7 @@ static const short yytable[] = { 68, 0, 0, 0, 0, 0, 49, 0, 0, 50, 51, 52, 53, 0, 54, 0, 2, 0, 3, 4, 5, 6, 7, 0, 0, -4, 8, 9, 55, 56, -4, - 10, 0, 11, 12, 13, 14, 15, 16, 17, -4, + 10, -4, 11, 12, 13, 14, 15, 16, 17, -4, -4, 18, 19, 20, 21, 22, 23, 24, 0, 0, 25, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, @@ -953,8 +935,8 @@ static const short yytable[] = { 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 50, 51, 52, 53, 0, 54, 0, 2, 0, 3, 4, - 5, 6, 7, 0, -4, -4, 8, 9, 55, 56, - 0, 10, 0, 11, 12, 13, 14, 15, 16, 17, + 5, 6, 7, 0, 0, -4, 8, 9, 55, 56, + -4, 10, 0, 11, 12, 13, 14, 15, 16, 17, -4, -4, 18, 19, 20, 21, 22, 23, 24, 0, 0, 25, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, @@ -962,8 +944,8 @@ static const short yytable[] = { 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 50, 51, 52, 53, 0, 54, 0, 2, 0, 3, - 4, 5, 6, 7, 0, 0, 0, 8, 9, 55, - 56, 0, 10, -4, 11, 12, 13, 14, 15, 16, + 4, 5, 6, 7, 0, -4, -4, 8, 9, 55, + 56, 0, 10, 0, 11, 12, 13, 14, 15, 16, 17, -4, -4, 18, 19, 20, 21, 22, 23, 24, 0, 0, 25, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, @@ -972,47 +954,47 @@ static const short yytable[] = { 68, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 50, 51, 52, 53, 0, 54, 0, 2, 0, 3, 4, 5, 6, 7, 0, 0, 0, 8, 9, - 55, 56, 0, 10, 0, 11, 12, 13, 14, 15, + 55, 56, 0, 10, -4, 11, 12, 13, 14, 15, 16, 17, -4, -4, 18, 19, 20, 21, 22, 23, 24, 0, 0, 25, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, - 0, 0, 223, 51, 52, 53, 0, 54, 0, 0, + 0, 0, 50, 51, 52, 53, 0, 54, 0, 2, + 0, 3, 4, 5, 6, 7, 0, 0, 0, 8, + 9, 55, 56, 0, 10, 0, 11, 12, 13, 14, + 15, 16, 17, -4, -4, 18, 19, 20, 21, 22, + 23, 24, 0, 0, 25, 0, 0, 0, 0, 26, + 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 55, 56, 0, 0, 0, 2, -4, 3, 4, - 5, 6, 7, -4, -4, 0, 8, 9, 0, 0, - 0, 10, 0, 11, 12, 13, 14, 15, 16, 17, - 0, 0, 18, 19, 20, 21, 22, 23, 24, 0, - 0, 25, 0, 0, 0, 0, 26, 27, 28, 29, - 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, 46, 47, 48, 0, + 49, 0, 0, 223, 51, 52, 53, 0, 54, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, - 50, 51, 52, 53, 0, 54, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 55, - 56, 0, 0, 0, 2, -4, 3, 4, 5, 6, - 7, -4, -4, 0, 8, 9, 0, 0, 0, 10, - 0, 11, 12, 13, 14, 15, 16, 17, 0, 0, - 18, 19, 20, 21, 22, 23, 24, 0, 0, 25, - 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, + 0, 0, 55, 56, 0, 0, 0, 2, -4, 3, + 4, 5, 6, 7, -4, -4, 0, 8, 9, 0, + 0, 0, 10, 0, 11, 12, 13, 14, 15, 16, + 17, 0, 0, 18, 19, 20, 21, 22, 23, 24, + 0, 0, 25, 0, 0, 0, 0, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 49, 0, 0, 50, 51, - 52, 53, 0, 54, 0, 2, 0, 3, 4, 5, - 6, 7, 0, 0, -4, 8, 9, 55, 56, 0, - 10, -4, 11, 12, 13, 14, 15, 16, 17, -4, - -4, 18, 19, 20, 21, 22, 23, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, + 0, 50, 51, 52, 53, 0, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 56, 0, 0, 0, 2, -4, 3, 4, 5, + 6, 7, -4, -4, 0, 8, 9, 0, 0, 0, + 10, 0, 11, 12, 13, 14, 15, 16, 17, 0, + 0, 18, 19, 20, 21, 22, 23, 24, 0, 0, 25, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 50, - 51, 52, 53, 0, 54, 0, 0, 0, 3, 4, - 5, 6, 7, 0, 0, 0, 8, 9, 55, 56, - 0, 10, 0, 11, 12, 13, 14, 15, 16, 17, + 51, 52, 53, 0, 54, 0, 2, 0, 3, 4, + 5, 6, 7, 0, 0, -4, 8, 9, 55, 56, + 0, 10, -4, 11, 12, 13, 14, 15, 16, 17, -4, -4, 18, 19, 20, 21, 22, 23, 24, 0, 0, 25, 0, 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, @@ -1020,45 +1002,66 @@ static const short yytable[] = { 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 50, 51, 52, 53, 0, 54, 0, 0, 0, 3, - 4, 5, 0, 7, 0, 0, 0, 8, 9, 55, + 4, 5, 6, 7, 0, 0, 0, 8, 9, 55, 56, 0, 10, 0, 11, 12, 13, 14, 15, 16, - 17, 0, 362, 181, 182, 20, 21, 22, 23, 24, + 17, -4, -4, 18, 19, 20, 21, 22, 23, 24, + 0, 0, 25, 0, 0, 0, 0, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, + 0, 50, 51, 52, 53, 0, 54, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 55, 56, 0, 0, 83, 84, 85, 86, 87, 88, + 89, 90, 0, 362, 91, 92, 93, 94, 95, 0, + 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, + 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, + 34, 35, 125, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 126, 127, 128, 129, 130, 131, 0, + 132, 133, 0, 0, 134, 0, 135, 0, 136, 137, + 138, 139, 0, 0, 0, 0, 0, 0, 0, 140, + 0, 0, 0, 0, 0, 141, 142, 143, 144, 145, + 146, 147, 148, 149, 150, 0, 151, 0, 0, 3, + 4, 5, 0, 7, 0, 152, 153, 8, 9, 0, + 0, 0, 10, 0, 11, 12, 13, 14, 15, 16, + 17, 0, 0, 181, 182, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, - 0, 192, 51, 52, 193, 194, 54, 0, 0, -343, - -343, -343, 0, -343, 0, 0, 0, -343, -343, 0, - 195, 56, -343, 289, -343, -343, -343, -343, -343, -343, - -343, 295, 0, -343, -343, -343, -343, -343, -343, -343, - 0, 0, 0, 0, 0, 0, 0, 0, -343, 0, - 0, -343, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, + 0, 192, 51, 52, 193, 194, 54, 0, 0, -346, + -346, -346, 0, -346, 0, 0, 0, -346, -346, 0, + 195, 56, -346, 289, -346, -346, -346, -346, -346, -346, + -346, 295, 0, -346, -346, -346, -346, -346, -346, -346, + 0, 0, 0, 0, 0, 0, 0, 0, -346, 0, + 0, -346, -346, -346, -346, -346, -346, -346, -346, -346, + -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -343, 0, - 0, -343, -343, -343, -343, -343, -343, 0, 0, -345, - -345, -345, 0, -345, 0, 0, 0, -345, -345, 0, - -343, -343, -345, -343, -345, -345, -345, -345, -345, -345, - -345, -343, 0, -345, -345, -345, -345, -345, -345, -345, - 0, 0, 0, 0, 0, 0, 0, 0, -345, 0, - 0, -345, -345, -345, -345, -345, -345, -345, -345, -345, - -345, -345, -345, -345, -345, -345, -345, -345, -345, -345, + 0, 0, 0, 0, 0, 0, 0, 0, -346, 0, + 0, -346, -346, -346, -346, -346, -346, 0, 0, -348, + -348, -348, 0, -348, 0, 0, 0, -348, -348, 0, + -346, -346, -348, -346, -348, -348, -348, -348, -348, -348, + -348, -346, 0, -348, -348, -348, -348, -348, -348, -348, + 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, + 0, -348, -348, -348, -348, -348, -348, -348, -348, -348, + -348, -348, -348, -348, -348, -348, -348, -348, -348, -348, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -345, 0, - 0, -345, -345, -345, -345, -345, -345, 0, 0, -344, - -344, -344, 0, -344, 0, 0, 0, -344, -344, 0, - -345, -345, -344, -345, -344, -344, -344, -344, -344, -344, - -344, -345, 0, -344, -344, -344, -344, -344, -344, -344, - 0, 0, 0, 0, 0, 0, 0, 0, -344, 0, - 0, -344, -344, -344, -344, -344, -344, -344, -344, -344, - -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, + 0, 0, 0, 0, 0, 0, 0, 0, -348, 0, + 0, -348, -348, -348, -348, -348, -348, 0, 0, -347, + -347, -347, 0, -347, 0, 0, 0, -347, -347, 0, + -348, -348, -347, -348, -347, -347, -347, -347, -347, -347, + -347, -348, 0, -347, -347, -347, -347, -347, -347, -347, + 0, 0, 0, 0, 0, 0, 0, 0, -347, 0, + 0, -347, -347, -347, -347, -347, -347, -347, -347, -347, + -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -344, 0, - 0, -344, -344, -344, -344, -344, -344, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, -347, 0, + 0, -347, -347, -347, -347, -347, -347, 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, 8, 9, 0, - -344, -344, 10, -344, 11, 12, 13, 14, 15, 16, - 17, -344, 0, 181, 182, 20, 21, 22, 23, 24, + -347, -347, 10, -347, 11, 12, 13, 14, 15, 16, + 17, -347, 0, 181, 182, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, @@ -1082,28 +1085,28 @@ static const short yytable[] = { 68, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, - 0, 192, 51, 52, 193, 194, 54, 0, 0, -343, - -343, -343, 0, -343, 0, 0, 0, -343, -343, 0, - 195, 56, -343, 0, -343, -343, -343, -343, -343, -343, - -343, 210, 0, -343, -343, -343, -343, -343, -343, -343, - 0, 0, 0, 0, 0, 0, 0, 0, -343, 0, - 0, -343, -343, -343, -343, -343, -343, -343, -343, -343, - -343, -343, -343, -343, -343, -343, -343, -343, -343, -343, + 0, 192, 51, 52, 193, 194, 54, 0, 0, -346, + -346, -346, 0, -346, 0, 0, 0, -346, -346, 0, + 195, 56, -346, 0, -346, -346, -346, -346, -346, -346, + -346, 210, 0, -346, -346, -346, -346, -346, -346, -346, + 0, 0, 0, 0, 0, 0, 0, 0, -346, 0, + 0, -346, -346, -346, -346, -346, -346, -346, -346, -346, + -346, -346, -346, -346, -346, -346, -346, -346, -346, -346, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -343, 0, - 0, -343, -343, -343, -343, -343, -343, 0, 0, -344, - -344, -344, 0, -344, 0, 0, 0, -344, -344, 0, - -343, -343, -344, 0, -344, -344, -344, -344, -344, -344, - -344, -343, 0, -344, -344, -344, -344, -344, -344, -344, - 0, 0, 0, 0, 0, 0, 0, 0, -344, 0, - 0, -344, -344, -344, -344, -344, -344, -344, -344, -344, - -344, -344, -344, -344, -344, -344, -344, -344, -344, -344, + 0, 0, 0, 0, 0, 0, 0, 0, -346, 0, + 0, -346, -346, -346, -346, -346, -346, 0, 0, -347, + -347, -347, 0, -347, 0, 0, 0, -347, -347, 0, + -346, -346, -347, 0, -347, -347, -347, -347, -347, -347, + -347, -346, 0, -347, -347, -347, -347, -347, -347, -347, + 0, 0, 0, 0, 0, 0, 0, 0, -347, 0, + 0, -347, -347, -347, -347, -347, -347, -347, -347, -347, + -347, -347, -347, -347, -347, -347, -347, -347, -347, -347, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, -344, 0, - 0, -344, -344, -344, -344, -344, -344, 0, 0, 3, + 0, 0, 0, 0, 0, 0, 0, 0, -347, 0, + 0, -347, -347, -347, -347, -347, -347, 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, 8, 9, 0, - -344, -344, 10, 0, 11, 12, 13, 14, 15, 16, - 17, -344, 0, 181, 182, 20, 21, 22, 23, 24, + -347, -347, 10, 0, 11, 12, 13, 14, 15, 16, + 17, -347, 0, 181, 182, 20, 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, @@ -1122,453 +1125,434 @@ static const short yytable[] = { 68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 195, 56, 83, 84, 85, 86, 87, 88, 89, 90, 0, 491, 91, 92, 93, 94, 95, 0, 0, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, - 117, 118, 119, 120, 121, 122, 123, 124, 34, 35, - 125, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 97, 98, 99, 100, 101, 102, 103, 104, 105, 160, + 161, 162, 163, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 164, 165, 166, 124, 234, 235, + 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 127, 128, 129, 130, 131, 0, 132, 133, 0, 0, 134, 0, 135, 0, 136, 137, 138, 139, - 0, 0, 0, 0, 140, 0, 0, 141, 0, 0, - 0, 0, 0, 142, 143, 144, 145, 146, 147, 148, - 149, 150, 151, 0, 152, 83, 84, 85, 86, 87, - 88, 89, 90, 153, 0, 91, 92, 93, 94, 95, + 0, 0, 0, 0, 0, 0, 0, 140, 0, 0, + 0, 0, 0, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 0, 151, 83, 84, 85, 86, 87, + 88, 89, 90, 152, 0, 91, 92, 93, 94, 95, 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 160, 161, 162, 163, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 164, 165, 166, - 124, 234, 235, 167, 0, 0, 0, 0, 0, 0, + 124, 213, 0, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 127, 128, 129, 130, 131, 0, 132, 133, 0, 0, 134, 0, 135, 0, 136, 137, 138, 139, 0, 0, 0, 0, 0, 0, 0, - 141, 0, 0, 0, 0, 0, 142, 143, 144, 145, - 146, 147, 148, 149, 150, 151, 0, 152, 83, 84, - 85, 86, 87, 88, 89, 90, 153, 0, 91, 92, + 140, 0, 0, 0, 0, 0, 141, 142, 143, 144, + 145, 146, 147, 148, 149, 150, 0, 151, 83, 84, + 85, 86, 87, 88, 89, 90, 152, 0, 91, 92, 93, 94, 95, 0, 0, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 160, 161, 162, 163, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 164, 165, 166, 124, 213, 0, 167, 0, 0, 0, + 164, 165, 166, 124, 0, 0, 167, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 126, 127, 128, 129, 130, 131, 0, 132, 133, 0, 0, 134, 0, 135, 0, 136, 137, 138, 139, 0, 0, 0, 0, - 0, 0, 0, 141, 0, 0, 0, 0, 0, 142, - 143, 144, 145, 146, 147, 148, 149, 150, 151, 0, - 152, 83, 84, 85, 86, 87, 88, 89, 90, 153, - 0, 91, 92, 93, 94, 95, 0, 0, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 160, 161, - 162, 163, 110, 111, 112, 113, 114, 115, 116, 117, - 118, 119, 120, 164, 165, 166, 124, 0, 0, 167, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 126, 127, 128, 129, 130, 131, 0, 132, 133, 0, - 0, 134, 0, 135, 0, 136, 137, 138, 139, 0, - 0, 0, 0, 0, 0, 0, 141, 0, 0, 0, - 0, 0, 142, 143, 144, 145, 146, 147, 148, 149, - 150, 151, 0, 152, 0, 3, 4, 5, 0, 7, - 0, 0, 153, 8, 9, 0, 0, 0, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 20, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 0, 0, 140, 0, 0, 0, 0, 0, 141, + 142, 143, 144, 145, 146, 147, 148, 149, 150, 0, + 151, 0, 3, 4, 5, 0, 7, 0, 0, 152, + 8, 9, 0, 0, 0, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 20, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 193, 194, 54, 0, 0, 0, 0, 0, 0, 0, - 3, 4, 5, 0, 7, 0, 195, 56, 8, 9, - 0, 0, 329, 10, 0, 11, 12, 13, 14, 15, - 16, 17, 0, 0, 181, 182, 20, 21, 22, 23, - 24, 0, 0, 0, 0, 0, 0, 0, 0, 27, - 0, 0, 30, 31, 171, 172, 34, 35, 173, 37, - 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, - 0, 0, 192, 51, 52, 193, 194, 54, 0, 0, - 0, 0, 0, 0, 0, 3, 4, 5, 6, 7, - 0, 195, 56, 8, 9, 0, 0, 338, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 18, - 19, 20, 21, 22, 23, 24, 0, 0, 25, 0, - 0, 0, 0, 26, 27, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 193, 194, 54, + 0, 0, 0, 0, 0, 0, 0, 3, 4, 5, + 0, 7, 0, 195, 56, 8, 9, 0, 0, 329, + 10, 0, 11, 12, 13, 14, 15, 16, 17, 0, + 0, 181, 182, 20, 21, 22, 23, 24, 0, 0, + 0, 0, 0, 0, 0, 0, 27, 0, 0, 30, + 31, 171, 172, 34, 35, 173, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 50, 51, 52, - 53, 0, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 55, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 18, - 19, 20, 21, 22, 23, 24, 0, 0, 25, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 49, 0, 0, 192, + 51, 52, 193, 194, 54, 0, 0, 0, 0, 0, + 0, 0, 3, 4, 5, 6, 7, 0, 195, 56, + 8, 9, 0, 0, 338, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 18, 19, 20, 21, + 22, 23, 24, 0, 0, 25, 0, 0, 0, 0, + 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 50, 51, 52, - 53, 0, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 55, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 20, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 50, 51, 52, 53, 0, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 55, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 18, 19, 20, 21, + 22, 23, 24, 0, 0, 25, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 193, 194, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 195, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 183, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 50, 51, 52, 53, 0, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 55, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 20, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 460, 194, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 195, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 183, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 193, 194, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 195, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 183, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 466, 194, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 195, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 183, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 460, 194, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 195, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 183, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 582, 194, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 195, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 183, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 466, 194, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 195, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 183, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 370, 0, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 195, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 183, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 582, 194, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 195, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 183, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 444, 0, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 195, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 183, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 370, 0, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 195, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 183, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 543, 0, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 195, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 183, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 444, 0, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 195, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 183, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 578, 0, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 195, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 183, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 543, 0, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 195, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 183, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 0, 0, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 195, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 20, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 27, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 47, 48, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 578, 0, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 195, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 183, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 192, 51, 52, - 0, 0, 54, 0, 0, 3, 4, 5, 0, 7, - 0, 0, 0, 8, 9, 0, 195, 56, 10, 0, - 11, 12, 13, 14, 15, 16, 17, 0, 0, 181, - 182, 183, 21, 22, 23, 24, 0, 0, 0, 0, - 0, 0, 0, 0, 184, 0, 0, 30, 31, 171, - 172, 34, 35, 173, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 0, 0, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 195, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 20, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 27, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 47, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 49, 0, 0, 50, 51, 52, - 53, 0, 54, 3, 4, 5, 0, 7, 554, 0, - 0, 8, 9, 0, 0, 0, 10, 0, 11, 12, - 13, 14, 15, 16, 17, 0, 0, 181, 182, 183, - 21, 22, 23, 24, 0, 0, 0, 0, 0, 0, - 0, 0, 184, 0, 0, 30, 31, 171, 172, 34, - 35, 173, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 49, 0, 0, 192, 51, 52, 0, 0, 54, + 0, 0, 3, 4, 5, 0, 7, 0, 0, 0, + 8, 9, 0, 195, 56, 10, 0, 11, 12, 13, + 14, 15, 16, 17, 0, 0, 181, 182, 183, 21, + 22, 23, 24, 0, 0, 0, 0, 0, 0, 0, + 0, 184, 0, 0, 30, 31, 171, 172, 34, 35, + 173, 37, 38, 39, 40, 41, 42, 43, 44, 45, + 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 49, 0, 0, 50, 51, 52, 53, 0, - 54, 3, 4, 5, 0, 7, 0, 0, 0, 8, - 9, 0, 0, 0, 10, 0, 11, 12, 13, 14, - 15, 16, 17, 0, 0, 181, 182, 183, 21, 22, - 23, 24, 0, 0, 0, 0, 0, 0, 0, 0, - 184, 0, 0, 30, 31, 171, 172, 34, 35, 173, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + 0, 49, 0, 0, 50, 51, 52, 53, 0, 54, + 3, 4, 5, 0, 7, 554, 0, 0, 8, 9, + 0, 0, 0, 10, 0, 11, 12, 13, 14, 15, + 16, 17, 0, 0, 181, 182, 183, 21, 22, 23, + 24, 0, 0, 0, 0, 0, 0, 0, 0, 184, + 0, 0, 30, 31, 171, 172, 34, 35, 173, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, + 0, 0, 50, 51, 52, 53, 0, 54, 3, 4, + 5, 0, 7, 0, 0, 0, 8, 9, 0, 0, + 0, 10, 0, 11, 12, 13, 14, 15, 16, 17, + 0, 0, 181, 182, 183, 21, 22, 23, 24, 0, + 0, 0, 0, 0, 0, 0, 0, 184, 0, 0, + 30, 31, 171, 172, 34, 35, 173, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 49, 0, 0, 254, 51, 52, 255, 0, 54, 3, - 4, 5, 0, 7, 0, 0, 0, 8, 9, 0, - 0, 0, 10, 0, 11, 12, 13, 14, 15, 16, - 17, 0, 0, 181, 182, 183, 21, 22, 23, 24, - 0, 0, 0, 0, 0, 0, 0, 0, 184, 0, - 0, 30, 31, 171, 172, 34, 35, 173, 37, 38, - 39, 40, 41, 42, 43, 44, 45, 46, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, + 254, 51, 52, 255, 0, 54, 3, 4, 5, 0, + 7, 0, 0, 0, 8, 9, 0, 0, 0, 10, + 0, 11, 12, 13, 14, 15, 16, 17, 0, 0, + 181, 182, 183, 21, 22, 23, 24, 0, 0, 0, + 0, 0, 0, 0, 0, 184, 0, 0, 30, 31, + 171, 172, 34, 35, 173, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, - 0, 254, 51, 52, 482, 0, 54, 3, 4, 5, - 0, 7, 0, 0, 0, 8, 9, 0, 0, 0, - 10, 0, 11, 12, 13, 14, 15, 16, 17, 0, - 0, 181, 182, 183, 21, 22, 23, 24, 0, 0, - 0, 0, 0, 0, 0, 0, 184, 0, 0, 30, - 31, 171, 172, 34, 35, 173, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 46, 0, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, - 0, 0, 271, 272, 0, 0, 49, 0, 0, 192, - 51, 52, 0, 0, 54, 273, 0, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 258, 259, 260, - 261, 262, 263, 264, 265, 266, 267, 268,-32768,-32768, - 0, 0, 271, 272, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283, 258, 259, 260, - 261, 262, 263, 264, 265, 0, 267, 268, 0, 0, - 0, 0, 271, 272, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 274, 275, 276, - 277, 278, 279, 280, 281, 282, 283 + 0, 0, 0, 0, 0, 49, 0, 0, 254, 51, + 52, 482, 0, 54, 3, 4, 5, 0, 7, 0, + 0, 0, 8, 9, 0, 0, 0, 10, 0, 11, + 12, 13, 14, 15, 16, 17, 0, 0, 181, 182, + 183, 21, 22, 23, 24, 0, 0, 0, 0, 0, + 0, 0, 0, 184, 0, 0, 30, 31, 171, 172, + 34, 35, 173, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 0, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 0, 0, 271, + 272, 0, 0, 49, 331, 0, 192, 51, 52, 0, + 0, 54, 273, 0, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 0, 0, 271, + 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 273, 484, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268, 269, 270, 0, 0, 271, + 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 273, 0, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 258, 259, 260, 261, 262, 263, + 264, 265, 266, 267, 268,-32768,-32768, 0, 0, 271, + 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 258, 259, 260, 261, 262, 263, + 264, 265, 0, 267, 268, 0, 0, 0, 0, 271, + 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 258,-32768,-32768,-32768,-32768, 263, + 264, 0, 0,-32768,-32768, 0, 0, 0, 0, 271, + 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283, 258, 259, 260, 261, 262, 263, + 264, 0, 0, 267, 268, 0, 0, 0, 0, 271, + 272, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 274, 275, 276, 277, 278, 279, + 280, 281, 282, 283 }; static const short yycheck[] = { 1, - 2, 58, 13, 177, 206, 7, 8, 9, 10, 11, - 12, 13, 6, 210, 184, 65, 18, 19, 20, 52, - 180, 311, 50, 25, 81, 18, 19, 20, 13, 76, - 305, 332, 26, 2, 336, 336, 19, 13, 51, 52, - 26, 1, 432, 433, 47, 13, 26, 26, 50, 4, - 512, 53, 514, 55, 34, 35, 34, 35, 360, 47, - 54, 34, 35, 65, 34, 35, 34, 35, 53, 514, - 116, 81, 47, 223, 76, 47, 47, 325, 80, 51, - 81, 81, 81, 76, 49, 88, 89, 335, 111, 107, - 116, 117, 81, 116, 49, 60, 61, 115, 295, 109, - 88, 89, 8, 9, 254, 11, 12, 79, 109, 109, - 109, 112, 115, 88, 89, 1, 2, 88, 89, 25, - 109, 7, 179, 180, 10, 327, 34, 35, 107, 64, - 116, 117, 110, 595, 304, 95, 116, 117, 140, 72, - 116, 117, 81, 116, 191, 107, 116, 117, 116, 117, - 595, 81, 427, 443, 91, 456, 116, 117, 81, 81, - 81, 26, 64, 96, 50, 81, 101, 102, 103, 111, - 109, 341, 26, 112, 80, 565, 566, 79, 80, 109, - 570, 47, 112, 81, 111, 51, 109, 109, 109, 112, - 192, 112, 64, 109, 196, 223, 98, 99, 100, 101, - 102, 103, 111, 196, 83, 81, 208, 116, 210, 107, - 81, 109, 91, 196, 112, 208, 218, 115, 608, 8, - 15, 223, 17, 81, 107, 208, 254, 99, 100, 101, - 102, 103, 111, 109, 140, 537, 537, 17, 109, 252, - 81, 298, 299, 245, 246, 247, 248, 249, 250, 251, - 83, 109, 254, 255, 112, 81, 1, 2, 91, 14, - 15, 463, 7, 8, 9, 10, 11, 12, 109, 115, - 255, 112, 446, 18, 19, 20, 245, 437, 111, 83, - 25, 47, 48, 109, 286, 51, 115, 91, 485, 579, - 83, 115, 83, 295, 491, 455, 571, 310, 91, 332, - 91, 303, 111, 316, 83, 50, 192, 111, 83, 25, - 55, 313, 91, 315, 83, 111, 91, 319, 111, 321, - 83, 111, 91, 325, 326, 375, 47, 48, 91, 115, - 51, 76, 218, 335, 536, 80, 107, 223, 540, 509, - 246, 247, 248, 249, 250, 251, 348, 64, 230, 64, - 232, 345, 47, 48, 64, 113, 51, 47, 48, 245, - 110, 51, 110, 111, 79, 80, 110, 110, 254, 79, - 80, 108, 429, 375, 37, 38, 39, 40, 111, 15, - 437, 96, 97, 98, 99, 100, 101, 102, 103, 99, - 100, 101, 102, 103, 13, 140, 10, 110, 455, 110, - 10, 575, 110, 405, 108, 607, 408, 110, 113, 111, - 111, 110, 405, 110, 110, 408, 91, 303, 420, 421, - 326, 47, 47, 111, 111, 111, 428, 313, 111, 315, - 9, 111, 10, 319, 10, 321, 115, 439, 115, 113, - 89, 435, 436, 111, 113, 502, 108, 192, 10, 10, - 89, 196, 10, 10, 10, 110, 110, 10, 96, 10, - 108, 111, 348, 208, 110, 210, 10, 10, 0, 0, - 610, 473, 412, 218, 495, 579, 572, 5, 223, 1, - 482, 571, 427, 485, 495, 7, -1, 512, 10, 491, - -1, -1, -1, 495, 496, 497, -1, 482, -1, 501, - 245, 246, 247, 248, 249, 250, 251, -1, -1, 254, - 495, -1, -1, -1, 420, -1, -1, -1, 520, -1, - -1, 523, -1, 525, -1, -1, -1, -1, -1, 531, - -1, -1, -1, 535, -1, 421, -1, -1, -1, 284, - 285, 286, 428, -1, -1, -1, -1, -1, -1, -1, - 295, -1, -1, 439, -1, -1, -1, -1, 303, -1, - -1, -1, -1, -1, -1, -1, -1, 473, 313, -1, - 315, -1, -1, -1, 319, -1, 321, -1, 323, 324, - 325, 326, -1, -1, -1, -1, -1, -1, -1, 334, - 335, -1, -1, -1, -1, -1, -1, 599, -1, 601, - -1, -1, -1, 348, -1, 350, -1, -1, -1, -1, - 496, 497, -1, -1, -1, 501, 1, 2, -1, 525, - 5, -1, 7, 8, 9, 10, 11, 12, 13, -1, - -1, -1, -1, -1, 520, -1, -1, 523, -1, -1, - 25, -1, -1, -1, -1, 531, -1, -1, -1, 535, + 2, 6, 184, 13, 206, 7, 8, 9, 10, 11, + 12, 13, 65, 180, 177, 13, 18, 19, 20, 210, + 305, 26, 52, 25, 311, 50, 8, 9, 76, 11, + 12, 58, 2, 18, 19, 20, 332, 336, 51, 52, + 336, 19, 13, 25, 432, 433, 34, 35, 50, 54, + 1, 53, 26, 55, 81, 53, 4, 64, 13, 34, + 35, 360, 116, 65, 47, 107, 47, 26, 34, 35, + 47, 223, 81, 26, 76, 34, 35, 64, 80, 34, + 35, 81, 47, 111, 512, 47, 514, 514, 116, 51, + 81, 76, 99, 100, 101, 102, 103, 15, 80, 17, + 109, 49, 254, 112, 295, 88, 89, 88, 89, 109, + 325, 88, 89, 26, 101, 102, 103, 79, 109, 83, + 335, 112, 304, 88, 89, 327, 83, 91, 116, 117, + 1, 2, 115, 107, 91, 110, 7, 8, 9, 10, + 11, 12, 427, 191, 95, 116, 117, 18, 19, 20, + 116, 153, 179, 180, 25, 81, 443, 116, 117, 341, + 456, 116, 117, 116, 117, 116, 117, 595, 595, 72, + 111, 153, 81, 81, 81, 116, 91, 565, 566, 50, + 107, 107, 570, 109, 55, 26, 112, 83, 115, 115, + 192, 81, 111, 96, 196, 91, 81, 64, 223, 83, + 109, 109, 109, 112, 112, 76, 208, 91, 210, 80, + 47, 196, 79, 80, 51, 111, 218, 83, 196, 109, + 608, 223, 112, 208, 109, 91, 81, 112, 81, 254, + 208, 98, 99, 100, 101, 102, 103, 111, 537, 252, + 230, 537, 232, 245, 246, 247, 248, 249, 250, 251, + 83, 8, 254, 255, 109, 107, 109, 255, 91, 112, + 111, 463, 81, 81, 246, 247, 248, 249, 250, 251, + 437, 298, 299, 116, 117, 245, 81, 83, 111, 83, + 81, 81, 153, 446, 286, 91, 571, 91, 455, 17, + 109, 109, 579, 295, 485, 47, 48, 310, 83, 51, + 491, 303, 332, 316, 109, 111, 91, 111, 109, 109, + 25, 313, 115, 315, 111, 81, 115, 319, 49, 321, + 115, 192, 375, 325, 326, 196, 64, 509, 111, 60, + 61, 47, 48, 335, 536, 51, 115, 208, 540, 210, + 345, 79, 80, 109, 326, 1, 348, 218, 107, 47, + 48, 7, 223, 51, 10, 34, 35, 64, 96, 97, + 98, 99, 100, 101, 102, 103, 47, 48, 14, 15, + 51, 110, 111, 375, 245, 246, 247, 248, 249, 250, + 251, 110, 15, 254, 110, 110, 113, 1, 2, 108, + 111, 5, 13, 7, 8, 9, 10, 11, 12, 13, + 10, 110, 429, 405, 110, 607, 408, 110, 108, 110, + 437, 25, 575, 284, 285, 286, 111, 111, 420, 421, + 405, 110, 113, 408, 295, 110, 428, 10, 455, 91, + 435, 436, 303, 110, 47, 47, 50, 439, 420, 53, + 111, 111, 313, 111, 315, 111, 9, 111, 319, 10, + 321, 65, 323, 324, 325, 326, 37, 38, 39, 40, + 10, 115, 115, 334, 335, 113, 80, 89, 111, 113, + 108, 473, 10, 10, 89, 502, 10, 348, 10, 350, + 482, 10, 110, 485, 482, 495, 110, 96, 10, 491, + 108, 473, 10, 495, 496, 497, 10, 495, 10, 501, + 111, 0, 110, 1, 2, 0, 610, 412, 579, 7, + 8, 9, 10, 11, 12, 13, 495, 572, 520, 5, + 571, 523, -1, 525, -1, 427, 512, 25, -1, 531, + -1, -1, -1, 535, 405, -1, -1, 408, 64, 153, + -1, -1, -1, 525, -1, -1, -1, -1, -1, 420, + 421, -1, 50, 79, 80, 53, -1, 428, -1, -1, + -1, -1, 218, -1, -1, -1, -1, 65, 439, -1, + -1, -1, -1, 99, 100, 101, 102, 103, 192, -1, + -1, -1, 80, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 599, -1, 601, + -1, -1, 473, -1, 218, -1, -1, -1, -1, 223, + -1, -1, -1, -1, 485, -1, -1, -1, -1, -1, + 491, -1, -1, -1, -1, 496, 497, -1, -1, -1, + 501, 245, 246, 247, 248, 249, 250, 251, -1, -1, + 254, 255, -1, -1, 1, 2, -1, 303, -1, 520, + 7, -1, 523, 10, 525, 153, -1, 313, -1, 315, + 531, -1, -1, 319, 535, 321, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 405, -1, -1, 408, -1, 50, -1, -1, 53, -1, - -1, -1, -1, -1, -1, 420, 421, -1, -1, -1, - 65, -1, -1, 428, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 439, 80, 218, -1, 1, 2, - -1, -1, -1, -1, 7, 8, 9, 10, 11, 12, - 13, -1, -1, 599, -1, 601, -1, -1, -1, -1, - -1, -1, 25, -1, -1, -1, -1, -1, 473, -1, - -1, -1, -1, 64, 65, 66, 67, 68, 69, 70, - 485, -1, 73, 74, -1, -1, 491, 50, 79, 80, - 53, 496, 497, -1, -1, 140, 501, -1, -1, -1, - -1, -1, 65, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, -1, -1, 520, -1, 80, 523, -1, - 525, 303, -1, -1, -1, -1, 531, -1, -1, -1, - 535, 313, -1, 315, -1, -1, -1, 319, -1, 321, - -1, -1, -1, -1, -1, -1, -1, 192, -1, -1, - -1, -1, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, -1, 348, 79, 80, -1, - -1, -1, -1, 218, -1, -1, -1, 140, 223, -1, - 92, -1, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, -1, -1, 599, -1, 601, -1, -1, 111, - 245, 246, 247, 248, 249, 250, 251, -1, -1, 254, - 255, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 192, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 421, - -1, -1, -1, -1, -1, -1, 428, -1, -1, -1, - -1, -1, -1, -1, -1, 218, -1, 439, 303, -1, - 223, -1, -1, -1, -1, -1, -1, -1, 313, -1, - 315, -1, -1, -1, 319, -1, 321, -1, -1, -1, - -1, 326, 245, 246, 247, 248, 249, 250, 251, -1, - -1, 254, 255, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 348, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 496, 497, -1, -1, -1, 501, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 303, + -1, -1, 348, 50, 192, -1, -1, -1, -1, 313, + -1, 315, -1, -1, -1, 319, -1, 321, -1, -1, + -1, -1, 326, -1, -1, -1, -1, -1, -1, -1, + 218, -1, -1, -1, -1, 223, -1, -1, 599, -1, + 601, -1, -1, -1, 348, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 245, 246, 247, + 248, 249, 250, 251, -1, -1, 254, 255, -1, -1, + -1, 375, -1, -1, -1, 421, -1, -1, -1, -1, + -1, -1, 428, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 439, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 375, -1, -1, -1, -1, -1, -1, -1, 520, -1, - 303, 523, -1, -1, -1, -1, -1, -1, -1, 531, - 313, -1, 315, 535, -1, -1, 319, -1, 321, -1, - -1, -1, -1, 326, -1, -1, -1, -1, -1, 18, - 19, 20, -1, -1, -1, 420, 421, -1, -1, -1, - -1, -1, -1, 428, -1, 348, -1, -1, -1, -1, - -1, -1, -1, -1, 439, -1, -1, -1, 47, 48, - -1, -1, 51, 52, -1, -1, 55, 56, -1, -1, - -1, -1, 375, -1, -1, -1, -1, 599, -1, 601, - -1, -1, -1, -1, -1, -1, -1, 76, 473, -1, - -1, -1, -1, -1, -1, -1, -1, 482, -1, -1, + -1, -1, -1, -1, -1, 303, 420, 421, -1, -1, + -1, -1, -1, -1, 428, 313, -1, 315, -1, -1, + -1, 319, -1, 321, -1, 439, -1, -1, 326, -1, + -1, -1, -1, -1, -1, 192, -1, -1, -1, -1, + 496, 497, -1, -1, -1, 501, -1, -1, -1, -1, + 348, -1, -1, -1, -1, -1, -1, -1, -1, 473, + -1, 218, -1, -1, 520, -1, 223, 523, 482, -1, + 18, 19, 20, -1, -1, 531, -1, 375, -1, 535, + -1, 495, 496, 497, -1, -1, -1, 501, 245, -1, + -1, -1, -1, -1, -1, -1, -1, 254, -1, 47, + 48, -1, -1, 51, 52, -1, 520, 55, 56, 523, + -1, 525, -1, -1, -1, -1, -1, 531, -1, -1, + -1, 535, 420, 421, -1, -1, -1, -1, 76, -1, + 428, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 439, -1, 599, -1, 601, 303, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 313, -1, 315, -1, + -1, -1, 319, -1, 321, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, 473, -1, -1, -1, -1, + -1, -1, -1, -1, 482, 599, -1, 601, -1, -1, + -1, 348, -1, -1, -1, -1, -1, 495, 496, 497, + -1, -1, -1, 501, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 495, 496, 497, -1, -1, -1, 501, 420, 421, -1, - -1, -1, -1, -1, -1, 428, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 520, 439, -1, 523, -1, - 525, -1, -1, -1, -1, -1, 531, -1, -1, -1, - 535, -1, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, -1, -1, 79, 80, -1, - 473, -1, 84, -1, -1, -1, -1, -1, -1, 482, - 92, -1, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 495, 496, 497, -1, -1, -1, 501, -1, - -1, -1, -1, -1, 193, 194, 195, 196, -1, -1, - -1, -1, -1, -1, 599, -1, 601, 520, -1, 208, - 523, 210, 525, -1, -1, -1, -1, -1, 531, -1, - -1, -1, 535, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 520, -1, -1, 523, -1, 525, -1, -1, + -1, -1, -1, 531, -1, -1, -1, 535, -1, -1, + -1, -1, -1, -1, -1, 193, 194, 195, 196, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 208, -1, 210, -1, 421, -1, -1, -1, -1, -1, + -1, 428, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 439, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, 252, -1, -1, -1, -1, -1, 258, - 259, 260, 261, 262, 263, 264, 265, 266, 267, 268, - 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, - 279, 280, 281, 282, 283, -1, 599, 286, 601, -1, - -1, -1, -1, -1, 293, 294, 295, -1, -1, -1, + -1, 599, -1, 601, 252, -1, -1, -1, -1, -1, + 258, 259, 260, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 280, 281, 282, 283, -1, -1, 286, 496, + 497, -1, -1, -1, 501, 293, 294, 295, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 310, 520, -1, -1, 523, -1, 316, 8, + 9, -1, 11, 12, 531, -1, -1, 325, 535, 18, + 19, 20, -1, 331, 332, -1, 25, 335, 336, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 347, + -1, -1, -1, -1, -1, -1, 354, -1, -1, -1, + -1, -1, 360, -1, -1, -1, 55, -1, -1, -1, + -1, -1, 370, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 76, -1, -1, + -1, 80, 599, -1, 601, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 405, -1, -1, + 408, -1, -1, -1, -1, 413, 414, -1, -1, 64, + 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, -1, -1, 79, 80, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 444, 92, -1, 94, + 95, 96, 97, 98, 99, 100, 101, 102, 103, -1, + -1, -1, 460, -1, 153, -1, 111, -1, 466, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 310, -1, -1, -1, -1, -1, 316, 8, 9, - -1, 11, 12, -1, -1, -1, 325, -1, 18, 19, - 20, -1, 331, 332, -1, 25, 335, 336, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 347, -1, - -1, -1, -1, -1, -1, 354, -1, -1, -1, -1, - -1, 360, -1, -1, -1, 55, -1, -1, -1, -1, - -1, 370, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 76, -1, -1, -1, - 80, -1, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, -1, 405, 79, 80, 408, - -1, -1, -1, -1, 413, 414, -1, -1, -1, -1, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, -1, -1, -1, -1, -1, -1, 64, 65, - 66, 67, 68, 69, 70, 444, -1, 73, 74, -1, - 140, -1, -1, 79, 80, -1, -1, -1, -1, -1, - -1, 460, -1, -1, -1, -1, -1, 466, 94, 95, - 96, 97, 98, 99, 100, 101, 102, 103, -1, -1, - -1, 480, -1, -1, -1, 484, 485, -1, 487, 488, - 489, 490, 491, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 196, 506, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 208, -1, - 210, -1, 521, -1, -1, -1, -1, -1, -1, -1, - -1, 530, -1, -1, -1, -1, -1, -1, 537, -1, - -1, -1, -1, -1, 543, -1, -1, -1, -1, -1, - -1, -1, -1, 552, 553, -1, 246, 247, 248, 249, - 250, 251, -1, -1, -1, -1, -1, -1, -1, -1, - 0, 1, -1, 3, 4, 5, 6, 7, -1, 578, - -1, 11, 12, 582, -1, -1, 16, -1, 18, 19, - 20, 21, 22, 23, 24, -1, 286, 27, 28, 29, - 30, 31, 32, 33, -1, 295, 36, -1, -1, -1, - -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, 62, 63, -1, 325, 326, -1, -1, -1, - -1, -1, -1, -1, -1, 335, -1, -1, -1, -1, - -1, -1, 82, -1, -1, 85, 86, 87, 88, -1, - 90, -1, -1, -1, -1, -1, -1, -1, 0, -1, - -1, -1, -1, -1, 104, 105, 8, 9, 10, -1, - -1, -1, 14, 15, -1, 17, 116, 117, -1, -1, + -1, -1, 480, -1, -1, -1, 484, 485, -1, 487, + 488, 489, 490, 491, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 196, 506, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 208, + -1, 210, -1, 521, -1, -1, -1, -1, -1, -1, + -1, -1, 530, -1, -1, -1, -1, -1, -1, 537, + -1, -1, -1, -1, -1, 543, -1, -1, -1, -1, + -1, -1, -1, -1, 552, 553, -1, 246, 247, 248, + 249, 250, 251, -1, -1, -1, -1, -1, -1, -1, + -1, 0, 1, -1, 3, 4, 5, 6, 7, -1, + 578, -1, 11, 12, 582, -1, -1, 16, -1, 18, + 19, 20, 21, 22, 23, 24, -1, 286, 27, 28, + 29, 30, 31, 32, 33, -1, 295, 36, -1, -1, + -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, -1, 325, 326, -1, -1, + -1, -1, -1, -1, -1, -1, 335, -1, -1, -1, + -1, -1, -1, 82, -1, -1, 85, 86, 87, 88, + -1, 90, -1, -1, -1, -1, -1, -1, -1, 0, + -1, -1, -1, -1, -1, 104, 105, 8, 9, 10, + -1, -1, -1, 14, 15, -1, 17, 116, 117, -1, + -1, -1, -1, -1, -1, 26, -1, -1, -1, -1, + -1, -1, -1, 34, 35, -1, 37, 38, 39, 40, + -1, -1, -1, -1, -1, -1, 405, -1, -1, 408, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 420, -1, 64, 65, 66, 67, 68, 69, 70, + 71, 72, 73, 74, 75, 76, -1, -1, 79, 80, + 81, -1, 83, -1, -1, -1, -1, -1, -1, -1, + 91, 92, -1, 94, 95, 96, 97, 98, 99, 100, + 101, 102, 103, -1, -1, -1, -1, 108, 109, 110, + 111, 112, -1, 0, 473, 116, 117, -1, -1, -1, + -1, 8, 9, 10, -1, -1, 485, 14, 15, -1, + 17, -1, 491, -1, -1, -1, -1, -1, -1, 26, + -1, -1, -1, -1, -1, -1, -1, 34, 35, -1, + 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 525, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, + -1, -1, 79, 80, 81, -1, 83, -1, -1, -1, + -1, -1, -1, -1, 91, 92, -1, 94, 95, 96, + 97, 98, 99, 100, 101, 102, 103, -1, 0, -1, + -1, 108, 109, 110, 111, 112, 8, 9, 10, 116, + 117, -1, 14, 15, -1, 17, -1, -1, -1, -1, -1, -1, -1, -1, 26, -1, -1, -1, -1, -1, -1, -1, 34, 35, -1, 37, 38, 39, 40, -1, - -1, -1, -1, -1, -1, 405, -1, -1, 408, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 420, -1, 64, 65, 66, 67, 68, 69, 70, 71, - 72, 73, 74, 75, 76, -1, -1, 79, 80, 81, - -1, 83, -1, -1, -1, -1, -1, -1, -1, 91, - 92, -1, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, -1, -1, -1, -1, 108, 109, 110, 111, - 112, -1, 0, 473, 116, 117, -1, -1, -1, -1, - 8, 9, 10, -1, -1, 485, 14, 15, -1, 17, - -1, 491, -1, -1, -1, -1, -1, -1, 26, -1, - -1, -1, -1, -1, -1, -1, 34, 35, -1, 37, - 38, 39, 40, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 525, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 64, 65, 66, 67, - 68, 69, 70, 71, 72, 73, 74, 75, 76, -1, - -1, 79, 80, 81, -1, 83, -1, -1, -1, -1, - -1, -1, -1, 91, 92, -1, 94, 95, 96, 97, - 98, 99, 100, 101, 102, 103, -1, 0, -1, -1, - 108, 109, 110, 111, 112, 8, 9, 10, 116, 117, - -1, 14, 15, -1, 17, -1, -1, -1, -1, -1, - -1, -1, -1, 26, -1, -1, -1, -1, -1, -1, - -1, 34, 35, -1, 37, 38, 39, 40, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 64, 65, 66, 67, 68, 69, 70, 71, + 72, 73, 74, 75, 76, -1, -1, 79, 80, 81, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 64, 65, 66, 67, 68, 69, 70, 71, 72, - 73, 74, 75, 76, -1, -1, 79, 80, 81, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 92, - -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 103, -1, -1, -1, -1, 108, 109, 110, -1, 112, - -1, -1, -1, 116, 117, 1, -1, 3, 4, 5, - 6, 7, 8, 9, 10, 11, 12, -1, -1, 15, - 16, -1, 18, 19, 20, 21, 22, 23, 24, -1, - -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, - 36, -1, -1, -1, -1, 41, 42, 43, 44, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 82, -1, -1, 85, - 86, 87, 88, -1, 90, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 104, 105, - -1, -1, -1, 1, -1, 3, 4, 5, 6, 7, - 116, 117, 10, 11, 12, -1, 14, 15, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, 36, -1, - -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + 92, -1, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, -1, -1, -1, -1, 108, 109, 110, -1, + 112, -1, -1, -1, 116, 117, 1, -1, 3, 4, + 5, 6, 7, 8, 9, 10, 11, 12, -1, -1, + 15, 16, -1, 18, 19, 20, 21, 22, 23, 24, + -1, -1, 27, 28, 29, 30, 31, 32, 33, -1, + -1, 36, -1, -1, -1, -1, 41, 42, 43, 44, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, -1, 90, -1, 1, -1, 3, 4, 5, 6, - 7, -1, -1, 10, 11, 12, 104, 105, 15, 16, - 17, 18, 19, 20, 21, 22, 23, 24, 116, 117, + -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, + 85, 86, 87, 88, -1, 90, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, + 105, -1, -1, -1, 1, -1, 3, 4, 5, 6, + 7, 116, 117, 10, 11, 12, -1, 14, 15, 16, + -1, 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, 36, -1, -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, @@ -1577,7 +1561,7 @@ static const short yycheck[] = { 1, -1, -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, -1, 1, -1, 3, 4, 5, 6, 7, -1, -1, 10, 11, 12, 104, 105, 15, - 16, -1, 18, 19, 20, 21, 22, 23, 24, 116, + 16, 17, 18, 19, 20, 21, 22, 23, 24, 116, 117, 27, 28, 29, 30, 31, 32, 33, -1, -1, 36, -1, -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, @@ -1585,8 +1569,8 @@ static const short yycheck[] = { 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, -1, 1, -1, 3, 4, - 5, 6, 7, -1, 9, 10, 11, 12, 104, 105, - -1, 16, -1, 18, 19, 20, 21, 22, 23, 24, + 5, 6, 7, -1, -1, 10, 11, 12, 104, 105, + 15, 16, -1, 18, 19, 20, 21, 22, 23, 24, 116, 117, 27, 28, 29, 30, 31, 32, 33, -1, -1, 36, -1, -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, @@ -1594,8 +1578,8 @@ static const short yycheck[] = { 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, -1, 1, -1, 3, - 4, 5, 6, 7, -1, -1, -1, 11, 12, 104, - 105, -1, 16, 17, 18, 19, 20, 21, 22, 23, + 4, 5, 6, 7, -1, 9, 10, 11, 12, 104, + 105, -1, 16, -1, 18, 19, 20, 21, 22, 23, 24, 116, 117, 27, 28, 29, 30, 31, 32, 33, -1, -1, 36, -1, -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, @@ -1604,47 +1588,47 @@ static const short yycheck[] = { 1, -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, -1, 1, -1, 3, 4, 5, 6, 7, -1, -1, -1, 11, 12, - 104, 105, -1, 16, -1, 18, 19, 20, 21, 22, + 104, 105, -1, 16, 17, 18, 19, 20, 21, 22, 23, 24, 116, 117, 27, 28, 29, 30, 31, 32, 33, -1, -1, 36, -1, -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, - -1, -1, 85, 86, 87, 88, -1, 90, -1, -1, + -1, -1, 85, 86, 87, 88, -1, 90, -1, 1, + -1, 3, 4, 5, 6, 7, -1, -1, -1, 11, + 12, 104, 105, -1, 16, -1, 18, 19, 20, 21, + 22, 23, 24, 116, 117, 27, 28, 29, 30, 31, + 32, 33, -1, -1, 36, -1, -1, -1, -1, 41, + 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 104, 105, -1, -1, -1, 1, 110, 3, 4, - 5, 6, 7, 116, 117, -1, 11, 12, -1, -1, - -1, 16, -1, 18, 19, 20, 21, 22, 23, 24, - -1, -1, 27, 28, 29, 30, 31, 32, 33, -1, - -1, 36, -1, -1, -1, -1, 41, 42, 43, 44, - 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, - 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, + 82, -1, -1, 85, 86, 87, 88, -1, 90, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, - 85, 86, 87, 88, -1, 90, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 104, - 105, -1, -1, -1, 1, 110, 3, 4, 5, 6, - 7, 116, 117, -1, 11, 12, -1, -1, -1, 16, - -1, 18, 19, 20, 21, 22, 23, 24, -1, -1, - 27, 28, 29, 30, 31, 32, 33, -1, -1, 36, - -1, -1, -1, -1, 41, 42, 43, 44, 45, 46, - 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, - 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, + -1, -1, 104, 105, -1, -1, -1, 1, 110, 3, + 4, 5, 6, 7, 116, 117, -1, 11, 12, -1, + -1, -1, 16, -1, 18, 19, 20, 21, 22, 23, + 24, -1, -1, 27, 28, 29, 30, 31, 32, 33, + -1, -1, 36, -1, -1, -1, -1, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, 82, -1, -1, 85, 86, - 87, 88, -1, 90, -1, 1, -1, 3, 4, 5, - 6, 7, -1, -1, 10, 11, 12, 104, 105, -1, - 16, 108, 18, 19, 20, 21, 22, 23, 24, 116, - 117, 27, 28, 29, 30, 31, 32, 33, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, + -1, 85, 86, 87, 88, -1, 90, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 104, 105, -1, -1, -1, 1, 110, 3, 4, 5, + 6, 7, 116, 117, -1, 11, 12, -1, -1, -1, + 16, -1, 18, 19, 20, 21, 22, 23, 24, -1, + -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, 36, -1, -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, 85, - 86, 87, 88, -1, 90, -1, -1, -1, 3, 4, - 5, 6, 7, -1, -1, -1, 11, 12, 104, 105, - -1, 16, -1, 18, 19, 20, 21, 22, 23, 24, + 86, 87, 88, -1, 90, -1, 1, -1, 3, 4, + 5, 6, 7, -1, -1, 10, 11, 12, 104, 105, + -1, 16, 108, 18, 19, 20, 21, 22, 23, 24, 116, 117, 27, 28, 29, 30, 31, 32, 33, -1, -1, 36, -1, -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, @@ -1652,9 +1636,30 @@ static const short yycheck[] = { 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, -1, -1, -1, 3, - 4, 5, -1, 7, -1, -1, -1, 11, 12, 104, + 4, 5, 6, 7, -1, -1, -1, 11, 12, 104, 105, -1, 16, -1, 18, 19, 20, 21, 22, 23, - 24, -1, 117, 27, 28, 29, 30, 31, 32, 33, + 24, 116, 117, 27, 28, 29, 30, 31, 32, 33, + -1, -1, 36, -1, -1, -1, -1, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, + 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, + -1, 85, 86, 87, 88, -1, 90, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + 104, 105, -1, -1, 3, 4, 5, 6, 7, 8, + 9, 10, -1, 117, 13, 14, 15, 16, 17, -1, + -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, + 49, 50, 51, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 62, 63, 64, 65, 66, 67, -1, + 69, 70, -1, -1, 73, -1, 75, -1, 77, 78, + 79, 80, -1, -1, -1, -1, -1, -1, -1, 88, + -1, -1, -1, -1, -1, 94, 95, 96, 97, 98, + 99, 100, 101, 102, 103, -1, 105, -1, -1, 3, + 4, 5, -1, 7, -1, 114, 115, 11, 12, -1, + -1, -1, 16, -1, 18, 19, 20, 21, 22, 23, + 24, -1, -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, @@ -1760,14 +1765,14 @@ static const short yycheck[] = { 1, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, 63, 64, 65, 66, 67, -1, 69, 70, -1, -1, 73, -1, 75, -1, 77, 78, 79, 80, - -1, -1, -1, -1, 85, -1, -1, 88, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, -1, -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, -1, 105, 3, 4, 5, 6, 7, 8, 9, 10, 114, -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, -1, -1, -1, -1, -1, -1, + 48, 49, -1, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, 63, 64, 65, 66, 67, -1, 69, 70, -1, -1, 73, -1, 75, -1, 77, 78, 79, 80, -1, -1, -1, -1, -1, -1, -1, @@ -1777,203 +1782,209 @@ static const short yycheck[] = { 1, 15, 16, 17, -1, -1, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 46, 47, 48, 49, -1, 51, -1, -1, -1, + 45, 46, 47, 48, -1, -1, 51, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, 63, 64, 65, 66, 67, -1, 69, 70, -1, -1, 73, -1, 75, -1, 77, 78, 79, 80, -1, -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, -1, -1, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, -1, - 105, 3, 4, 5, 6, 7, 8, 9, 10, 114, - -1, 13, 14, 15, 16, 17, -1, -1, 20, 21, - 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, 45, 46, 47, 48, -1, -1, 51, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 62, 63, 64, 65, 66, 67, -1, 69, 70, -1, - -1, 73, -1, 75, -1, 77, 78, 79, 80, -1, - -1, -1, -1, -1, -1, -1, 88, -1, -1, -1, - -1, -1, 94, 95, 96, 97, 98, 99, 100, 101, - 102, 103, -1, 105, -1, 3, 4, 5, -1, 7, - -1, -1, 114, 11, 12, -1, -1, -1, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + 105, -1, 3, 4, 5, -1, 7, -1, -1, 114, + 11, 12, -1, -1, -1, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, 89, 90, -1, -1, -1, -1, -1, -1, -1, - 3, 4, 5, -1, 7, -1, 104, 105, 11, 12, - -1, -1, 110, 16, -1, 18, 19, 20, 21, 22, - 23, 24, -1, -1, 27, 28, 29, 30, 31, 32, - 33, -1, -1, -1, -1, -1, -1, -1, -1, 42, - -1, -1, 45, 46, 47, 48, 49, 50, 51, 52, - 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, - 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, - -1, -1, 85, 86, 87, 88, 89, 90, -1, -1, - -1, -1, -1, -1, -1, 3, 4, 5, 6, 7, - -1, 104, 105, 11, 12, -1, -1, 110, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, 36, -1, - -1, -1, -1, 41, 42, 43, 44, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, 89, 90, + -1, -1, -1, -1, -1, -1, -1, 3, 4, 5, + -1, 7, -1, 104, 105, 11, 12, -1, -1, 110, + 16, -1, 18, 19, 20, 21, 22, 23, 24, -1, + -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, + -1, -1, -1, -1, -1, -1, 42, -1, -1, 45, + 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, -1, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, 36, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 82, -1, -1, 85, + 86, 87, 88, 89, 90, -1, -1, -1, -1, -1, + -1, -1, 3, 4, 5, 6, 7, -1, 104, 105, + 11, 12, -1, -1, 110, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, 36, -1, -1, -1, -1, + 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, -1, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, 36, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, 89, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, 89, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, 89, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, 89, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, 89, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, 89, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, 89, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, -1, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, 89, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, -1, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, -1, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, -1, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - -1, -1, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, 62, 63, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - -1, -1, 90, -1, -1, 3, 4, 5, -1, 7, - -1, -1, -1, 11, 12, -1, 104, 105, 16, -1, - 18, 19, 20, 21, 22, 23, 24, -1, -1, 27, - 28, 29, 30, 31, 32, 33, -1, -1, -1, -1, - -1, -1, -1, -1, 42, -1, -1, 45, 46, 47, - 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, - 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, -1, -1, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, 62, 63, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, 82, -1, -1, 85, 86, 87, - 88, -1, 90, 3, 4, 5, -1, 7, 96, -1, - -1, 11, 12, -1, -1, -1, 16, -1, 18, 19, - 20, 21, 22, 23, 24, -1, -1, 27, 28, 29, - 30, 31, 32, 33, -1, -1, -1, -1, -1, -1, - -1, -1, 42, -1, -1, 45, 46, 47, 48, 49, - 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, - 60, 61, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 82, -1, -1, 85, 86, 87, -1, -1, 90, + -1, -1, 3, 4, 5, -1, 7, -1, -1, -1, + 11, 12, -1, 104, 105, 16, -1, 18, 19, 20, + 21, 22, 23, 24, -1, -1, 27, 28, 29, 30, + 31, 32, 33, -1, -1, -1, -1, -1, -1, -1, + -1, 42, -1, -1, 45, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, + 61, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 82, -1, -1, 85, 86, 87, 88, -1, - 90, 3, 4, 5, -1, 7, -1, -1, -1, 11, - 12, -1, -1, -1, 16, -1, 18, 19, 20, 21, - 22, 23, 24, -1, -1, 27, 28, 29, 30, 31, - 32, 33, -1, -1, -1, -1, -1, -1, -1, -1, - 42, -1, -1, 45, 46, 47, 48, 49, 50, 51, - 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, + -1, 82, -1, -1, 85, 86, 87, 88, -1, 90, + 3, 4, 5, -1, 7, 96, -1, -1, 11, 12, + -1, -1, -1, 16, -1, 18, 19, 20, 21, 22, + 23, 24, -1, -1, 27, 28, 29, 30, 31, 32, + 33, -1, -1, -1, -1, -1, -1, -1, -1, 42, + -1, -1, 45, 46, 47, 48, 49, 50, 51, 52, + 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 82, + -1, -1, 85, 86, 87, 88, -1, 90, 3, 4, + 5, -1, 7, -1, -1, -1, 11, 12, -1, -1, + -1, 16, -1, 18, 19, 20, 21, 22, 23, 24, + -1, -1, 27, 28, 29, 30, 31, 32, 33, -1, + -1, -1, -1, -1, -1, -1, -1, 42, -1, -1, + 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, + 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 82, -1, -1, 85, 86, 87, 88, -1, 90, 3, - 4, 5, -1, 7, -1, -1, -1, 11, 12, -1, - -1, -1, 16, -1, 18, 19, 20, 21, 22, 23, - 24, -1, -1, 27, 28, 29, 30, 31, 32, 33, - -1, -1, -1, -1, -1, -1, -1, -1, 42, -1, - -1, 45, 46, 47, 48, 49, 50, 51, 52, 53, - 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 82, -1, -1, + 85, 86, 87, 88, -1, 90, 3, 4, 5, -1, + 7, -1, -1, -1, 11, 12, -1, -1, -1, 16, + -1, 18, 19, 20, 21, 22, 23, 24, -1, -1, + 27, 28, 29, 30, 31, 32, 33, -1, -1, -1, + -1, -1, -1, -1, -1, 42, -1, -1, 45, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, + 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 82, -1, - -1, 85, 86, 87, 88, -1, 90, 3, 4, 5, - -1, 7, -1, -1, -1, 11, 12, -1, -1, -1, - 16, -1, 18, 19, 20, 21, 22, 23, 24, -1, - -1, 27, 28, 29, 30, 31, 32, 33, -1, -1, - -1, -1, -1, -1, -1, -1, 42, -1, -1, 45, - 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, - 56, 57, 58, 59, 60, 61, -1, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - -1, -1, 79, 80, -1, -1, 82, -1, -1, 85, - 86, 87, -1, -1, 90, 92, -1, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 64, 65, 66, - 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, - -1, -1, 79, 80, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 64, 65, 66, - 67, 68, 69, 70, 71, -1, 73, 74, -1, -1, - -1, -1, 79, 80, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 94, 95, 96, - 97, 98, 99, 100, 101, 102, 103 + -1, -1, -1, -1, -1, 82, -1, -1, 85, 86, + 87, 88, -1, 90, 3, 4, 5, -1, 7, -1, + -1, -1, 11, 12, -1, -1, -1, 16, -1, 18, + 19, 20, 21, 22, 23, 24, -1, -1, 27, 28, + 29, 30, 31, 32, 33, -1, -1, -1, -1, -1, + -1, -1, -1, 42, -1, -1, 45, 46, 47, 48, + 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, -1, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, -1, -1, 79, + 80, -1, -1, 82, 84, -1, 85, 86, 87, -1, + -1, 90, 92, -1, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, -1, -1, 79, + 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, -1, -1, 79, + 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 92, -1, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 64, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, -1, -1, 79, + 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 64, 65, 66, 67, 68, 69, + 70, 71, -1, 73, 74, -1, -1, -1, -1, 79, + 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 64, 65, 66, 67, 68, 69, + 70, -1, -1, 73, 74, -1, -1, -1, -1, 79, + 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 64, 65, 66, 67, 68, 69, + 70, -1, -1, 73, 74, -1, -1, -1, -1, 79, + 80, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103 }; /* -*-C-*- Note some compilers choke on comments on `#line' lines. */ #line 3 "/usr/share/misc/bison.simple" @@ -2518,7 +2529,7 @@ yyreduce: switch (yyn) { case 1: -#line 231 "parse.y" +#line 233 "parse.y" { yyval.vars = ruby_dyna_vars; lex_state = EXPR_BEG; @@ -2529,7 +2540,7 @@ case 1: ; break;} case 2: -#line 240 "parse.y" +#line 242 "parse.y" { ruby_eval_tree = block_append(ruby_eval_tree, yyvsp[0].node); top_local_setup(); @@ -2539,31 +2550,31 @@ case 2: ; break;} case 4: -#line 251 "parse.y" +#line 253 "parse.y" { yyval.node = 0; ; break;} case 5: -#line 255 "parse.y" +#line 257 "parse.y" { yyval.node = newline_node(yyvsp[0].node); ; break;} case 6: -#line 259 "parse.y" +#line 261 "parse.y" { yyval.node = block_append(yyvsp[-2].node, newline_node(yyvsp[0].node)); ; break;} case 7: -#line 263 "parse.y" +#line 265 "parse.y" { yyval.node = yyvsp[0].node; ; break;} case 8: -#line 268 "parse.y" +#line 270 "parse.y" { if (yyvsp[-1].node && nd_type(yyvsp[-1].node) == NODE_BLOCK_PASS) { rb_compile_error("both block arg and actual block given"); @@ -2574,11 +2585,11 @@ case 8: ; break;} case 9: -#line 276 "parse.y" +#line 278 "parse.y" {lex_state = EXPR_FNAME;; break;} case 10: -#line 277 "parse.y" +#line 279 "parse.y" { if (cur_mid || in_single) yyerror("alias within method"); @@ -2586,7 +2597,7 @@ case 10: ; break;} case 11: -#line 283 "parse.y" +#line 285 "parse.y" { if (cur_mid || in_single) yyerror("alias within method"); @@ -2594,7 +2605,7 @@ case 11: ; break;} case 12: -#line 289 "parse.y" +#line 291 "parse.y" { char buf[3]; @@ -2605,14 +2616,14 @@ case 12: ; break;} case 13: -#line 298 "parse.y" +#line 300 "parse.y" { yyerror("can't make alias for the number variables"); yyval.node = 0; ; break;} case 14: -#line 303 "parse.y" +#line 305 "parse.y" { if (cur_mid || in_single) yyerror("undef within method"); @@ -2620,7 +2631,7 @@ case 14: ; break;} case 15: -#line 309 "parse.y" +#line 311 "parse.y" { value_expr(yyvsp[0].node); yyval.node = NEW_IF(cond(yyvsp[0].node), yyvsp[-2].node, 0); @@ -2628,7 +2639,7 @@ case 15: ; break;} case 16: -#line 315 "parse.y" +#line 317 "parse.y" { value_expr(yyvsp[0].node); yyval.node = NEW_UNLESS(cond(yyvsp[0].node), yyvsp[-2].node, 0); @@ -2636,7 +2647,7 @@ case 16: ; break;} case 17: -#line 321 "parse.y" +#line 323 "parse.y" { value_expr(yyvsp[0].node); if (nd_type(yyvsp[-2].node) == NODE_BEGIN) { @@ -2648,7 +2659,7 @@ case 17: ; break;} case 18: -#line 331 "parse.y" +#line 333 "parse.y" { value_expr(yyvsp[0].node); if (nd_type(yyvsp[-2].node) == NODE_BEGIN) { @@ -2660,7 +2671,7 @@ case 18: ; break;} case 19: -#line 341 "parse.y" +#line 343 "parse.y" { if (cur_mid || in_single) { yyerror("BEGIN in method"); @@ -2670,7 +2681,7 @@ case 19: ; break;} case 20: -#line 349 "parse.y" +#line 351 "parse.y" { ruby_eval_tree_begin = block_append(ruby_eval_tree_begin, NEW_PREEXE(yyvsp[-1].node)); @@ -2679,7 +2690,7 @@ case 20: ; break;} case 21: -#line 356 "parse.y" +#line 358 "parse.y" { if (cur_mid || in_single) { yyerror("END in method; use at_exit"); @@ -2689,7 +2700,7 @@ case 21: ; break;} case 23: -#line 366 "parse.y" +#line 368 "parse.y" { value_expr(yyvsp[0].node); yyvsp[-2].node->nd_value = yyvsp[0].node; @@ -2697,7 +2708,7 @@ case 23: ; break;} case 24: -#line 372 "parse.y" +#line 374 "parse.y" { value_expr(yyvsp[0].node); if (!cur_mid && !in_single) @@ -2706,47 +2717,47 @@ case 24: ; break;} case 25: -#line 379 "parse.y" +#line 381 "parse.y" { value_expr(yyvsp[0].node); yyval.node = NEW_YIELD(yyvsp[0].node); ; break;} case 27: -#line 385 "parse.y" +#line 387 "parse.y" { yyval.node = logop(NODE_AND, yyvsp[-2].node, yyvsp[0].node); ; break;} case 28: -#line 389 "parse.y" +#line 391 "parse.y" { yyval.node = logop(NODE_OR, yyvsp[-2].node, yyvsp[0].node); ; break;} case 29: -#line 393 "parse.y" +#line 395 "parse.y" { value_expr(yyvsp[0].node); yyval.node = NEW_NOT(cond(yyvsp[0].node)); ; break;} case 30: -#line 398 "parse.y" +#line 400 "parse.y" { value_expr(yyvsp[0].node); yyval.node = NEW_NOT(cond(yyvsp[0].node)); ; break;} case 32: -#line 405 "parse.y" +#line 407 "parse.y" { yyval.node = new_fcall(yyvsp[-1].id, yyvsp[0].node); fixpos(yyval.node, yyvsp[0].node); ; break;} case 33: -#line 410 "parse.y" +#line 412 "parse.y" { value_expr(yyvsp[-3].node); yyval.node = new_call(yyvsp[-3].node, yyvsp[-1].id, yyvsp[0].node); @@ -2754,7 +2765,7 @@ case 33: ; break;} case 34: -#line 416 "parse.y" +#line 418 "parse.y" { value_expr(yyvsp[-3].node); yyval.node = new_call(yyvsp[-3].node, yyvsp[-1].id, yyvsp[0].node); @@ -2762,7 +2773,7 @@ case 34: ; break;} case 35: -#line 422 "parse.y" +#line 424 "parse.y" { if (!cur_mid && !in_single && !in_defined) yyerror("super called outside of method"); @@ -2771,246 +2782,246 @@ case 35: ; break;} case 37: -#line 431 "parse.y" +#line 433 "parse.y" { yyval.node = yyvsp[-1].node; ; break;} case 39: -#line 437 "parse.y" +#line 439 "parse.y" { yyval.node = NEW_MASGN(NEW_LIST(yyvsp[-1].node), 0); ; break;} case 40: -#line 442 "parse.y" +#line 444 "parse.y" { yyval.node = NEW_MASGN(NEW_LIST(yyvsp[0].node), 0); ; break;} case 41: -#line 446 "parse.y" +#line 448 "parse.y" { yyval.node = NEW_MASGN(NEW_LIST(yyvsp[-2].node), yyvsp[0].node); ; break;} case 42: -#line 450 "parse.y" +#line 452 "parse.y" { yyval.node = NEW_MASGN(list_concat(NEW_LIST(yyvsp[-1].node),yyvsp[0].node), 0); ; break;} case 43: -#line 454 "parse.y" +#line 456 "parse.y" { yyval.node = NEW_MASGN(list_concat(NEW_LIST(yyvsp[-4].node),yyvsp[-3].node),yyvsp[0].node); ; break;} case 44: -#line 458 "parse.y" +#line 460 "parse.y" { yyval.node = NEW_MASGN(0, yyvsp[0].node); ; break;} case 46: -#line 464 "parse.y" +#line 466 "parse.y" { yyval.node = yyvsp[-1].node; ; break;} case 47: -#line 469 "parse.y" +#line 471 "parse.y" { yyval.node = yyvsp[-1].node; ; break;} case 48: -#line 474 "parse.y" +#line 476 "parse.y" { yyval.node = NEW_LIST(yyvsp[0].node); ; break;} case 49: -#line 478 "parse.y" +#line 480 "parse.y" { yyval.node = list_append(yyvsp[-2].node, yyvsp[0].node); ; break;} case 50: -#line 483 "parse.y" +#line 485 "parse.y" { yyval.node = assignable(yyvsp[0].id, 0); ; break;} case 51: -#line 487 "parse.y" +#line 489 "parse.y" { yyval.node = aryset(yyvsp[-3].node, yyvsp[-1].node, 0); ; break;} case 52: -#line 491 "parse.y" +#line 493 "parse.y" { yyval.node = attrset(yyvsp[-2].node, yyvsp[0].id, 0); ; break;} case 53: -#line 495 "parse.y" +#line 497 "parse.y" { rb_backref_error(yyvsp[0].node); yyval.node = 0; ; break;} case 54: -#line 501 "parse.y" +#line 503 "parse.y" { yyerror("class/module name must be CONSTANT"); ; break;} case 59: -#line 510 "parse.y" +#line 512 "parse.y" { lex_state = EXPR_END; yyval.id = yyvsp[0].id; ; break;} case 60: -#line 515 "parse.y" +#line 517 "parse.y" { lex_state = EXPR_END; yyval.id = yyvsp[0].id; ; break;} case 61: -#line 521 "parse.y" +#line 523 "parse.y" { yyval.node = NEW_UNDEF(yyvsp[0].id); ; break;} case 62: -#line 524 "parse.y" +#line 526 "parse.y" {lex_state = EXPR_FNAME;; break;} case 63: -#line 525 "parse.y" +#line 527 "parse.y" { yyval.node = block_append(yyvsp[-3].node, NEW_UNDEF(yyvsp[0].id)); ; break;} case 64: -#line 529 "parse.y" +#line 531 "parse.y" { yyval.id = tDOT2; ; break;} case 65: -#line 530 "parse.y" +#line 532 "parse.y" { yyval.id = '|'; ; break;} case 66: -#line 531 "parse.y" +#line 533 "parse.y" { yyval.id = '^'; ; break;} case 67: -#line 532 "parse.y" +#line 534 "parse.y" { yyval.id = '&'; ; break;} case 68: -#line 533 "parse.y" +#line 535 "parse.y" { yyval.id = tCMP; ; break;} case 69: -#line 534 "parse.y" +#line 536 "parse.y" { yyval.id = tEQ; ; break;} case 70: -#line 535 "parse.y" +#line 537 "parse.y" { yyval.id = tEQQ; ; break;} case 71: -#line 536 "parse.y" +#line 538 "parse.y" { yyval.id = tMATCH; ; break;} case 72: -#line 537 "parse.y" +#line 539 "parse.y" { yyval.id = '>'; ; break;} case 73: -#line 538 "parse.y" +#line 540 "parse.y" { yyval.id = tGEQ; ; break;} case 74: -#line 539 "parse.y" +#line 541 "parse.y" { yyval.id = '<'; ; break;} case 75: -#line 540 "parse.y" +#line 542 "parse.y" { yyval.id = tLEQ; ; break;} case 76: -#line 541 "parse.y" +#line 543 "parse.y" { yyval.id = tLSHFT; ; break;} case 77: -#line 542 "parse.y" +#line 544 "parse.y" { yyval.id = tRSHFT; ; break;} case 78: -#line 543 "parse.y" +#line 545 "parse.y" { yyval.id = '+'; ; break;} case 79: -#line 544 "parse.y" +#line 546 "parse.y" { yyval.id = '-'; ; break;} case 80: -#line 545 "parse.y" +#line 547 "parse.y" { yyval.id = '*'; ; break;} case 81: -#line 546 "parse.y" +#line 548 "parse.y" { yyval.id = '*'; ; break;} case 82: -#line 547 "parse.y" +#line 549 "parse.y" { yyval.id = '/'; ; break;} case 83: -#line 548 "parse.y" +#line 550 "parse.y" { yyval.id = '%'; ; break;} case 84: -#line 549 "parse.y" +#line 551 "parse.y" { yyval.id = tPOW; ; break;} case 85: -#line 550 "parse.y" +#line 552 "parse.y" { yyval.id = '~'; ; break;} case 86: -#line 551 "parse.y" +#line 553 "parse.y" { yyval.id = tUPLUS; ; break;} case 87: -#line 552 "parse.y" +#line 554 "parse.y" { yyval.id = tUMINUS; ; break;} case 88: -#line 553 "parse.y" +#line 555 "parse.y" { yyval.id = tAREF; ; break;} case 89: -#line 554 "parse.y" +#line 556 "parse.y" { yyval.id = tASET; ; break;} case 90: -#line 555 "parse.y" +#line 557 "parse.y" { yyval.id = '`'; ; break;} case 131: -#line 565 "parse.y" +#line 567 "parse.y" {yyval.node = assignable(yyvsp[-1].id, 0);; break;} case 132: -#line 566 "parse.y" +#line 568 "parse.y" { yyval.node = yyvsp[-1].node; if (yyval.node) { @@ -3020,28 +3031,28 @@ case 132: ; break;} case 133: -#line 574 "parse.y" +#line 576 "parse.y" { yyval.node = aryset(yyvsp[-5].node, yyvsp[-3].node, yyvsp[0].node); fixpos(yyval.node, yyvsp[-5].node); ; break;} case 134: -#line 579 "parse.y" +#line 581 "parse.y" { yyval.node = attrset(yyvsp[-4].node, yyvsp[-2].id, yyvsp[0].node); fixpos(yyval.node, yyvsp[0].node); ; break;} case 135: -#line 584 "parse.y" +#line 586 "parse.y" { yyval.node = attrset(yyvsp[-4].node, yyvsp[-2].id, yyvsp[0].node); fixpos(yyval.node, yyvsp[0].node); ; break;} case 136: -#line 589 "parse.y" +#line 591 "parse.y" { value_expr(yyvsp[0].node); rb_backref_error(yyvsp[-2].node); @@ -3049,11 +3060,11 @@ case 136: ; break;} case 137: -#line 594 "parse.y" +#line 596 "parse.y" {yyval.node = assignable(yyvsp[-1].id, 0);; break;} case 138: -#line 595 "parse.y" +#line 597 "parse.y" { if (yyvsp[-2].id == tOROP) { yyvsp[-1].node->nd_value = yyvsp[0].node; @@ -3071,7 +3082,7 @@ case 138: ; break;} case 139: -#line 611 "parse.y" +#line 613 "parse.y" { NODE *args = NEW_LIST(yyvsp[0].node); @@ -3088,7 +3099,7 @@ case 139: ; break;} case 140: -#line 626 "parse.y" +#line 628 "parse.y" { if (yyvsp[-1].id == tOROP) { yyvsp[-1].id = 0; @@ -3101,7 +3112,7 @@ case 140: ; break;} case 141: -#line 637 "parse.y" +#line 639 "parse.y" { if (yyvsp[-1].id == tOROP) { yyvsp[-1].id = 0; @@ -3114,200 +3125,200 @@ case 141: ; break;} case 142: -#line 648 "parse.y" +#line 650 "parse.y" { rb_backref_error(yyvsp[-2].node); yyval.node = 0; ; break;} case 143: -#line 653 "parse.y" +#line 655 "parse.y" { yyval.node = NEW_DOT2(yyvsp[-2].node, yyvsp[0].node); ; break;} case 144: -#line 657 "parse.y" +#line 659 "parse.y" { yyval.node = NEW_DOT3(yyvsp[-2].node, yyvsp[0].node); ; break;} case 145: -#line 661 "parse.y" +#line 663 "parse.y" { yyval.node = call_op(yyvsp[-2].node, '+', 1, yyvsp[0].node); ; break;} case 146: -#line 665 "parse.y" +#line 667 "parse.y" { yyval.node = call_op(yyvsp[-2].node, '-', 1, yyvsp[0].node); ; break;} case 147: -#line 669 "parse.y" +#line 671 "parse.y" { yyval.node = call_op(yyvsp[-2].node, '*', 1, yyvsp[0].node); ; break;} case 148: -#line 673 "parse.y" +#line 675 "parse.y" { yyval.node = call_op(yyvsp[-2].node, '/', 1, yyvsp[0].node); ; break;} case 149: -#line 677 "parse.y" +#line 679 "parse.y" { yyval.node = call_op(yyvsp[-2].node, '%', 1, yyvsp[0].node); ; break;} case 150: -#line 681 "parse.y" +#line 683 "parse.y" { yyval.node = call_op(yyvsp[-2].node, tPOW, 1, yyvsp[0].node); ; break;} case 151: -#line 685 "parse.y" +#line 687 "parse.y" { yyval.node = call_op(yyvsp[0].node, tUPLUS, 0); ; break;} case 152: -#line 689 "parse.y" +#line 691 "parse.y" { yyval.node = call_op(yyvsp[0].node, tUMINUS, 0); ; break;} case 153: -#line 693 "parse.y" +#line 695 "parse.y" { yyval.node = call_op(yyvsp[-2].node, '|', 1, yyvsp[0].node); ; break;} case 154: -#line 697 "parse.y" +#line 699 "parse.y" { yyval.node = call_op(yyvsp[-2].node, '^', 1, yyvsp[0].node); ; break;} case 155: -#line 701 "parse.y" +#line 703 "parse.y" { yyval.node = call_op(yyvsp[-2].node, '&', 1, yyvsp[0].node); ; break;} case 156: -#line 705 "parse.y" +#line 707 "parse.y" { yyval.node = call_op(yyvsp[-2].node, tCMP, 1, yyvsp[0].node); ; break;} case 157: -#line 709 "parse.y" +#line 711 "parse.y" { yyval.node = call_op(yyvsp[-2].node, '>', 1, yyvsp[0].node); ; break;} case 158: -#line 713 "parse.y" +#line 715 "parse.y" { yyval.node = call_op(yyvsp[-2].node, tGEQ, 1, yyvsp[0].node); ; break;} case 159: -#line 717 "parse.y" +#line 719 "parse.y" { yyval.node = call_op(yyvsp[-2].node, '<', 1, yyvsp[0].node); ; break;} case 160: -#line 721 "parse.y" +#line 723 "parse.y" { yyval.node = call_op(yyvsp[-2].node, tLEQ, 1, yyvsp[0].node); ; break;} case 161: -#line 725 "parse.y" +#line 727 "parse.y" { yyval.node = call_op(yyvsp[-2].node, tEQ, 1, yyvsp[0].node); ; break;} case 162: -#line 729 "parse.y" +#line 731 "parse.y" { yyval.node = call_op(yyvsp[-2].node, tEQQ, 1, yyvsp[0].node); ; break;} case 163: -#line 733 "parse.y" +#line 735 "parse.y" { yyval.node = NEW_NOT(call_op(yyvsp[-2].node, tEQ, 1, yyvsp[0].node)); ; break;} case 164: -#line 737 "parse.y" +#line 739 "parse.y" { yyval.node = match_gen(yyvsp[-2].node, yyvsp[0].node); ; break;} case 165: -#line 741 "parse.y" +#line 743 "parse.y" { yyval.node = NEW_NOT(match_gen(yyvsp[-2].node, yyvsp[0].node)); ; break;} case 166: -#line 745 "parse.y" +#line 747 "parse.y" { value_expr(yyvsp[0].node); yyval.node = NEW_NOT(cond(yyvsp[0].node)); ; break;} case 167: -#line 750 "parse.y" +#line 752 "parse.y" { yyval.node = call_op(yyvsp[0].node, '~', 0); ; break;} case 168: -#line 754 "parse.y" +#line 756 "parse.y" { yyval.node = call_op(yyvsp[-2].node, tLSHFT, 1, yyvsp[0].node); ; break;} case 169: -#line 758 "parse.y" +#line 760 "parse.y" { yyval.node = call_op(yyvsp[-2].node, tRSHFT, 1, yyvsp[0].node); ; break;} case 170: -#line 762 "parse.y" +#line 764 "parse.y" { yyval.node = logop(NODE_AND, yyvsp[-2].node, yyvsp[0].node); ; break;} case 171: -#line 766 "parse.y" +#line 768 "parse.y" { yyval.node = logop(NODE_OR, yyvsp[-2].node, yyvsp[0].node); ; break;} case 172: -#line 769 "parse.y" +#line 771 "parse.y" {in_defined = 1;; break;} case 173: -#line 770 "parse.y" +#line 772 "parse.y" { in_defined = 0; yyval.node = NEW_DEFINED(yyvsp[0].node); ; break;} case 174: -#line 775 "parse.y" +#line 777 "parse.y" { value_expr(yyvsp[-4].node); yyval.node = NEW_IF(cond(yyvsp[-4].node), yyvsp[-2].node, yyvsp[0].node); @@ -3315,13 +3326,13 @@ case 174: ; break;} case 175: -#line 781 "parse.y" +#line 783 "parse.y" { yyval.node = yyvsp[0].node; ; break;} case 176: -#line 786 "parse.y" +#line 788 "parse.y" { if (yyvsp[0].node && nd_type(yyvsp[0].node) == NODE_BLOCK_PASS) { rb_compile_error("block argument should not be given"); @@ -3330,107 +3341,125 @@ case 176: ; break;} case 177: -#line 794 "parse.y" +#line 796 "parse.y" { yyval.node = 0; ; break;} case 179: -#line 800 "parse.y" +#line 802 "parse.y" { value_expr(yyvsp[0].node); yyval.node = NEW_LIST(yyvsp[0].node); ; break;} case 180: -#line 805 "parse.y" +#line 807 "parse.y" { - yyval.node = arg_blk_pass(yyvsp[-1].node, yyvsp[0].node); + yyval.node = yyvsp[-1].node; ; break;} case 181: -#line 809 "parse.y" +#line 811 "parse.y" { - yyval.node = arg_add(yyvsp[-4].node, yyvsp[-1].node); - yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node); + yyval.node = arg_blk_pass(yyvsp[-1].node, yyvsp[0].node); ; break;} case 182: -#line 814 "parse.y" +#line 815 "parse.y" { - yyval.node = NEW_LIST(NEW_HASH(yyvsp[-1].node)); + yyval.node = arg_add(yyvsp[-4].node, yyvsp[-1].node); yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node); ; break;} case 183: -#line 819 "parse.y" +#line 820 "parse.y" { - yyval.node = arg_add(NEW_LIST(NEW_HASH(yyvsp[-4].node)), yyvsp[-1].node); - yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node); + yyval.node = NEW_LIST(NEW_HASH(yyvsp[-1].node)); ; break;} case 184: #line 824 "parse.y" { - yyval.node = list_append(yyvsp[-3].node, NEW_HASH(yyvsp[-1].node)); + yyval.node = NEW_LIST(NEW_HASH(yyvsp[-1].node)); yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node); ; break;} case 185: #line 829 "parse.y" { - yyval.node = arg_add(list_append(yyvsp[-6].node, NEW_HASH(yyvsp[-4].node)), yyvsp[-1].node); + yyval.node = arg_add(NEW_LIST(NEW_HASH(yyvsp[-4].node)), yyvsp[-1].node); yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node); ; break;} case 186: #line 834 "parse.y" +{ + yyval.node = list_append(yyvsp[-3].node, NEW_HASH(yyvsp[-1].node)); + yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node); + ; + break;} +case 187: +#line 839 "parse.y" +{ + yyval.node = list_append(yyvsp[-3].node, NEW_HASH(yyvsp[-1].node)); + ; + break;} +case 188: +#line 843 "parse.y" +{ + yyval.node = arg_add(list_append(yyvsp[-6].node, NEW_HASH(yyvsp[-4].node)), yyvsp[-1].node); + yyval.node = arg_blk_pass(yyval.node, yyvsp[0].node); + ; + break;} +case 189: +#line 848 "parse.y" { value_expr(yyvsp[-1].node); yyval.node = arg_blk_pass(NEW_RESTARGS(yyvsp[-1].node), yyvsp[0].node); ; break;} -case 188: -#line 841 "parse.y" +case 191: +#line 855 "parse.y" { value_expr(yyvsp[0].node); yyval.node = NEW_BLOCK_PASS(yyvsp[0].node); ; break;} -case 189: -#line 847 "parse.y" +case 192: +#line 861 "parse.y" { yyval.node = yyvsp[0].node; ; break;} -case 190: -#line 851 "parse.y" +case 193: +#line 865 "parse.y" { yyval.node = 0; ; break;} -case 192: -#line 857 "parse.y" +case 195: +#line 871 "parse.y" { yyval.node = 0; ; break;} -case 193: -#line 862 "parse.y" +case 196: +#line 876 "parse.y" { value_expr(yyvsp[0].node); yyval.node = NEW_LIST(yyvsp[0].node); ; break;} -case 194: -#line 867 "parse.y" +case 197: +#line 881 "parse.y" { value_expr(yyvsp[0].node); yyval.node = list_append(yyvsp[-2].node, yyvsp[0].node); ; break;} -case 195: -#line 873 "parse.y" +case 198: +#line 887 "parse.y" { if (yyvsp[0].node && nd_type(yyvsp[0].node) == NODE_ARRAY && @@ -3443,22 +3472,22 @@ case 195: } ; break;} -case 196: -#line 885 "parse.y" +case 199: +#line 899 "parse.y" { value_expr(yyvsp[0].node); yyval.node = arg_add(yyvsp[-3].node, yyvsp[0].node); ; break;} -case 197: -#line 890 "parse.y" +case 200: +#line 904 "parse.y" { value_expr(yyvsp[0].node); yyval.node = yyvsp[0].node; ; break;} -case 198: -#line 896 "parse.y" +case 201: +#line 910 "parse.y" { yyval.node = yyvsp[0].node; if (yyvsp[0].node) { @@ -3472,59 +3501,59 @@ case 198: } ; break;} -case 199: -#line 910 "parse.y" +case 202: +#line 924 "parse.y" { yyval.node = 0; ; break;} -case 201: -#line 916 "parse.y" +case 204: +#line 930 "parse.y" { yyval.node = NEW_LIT(yyvsp[0].val); ; break;} -case 202: -#line 920 "parse.y" +case 205: +#line 934 "parse.y" { value_expr(yyvsp[-2].node); yyval.node = NEW_COLON2(yyvsp[-2].node, yyvsp[0].id); ; break;} -case 203: -#line 925 "parse.y" +case 206: +#line 939 "parse.y" { value_expr(yyvsp[-2].node); yyval.node = new_call(yyvsp[-2].node, yyvsp[0].id, 0); ; break;} -case 204: -#line 930 "parse.y" +case 207: +#line 944 "parse.y" { yyval.node = NEW_COLON3(yyvsp[0].id); ; break;} -case 205: -#line 934 "parse.y" +case 208: +#line 948 "parse.y" { yyval.node = NEW_STR(yyvsp[0].val); ; break;} -case 207: -#line 939 "parse.y" +case 210: +#line 953 "parse.y" { yyval.node = NEW_XSTR(yyvsp[0].val); ; break;} -case 212: -#line 947 "parse.y" +case 215: +#line 961 "parse.y" { value_expr(yyvsp[-3].node); yyval.node = NEW_CALL(yyvsp[-3].node, tAREF, yyvsp[-1].node); ; break;} -case 213: -#line 952 "parse.y" +case 216: +#line 966 "parse.y" { if (yyvsp[-1].node == 0) yyval.node = NEW_ZARRAY(); /* zero length array*/ @@ -3533,14 +3562,14 @@ case 213: } ; break;} -case 214: -#line 960 "parse.y" +case 217: +#line 974 "parse.y" { yyval.node = NEW_HASH(yyvsp[-1].node); ; break;} -case 215: -#line 964 "parse.y" +case 218: +#line 978 "parse.y" { if (!cur_mid && !in_single) yyerror("return appeared outside of method"); @@ -3548,67 +3577,67 @@ case 215: yyval.node = NEW_RETURN(yyvsp[-1].node); ; break;} -case 216: -#line 971 "parse.y" +case 219: +#line 985 "parse.y" { if (!cur_mid && !in_single) yyerror("return appeared outside of method"); yyval.node = NEW_RETURN(0); ; break;} -case 217: -#line 977 "parse.y" +case 220: +#line 991 "parse.y" { if (!cur_mid && !in_single) yyerror("return appeared outside of method"); yyval.node = NEW_RETURN(0); ; break;} -case 218: -#line 983 "parse.y" +case 221: +#line 997 "parse.y" { value_expr(yyvsp[-1].node); yyval.node = NEW_YIELD(yyvsp[-1].node); ; break;} -case 219: -#line 988 "parse.y" +case 222: +#line 1002 "parse.y" { yyval.node = NEW_YIELD(0); ; break;} -case 220: -#line 992 "parse.y" +case 223: +#line 1006 "parse.y" { yyval.node = NEW_YIELD(0); ; break;} -case 221: -#line 995 "parse.y" +case 224: +#line 1009 "parse.y" {in_defined = 1;; break;} -case 222: -#line 996 "parse.y" +case 225: +#line 1010 "parse.y" { in_defined = 0; yyval.node = NEW_DEFINED(yyvsp[-1].node); ; break;} -case 223: -#line 1001 "parse.y" +case 226: +#line 1015 "parse.y" { yyval.node = NEW_VCALL(yyvsp[0].id); ; break;} -case 224: -#line 1005 "parse.y" +case 227: +#line 1019 "parse.y" { yyvsp[0].node->nd_iter = NEW_FCALL(yyvsp[-1].id, 0); yyval.node = yyvsp[0].node; ; break;} -case 226: -#line 1011 "parse.y" +case 229: +#line 1025 "parse.y" { if (yyvsp[-1].node && nd_type(yyvsp[-1].node) == NODE_BLOCK_PASS) { rb_compile_error("both block arg and actual block given"); @@ -3618,56 +3647,56 @@ case 226: fixpos(yyval.node, yyvsp[-1].node); ; break;} -case 227: -#line 1023 "parse.y" +case 230: +#line 1037 "parse.y" { value_expr(yyvsp[-4].node); yyval.node = NEW_IF(cond(yyvsp[-4].node), yyvsp[-2].node, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-4].node); ; break;} -case 228: -#line 1032 "parse.y" +case 231: +#line 1046 "parse.y" { value_expr(yyvsp[-4].node); yyval.node = NEW_UNLESS(cond(yyvsp[-4].node), yyvsp[-2].node, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-4].node); ; break;} -case 229: -#line 1040 "parse.y" +case 232: +#line 1054 "parse.y" { value_expr(yyvsp[-3].node); yyval.node = NEW_WHILE(cond(yyvsp[-3].node), yyvsp[-1].node, 1); fixpos(yyval.node, yyvsp[-3].node); ; break;} -case 230: -#line 1048 "parse.y" +case 233: +#line 1062 "parse.y" { value_expr(yyvsp[-3].node); yyval.node = NEW_UNTIL(cond(yyvsp[-3].node), yyvsp[-1].node, 1); fixpos(yyval.node, yyvsp[-3].node); ; break;} -case 231: -#line 1056 "parse.y" +case 234: +#line 1070 "parse.y" { value_expr(yyvsp[-2].node); yyval.node = NEW_CASE(yyvsp[-2].node, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-2].node); ; break;} -case 232: -#line 1064 "parse.y" +case 235: +#line 1078 "parse.y" { value_expr(yyvsp[-5].node); yyval.node = NEW_FOR(yyvsp[-5].node, yyvsp[-3].node, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-5].node); ; break;} -case 233: -#line 1075 "parse.y" +case 236: +#line 1089 "parse.y" { if (!yyvsp[-3].node && !yyvsp[-2].node && !yyvsp[-1].node) yyval.node = NEW_BEGIN(yyvsp[-4].node); @@ -3683,14 +3712,14 @@ case 233: fixpos(yyval.node, yyvsp[-4].node); ; break;} -case 234: -#line 1090 "parse.y" +case 237: +#line 1104 "parse.y" { yyval.node = yyvsp[-1].node; ; break;} -case 235: -#line 1094 "parse.y" +case 238: +#line 1108 "parse.y" { if (cur_mid || in_single) yyerror("class definition in method body"); @@ -3700,8 +3729,8 @@ case 235: local_push(); ; break;} -case 236: -#line 1104 "parse.y" +case 239: +#line 1118 "parse.y" { yyval.node = NEW_CLASS(yyvsp[-4].id, yyvsp[-1].node, yyvsp[-3].node); fixpos(yyval.node, yyvsp[-3].node); @@ -3710,16 +3739,16 @@ case 236: class_nest--; ; break;} -case 237: -#line 1112 "parse.y" +case 240: +#line 1126 "parse.y" { class_nest++; cref_push(); local_push(); ; break;} -case 238: -#line 1119 "parse.y" +case 241: +#line 1133 "parse.y" { yyval.node = NEW_SCLASS(yyvsp[-4].node, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-4].node); @@ -3728,8 +3757,8 @@ case 238: class_nest--; ; break;} -case 239: -#line 1127 "parse.y" +case 242: +#line 1141 "parse.y" { if (cur_mid || in_single) yyerror("module definition in method body"); @@ -3738,8 +3767,8 @@ case 239: local_push(); ; break;} -case 240: -#line 1136 "parse.y" +case 243: +#line 1150 "parse.y" { yyval.node = NEW_MODULE(yyvsp[-3].id, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-1].node); @@ -3748,8 +3777,8 @@ case 240: class_nest--; ; break;} -case 241: -#line 1144 "parse.y" +case 244: +#line 1158 "parse.y" { if (cur_mid || in_single) yyerror("nested method definition"); @@ -3757,8 +3786,8 @@ case 241: local_push(); ; break;} -case 242: -#line 1153 "parse.y" +case 245: +#line 1167 "parse.y" { /* NOEX_PRIVATE for toplevel */ yyval.node = NEW_DEFN(yyvsp[-4].id, yyvsp[-2].node, yyvsp[-1].node, class_nest?0:1); @@ -3767,12 +3796,12 @@ case 242: cur_mid = 0; ; break;} -case 243: -#line 1160 "parse.y" +case 246: +#line 1174 "parse.y" {lex_state = EXPR_FNAME;; break;} -case 244: -#line 1161 "parse.y" +case 247: +#line 1175 "parse.y" { value_expr(yyvsp[-3].node); in_single++; @@ -3780,8 +3809,8 @@ case 244: lex_state = EXPR_END; /* force for args */ ; break;} -case 245: -#line 1170 "parse.y" +case 248: +#line 1184 "parse.y" { yyval.node = NEW_DEFS(yyvsp[-7].node, yyvsp[-4].id, yyvsp[-2].node, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-7].node); @@ -3789,339 +3818,339 @@ case 245: in_single--; ; break;} -case 246: -#line 1177 "parse.y" +case 249: +#line 1191 "parse.y" { yyval.node = NEW_BREAK(); ; break;} -case 247: -#line 1181 "parse.y" +case 250: +#line 1195 "parse.y" { yyval.node = NEW_NEXT(); ; break;} -case 248: -#line 1185 "parse.y" +case 251: +#line 1199 "parse.y" { yyval.node = NEW_REDO(); ; break;} -case 249: -#line 1189 "parse.y" +case 252: +#line 1203 "parse.y" { yyval.node = NEW_RETRY(); ; break;} -case 256: -#line 1204 "parse.y" +case 259: +#line 1218 "parse.y" { value_expr(yyvsp[-3].node); yyval.node = NEW_IF(cond(yyvsp[-3].node), yyvsp[-1].node, yyvsp[0].node); fixpos(yyval.node, yyvsp[-3].node); ; break;} -case 257: -#line 1211 "parse.y" +case 260: +#line 1225 "parse.y" { yyval.node = 0; ; break;} -case 258: -#line 1215 "parse.y" +case 261: +#line 1229 "parse.y" { yyval.node = yyvsp[0].node; ; break;} -case 261: -#line 1223 "parse.y" +case 264: +#line 1237 "parse.y" { yyval.node = 0; ; break;} -case 262: -#line 1227 "parse.y" +case 265: +#line 1241 "parse.y" { yyval.node = 0; ; break;} -case 263: -#line 1231 "parse.y" +case 266: +#line 1245 "parse.y" { yyval.node = 0; ; break;} -case 264: -#line 1235 "parse.y" +case 267: +#line 1249 "parse.y" { yyval.node = yyvsp[-1].node; ; break;} -case 265: -#line 1240 "parse.y" +case 268: +#line 1254 "parse.y" { yyval.vars = dyna_push(); ; break;} -case 266: -#line 1246 "parse.y" +case 269: +#line 1260 "parse.y" { yyval.node = NEW_ITER(yyvsp[-2].node, 0, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-2].node?yyvsp[-2].node:yyvsp[-1].node); dyna_pop(yyvsp[-3].vars); ; break;} -case 267: -#line 1253 "parse.y" +case 270: +#line 1267 "parse.y" { yyval.vars = dyna_push(); ; break;} -case 268: -#line 1258 "parse.y" +case 271: +#line 1272 "parse.y" { yyval.node = NEW_ITER(yyvsp[-2].node, 0, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-2].node?yyvsp[-2].node:yyvsp[-1].node); dyna_pop(yyvsp[-3].vars); ; break;} -case 269: -#line 1265 "parse.y" +case 272: +#line 1279 "parse.y" { yyval.node = NEW_VCALL(yyvsp[0].id); ; break;} -case 270: -#line 1269 "parse.y" +case 273: +#line 1283 "parse.y" { yyval.node = NEW_VCALL(yyvsp[0].id); ; break;} -case 271: -#line 1273 "parse.y" +case 274: +#line 1287 "parse.y" { yyval.node = NEW_VCALL(yyvsp[0].id); ; break;} -case 274: -#line 1280 "parse.y" +case 277: +#line 1294 "parse.y" { yyval.node = new_fcall(yyvsp[-3].id, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-1].node); ; break;} -case 275: -#line 1285 "parse.y" +case 278: +#line 1299 "parse.y" { value_expr(yyvsp[-5].node); yyval.node = new_call(yyvsp[-5].node, yyvsp[-3].id, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-5].node); ; break;} -case 276: -#line 1291 "parse.y" +case 279: +#line 1305 "parse.y" { value_expr(yyvsp[-2].node); yyval.node = new_call(yyvsp[-2].node, yyvsp[0].id, 0); fixpos(yyval.node, yyvsp[-2].node); ; break;} -case 277: -#line 1297 "parse.y" +case 280: +#line 1311 "parse.y" { value_expr(yyvsp[-5].node); yyval.node = new_call(yyvsp[-5].node, yyvsp[-3].id, yyvsp[-1].node); fixpos(yyval.node, yyvsp[-5].node); ; break;} -case 278: -#line 1303 "parse.y" +case 281: +#line 1317 "parse.y" { if (!cur_mid && !in_single && !in_defined) yyerror("super called outside of method"); yyval.node = NEW_SUPER(yyvsp[-1].node); ; break;} -case 279: -#line 1309 "parse.y" +case 282: +#line 1323 "parse.y" { if (!cur_mid && !in_single && !in_defined) yyerror("super called outside of method"); yyval.node = NEW_ZSUPER(); ; break;} -case 280: -#line 1319 "parse.y" +case 283: +#line 1333 "parse.y" { yyval.node = NEW_WHEN(yyvsp[-3].node, yyvsp[-1].node, yyvsp[0].node); ; break;} -case 282: -#line 1325 "parse.y" +case 285: +#line 1339 "parse.y" { value_expr(yyvsp[0].node); yyval.node = list_append(yyvsp[-3].node, NEW_WHEN(yyvsp[0].node, 0, 0)); ; break;} -case 283: -#line 1330 "parse.y" +case 286: +#line 1344 "parse.y" { value_expr(yyvsp[0].node); yyval.node = NEW_LIST(NEW_WHEN(yyvsp[0].node, 0, 0)); ; break;} -case 286: -#line 1341 "parse.y" +case 289: +#line 1355 "parse.y" { yyval.node = NEW_RESBODY(yyvsp[-3].node, yyvsp[-1].node, yyvsp[0].node); fixpos(yyval.node, yyvsp[-3].node?yyvsp[-3].node:yyvsp[-1].node); ; break;} -case 287: -#line 1346 "parse.y" +case 290: +#line 1360 "parse.y" { yyval.node = 0; ; break;} -case 288: -#line 1351 "parse.y" +case 291: +#line 1365 "parse.y" { yyval.node = 0; ; break;} -case 289: -#line 1355 "parse.y" +case 292: +#line 1369 "parse.y" { yyval.node = yyvsp[0].node; ; break;} -case 291: -#line 1361 "parse.y" +case 294: +#line 1375 "parse.y" { yyval.val = INT2FIX(yyvsp[0].id); ; break;} -case 302: -#line 1377 "parse.y" +case 305: +#line 1391 "parse.y" {yyval.id = kNIL;; break;} -case 303: -#line 1378 "parse.y" +case 306: +#line 1392 "parse.y" {yyval.id = kSELF;; break;} -case 304: -#line 1379 "parse.y" +case 307: +#line 1393 "parse.y" {yyval.id = kTRUE;; break;} -case 305: -#line 1380 "parse.y" +case 308: +#line 1394 "parse.y" {yyval.id = kFALSE;; break;} -case 306: -#line 1381 "parse.y" +case 309: +#line 1395 "parse.y" {yyval.id = k__FILE__;; break;} -case 307: -#line 1382 "parse.y" +case 310: +#line 1396 "parse.y" {yyval.id = k__LINE__;; break;} -case 308: -#line 1385 "parse.y" +case 311: +#line 1399 "parse.y" { yyval.node = gettable(yyvsp[0].id); ; break;} -case 311: -#line 1393 "parse.y" +case 314: +#line 1407 "parse.y" { yyval.node = 0; ; break;} -case 312: -#line 1397 "parse.y" +case 315: +#line 1411 "parse.y" { lex_state = EXPR_BEG; ; break;} -case 313: -#line 1401 "parse.y" +case 316: +#line 1415 "parse.y" { yyval.node = yyvsp[-1].node; ; break;} -case 314: -#line 1404 "parse.y" +case 317: +#line 1418 "parse.y" {yyerrok; yyval.node = 0;; break;} -case 315: -#line 1407 "parse.y" +case 318: +#line 1421 "parse.y" { yyval.node = yyvsp[-2].node; lex_state = EXPR_BEG; ; break;} -case 316: -#line 1412 "parse.y" +case 319: +#line 1426 "parse.y" { yyval.node = yyvsp[-1].node; ; break;} -case 317: -#line 1417 "parse.y" +case 320: +#line 1431 "parse.y" { yyval.node = block_append(NEW_ARGS(yyvsp[-5].num, yyvsp[-3].node, yyvsp[-1].id), yyvsp[0].node); ; break;} -case 318: -#line 1421 "parse.y" +case 321: +#line 1435 "parse.y" { yyval.node = block_append(NEW_ARGS(yyvsp[-3].num, yyvsp[-1].node, -1), yyvsp[0].node); ; break;} -case 319: -#line 1425 "parse.y" +case 322: +#line 1439 "parse.y" { yyval.node = block_append(NEW_ARGS(yyvsp[-3].num, 0, yyvsp[-1].id), yyvsp[0].node); ; break;} -case 320: -#line 1429 "parse.y" +case 323: +#line 1443 "parse.y" { yyval.node = block_append(NEW_ARGS(yyvsp[-1].num, 0, -1), yyvsp[0].node); ; break;} -case 321: -#line 1433 "parse.y" +case 324: +#line 1447 "parse.y" { yyval.node = block_append(NEW_ARGS(0, yyvsp[-3].node, yyvsp[-1].id), yyvsp[0].node); ; break;} -case 322: -#line 1437 "parse.y" +case 325: +#line 1451 "parse.y" { yyval.node = block_append(NEW_ARGS(0, yyvsp[-1].node, -1), yyvsp[0].node); ; break;} -case 323: -#line 1441 "parse.y" +case 326: +#line 1455 "parse.y" { yyval.node = block_append(NEW_ARGS(0, 0, yyvsp[-1].id), yyvsp[0].node); ; break;} -case 324: -#line 1445 "parse.y" +case 327: +#line 1459 "parse.y" { yyval.node = block_append(NEW_ARGS(0, 0, -1), yyvsp[0].node); ; break;} -case 325: -#line 1449 "parse.y" +case 328: +#line 1463 "parse.y" { yyval.node = NEW_ARGS(0, 0, -1); ; break;} -case 326: -#line 1454 "parse.y" +case 329: +#line 1468 "parse.y" { if (!is_local_id(yyvsp[0].id)) yyerror("formal argument must be local variable"); @@ -4129,8 +4158,8 @@ case 326: yyval.num = 1; ; break;} -case 327: -#line 1461 "parse.y" +case 330: +#line 1475 "parse.y" { if (!is_local_id(yyvsp[0].id)) yyerror("formal argument must be local variable"); @@ -4138,55 +4167,55 @@ case 327: yyval.num += 1; ; break;} -case 328: -#line 1469 "parse.y" +case 331: +#line 1483 "parse.y" { if (!is_local_id(yyvsp[-2].id)) yyerror("formal argument must be local variable"); yyval.node = assignable(yyvsp[-2].id, yyvsp[0].node); ; break;} -case 329: -#line 1476 "parse.y" +case 332: +#line 1490 "parse.y" { yyval.node = NEW_BLOCK(yyvsp[0].node); yyval.node->nd_end = yyval.node; ; break;} -case 330: -#line 1481 "parse.y" +case 333: +#line 1495 "parse.y" { yyval.node = block_append(yyvsp[-2].node, yyvsp[0].node); ; break;} -case 331: -#line 1486 "parse.y" +case 334: +#line 1500 "parse.y" { if (!is_local_id(yyvsp[0].id)) yyerror("rest argument must be local variable"); yyval.id = local_cnt(yyvsp[0].id); ; break;} -case 332: -#line 1493 "parse.y" +case 335: +#line 1507 "parse.y" { yyval.node = NEW_BLOCK_ARG(yyvsp[0].id); ; break;} -case 333: -#line 1498 "parse.y" +case 336: +#line 1512 "parse.y" { yyval.node = yyvsp[0].node; ; break;} -case 334: -#line 1502 "parse.y" +case 337: +#line 1516 "parse.y" { yyval.node = 0; ; break;} -case 335: -#line 1507 "parse.y" +case 338: +#line 1521 "parse.y" { if (nd_type(yyvsp[0].node) == NODE_SELF) { yyval.node = NEW_SELF(); @@ -4200,8 +4229,8 @@ case 335: } ; break;} -case 336: -#line 1520 "parse.y" +case 339: +#line 1534 "parse.y" { switch (nd_type(yyvsp[-2].node)) { case NODE_STR: @@ -4212,27 +4241,27 @@ case 336: case NODE_LIT: case NODE_ARRAY: case NODE_ZARRAY: - yyerror("Can't define single method for literals."); + yyerror("can't define single method for literals."); default: break; } yyval.node = yyvsp[-2].node; ; break;} -case 337: -#line 1538 "parse.y" +case 340: +#line 1552 "parse.y" { yyval.node = 0; ; break;} -case 338: -#line 1542 "parse.y" +case 341: +#line 1556 "parse.y" { yyval.node = yyvsp[-1].node; ; break;} -case 339: -#line 1546 "parse.y" +case 342: +#line 1560 "parse.y" { if (yyvsp[-1].node->nd_alen%2 != 0) { yyerror("odd number list for Hash"); @@ -4240,24 +4269,24 @@ case 339: yyval.node = yyvsp[-1].node; ; break;} -case 341: -#line 1555 "parse.y" +case 344: +#line 1569 "parse.y" { yyval.node = list_concat(yyvsp[-2].node, yyvsp[0].node); ; break;} -case 342: -#line 1560 "parse.y" +case 345: +#line 1574 "parse.y" { yyval.node = list_append(NEW_LIST(yyvsp[-2].node), yyvsp[0].node); ; break;} -case 355: -#line 1581 "parse.y" +case 358: +#line 1595 "parse.y" {yyerrok;; break;} -case 358: -#line 1585 "parse.y" +case 361: +#line 1599 "parse.y" {yyerrok;; break;} } @@ -4482,7 +4511,7 @@ yyerrhandle: } return 1; } -#line 1586 "parse.y" +#line 1600 "parse.y" #include #include @@ -4565,6 +4594,7 @@ yycompile(f) ruby__end__seen = 0; ruby_eval_tree = 0; newline_seen = 0; + heredoc_end = 0; ruby_sourcefile = f; ruby_in_compile = 1; n = yyparse(); @@ -4645,6 +4675,10 @@ normalize_newline(line) RSTRING(line)->ptr[RSTRING(line)->len-2] = '\n'; RSTRING(line)->len--; } +#ifdef __MACOS__ + else if (RSTRING(line)->ptr[RSTRING(line)->len-1] == '\r') + RSTRING(line)->ptr[RSTRING(line)->len-1] = '\n'; +#endif } static int @@ -4664,7 +4698,9 @@ nextc() normalize_newline(v); while (RSTRING(v)->len >= 2 && RSTRING(v)->ptr[RSTRING(v)->len-1] == '\n' && - RSTRING(v)->ptr[RSTRING(v)->len-2] == '\\') { + RSTRING(v)->ptr[RSTRING(v)->len-2] == '\\' && + (RSTRING(v)->len == 2 || + RSTRING(v)->ptr[RSTRING(v)->len-3] != '\\')) { VALUE v2 = (*lex_gets)(lex_input); if (!NIL_P(v2)) { @@ -4911,8 +4947,10 @@ parse_regx(term, paren) } /* fall through */ default: - if (c == paren) nest++; - if (c == term) nest--; + if (paren) { + if (c == paren) nest++; + if (c == term) nest--; + } if (c == '\n') { ruby_sourceline++; } @@ -5056,10 +5094,12 @@ parse_string(func, term, paren) } continue; } - if (c == paren) nest++; - if (c == term) { - nest--; - if (nest == 0) break; + if (paren) { + if (c == paren) nest++; + if (c == term) { + nest--; + if (nest == 0) break; + } } tokadd(c); } @@ -5134,10 +5174,12 @@ parse_qstring(term, paren) tokadd('\\'); } } - if (c == paren) nest++; - if (c == term) { - nest--; - if (nest == 0) break; + if (paren) { + if (c == paren) nest++; + if (c == term) { + nest--; + if (nest == 0) break; + } } tokadd(c); } @@ -5168,7 +5210,7 @@ here_document(term, indent) char *eos, *p; int len; VALUE str; - volatile VALUE line; + volatile VALUE line = 0; VALUE lastline_save; int offset_save; NODE *list = 0; @@ -5207,15 +5249,15 @@ here_document(term, indent) str = rb_str_new(0,0); for (;;) { - line = (*lex_gets)(lex_input); + lex_lastline = line = (*lex_gets)(lex_input); if (NIL_P(line)) { error: ruby_sourceline = linesave; rb_compile_error("can't find string \"%s\" anywhere before EOF", eos); - free(eos); - return 0; + free(eos); + return 0; } - normalize_newline(line); + normalize_newline(line); ruby_sourceline++; p = RSTRING(line)->ptr; if (indent) { @@ -5236,6 +5278,7 @@ here_document(term, indent) } } #endif + retry: switch (parse_string(term, '\n', '\n')) { case tSTRING: case tXSTRING: @@ -5260,6 +5303,9 @@ here_document(term, indent) case 0: goto error; } + if (lex_p != lex_pend) { + goto retry; + } } free(eos); lex_lastline = lastline_save; @@ -5296,8 +5342,8 @@ arg_ambiguous() rb_warning("ambiguous first argument; make sure"); } -#ifndef atof -double atof(); +#ifndef strtod +double strtod (); #endif static int @@ -5330,21 +5376,26 @@ retry: while ((c = nextc()) != '\n') { if (c == -1) return 0; - if (c == '\\') { /* skip a char */ - c = nextc(); - if (c == '\n') ruby_sourceline++; - } if (ismbchar(c)) { int i, len = mbclen(c)-1; for (i = 0; i < len; i++) { c = nextc(); if (c == '\n') { - ruby_sourceline++; + pushback(c); break; } } } + else if (c == ' ') { + if ((c = nextc()) == '\\') { + c = nextc(); + if (c == '\n') ruby_sourceline++; + } + else { + pushback(c); + } + } } /* fall through */ case '\n': @@ -5498,7 +5549,7 @@ retry: return parse_string(c,c,c); case '\'': - return parse_qstring(c,c); + return parse_qstring(c,0); case '?': if (lex_state == EXPR_END) { @@ -5653,29 +5704,49 @@ retry: c = nextc(); if (c == 'x' || c == 'X') { /* hexadecimal */ - while (c = nextc()) { + c = nextc(); + if (!ISXDIGIT(c)) { + yyerror("hexadecimal number without hex-digits"); + } + do { if (c == '_') continue; if (!ISXDIGIT(c)) break; tokadd(c); - } + } while (c = nextc()); pushback(c); tokfix(); yylval.val = rb_str2inum(tok(), 16); return tINTEGER; } - else if (c >= '0' && c <= '7') { - /* octal */ + if (c == 'b' || c == 'B') { + /* binary */ + c = nextc(); + if (c != '0' && c != '1') { + yyerror("numeric constant with no digits"); + } do { + if (c == '_') continue; + if (c != '0'&& c != '1') break; + tokadd(c); + } while (c = nextc()); + pushback(c); + tokfix(); + yylval.val = rb_str2inum(tok(), 2); + return tINTEGER; + } + if (c >= '0' && c <= '7' || c == '_') { + /* octal */ + do { + if (c == '_') continue; + if (c < '0' || c > '7') break; tokadd(c); - while ((c = nextc()) == '_') - ; - } while (c >= '0' && c <= '9'); + } while (c = nextc()); pushback(c); tokfix(); yylval.val = rb_str2inum(tok(), 8); return tINTEGER; } - else if (c > '7' && c <= '9') { + if (c > '7' && c <= '9') { yyerror("Illegal octal digit"); } else if (c == '.') { @@ -5740,7 +5811,12 @@ retry: pushback(c); tokfix(); if (is_float) { - yylval.val = rb_float_new(atof(tok())); + double d = strtod(tok(), 0); + if (errno == ERANGE) { + rb_warn("Float %s out of range", tok()); + errno = 0; + } + yylval.val = rb_float_new(d); return tFLOAT; } yylval.val = rb_str2inum(tok(), 10); @@ -5885,7 +5961,7 @@ retry: rb_compile_error("unterminated quoted string meets end of file"); return 0; } - paren = term; + paren = 0; if (term == '(') term = ')'; else if (term == '[') term = ']'; else if (term == '{') term = '}'; @@ -6030,6 +6106,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); @@ -6323,7 +6406,7 @@ block_append(head, tail) end = head->nd_end; } - if (RTEST(rb_verbose)) { + if (RTEST(ruby_verbose)) { NODE *nd = end->nd_head; newline: switch (nd_type(nd)) { diff --git a/parse.y b/parse.y index a4142bbe20..2d5ecfb4c7 100644 --- a/parse.y +++ b/parse.y @@ -6,7 +6,7 @@ $Date$ created at: Fri May 28 18:02:42 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -18,6 +18,8 @@ #include "node.h" #include "st.h" #include +#include +#include /* hack for bison */ #ifdef const @@ -801,6 +803,10 @@ call_args : command_call value_expr($1); $$ = NEW_LIST($1); } + | args ',' + { + $$ = $1; + } | args opt_block_arg { $$ = arg_blk_pass($1, $2); @@ -810,6 +816,10 @@ call_args : command_call $$ = arg_add($1, $4); $$ = arg_blk_pass($$, $5); } + | assocs ',' + { + $$ = NEW_LIST(NEW_HASH($1)); + } | assocs opt_block_arg { $$ = NEW_LIST(NEW_HASH($1)); @@ -825,6 +835,10 @@ call_args : command_call $$ = list_append($1, NEW_HASH($3)); $$ = arg_blk_pass($$, $4); } + | args ',' assocs ',' + { + $$ = list_append($1, NEW_HASH($3)); + } | args ',' assocs ',' tSTAR arg opt_block_arg { $$ = arg_add(list_append($1, NEW_HASH($3)), $6); @@ -1516,7 +1530,7 @@ singleton : var_ref $$ = $1; } } - | tLPAREN expr opt_nl ')' + | '(' expr opt_nl ')' { switch (nd_type($2)) { case NODE_STR: @@ -1527,7 +1541,7 @@ singleton : var_ref case NODE_LIT: case NODE_ARRAY: case NODE_ZARRAY: - yyerror("Can't define single method for literals."); + yyerror("can't define single method for literals."); default: break; } @@ -1665,6 +1679,7 @@ yycompile(f) ruby__end__seen = 0; ruby_eval_tree = 0; newline_seen = 0; + heredoc_end = 0; ruby_sourcefile = f; ruby_in_compile = 1; n = yyparse(); @@ -1745,6 +1760,10 @@ normalize_newline(line) RSTRING(line)->ptr[RSTRING(line)->len-2] = '\n'; RSTRING(line)->len--; } +#ifdef __MACOS__ + else if (RSTRING(line)->ptr[RSTRING(line)->len-1] == '\r') + RSTRING(line)->ptr[RSTRING(line)->len-1] = '\n'; +#endif } static int @@ -1764,7 +1783,9 @@ nextc() normalize_newline(v); while (RSTRING(v)->len >= 2 && RSTRING(v)->ptr[RSTRING(v)->len-1] == '\n' && - RSTRING(v)->ptr[RSTRING(v)->len-2] == '\\') { + RSTRING(v)->ptr[RSTRING(v)->len-2] == '\\' && + (RSTRING(v)->len == 2 || + RSTRING(v)->ptr[RSTRING(v)->len-3] != '\\')) { VALUE v2 = (*lex_gets)(lex_input); if (!NIL_P(v2)) { @@ -2011,8 +2032,10 @@ parse_regx(term, paren) } /* fall through */ default: - if (c == paren) nest++; - if (c == term) nest--; + if (paren) { + if (c == paren) nest++; + if (c == term) nest--; + } if (c == '\n') { ruby_sourceline++; } @@ -2156,10 +2179,12 @@ parse_string(func, term, paren) } continue; } - if (c == paren) nest++; - if (c == term) { - nest--; - if (nest == 0) break; + if (paren) { + if (c == paren) nest++; + if (c == term) { + nest--; + if (nest == 0) break; + } } tokadd(c); } @@ -2234,10 +2259,12 @@ parse_qstring(term, paren) tokadd('\\'); } } - if (c == paren) nest++; - if (c == term) { - nest--; - if (nest == 0) break; + if (paren) { + if (c == paren) nest++; + if (c == term) { + nest--; + if (nest == 0) break; + } } tokadd(c); } @@ -2268,7 +2295,7 @@ here_document(term, indent) char *eos, *p; int len; VALUE str; - volatile VALUE line; + volatile VALUE line = 0; VALUE lastline_save; int offset_save; NODE *list = 0; @@ -2307,15 +2334,15 @@ here_document(term, indent) str = rb_str_new(0,0); for (;;) { - line = (*lex_gets)(lex_input); + lex_lastline = line = (*lex_gets)(lex_input); if (NIL_P(line)) { error: ruby_sourceline = linesave; rb_compile_error("can't find string \"%s\" anywhere before EOF", eos); - free(eos); - return 0; + free(eos); + return 0; } - normalize_newline(line); + normalize_newline(line); ruby_sourceline++; p = RSTRING(line)->ptr; if (indent) { @@ -2336,6 +2363,7 @@ here_document(term, indent) } } #endif + retry: switch (parse_string(term, '\n', '\n')) { case tSTRING: case tXSTRING: @@ -2360,6 +2388,9 @@ here_document(term, indent) case 0: goto error; } + if (lex_p != lex_pend) { + goto retry; + } } free(eos); lex_lastline = lastline_save; @@ -2396,8 +2427,8 @@ arg_ambiguous() rb_warning("ambiguous first argument; make sure"); } -#ifndef atof -double atof(); +#ifndef strtod +double strtod (); #endif static int @@ -2430,21 +2461,26 @@ retry: while ((c = nextc()) != '\n') { if (c == -1) return 0; - if (c == '\\') { /* skip a char */ - c = nextc(); - if (c == '\n') ruby_sourceline++; - } if (ismbchar(c)) { int i, len = mbclen(c)-1; for (i = 0; i < len; i++) { c = nextc(); if (c == '\n') { - ruby_sourceline++; + pushback(c); break; } } } + else if (c == ' ') { + if ((c = nextc()) == '\\') { + c = nextc(); + if (c == '\n') ruby_sourceline++; + } + else { + pushback(c); + } + } } /* fall through */ case '\n': @@ -2598,7 +2634,7 @@ retry: return parse_string(c,c,c); case '\'': - return parse_qstring(c,c); + return parse_qstring(c,0); case '?': if (lex_state == EXPR_END) { @@ -2753,29 +2789,49 @@ retry: c = nextc(); if (c == 'x' || c == 'X') { /* hexadecimal */ - while (c = nextc()) { + c = nextc(); + if (!ISXDIGIT(c)) { + yyerror("hexadecimal number without hex-digits"); + } + do { if (c == '_') continue; if (!ISXDIGIT(c)) break; tokadd(c); - } + } while (c = nextc()); pushback(c); tokfix(); yylval.val = rb_str2inum(tok(), 16); return tINTEGER; } - else if (c >= '0' && c <= '7') { - /* octal */ + if (c == 'b' || c == 'B') { + /* binary */ + c = nextc(); + if (c != '0' && c != '1') { + yyerror("numeric constant with no digits"); + } do { + if (c == '_') continue; + if (c != '0'&& c != '1') break; tokadd(c); - while ((c = nextc()) == '_') - ; - } while (c >= '0' && c <= '9'); + } while (c = nextc()); + pushback(c); + tokfix(); + yylval.val = rb_str2inum(tok(), 2); + return tINTEGER; + } + if (c >= '0' && c <= '7' || c == '_') { + /* octal */ + do { + if (c == '_') continue; + if (c < '0' || c > '7') break; + tokadd(c); + } while (c = nextc()); pushback(c); tokfix(); yylval.val = rb_str2inum(tok(), 8); return tINTEGER; } - else if (c > '7' && c <= '9') { + if (c > '7' && c <= '9') { yyerror("Illegal octal digit"); } else if (c == '.') { @@ -2840,7 +2896,12 @@ retry: pushback(c); tokfix(); if (is_float) { - yylval.val = rb_float_new(atof(tok())); + double d = strtod(tok(), 0); + if (errno == ERANGE) { + rb_warn("Float %s out of range", tok()); + errno = 0; + } + yylval.val = rb_float_new(d); return tFLOAT; } yylval.val = rb_str2inum(tok(), 10); @@ -2985,7 +3046,7 @@ retry: rb_compile_error("unterminated quoted string meets end of file"); return 0; } - paren = term; + paren = 0; if (term == '(') term = ')'; else if (term == '[') term = ']'; else if (term == '{') term = '}'; @@ -3130,6 +3191,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); @@ -3423,7 +3491,7 @@ block_append(head, tail) end = head->nd_end; } - if (RTEST(rb_verbose)) { + if (RTEST(ruby_verbose)) { NODE *nd = end->nd_head; newline: switch (nd_type(nd)) { diff --git a/process.c b/process.c index d3e6559ca3..8a275652d9 100644 --- a/process.c +++ b/process.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 14:30:50 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -117,7 +117,7 @@ rb_waitpid(pid, flags, st) } if (flags) { - rb_raise(rb_eArgError, "Can't do waitpid with flags"); + rb_raise(rb_eArgError, "can't do waitpid with flags"); } for (;;) { @@ -138,7 +138,7 @@ rb_waitpid(pid, flags, st) pid_tbl = st_init_numtable(); st_insert(pid_tbl, pid, st); #ifdef USE_THREAD - if (!thread_alone()) rb_thread_schedule(); + if (!rb_thread_alone()) rb_thread_schedule(); #endif } #endif @@ -521,7 +521,7 @@ static VALUE rb_f_fork(obj) VALUE obj; { -#if !defined(__human68k__) +#if !defined(__human68k__) && !defined(__MACOS__) int pid; rb_secure(2); @@ -670,7 +670,10 @@ rb_f_system(argc, argv) rb_last_status = state == -1 ? INT2FIX(127) : INT2FIX(state); return state == 0 ? Qtrue : Qfalse ; #else - volatile VALUE prog = 0; +#if defined(USE_CWGUSI) + rb_notimplement(); +#else + volatile VALUE prog = 0; int pid; int i; @@ -725,9 +728,10 @@ rb_f_system(argc, argv) if (rb_last_status == INT2FIX(0)) return Qtrue; return Qfalse; -#endif -#endif -#endif +#endif /* USE_CWGUSI */ +#endif /* __human68k__ */ +#endif /* DJGPP */ +#endif /* NT */ } static VALUE @@ -771,26 +775,29 @@ 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; -#ifdef BSD_GETPGRP +#ifndef GETPGRP_VOID VALUE vpid; int pid; rb_scan_args(argc, argv, "01", &vpid); pid = NIL_P(vpid)?0:NUM2INT(vpid); - pgrp = BSD_GETPGRP(pid); + pgrp = getpgrp(pid); #else rb_scan_args(argc, argv, "0"); pgrp = getpgrp(); #endif if (pgrp < 0) rb_sys_fail(0); return INT2FIX(pgrp); +#else + rb_notimplement(); +#endif } static VALUE @@ -799,7 +806,7 @@ proc_setpgrp(argc, argv) VALUE *argv; { #ifdef HAVE_SETPGRP -#ifdef BSD_SETPGRP +#ifndef SETPGRP_VOID VALUE pid, pgrp; int ipid, ipgrp; @@ -807,7 +814,7 @@ proc_setpgrp(argc, argv) ipid = NIL_P(pid)?0:NUM2INT(pid); ipgrp = NIL_P(pgrp)?0:NUM2INT(pgrp); - if (BSD_SETPGRP(ipid, ipgrp) < 0) rb_sys_fail(0); + if (setpgrp(ipid, ipgrp) < 0) rb_sys_fail(0); #else rb_scan_args(argc, argv, "0"); if (setpgrp() < 0) rb_sys_fail(0); @@ -898,7 +905,6 @@ proc_setpriority(obj, which, who, prio) rb_notimplement(); #endif } -#endif static VALUE proc_getuid(obj) @@ -1032,13 +1038,11 @@ Init_process() #ifndef USE_CWGUSI rb_define_global_function("exec", rb_f_exec, -1); #endif -#if !defined(NT) && !defined(USE_CWGUSI) +#if !defined(NT) rb_define_global_function("fork", rb_f_fork, 0); #endif rb_define_global_function("exit!", rb_f_exit_bang, 1); -#ifndef USE_CWGUSI rb_define_global_function("system", rb_f_system, -1); -#endif rb_define_global_function("sleep", rb_f_sleep, -1); rb_mProcess = rb_define_module("Process"); @@ -1056,7 +1060,7 @@ Init_process() #endif #endif -#if !defined(NT) && !defined(USE_CWGUSI) +#if !defined(NT) rb_define_singleton_method(rb_mProcess, "fork", rb_f_fork, 0); #endif rb_define_singleton_method(rb_mProcess, "exit!", rb_f_exit_bang, 1); @@ -1073,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); @@ -1098,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/random.c b/random.c index 7b57d472cd..137b34d579 100644 --- a/random.c +++ b/random.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Dec 24 16:39:21 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ diff --git a/range.c b/range.c index 9fc363e2a8..30c9996153 100644 --- a/range.c +++ b/range.c @@ -6,7 +6,7 @@ $Date$ created at: Thu Aug 19 17:46:47 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -35,11 +35,10 @@ range_s_new(klass, beg, end) VALUE klass, beg, end; { VALUE obj; + VALUE args[2]; + args[0] = beg; args[1] = end; if (!FIXNUM_P(beg) || !FIXNUM_P(end)) { - VALUE args[2]; - - args[0] = beg; args[1] = end; rb_rescue(range_check, (VALUE)args, range_failed, 0); } @@ -47,7 +46,7 @@ range_s_new(klass, beg, end) rb_ivar_set(obj, id_beg, beg); rb_ivar_set(obj, id_end, end); - rb_obj_call_init(obj); + rb_obj_call_init(obj, 2, args); return obj; } diff --git a/re.c b/re.c index 287c6c1bd4..f8c268ea37 100644 --- a/re.c +++ b/re.c @@ -5,7 +5,7 @@ $Author$ created at: Mon Aug 9 18:24:49 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -330,7 +330,7 @@ rb_reg_kcode_method(re) static Regexp* make_regexp(s, len, flag) char *s; - size_t len, flag; + int len, flag; { Regexp *rp; char *err; @@ -392,6 +392,21 @@ match_clone(orig) return (VALUE)match; } +#define MATCH_BUSY FL_USER2 + +void +rb_match_busy(match, busy) + VALUE match; + int busy; +{ + if (busy) { + FL_SET(match, MATCH_BUSY); + } + else { + FL_UNSET(match, MATCH_BUSY); + } +} + int ruby_ignorecase; static int may_need_recompile; static VALUE matchcache; @@ -462,7 +477,7 @@ rb_reg_search(reg, str, start, reverse) #else match = rb_backref_get(); #endif - if (NIL_P(match)) { + if (NIL_P(match) || FL_TEST(match, MATCH_BUSY)) { if (matchcache) { match = matchcache; matchcache = 0; @@ -481,6 +496,8 @@ rb_reg_search(reg, str, start, reverse) } result = re_search(RREGEXP(reg)->ptr,RSTRING(str)->ptr,RSTRING(str)->len, start, range, regs); + if (FL_TEST(reg, KCODE_FIXED)) + kcode_reset_option(); if (result == -2) { rb_reg_raise(RREGEXP(reg)->str, RREGEXP(reg)->len, @@ -653,7 +670,7 @@ static VALUE rb_reg_new_1(klass, s, len, options) VALUE klass; char *s; - size_t len; + int len; int options; /* CASEFOLD = 1 */ /* EXTENDED = 2 */ /* CODE_NONE = 4 */ @@ -703,7 +720,7 @@ rb_reg_new_1(klass, s, len, options) if (options & ~0x3) { kcode_reset_option(); } - rb_obj_call_init((VALUE)re); + rb_obj_call_init((VALUE)re, 0, 0); return (VALUE)re; } @@ -711,7 +728,7 @@ rb_reg_new_1(klass, s, len, options) VALUE rb_reg_new(s, len, options) char *s; - size_t len; + int len; int options; { return rb_reg_new_1(rb_cRegexp, s, len, options); @@ -826,6 +843,9 @@ rb_reg_s_new(argc, argv, self) case 's': case 'S': flag |= 12; break; + case 'u': case 'U': + flag |= 16; + break; default: break; } @@ -837,7 +857,7 @@ rb_reg_s_new(argc, argv, self) } else { char *p; - size_t len; + int len; p = str2cstr(src, &len); return rb_reg_new_1(self, p, len, flag); @@ -859,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 == ']' @@ -886,6 +909,8 @@ rb_kcode() return MBCTYPE_EUC; case KCODE_SJIS: return MBCTYPE_SJIS; + case KCODE_UTF8: + return MBCTYPE_UTF8; case KCODE_NONE: return MBCTYPE_ASCII; } @@ -905,6 +930,8 @@ rb_reg_get_kcode(re) kcode |= 8; break; case KCODE_SJIS: kcode |= 12; break; + case KCODE_UTF8: + kcode |= 16; break; default: break; } @@ -955,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; @@ -1092,7 +1119,10 @@ ignorecase_setter(val) static VALUE match_getter() { - return match_clone(rb_backref_get()); + VALUE match = rb_backref_get(); + + if (NIL_P(match)) return Qnil; + return match_clone(match); } static void diff --git a/re.h b/re.h index 4d7220b5e6..dc4cd17354 100644 --- a/re.h +++ b/re.h @@ -6,7 +6,7 @@ $Date$ created at: Thu Sep 30 14:18:32 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ diff --git a/regex.c b/regex.c new file mode 100644 index 0000000000..4a33461ebe --- /dev/null +++ b/regex.c @@ -0,0 +1,4485 @@ +/* Extended regular expression matching and search library. + Copyright (C) 1993, 94, 95, 96, 97, 98 Free Software Foundation, Inc. + + 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., 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 */ +/* removed gapped buffer support, multiple syntax support by matz */ +/* Perl5 extension added by matz */ +/* UTF-8 extension added Jan 16 1999 by Yoshida Masato */ + +#include "config.h" +#ifdef RUBY_PLATFORM +# define RUBY +#endif + +/* We write fatal error messages on standard error. */ +#include + +/* isalpha(3) etc. are used for the character classes. */ +#include +#include + +#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 +#else +/* We need this for `regex.h', and perhaps for the Emacs include files. */ +# include +#endif + +#if defined(STDC_HEADERS) +# include +#else +/* We need this for `regex.h', and perhaps for the Emacs include files. */ +# include +#endif + +#ifndef __STDC__ +# define volatile +# ifdef __GNUC__ +# define const __const__ +# else +# define const +# endif +#endif + +#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 +/* Make alloca work the best possible way. */ +#ifdef __GNUC__ +# ifndef atarist +# ifndef alloca +# define alloca __builtin_alloca +# endif +# endif /* atarist */ +#else +# if defined(HAVE_ALLOCA_H) +# include +# else +char *alloca(); +# endif +#endif /* __GNUC__ */ + +#ifdef _AIX +#pragma alloca +#endif + +#ifdef HAVE_STRING_H +# include +#else +# include +#endif + +#define RE_ALLOCATE alloca +#ifdef C_ALLOCA +#define FREE_VARIABLES() alloca(0) +#else +#define FREE_VARIABLES() +#endif + +#define FREE_AND_RETURN_VOID(stackb) return +#define FREE_AND_RETURN(stackb,val) return(val) +#define DOUBLE_STACK(stackx,stackb,len,type) \ + (stackx = (type*)alloca(2 * len * sizeof(type)), \ + /* Only copy what is in use. */ \ + (type*)memcpy(stackx, stackb, len * sizeof (type))) +#else /* NO_ALLOCA defined */ + +#define RE_ALLOCATE xmalloc + +#define FREE_VAR(var) if (var) free(var); var = NULL +#define FREE_VARIABLES() \ + do { \ + FREE_VAR(regstart); \ + FREE_VAR(regend); \ + FREE_VAR(old_regstart) \ + FREE_VAR(old_regend); \ + FREE_VAR(best_regstart); \ + FREE_VAR(best_regend); \ + FREE_VAR(reg_info); \ + } while (0) + +#define FREE_AND_RETURN_VOID(stackb) free(stackb);return +#define FREE_AND_RETURN(stackb,val) free(stackb);return(val) +#define DOUBLE_STACK(stackx,stackb,len,type) \ + (type*)xrealloc(stackb, 2 * len * sizeof(type)) +#endif /* NO_ALLOCA */ + +#define RE_TALLOC(n,t) ((t*)RE_ALLOCATE((n)*sizeof(t))) +#define TMALLOC(n,t) ((t*)xmalloc((n)*sizeof(t))) +#define TREALLOC(s,n,t) (s=((t*)xrealloc(s,(n)*sizeof(t)))) + +#define EXPAND_FAIL_STACK(stackx,stackb,len) \ + do {\ + /* Roughly double the size of the stack. */ \ + stackx = DOUBLE_STACK(stackx,stackb,len,unsigned char*); \ + /* Rearrange the pointers. */ \ + stackp = stackx + (stackp - stackb); \ + stackb = stackx; \ + stacke = stackb + 2 * len; \ + } while (0) + +/* Get the interface, including the syntax bits. */ +#include "regex.h" + +/* Subroutines for re_compile_pattern. */ +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. */ + +/* This must be nonzero for the wordchar and notwordchar pattern + commands in re_match. */ +#define Sword 1 +#define Sword2 2 + +#define SYNTAX(c) re_syntax_table[c] + +static char re_syntax_table[256]; +static void init_syntax_once _((void)); +static unsigned char *translate = 0; +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() +{ + register int c; + static int done = 0; + + if (done) + return; + + memset(re_syntax_table, 0, sizeof re_syntax_table); + + for (c=0; c<0x7f; c++) + if (isalnum(c)) + re_syntax_table[c] = Sword; + re_syntax_table['_'] = Sword; + + for (c=0x80; c<=0xff; c++) + if (isalnum(c)) + re_syntax_table[c] = Sword2; + done = 1; +} + +void +re_set_casetable(table) + char *table; +{ + translate = (unsigned char*)table; +} + +/* Jim Meyering writes: + + "... Some ctype macros are valid only for character codes that + isascii says are ASCII (SGI's IRIX-4.0.5 is one such system --when + using /bin/cc or gcc but without giving an ansi option). So, all + ctype uses should be through macros like ISPRINT... If + 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." + 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) (ISASCII (c) && isblank (c)) +#else +# define ISBLANK(c) ((c) == ' ' || (c) == '\t') +#endif +#ifdef isgraph +# define ISGRAPH(c) (ISASCII (c) && isgraph (c)) +#else +# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) +#endif + +#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 + argument bytes. A command code can specify any interpretation + whatsoever for its arguments. Zero-bytes may appear in the compiled + regular expression. + + The value of `exactn' is needed in search.c (search_buffer) in emacs. + So regex.h defines a symbol `RE_EXACTN_VALUE' to be 1; the value of + `exactn' we use here must also be 1. */ + +enum regexpcode + { + unused=0, + exactn=1, /* Followed by one byte giving n, then by n literal bytes. */ + begline, /* Fail unless at beginning of line. */ + endline, /* Fail unless at end of line. */ + begbuf, /* Succeeds if at beginning of buffer (if emacs) or at beginning + of string to be matched (if not). */ + endbuf, /* Analogously, for end of buffer/string. */ + endbuf2, /* End of buffer/string, or newline just before it. */ + jump, /* Followed by two bytes giving relative address to jump to. */ + jump_past_alt,/* Same as jump, but marks the end of an alternative. */ + on_failure_jump, /* Followed by two bytes giving relative address of + place to resume at in case of failure. */ + finalize_jump, /* Throw away latest failure point and then jump to + address. */ + maybe_finalize_jump, /* Like jump but finalize if safe to do so. + This is used to jump back to the beginning + of a repeat. If the command that follows + this jump is clearly incompatible with the + one at the beginning of the repeat, such that + we can be sure that there is no use backtracking + out of repetitions already completed, + then we finalize. */ + dummy_failure_jump, /* Jump, and push a dummy failure point. This + failure point will be thrown away if an attempt + is made to use it for a failure. A + construct + makes this before the first repeat. Also + use it as an intermediary kind of jump when + compiling an or construct. */ + push_dummy_failure, /* Push a dummy failure point and continue. Used at the end of + alternatives. */ + succeed_n, /* Used like on_failure_jump except has to succeed n times; + then gets turned into an on_failure_jump. The relative + address following it is useless until then. The + address is followed by two bytes containing n. */ + jump_n, /* Similar to jump, but jump n times only; also the relative + address following is in turn followed by yet two more bytes + containing n. */ + try_next, /* Jump to next pattern for the first time, + leaving this pattern on the failure stack. */ + finalize_push, /* Finalize stack and push the beginning of the pattern + on the stack to retry (used for non-greedy match) */ + finalize_push_n, /* Similar to finalize_push, buf finalize n time only */ + set_number_at, /* Set the following relative location to the + subsequent number. */ + anychar, /* Matches any (more or less) one character. */ + charset, /* Matches any one char belonging to specified set. + First following byte is number of bitmap bytes. + Then come bytes for a bitmap saying which chars are in. + Bits in each byte are ordered low-bit-first. + A character is in the set if its bit is 1. + A character too large to have a bit in the map + is automatically not in the set. */ + charset_not, /* Same parameters as charset, but match any character + that is not one of those specified. */ + start_memory, /* Start remembering the text that is matched, for + storing in a memory register. Followed by one + byte containing the register number. Register numbers + must be in the range 0 through RE_NREGS. */ + stop_memory, /* Stop remembering the text that is matched + and store it in a memory register. Followed by + one byte containing the register number. Register + numbers must be in the range 0 through RE_NREGS. */ + stop_paren, /* Place holder at the end of (?:..). */ + casefold_on, /* Turn on casefold flag. */ + casefold_off, /* Turn off casefold flag. */ + start_nowidth, /* Save string point to the stack. */ + stop_nowidth, /* Restore string place at the point start_nowidth. */ + pop_and_fail, /* Fail after popping nowidth entry from stack. */ + duplicate, /* Match a duplicate of something remembered. + Followed by one byte containing the index of the memory + register. */ + wordchar, /* Matches any word-constituent character. */ + notwordchar, /* Matches any char that is not a word-constituent. */ + wordbeg, /* Succeeds if at word beginning. */ + wordend, /* Succeeds if at word end. */ + wordbound, /* Succeeds if at a word boundary. */ + notwordbound,/* Succeeds if not at a word boundary. */ + }; + + +/* Number of failure points to allocate space for initially, + when matching. If this number is exceeded, more space is allocated, + so it is not a hard limit. */ + +#ifndef NFAILURES +#define NFAILURES 80 +#endif + +/* Store NUMBER in two contiguous bytes starting at DESTINATION. */ +#define STORE_NUMBER(destination, number) \ + do { (destination)[0] = (number) & 0377; \ + (destination)[1] = (number) >> 8; } while (0) + +/* Same as STORE_NUMBER, except increment the destination pointer to + the byte after where the number is stored. Watch out that values for + DESTINATION such as p + 1 won't work, whereas p will. */ +#define STORE_NUMBER_AND_INCR(destination, number) \ + do { STORE_NUMBER(destination, number); \ + (destination) += 2; } while (0) + + +/* Put into DESTINATION a number stored in two contingous bytes starting + at SOURCE. */ +#define EXTRACT_NUMBER(destination, source) \ + do { (destination) = *(source) & 0377; \ + (destination) += SIGN_EXTEND_CHAR (*(char*)((source) + 1)) << 8; } while (0) + +/* Same as EXTRACT_NUMBER, except increment the pointer for source to + point to second byte of SOURCE. Note that SOURCE has to be a value + such as p, not, e.g., p + 1. */ +#define EXTRACT_NUMBER_AND_INCR(destination, source) \ + do { EXTRACT_NUMBER(destination, source); \ + (source) += 2; } while (0) + + +/* Specify the precise syntax of regexps for compilation. This provides + for compatibility for various utilities which historically have + different, incompatible syntaxes. + + The argument SYNTAX is a bit-mask comprised of the various bits + defined in regex.h. */ + +long +re_set_syntax(syntax) + long syntax; +{ + /* obsolete */ +} + + +/* Macros for re_compile_pattern, which is found below these definitions. */ + +#define TRANSLATE_P() ((options&RE_OPTION_IGNORECASE) && translate) +#define MAY_TRANSLATE() ((bufp->options&(RE_OPTION_IGNORECASE|RE_MAY_IGNORECASE)) && translate) +/* Fetch the next character in the uncompiled pattern---translating it + if necessary. Also cast from a signed character in the constant + string passed to us by the user to an unsigned char that we can use + as an array index (in, e.g., `translate'). */ +#define PATFETCH(c) \ + do {if (p == pend) goto end_of_pattern; \ + c = (unsigned char) *p++; \ + if (TRANSLATE_P()) c = (unsigned char)translate[c]; \ + } while (0) + +/* Fetch the next character in the uncompiled pattern, with no + translation. */ +#define PATFETCH_RAW(c) \ + do {if (p == pend) goto end_of_pattern; \ + c = (unsigned char)*p++; \ + } while (0) + +/* Go backwards one character in the pattern. */ +#define PATUNFETCH p-- + +#define MBC2WC(c, p)\ + do {\ + if (current_mbctype == MBCTYPE_UTF8) {\ + int n = mbclen(c) - 1;\ + int c1;\ + c &= (1<<(BYTEWIDTH-2-n)) - 1;\ + while (n--) {\ + c = c << 6 | *p++ & ((1<<6)-1);\ + }\ + }\ + else {\ + c <<= 8;\ + c |= (unsigned char)*(p)++;\ + }\ + } while (0) + +#define PATFETCH_MBC(c) \ + do {\ + if (p + mbclen(c) - 1 >= pend) goto end_of_pattern;\ + MBC2WC(c, p);\ + } while(0) + +#define WC2MBC1ST(c) \ + ((current_mbctype != MBCTYPE_UTF8)?(((c)>>8)&0xff):utf8_firstbyte(c)) + +static unsigned int +utf8_firstbyte(c) + unsigned int c; +{ + if (c < 0x80) return c; + if (c < 0x7ff) return ((c>>6)&0xff)|0xc0; + if (c < 0xffff) return ((c>>12)&0xff)|0xe0; + if (c < 0x1fffff) return ((c>>18)&0xff)|0xf0; + if (c < 0x3ffffff) return ((c>>24)&0xff)|0xf8; + if (c < 0x7fffffff) return ((c>>30)&0xff)|0xfc; +} + +static void +print_mbc(c) + unsigned int c; +{ + if (current_mbctype == MBCTYPE_UTF8) { + if (c < 0x80) + printf("%c", c); + else if (c < 0x7ff) + printf("%c%c", utf8_firstbyte(c), c&0x3f); + else if (c < 0xffff) + printf("%c%c%c", utf8_firstbyte(c), (c>>6)&0x3f, c&0x3f); + else if (c < 0x1fffff) + printf("%c%c%c%c", utf8_firstbyte(c), (c>>12)&0x3f, (c>>6)&0x3f, c&0x3f); + else if (c < 0x3ffffff) + printf("%c%c%c%c%c", utf8_firstbyte(c), (c>>18)&0x3f, (c>>12)&0x3f, (c>>6)&0x3f, c&0x3f); + else if (c < 0x7fffffff) + printf("%c%c%c%c%c", utf8_firstbyte(c), (c>>24)&0x3f, (c>>18)&0x3f, (c>>12)&0x3f, (c>>6)&0x3f, c&0x3f); + } + else { + printf("%c%c", c>>BYTEWIDTH, c&0xff); + } +} + +/* If the buffer isn't allocated when it comes in, use this. */ +#define INIT_BUF_SIZE 28 + +/* Make sure we have at least N more bytes of space in buffer. */ +#define GET_BUFFER_SPACE(n) \ + do { \ + while (b - bufp->buffer + (n) >= bufp->allocated) \ + EXTEND_BUFFER; \ + } while (0) + +/* Make sure we have one more byte of buffer space and then add CH to it. */ +#define BUFPUSH(ch) \ + do { \ + GET_BUFFER_SPACE(1); \ + *b++ = (char)(ch); \ + } while (0) + +/* Extend the buffer by twice its current size via reallociation and + reset the pointers that pointed into the old allocation to point to + the correct places in the new allocation. If extending the buffer + results in it being larger than 1 << 16, then flag memory exhausted. */ +#define EXTEND_BUFFER \ + do { char *old_buffer = bufp->buffer; \ + if (bufp->allocated == (1L<<16)) goto too_big; \ + bufp->allocated *= 2; \ + if (bufp->allocated > (1L<<16)) bufp->allocated = (1L<<16); \ + bufp->buffer = (char*)xrealloc (bufp->buffer, bufp->allocated); \ + if (bufp->buffer == 0) \ + goto memory_exhausted; \ + b = (b - old_buffer) + bufp->buffer; \ + if (fixup_alt_jump) \ + fixup_alt_jump = (fixup_alt_jump - old_buffer) + bufp->buffer; \ + if (laststart) \ + laststart = (laststart - old_buffer) + bufp->buffer; \ + begalt = (begalt - old_buffer) + bufp->buffer; \ + if (pending_exact) \ + pending_exact = (pending_exact - old_buffer) + bufp->buffer; \ + } while (0) + + +/* Set the bit for character C in a character set list. */ +#define SET_LIST_BIT(c) \ + (b[(unsigned char)(c) / BYTEWIDTH] \ + |= 1 << ((unsigned char)(c) % BYTEWIDTH)) + +/* Get the next unsigned number in the uncompiled pattern. */ +#define GET_UNSIGNED_NUMBER(num) \ + do { if (p != pend) { \ + PATFETCH(c); \ + while (ISDIGIT(c)) { \ + if (num < 0) \ + num = 0; \ + num = num * 10 + c - '0'; \ + if (p == pend) \ + break; \ + PATFETCH(c); \ + } \ + } \ + } while (0) + +#define STREQ(s1, s2) ((strcmp (s1, s2) == 0)) + +#define CHAR_CLASS_MAX_LENGTH 6 /* Namely, `xdigit'. */ + +#define IS_CHAR_CLASS(string) \ + (STREQ(string, "alpha") || STREQ(string, "upper") \ + || STREQ(string, "lower") || STREQ(string, "digit") \ + || STREQ(string, "alnum") || STREQ(string, "xdigit") \ + || STREQ(string, "space") || STREQ(string, "print") \ + || STREQ(string, "punct") || STREQ(string, "graph") \ + || STREQ(string, "cntrl") || STREQ(string, "blank")) + +#define STORE_MBC(p, c) \ + do { \ + (p)[0] = (unsigned char)(((c) >>24) & 0xff); \ + (p)[1] = (unsigned char)(((c) >>16) & 0xff); \ + (p)[2] = (unsigned char)(((c) >> 8) & 0xff); \ + (p)[3] = (unsigned char)(((c) >> 0) & 0xff); \ + } while (0) + +#define STORE_MBC_AND_INCR(p, c) \ + do { \ + *(p)++ = (unsigned char)(((c) >>24) & 0xff); \ + *(p)++ = (unsigned char)(((c) >>16) & 0xff); \ + *(p)++ = (unsigned char)(((c) >> 8) & 0xff); \ + *(p)++ = (unsigned char)(((c) >> 0) & 0xff); \ + } while (0) + +#define EXTRACT_MBC(p) \ + ((unsigned short)((unsigned char)(p)[0] << 24 | \ + (unsigned char)(p)[1] << 16 | \ + (unsigned char)(p)[2] << 8 | \ + (unsigned char)(p)[3])) + +#define EXTRACT_MBC_AND_INCR(p) \ + ((unsigned short)((p) += 4, \ + (unsigned char)(p)[-4] << 24 | \ + (unsigned char)(p)[-3] << 16 | \ + (unsigned char)(p)[-2] << 8 | \ + (unsigned char)(p)[-1])) + +#define EXTRACT_UNSIGNED(p) \ + ((unsigned char)(p)[0] | (unsigned char)(p)[1] << 8) +#define EXTRACT_UNSIGNED_AND_INCR(p) \ + ((p) += 2, (unsigned char)(p)[-2] | (unsigned char)(p)[-1] << 8) + +/* Handle (mb)?charset(_not)?. + + Structure of mbcharset(_not)? in compiled pattern. + + struct { + unsinged char id; mbcharset(_not)? + unsigned char sbc_size; + unsigned char sbc_map[sbc_size]; same as charset(_not)? up to here. + unsigned short mbc_size; number of intervals. + struct { + unsigned int beg; beginning of interval. + unsigned int end; end of interval. + } intervals[mbc_size]; + }; */ + +static void +set_list_bits(c1, c2, b) + unsigned int c1, c2; + unsigned char *b; +{ + unsigned char sbc_size = b[-1]; + unsigned short mbc_size = EXTRACT_UNSIGNED(&b[sbc_size]); + unsigned short beg, end, upb; + + if (c1 > c2) + return; + b = &b[sbc_size + 2]; + + for (beg = 0, upb = mbc_size; beg < upb; ) { + unsigned short mid = (unsigned short)(beg + upb) >> 1; + + if ((int)c1 - 1 > (int)EXTRACT_MBC(&b[mid*8+4])) + beg = mid + 1; + else + upb = mid; + } + + for (end = beg, upb = mbc_size; end < upb; ) { + unsigned short mid = (unsigned short)(end + upb) >> 1; + + if ((int)c2 >= (int)EXTRACT_MBC(&b[mid*8]) - 1) + end = mid + 1; + else + upb = mid; + } + + if (beg != end) { + if (c1 > EXTRACT_MBC(&b[beg*8])) + c1 = EXTRACT_MBC(&b[beg*8]); + if (c2 < EXTRACT_MBC(&b[(end - 1)*8+4])) + c2 = EXTRACT_MBC(&b[(end - 1)*8+4]); + } + if (end < mbc_size && end != beg + 1) + /* NOTE: memcpy() would not work here. */ + memmove(&b[(beg + 1)*8], &b[end*8], (mbc_size - end)*8); + STORE_MBC(&b[beg*8 + 0], c1); + STORE_MBC(&b[beg*8 + 4], c2); + mbc_size += beg - end + 1; + STORE_NUMBER(&b[-2], mbc_size); +} + +static int +is_in_list(c, b) + unsigned int c; + const unsigned char *b; +{ + unsigned short size; + unsigned short i, j; + int result = 0; + + size = *b++; + if ((int)c / BYTEWIDTH < (int)size && b[c / BYTEWIDTH] & 1 << c % BYTEWIDTH) { + return 2; + } + b += size + 2; + size = EXTRACT_UNSIGNED(&b[-2]); + if (size == 0) return 0; + + for (i = 0, j = size; i < j; ) { + unsigned short k = (unsigned short)(i + j) >> 1; + + if (c > EXTRACT_MBC(&b[k*8+4])) + i = k + 1; + else + j = k; + } + if (i < size && EXTRACT_MBC(&b[i*8]) <= c + && ((unsigned char)c != '\n' && (unsigned char)c != '\0')) + return 1; + return result; +} + +static void +print_partial_compiled_pattern(start, end) + unsigned char *start; + unsigned char *end; +{ + int mcnt, mcnt2; + unsigned char *p = start; + unsigned char *pend = end; + + if (start == NULL) + { + printf("(null)\n"); + return; + } + + /* Loop over pattern commands. */ + while (p < pend) + { + switch ((enum regexpcode)*p++) + { + case unused: + printf("/unused"); + break; + + case exactn: + mcnt = *p++; + printf("/exactn/%d", mcnt); + do + { + putchar('/'); + printf("%c", *p++); + } + while (--mcnt); + break; + + case start_memory: + mcnt = *p++; + printf("/start_memory/%d/%d", mcnt, *p++); + break; + + case stop_memory: + mcnt = *p++; + printf("/stop_memory/%d/%d", mcnt, *p++); + break; + + case stop_paren: + printf("/stop_paren"); + break; + + case casefold_on: + printf("/casefold_on"); + break; + + case casefold_off: + printf("/casefold_off"); + break; + + case start_nowidth: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf("/start_nowidth//%d", mcnt); + break; + + case stop_nowidth: + printf("/stop_nowidth//"); + p += 2; + break; + + case pop_and_fail: + printf("/pop_and_fail"); + break; + + case duplicate: + printf("/duplicate/%d", *p++); + break; + + case anychar: + printf("/anychar"); + break; + + case charset: + case charset_not: + { + register int c; + + printf("/charset%s", + (enum regexpcode)*(p - 1) == charset_not ? "_not" : ""); + + mcnt = *p++; + printf("/%d", mcnt); + for (c = 0; c < mcnt; c++) + { + unsigned bit; + unsigned char map_byte = p[c]; + + putchar ('/'); + + for (bit = 0; bit < BYTEWIDTH; bit++) + if (map_byte & (1 << bit)) + printf("%c", c * BYTEWIDTH + bit); + } + p += mcnt; + mcnt = EXTRACT_UNSIGNED_AND_INCR(p); + printf("/"); + while (mcnt--) { + print_mbc(EXTRACT_MBC_AND_INCR(p)); + printf("-"); + print_mbc(EXTRACT_MBC_AND_INCR(p)); + } + break; + } + + case begline: + printf("/begline"); + break; + + case endline: + printf("/endline"); + break; + + case on_failure_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf("/on_failure_jump//%d", mcnt); + break; + + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf("/dummy_failure_jump//%d", mcnt); + break; + + case push_dummy_failure: + printf("/push_dummy_failure"); + break; + + case finalize_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf("/finalize_jump//%d", mcnt); + break; + + case maybe_finalize_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf("/maybe_finalize_jump//%d", mcnt); + break; + + case jump_past_alt: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf("/jump_past_alt//%d", mcnt); + break; + + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + 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); + break; + + case jump_n: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + EXTRACT_NUMBER_AND_INCR (mcnt2, p); + 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); + break; + + case try_next: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + printf("/try_next//%d", mcnt); + break; + + case finalize_push: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + 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); + break; + + case wordbound: + printf("/wordbound"); + break; + + case notwordbound: + printf("/notwordbound"); + break; + + case wordbeg: + printf("/wordbeg"); + break; + + case wordend: + printf("/wordend"); + + case wordchar: + printf("/wordchar"); + break; + + case notwordchar: + printf("/notwordchar"); + break; + + case begbuf: + printf("/begbuf"); + break; + + case endbuf: + printf("/endbuf"); + break; + + case endbuf2: + printf("/endbuf2"); + break; + + default: + printf("?%d", *(p-1)); + } + } + printf("/\n"); +} + + +static void +print_compiled_pattern(bufp) + struct re_pattern_buffer *bufp; +{ + unsigned char *buffer = (unsigned char*)bufp->buffer; + + print_partial_compiled_pattern (buffer, buffer + bufp->used); +} + +static char* +calculate_must_string(start, end) + char *start; + char *end; +{ + int mcnt; + int max = 0; + char *p = start; + char *pend = end; + char *must = 0; + + if (start == NULL) return 0; + + /* Loop over pattern commands. */ + while (p < pend) + { + switch ((enum regexpcode)*p++) + { + case unused: + break; + + case exactn: + mcnt = *p; + if (mcnt > max) { + must = p; + max = mcnt; + } + p += mcnt+1; + break; + + case start_memory: + case stop_memory: + p += 2; + break; + + case duplicate: + p++; + break; + + case casefold_on: + case casefold_off: + return 0; /* should not check must_string */ + + case pop_and_fail: + case anychar: + case begline: + case endline: + case wordbound: + case notwordbound: + case wordbeg: + case wordend: + case wordchar: + case notwordchar: + case begbuf: + case endbuf: + case endbuf2: + case push_dummy_failure: + case stop_paren: + break; + + case charset: + case charset_not: + mcnt = *p++; + p += mcnt; + mcnt = EXTRACT_UNSIGNED_AND_INCR(p); + while (mcnt--) { + p += 4; + } + break; + + case on_failure_jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + if (mcnt > 0) p += mcnt; + if ((enum regexpcode)p[-3] == jump) { + p -= 3; + EXTRACT_NUMBER_AND_INCR (mcnt, p); + if (mcnt > 0) p += mcnt; + } + break; + + case dummy_failure_jump: + case succeed_n: + case try_next: + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p); + if (mcnt > 0) p += mcnt; + break; + + case start_nowidth: + case stop_nowidth: + case finalize_jump: + case maybe_finalize_jump: + case finalize_push: + p += 2; + break; + + case jump_n: + case set_number_at: + case finalize_push_n: + p += 4; + break; + + default: + break; + } + } + return must; +} + + +/* re_compile_pattern takes a regular-expression string + and converts it into a buffer full of byte commands for matching. + + PATTERN is the address of the pattern string + SIZE is the length of it. + BUFP is a struct re_pattern_buffer * which points to the info + on where to store the byte commands. + This structure contains a char * which points to the + actual space, which should have been obtained with malloc. + re_compile_pattern may use realloc to grow the buffer space. + + The number of bytes of commands can be found out by looking in + the `struct re_pattern_buffer' that bufp pointed to, after + re_compile_pattern returns. */ + +char * +re_compile_pattern(pattern, size, bufp) + char *pattern; + int size; + struct re_pattern_buffer *bufp; +{ + register char *b = bufp->buffer; + register char *p = pattern; + char *nextp; + char *pend = pattern + size; + register unsigned c, c1; + char *p0; + int numlen; + + /* Address of the count-byte of the most recently inserted `exactn' + command. This makes it possible to tell whether a new exact-match + character can be added to that command or requires a new `exactn' + command. */ + + char *pending_exact = 0; + + /* Address of the place where a forward-jump should go to the end of + the containing expression. Each alternative of an `or', except the + last, ends with a forward-jump of this sort. */ + + char *fixup_alt_jump = 0; + + /* Address of start of the most recently finished expression. + This tells postfix * where to find the start of its operand. */ + + char *laststart = 0; + + /* In processing a repeat, 1 means zero matches is allowed. */ + + char zero_times_ok; + + /* In processing a repeat, 1 means many matches is allowed. */ + + char many_times_ok; + + /* In processing a repeat, 1 means non-greedy matches. */ + + char greedy; + + /* Address of beginning of regexp, or inside of last (. */ + + char *begalt = b; + + /* Place in the uncompiled pattern (i.e., the {) to + which to go back if the interval is invalid. */ + char *beg_interval; + + /* In processing an interval, at least this many matches must be made. */ + int lower_bound; + + /* In processing an interval, at most this many matches can be made. */ + int upper_bound; + + /* Stack of information saved by ( and restored by ). + Five stack elements are pushed by each (: + First, the value of b. + Second, the value of fixup_alt_jump. + Third, the value of begalt. + Fourth, the value of regnum. + Fifth, the type of the paren. */ + + int *stackb = RE_TALLOC(40, int); + int *stackp = stackb; + int *stacke = stackb + 40; + int *stackt; + + /* Counts ('s as they are encountered. Remembered for the matching ), + where it becomes the register number to put in the stop_memory + command. */ + + int regnum = 1; + + int range = 0; + int had_mbchar = 0; + int had_char_class = 0; + + int options = bufp->options; + + bufp->fastmap_accurate = 0; + bufp->must = 0; + bufp->must_skip = 0; + bufp->stclass = 0; + + /* Initialize the syntax table. */ + init_syntax_once(); + + if (bufp->allocated == 0) { + bufp->allocated = INIT_BUF_SIZE; + if (bufp->buffer) + /* EXTEND_BUFFER loses when bufp->allocated is 0. */ + bufp->buffer = (char*)xrealloc (bufp->buffer, INIT_BUF_SIZE); + else + /* Caller did not allocate a buffer. Do it for them. */ + bufp->buffer = (char*)xmalloc(INIT_BUF_SIZE); + if (!bufp->buffer) goto memory_exhausted; + begalt = b = bufp->buffer; + } + + while (p != pend) { + PATFETCH(c); + + switch (c) + { + case '$': + { + p0 = p; + /* When testing what follows the $, + look past the \-constructs that don't consume anything. */ + + while (p0 != pend) + { + if (*p0 == '\\' && p0 + 1 != pend + && (p0[1] == 'b' || p0[1] == 'B')) + p0 += 2; + else + break; + } + /* $ means succeed if at end of line, but only in special contexts. + If validly in the middle of a pattern, it is a normal character. */ + + if (p0 == pend || *p0 == '\n' + || *p0 == ')' + || *p0 == '|') + { + BUFPUSH(endline); + break; + } + goto normal_char; + } + case '^': + /* ^ means succeed if at beg of line, but only if no preceding + pattern. */ + + if (laststart) + goto invalid_pattern; + if (laststart && p - 2 >= pattern && p[-2] != '\n') + goto normal_char; + BUFPUSH(begline); + break; + + case '+': + case '?': + case '*': + /* If there is no previous pattern, char not special. */ + if (!laststart) { + goto invalid_pattern; + } + /* If there is a sequence of repetition chars, + collapse it down to just one. */ + zero_times_ok = c != '+'; + many_times_ok = c != '?'; + greedy = 1; + if (p != pend) { + PATFETCH(c); + switch (c) { + case '?': + greedy = 0; + break; + case '*': + case '+': + goto nested_meta; + default: + PATUNFETCH; + break; + } + } + + repeat: + /* Star, etc. applied to an empty pattern is equivalent + to an empty pattern. */ + if (!laststart) + break; + + /* Now we know whether or not zero matches is allowed + and also whether or not two or more matches is allowed. */ + if (many_times_ok) { + /* If more than one repetition is allowed, put in at the + end a backward relative jump from b to before the next + jump we're going to put in below (which jumps from + laststart to after this jump). */ + GET_BUFFER_SPACE(3); + store_jump(b,greedy?maybe_finalize_jump:finalize_push,laststart-3); + b += 3; /* Because store_jump put stuff here. */ + } + + /* On failure, jump from laststart to next pattern, which will be the + end of the buffer after this jump is inserted. */ + GET_BUFFER_SPACE(3); + insert_jump(on_failure_jump, laststart, b + 3, b); + b += 3; + + if (zero_times_ok) { + if (greedy == 0) { + GET_BUFFER_SPACE(3); + insert_jump(try_next, laststart, b + 3, b); + b += 3; + } + } + else { + /* At least one repetition is required, so insert a + `dummy_failure_jump' before the initial + `on_failure_jump' instruction of the loop. This + effects a skip over that instruction the first time + we hit that loop. */ + GET_BUFFER_SPACE(3); + insert_jump(dummy_failure_jump, laststart, laststart + 6, b); + b += 3; + } + break; + + case '.': + laststart = b; + BUFPUSH(anychar); + break; + + case '[': + if (p == pend) + goto invalid_pattern; + while ((b - bufp->buffer + 9 + (1 << BYTEWIDTH) / BYTEWIDTH) + > bufp->allocated) + EXTEND_BUFFER; + + laststart = b; + if (*p == '^') + { + BUFPUSH(charset_not); + p++; + } + else + BUFPUSH(charset); + p0 = p; + + BUFPUSH((1 << BYTEWIDTH) / BYTEWIDTH); + /* Clear the whole map */ + memset(b, 0, (1 << BYTEWIDTH) / BYTEWIDTH + 2); + + had_mbchar = 0; + had_char_class = 0; + /* Read in characters and ranges, setting map bits. */ + for (;;) + { + int size; + unsigned last = (unsigned)-1; + + 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; + while (b + size + 1 > bufp->buffer + bufp->allocated) + EXTEND_BUFFER; + } + range_retry: + PATFETCH(c); + + if (c == ']') { + if (p == p0 + 1) { + if (p == pend) + goto invalid_pattern; + } + else + /* Stop if this isn't merely a ] inside a bracket + expression, but rather the end of a bracket + expression. */ + break; + } + /* Look ahead to see if it's a range when the last thing + was a character class. */ + if (had_char_class && c == '-' && *p != ']') + goto invalid_pattern; + if (ismbchar(c)) { + PATFETCH_MBC(c); + had_mbchar++; + } + + /* \ escapes characters when inside [...]. */ + if (c == '\\') { + PATFETCH(c); + switch (c) { + case 'w': + for (c = 0; c < (1 << BYTEWIDTH); c++) { + if (SYNTAX(c) == Sword || + (!current_mbctype && SYNTAX(c) == Sword2)) + SET_LIST_BIT(c); + } + if (current_mbctype) { + set_list_bits(0x80, 0xffffffff, b); + } + last = -1; + continue; + + case 'W': + for (c = 0; c < (1 << BYTEWIDTH); c++) { + if (SYNTAX(c) != Sword && + (current_mbctype || SYNTAX(c) != Sword2)) + SET_LIST_BIT(c); + } + last = -1; + continue; + + case 's': + for (c = 0; c < 256; c++) + if (ISSPACE(c)) + SET_LIST_BIT(c); + last = -1; + continue; + + case 'S': + for (c = 0; c < 256; c++) + if (!ISSPACE(c)) + SET_LIST_BIT(c); + if (current_mbctype) { + set_list_bits(0x80, 0xffffffff, b); + } + last = -1; + continue; + + case 'd': + for (c = '0'; c <= '9'; c++) + SET_LIST_BIT(c); + last = -1; + continue; + + case 'D': + for (c = 0; c < 256; c++) + if (!ISDIGIT(c)) + SET_LIST_BIT(c); + if (current_mbctype) { + set_list_bits(0x80, 0xffffffff, b); + } + last = -1; + continue; + + case 'x': + c = scan_hex(p, 2, &numlen); + p += numlen; + break; + + case '0': case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + PATUNFETCH; + c = scan_oct(p, 3, &numlen); + p += numlen; + break; + + default: + if (ismbchar(c)) { + PATFETCH_MBC(c); + had_mbchar++; + } + break; + } + } + + /* Get a range. */ + if (range) { + if (last > c) + goto invalid_pattern; + + range = 0; + if (had_mbchar == 0) { + for (;last<=c;last++) + SET_LIST_BIT(last); + } + else if (had_mbchar == 2) { + set_list_bits(last, c, b); + } + else { + /* restriction: range between sbc and mbc */ + goto invalid_pattern; + } + } + else if (p[0] == '-' && p[1] != ']') { + last = c; + PATFETCH(c1); + range = 1; + goto range_retry; + } + else if (c == '[' && *p == ':') { + /* Leave room for the null. */ + char str[CHAR_CLASS_MAX_LENGTH + 1]; + + PATFETCH_RAW (c); + c1 = 0; + + /* If pattern is `[[:'. */ + if (p == pend) + goto invalid_pattern; + + for (;;) { + PATFETCH (c); + if (c == ':' || c == ']' || p == pend + || c1 == CHAR_CLASS_MAX_LENGTH) + break; + str[c1++] = c; + } + str[c1] = '\0'; + + /* If isn't a word bracketed by `[:' and:`]': + undo the ending character, the letters, and leave + the leading `:' and `[' (but set bits for them). */ + if (c == ':' && *p == ']') { + int ch; + char is_alnum = STREQ(str, "alnum"); + char is_alpha = STREQ(str, "alpha"); + char is_blank = STREQ(str, "blank"); + char is_cntrl = STREQ(str, "cntrl"); + char is_digit = STREQ(str, "digit"); + char is_graph = STREQ(str, "graph"); + char is_lower = STREQ(str, "lower"); + char is_print = STREQ(str, "print"); + char is_punct = STREQ(str, "punct"); + char is_space = STREQ(str, "space"); + char is_upper = STREQ(str, "upper"); + char is_xdigit = STREQ(str, "xdigit"); + + if (!IS_CHAR_CLASS (str)) + goto invalid_pattern; + + /* Throw away the ] at the end of the character class. */ + PATFETCH (c); + + if (p == pend) + goto invalid_pattern; + + for (ch = 0; ch < 1 << BYTEWIDTH; ch++) { + if ( (is_alnum && ISALNUM(ch)) + || (is_alpha && ISALPHA(ch)) + || (is_blank && ISBLANK(ch)) + || (is_cntrl && ISCNTRL(ch)) + || (is_digit && ISDIGIT(ch)) + || (is_graph && ISGRAPH(ch)) + || (is_lower && ISLOWER(ch)) + || (is_print && ISPRINT(ch)) + || (is_punct && ISPUNCT(ch)) + || (is_space && ISSPACE(ch)) + || (is_upper && ISUPPER(ch)) + || (is_xdigit && ISXDIGIT(ch))) + SET_LIST_BIT (ch); + } + had_char_class = 1; + } + else { + c1++; + while (c1--) + PATUNFETCH; + SET_LIST_BIT(translate?translate['[']:'['); + SET_LIST_BIT(translate?translate[':']:':'); + had_char_class = 0; + last = ':'; + } + } + else if (had_mbchar == 0) + SET_LIST_BIT(c); + else + set_list_bits(c, c, b); + had_mbchar = 0; + } + + /* Discard any character set/class bitmap bytes that are all + 0 at the end of the map. Decrement the map-length byte too. */ + while ((int)b[-1] > 0 && b[b[-1] - 1] == 0) + b[-1]--; + if (b[-1] != (1 << BYTEWIDTH) / BYTEWIDTH) + memmove(&b[b[-1]], &b[(1 << BYTEWIDTH) / BYTEWIDTH], + 2 + EXTRACT_UNSIGNED (&b[(1 << BYTEWIDTH) / BYTEWIDTH])*8); + b += b[-1] + 2 + EXTRACT_UNSIGNED (&b[b[-1]])*8; + break; + + case '(': + PATFETCH(c); + if (c == '?') { + int negative = 0; + PATFETCH_RAW(c); + switch (c) { + case 'x': case 'i': case '-': + for (;;) { + switch (c) { + case '-': + negative = 1; + break; + + case ':': + case ')': + break; + + case 'x': + if (negative) + options &= ~RE_OPTION_EXTENDED; + else + options |= RE_OPTION_EXTENDED; + break; + case 'i': + if (negative) { + if (options&RE_OPTION_IGNORECASE) { + options &= ~RE_OPTION_IGNORECASE; + BUFPUSH(casefold_off); + } + } + else if (!(options&RE_OPTION_IGNORECASE)) { + options |= RE_OPTION_IGNORECASE; + BUFPUSH(casefold_on); + } + break; + + default: + FREE_AND_RETURN(stackb, "undefined (?...) inline option"); + } + if (c == ')') { + c = '#'; /* read whole in-line options */ + break; + } + if (c == ':') break; + PATFETCH_RAW(c); + } + break; + + case '#': + for (;;) { + PATFETCH(c); + if (c == ')') break; + } + c = '#'; + break; + + case ':': + case '=': + case '!': + break; + + default: + FREE_AND_RETURN(stackb, "undefined (?...) sequence"); + } + } + else { + PATUNFETCH; + c = '('; + } + if (c == '#') break; + if (stackp+8 >= stacke) { + int *stackx; + unsigned int len = stacke - stackb; + + stackx = DOUBLE_STACK(stackx,stackb,len,int); + /* Rearrange the pointers. */ + stackp = stackx + (stackp - stackb); + stackb = stackx; + stacke = stackb + 2 * len; + } + + /* Laststart should point to the start_memory that we are about + to push (unless the pattern has RE_NREGS or more ('s). */ + /* obsolete: now RE_NREGS is just a default register size. */ + *stackp++ = b - bufp->buffer; + *stackp++ = fixup_alt_jump ? fixup_alt_jump - bufp->buffer + 1 : 0; + *stackp++ = begalt - bufp->buffer; + switch (c) { + case '(': + BUFPUSH(start_memory); + BUFPUSH(regnum); + *stackp++ = regnum++; + *stackp++ = b - bufp->buffer; + BUFPUSH(0); + /* too many ()'s to fit in a byte. (max 254) */ + if (regnum >= RE_REG_MAX) goto too_big; + break; + + case '=': + case '!': + BUFPUSH(start_nowidth); + *stackp++ = b - bufp->buffer; + BUFPUSH(0); /* temporary value */ + BUFPUSH(0); + if (c == '=') break; + + BUFPUSH(on_failure_jump); + *stackp++ = b - bufp->buffer; + BUFPUSH(0); /* temporary value */ + BUFPUSH(0); + break; + + case ':': + pending_exact = 0; + default: + break; + } + *stackp++ = c; + *stackp++ = options; + fixup_alt_jump = 0; + laststart = 0; + begalt = b; + break; + + case ')': + if (stackp == stackb) + FREE_AND_RETURN(stackb, "unmatched )"); + if ((options ^ stackp[-1]) & RE_OPTION_IGNORECASE) { + BUFPUSH((options&RE_OPTION_IGNORECASE)?casefold_off:casefold_on); + } + pending_exact = 0; + if (fixup_alt_jump) + { /* Push a dummy failure point at the end of the + alternative for a possible future + `finalize_jump' to pop. See comments at + `push_dummy_failure' in `re_match'. */ + BUFPUSH(push_dummy_failure); + + /* We allocated space for this jump when we assigned + to `fixup_alt_jump', in the `handle_alt' case below. */ + store_jump(fixup_alt_jump, jump, b); + } + options = *--stackp; + switch (c = *--stackp) { + case '(': + { + char *loc = bufp->buffer + *--stackp; + *loc = regnum - stackp[-1]; + BUFPUSH(stop_memory); + BUFPUSH(stackp[-1]); + BUFPUSH(regnum - stackp[-1]); + stackp--; + } + break; + + case '!': + BUFPUSH(pop_and_fail); + /* back patch */ + STORE_NUMBER(bufp->buffer+stackp[-1], b - bufp->buffer - stackp[-1] - 2); + stackp--; + /* fall through */ + case '=': + BUFPUSH(stop_nowidth); + /* tell stack-pos place to start_nowidth */ + STORE_NUMBER(bufp->buffer+stackp[-1], b - bufp->buffer - stackp[-1] - 2); + BUFPUSH(0); /* space to hold stack pos */ + BUFPUSH(0); + stackp--; + break; + + case ':': + BUFPUSH(stop_paren); + break; + + default: + break; + } + begalt = *--stackp + bufp->buffer; + stackp--; + fixup_alt_jump = *stackp ? *stackp + bufp->buffer - 1 : 0; + laststart = *--stackp + bufp->buffer; + if (c == '!' || c == '=') laststart = b; + break; + + case '|': + /* Insert before the previous alternative a jump which + jumps to this alternative if the former fails. */ + GET_BUFFER_SPACE(3); + insert_jump(on_failure_jump, begalt, b + 6, b); + pending_exact = 0; + b += 3; + /* The alternative before this one has a jump after it + which gets executed if it gets matched. Adjust that + jump so it will jump to this alternative's analogous + jump (put in below, which in turn will jump to the next + (if any) alternative's such jump, etc.). The last such + jump jumps to the correct final destination. A picture: + _____ _____ + | | | | + | v | v + a | b | c + + If we are at `b', then fixup_alt_jump right now points to a + three-byte space after `a'. We'll put in the jump, set + fixup_alt_jump to right after `b', and leave behind three + bytes which we'll fill in when we get to after `c'. */ + + if (fixup_alt_jump) + store_jump(fixup_alt_jump, jump_past_alt, b); + + /* Mark and leave space for a jump after this alternative, + to be filled in later either by next alternative or + when know we're at the end of a series of alternatives. */ + fixup_alt_jump = b; + GET_BUFFER_SPACE(3); + b += 3; + + laststart = 0; + begalt = b; + break; + + case '{': + /* If there is no previous pattern, this isn't an interval. */ + if (!laststart || p == pend) + { + goto normal_char; + } + + beg_interval = p - 1; + + lower_bound = -1; /* So can see if are set. */ + upper_bound = -1; + GET_UNSIGNED_NUMBER(lower_bound); + if (c == ',') { + GET_UNSIGNED_NUMBER(upper_bound); + } + else + /* Interval such as `{1}' => match exactly once. */ + upper_bound = lower_bound; + + if (lower_bound < 0 || c != '}') + goto unfetch_interval; + + if (lower_bound >= RE_DUP_MAX || upper_bound >= RE_DUP_MAX) + FREE_AND_RETURN(stackb, "too big quantifier in {,}"); + if (upper_bound < 0) upper_bound = RE_DUP_MAX; + if (lower_bound > upper_bound) + FREE_AND_RETURN(stackb, "can't do {n,m} with n > m"); + + beg_interval = 0; + pending_exact = 0; + + greedy = 1; + if (p != pend) { + PATFETCH(c); + if (c == '?') greedy = 0; + else PATUNFETCH; + } + + if (lower_bound == 0) { + zero_times_ok = 1; + if (upper_bound == RE_DUP_MAX) { + many_times_ok = 1; + goto repeat; + } + if (upper_bound == 1) { + many_times_ok = 0; + goto repeat; + } + } + if (lower_bound == 1) { + if (upper_bound == 1) { + /* No need to repeat */ + break; + } + if (upper_bound == RE_DUP_MAX) { + many_times_ok = 1; + zero_times_ok = 0; + goto repeat; + } + } + + /* If upper_bound is zero, don't want to succeed at all; + jump from laststart to b + 3, which will be the end of + the buffer after this jump is inserted. */ + + if (upper_bound == 0) { + GET_BUFFER_SPACE(3); + insert_jump(jump, laststart, b + 3, b); + b += 3; + break; + } + + /* Otherwise, we have a nontrivial interval. When + we're all done, the pattern will look like: + set_number_at + set_number_at + succeed_n + + jump_n + (The upper bound and `jump_n' are omitted if + `upper_bound' is 1, though.) */ + { /* If the upper bound is > 1, we need to insert + more at the end of the loop. */ + unsigned nbytes = upper_bound == 1 ? 10 : 20; + + GET_BUFFER_SPACE(nbytes); + /* Initialize lower bound of the `succeed_n', even + though it will be set during matching by its + attendant `set_number_at' (inserted next), + because `re_compile_fastmap' needs to know. + Jump to the `jump_n' we might insert below. */ + insert_jump_n(succeed_n, laststart, b + (nbytes/2), + b, lower_bound); + b += 5; /* Just increment for the succeed_n here. */ + + /* Code to initialize the lower bound. Insert + before the `succeed_n'. The `5' is the last two + bytes of this `set_number_at', plus 3 bytes of + the following `succeed_n'. */ + insert_op_2(set_number_at, laststart, b, 5, lower_bound); + b += 5; + + if (upper_bound > 1) + { /* More than one repetition is allowed, so + append a backward jump to the `succeed_n' + that starts this interval. + + When we've reached this during matching, + we'll have matched the interval once, so + jump back only `upper_bound - 1' times. */ + GET_BUFFER_SPACE(5); + store_jump_n(b, greedy?jump_n:finalize_push_n, laststart + 5, + upper_bound - 1); + b += 5; + + /* The location we want to set is the second + parameter of the `jump_n'; that is `b-2' as + an absolute address. `laststart' will be + the `set_number_at' we're about to insert; + `laststart+3' the number to set, the source + for the relative address. But we are + inserting into the middle of the pattern -- + so everything is getting moved up by 5. + Conclusion: (b - 2) - (laststart + 3) + 5, + i.e., b - laststart. + + We insert this at the beginning of the loop + so that if we fail during matching, we'll + reinitialize the bounds. */ + insert_op_2(set_number_at, laststart, b, b - laststart, + upper_bound - 1); + b += 5; + } + } + break; + + unfetch_interval: + /* If an invalid interval, match the characters as literals. */ + p = beg_interval; + beg_interval = 0; + + /* normal_char and normal_backslash need `c'. */ + PATFETCH (c); + goto normal_char; + + case '\\': + if (p == pend) goto invalid_pattern; + /* Do not translate the character after the \, so that we can + distinguish, e.g., \B from \b, even if we normally would + translate, e.g., B to b. */ + PATFETCH_RAW(c); + switch (c) + { + case 's': + case 'S': + case 'd': + case 'D': + while (b - bufp->buffer + 9 + (1 << BYTEWIDTH) / BYTEWIDTH + > bufp->allocated) + EXTEND_BUFFER; + + laststart = b; + if (c == 's' || c == 'd') { + BUFPUSH(charset); + } + else { + BUFPUSH(charset_not); + } + + BUFPUSH((1 << BYTEWIDTH) / BYTEWIDTH); + memset(b, 0, (1 << BYTEWIDTH) / BYTEWIDTH + 2); + if (c == 's' || c == 'S') { + SET_LIST_BIT(' '); + SET_LIST_BIT('\t'); + SET_LIST_BIT('\n'); + SET_LIST_BIT('\r'); + SET_LIST_BIT('\f'); + } + else { + char cc; + + for (cc = '0'; cc <= '9'; cc++) { + SET_LIST_BIT(cc); + } + } + + while ((int)b[-1] > 0 && b[b[-1] - 1] == 0) + b[-1]--; + if (b[-1] != (1 << BYTEWIDTH) / BYTEWIDTH) + memmove(&b[b[-1]], &b[(1 << BYTEWIDTH) / BYTEWIDTH], + 2 + EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH])*8); + b += b[-1] + 2 + EXTRACT_UNSIGNED(&b[b[-1]])*8; + break; + + case 'w': + laststart = b; + BUFPUSH(wordchar); + break; + + case 'W': + laststart = b; + BUFPUSH(notwordchar); + break; + + case '<': + BUFPUSH(wordbeg); + break; + + case '>': + BUFPUSH(wordend); + break; + + case 'b': + BUFPUSH(wordbound); + break; + + case 'B': + BUFPUSH(notwordbound); + break; + + case 'A': + BUFPUSH(begbuf); + break; + + case 'Z': + BUFPUSH(endbuf2); + break; + + case 'z': + BUFPUSH(endbuf); + break; + + /* hex */ + case 'x': + had_mbchar = 0; + c = scan_hex(p, 2, &numlen); + p += numlen; + goto numeric_char; + + /* octal */ + case '0': + had_mbchar = 0; + c = scan_oct(p, 3, &numlen); + p += numlen; + goto numeric_char; + + /* back-ref or octal */ + case '1': case '2': case '3': + case '4': case '5': case '6': + case '7': case '8': case '9': + { + char *p_save; + + PATUNFETCH; + p_save = p; + + had_mbchar = 0; + c1 = 0; + GET_UNSIGNED_NUMBER(c1); + if (!ISDIGIT(c)) PATUNFETCH; + + if (c1 >= regnum) { + /* need to get octal */ + p = p_save; + c = scan_oct(p_save, 3, &numlen) & 0xff; + p = p_save + numlen; + c1 = 0; + goto numeric_char; + } + } + + /* Can't back reference to a subexpression if inside of it. */ + for (stackt = stackp - 2; stackt > stackb; stackt -= 5) + if (*stackt == c1) + goto normal_char; + laststart = b; + BUFPUSH(duplicate); + BUFPUSH(c1); + break; + + default: + goto normal_char; + } + break; + + case '#': + if (options & RE_OPTION_EXTENDED) + { + while (p != pend) { + PATFETCH(c); + if (c == '\n') break; + } + break; + } + goto normal_char; + + case ' ': + case '\t': + case '\f': + case '\r': + case '\n': + if (options & RE_OPTION_EXTENDED) + break; + + default: + normal_char: /* Expects the character in `c'. */ + had_mbchar = 0; + if (ismbchar(c)) { + had_mbchar = 1; + c1 = p - pattern; + } + numeric_char: + nextp = p + mbclen(c) - 1; + if (!pending_exact || pending_exact + *pending_exact + 1 != b + || *pending_exact >= (c1 ? 0176 : 0177) + || *nextp == '+' || *nextp == '?' + || *nextp == '*' || *nextp == '^' + || *nextp == '{') { + laststart = b; + BUFPUSH(exactn); + pending_exact = b; + BUFPUSH(0); + } + if (!had_mbchar && c > 0x7f) { + BUFPUSH(0xff); + (*pending_exact)++; + } + BUFPUSH(c); + (*pending_exact)++; + if (had_mbchar) { + int len = mbclen(c) - 1; + while (len--) { + PATFETCH_RAW(c); + BUFPUSH(c); + (*pending_exact)++; + } + } + } + } + + if (fixup_alt_jump) + store_jump(fixup_alt_jump, jump, b); + + if (stackp != stackb) + FREE_AND_RETURN(stackb, "unmatched ("); + + /* set optimize flags */ + laststart = bufp->buffer; + if (laststart != b) { + if (*laststart == start_memory) laststart += 3; + if (*laststart == dummy_failure_jump) laststart += 3; + else if (*laststart == try_next) laststart += 3; + if (*laststart == on_failure_jump) { + int mcnt; + + laststart++; + EXTRACT_NUMBER_AND_INCR(mcnt, laststart); + if (mcnt == 4 && *laststart == anychar) { + switch ((enum regexpcode)laststart[4]) { + case jump_n: + case finalize_jump: + case maybe_finalize_jump: + case jump: + case jump_past_alt: + case dummy_failure_jump: + bufp->options |= RE_OPTIMIZE_ANCHOR; + break; + } + } + else if (*laststart == charset || *laststart == charset_not) { + p0 = laststart; + mcnt = *++p0 ; + p0 += mcnt+1; + mcnt = EXTRACT_UNSIGNED_AND_INCR(p0); + p0 += 8*mcnt; + if (*p0 == maybe_finalize_jump) { + bufp->stclass = laststart; + } + } + } + } + + bufp->used = b - bufp->buffer; + bufp->re_nsub = regnum; + laststart = bufp->buffer; + if (laststart != b) { + if (*laststart == start_memory) laststart += 3; + if (*laststart == exactn) { + bufp->options |= RE_OPTIMIZE_EXACTN; + bufp->must = laststart+1; + } + } + else { + bufp->must = calculate_must_string(bufp->buffer, b); + } + if (current_mbctype == MBCTYPE_SJIS) bufp->options |= RE_OPTIMIZE_NO_BM; + else if (bufp->must) { + int i; + int len = (unsigned char)bufp->must[0]; + + for (i=1; imust[i] == 0xff || + (current_mbctype && ismbchar(bufp->must[i]))) { + bufp->options |= RE_OPTIMIZE_NO_BM; + break; + } + } + if (!(bufp->options & RE_OPTIMIZE_NO_BM)) { + bufp->must_skip = (int *) xmalloc((1 << BYTEWIDTH)*sizeof(int)); + bm_init_skip(bufp->must_skip, bufp->must+1, + (unsigned char)bufp->must[0], + MAY_TRANSLATE()?translate:0); + } + } + + FREE_AND_RETURN(stackb, 0); + + invalid_pattern: + FREE_AND_RETURN(stackb, "invalid regular expression"); + + end_of_pattern: + FREE_AND_RETURN(stackb, "premature end of regular expression"); + + too_big: + FREE_AND_RETURN(stackb, "regular expression too big"); + + memory_exhausted: + FREE_AND_RETURN(stackb, "memory exhausted"); + + nested_meta: + FREE_AND_RETURN(stackb, "nested *?+ in regexp"); +} + +void +re_free_pattern(bufp) + struct re_pattern_buffer *bufp; +{ + free(bufp->buffer); + free(bufp->fastmap); + if (bufp->must_skip) free(bufp->must_skip); + free(bufp); +} + +/* Store a jump of the form . + Store in the location FROM a jump operation to jump to relative + address FROM - TO. OPCODE is the opcode to store. */ + +static void +store_jump(from, opcode, to) + char *from, *to; + int opcode; +{ + from[0] = (char)opcode; + STORE_NUMBER(from + 1, to - (from + 3)); +} + + +/* Open up space before char FROM, and insert there a jump to TO. + CURRENT_END gives the end of the storage not in use, so we know + how much data to copy up. OP is the opcode of the jump to insert. + + If you call this function, you must zero out pending_exact. */ + +static void +insert_jump(op, from, to, current_end) + int op; + char *from, *to, *current_end; +{ + register char *pfrom = current_end; /* Copy from here... */ + register char *pto = current_end + 3; /* ...to here. */ + + while (pfrom != from) + *--pto = *--pfrom; + store_jump(from, op, to); +} + + +/* Store a jump of the form . + + Store in the location FROM a jump operation to jump to relative + address FROM - TO. OPCODE is the opcode to store, N is a number the + jump uses, say, to decide how many times to jump. + + If you call this function, you must zero out pending_exact. */ + +static void +store_jump_n(from, opcode, to, n) + char *from, *to; + int opcode; + unsigned n; +{ + from[0] = (char)opcode; + STORE_NUMBER(from + 1, to - (from + 3)); + STORE_NUMBER(from + 3, n); +} + + +/* Similar to insert_jump, but handles a jump which needs an extra + number to handle minimum and maximum cases. Open up space at + location FROM, and insert there a jump to TO. CURRENT_END gives the + end of the storage in use, so we know how much data to copy up. OP is + the opcode of the jump to insert. + + If you call this function, you must zero out pending_exact. */ + +static void +insert_jump_n(op, from, to, current_end, n) + int op; + char *from, *to, *current_end; + unsigned n; +{ + register char *pfrom = current_end; /* Copy from here... */ + register char *pto = current_end + 5; /* ...to here. */ + + while (pfrom != from) + *--pto = *--pfrom; + store_jump_n(from, op, to, n); +} + + +/* Open up space at location THERE, and insert operation OP. + CURRENT_END gives the end of the storage in use, so + we know how much data to copy up. + + If you call this function, you must zero out pending_exact. */ + +static void +insert_op(op, there, current_end) + int op; + char *there, *current_end; +{ + register char *pfrom = current_end; /* Copy from here... */ + register char *pto = current_end + 1; /* ...to here. */ + + while (pfrom != there) + *--pto = *--pfrom; + + there[0] = (char)op; +} + + +/* Open up space at location THERE, and insert operation OP followed by + NUM_1 and NUM_2. CURRENT_END gives the end of the storage in use, so + we know how much data to copy up. + + If you call this function, you must zero out pending_exact. */ + +static void +insert_op_2(op, there, current_end, num_1, num_2) + int op; + char *there, *current_end; + int num_1, num_2; +{ + register char *pfrom = current_end; /* Copy from here... */ + register char *pto = current_end + 5; /* ...to here. */ + + while (pfrom != there) + *--pto = *--pfrom; + + there[0] = (char)op; + STORE_NUMBER(there + 1, num_1); + STORE_NUMBER(there + 3, num_2); +} + + +#define trans_eq(c1, c2, translate) (translate?(translate[c1]==translate[c2]):((c1)==(c2))) +static int +slow_match(little, lend, big, bend, translate) + unsigned char *little, *lend; + unsigned char *big, *bend; + unsigned char *translate; +{ + int c; + + while (little < lend && big < bend) { + c = *little++; + if (c == 0xff) + c = *little++; + if (!trans_eq(*big++, c, translate)) break; + } + if (little == lend) return 1; + return 0; +} + +static int +slow_search(little, llen, big, blen, translate) + unsigned char *little; + int llen; + unsigned char *big; + int blen; + char *translate; +{ + unsigned char *bsave = big; + unsigned char *bend = big + blen; + register int c; + int fescape = 0; + + c = *little; + if (c == 0xff) { + c = little[1]; + fescape = 1; + } + else if (translate && !ismbchar(c)) { + c = translate[c]; + } + + while (big < bend) { + /* look for first character */ + if (fescape) { + while (big < bend) { + if (*big == c) break; + big++; + } + } + else if (translate && !ismbchar(c)) { + while (big < bend) { + if (ismbchar(*big)) big+=mbclen(*big)-1; + else if (translate[*big] == c) break; + big++; + } + } + else { + while (big < bend) { + if (*big == c) break; + if (ismbchar(*big)) big+=mbclen(*big)-1; + big++; + } + } + + if (slow_match(little, little+llen, big, bend, translate)) + return big - bsave; + + if (ismbchar(*big)) big+=mbclen(*big); + big++; + } + return -1; +} + +static void +bm_init_skip(skip, pat, m, translate) + int *skip; + unsigned char *pat; + int m; + char *translate; +{ + int j, c; + + for (c=0; c<256; c++) { + skip[c] = m; + } + if (translate) { + for (j=0; j= 0 && translate[big[k]] == translate[little[j]]) { + k--; + j--; + } + if (j < 0) return k+1; + + i += skip[translate[big[i]]]; + } + return -1; + } + while (i < blen) { + k = i; + j = llen-1; + while (j >= 0 && big[k] == little[j]) { + k--; + j--; + } + if (j < 0) return k+1; + + i += skip[big[i]]; + } + return -1; +} + +/* Given a pattern, compute a fastmap from it. The fastmap records + which of the (1 << BYTEWIDTH) possible characters can start a string + that matches the pattern. This fastmap is used by re_search to skip + quickly over totally implausible text. + + The caller must supply the address of a (1 << BYTEWIDTH)-byte data + area as bufp->fastmap. + The other components of bufp describe the pattern to be used. */ +void +re_compile_fastmap(bufp) + struct re_pattern_buffer *bufp; +{ + unsigned char *pattern = (unsigned char*)bufp->buffer; + int size = bufp->used; + register char *fastmap = bufp->fastmap; + register unsigned char *p = pattern; + register unsigned char *pend = pattern + size; + register int j, k; + unsigned is_a_succeed_n; + + unsigned char **stackb = RE_TALLOC(NFAILURES, unsigned char*); + unsigned char **stackp = stackb; + unsigned char **stacke = stackb + NFAILURES; + int options = bufp->options; + + memset(fastmap, 0, (1 << BYTEWIDTH)); + bufp->fastmap_accurate = 1; + bufp->can_be_null = 0; + + while (p) + { + is_a_succeed_n = 0; + if (p == pend) + { + bufp->can_be_null = 1; + break; + } +#ifdef SWITCH_ENUM_BUG + switch ((int)((enum regexpcode)*p++)) +#else + switch ((enum regexpcode)*p++) +#endif + { + case exactn: + if (p[1] == 0xff) { + if (TRANSLATE_P()) + fastmap[translate[p[2]]] = 2; + else + fastmap[p[2]] = 2; + } + else if (TRANSLATE_P()) + fastmap[translate[p[1]]] = 1; + else + fastmap[p[1]] = 1; + break; + + case begline: + case begbuf: + case endbuf: + case endbuf2: + case wordbound: + case notwordbound: + case wordbeg: + case wordend: + case pop_and_fail: + case push_dummy_failure: + case stop_paren: + continue; + + case casefold_on: + bufp->options |= RE_MAY_IGNORECASE; + case casefold_off: + options ^= RE_OPTION_IGNORECASE; + continue; + + case endline: + if (TRANSLATE_P()) + fastmap[translate['\n']] = 1; + else + fastmap['\n'] = 1; + + if (bufp->can_be_null == 0) + bufp->can_be_null = 2; + break; + + case jump_n: + case finalize_jump: + case maybe_finalize_jump: + case jump: + case jump_past_alt: + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR(j, p); + p += j; + if (j > 0) + continue; + /* Jump backward reached implies we just went through + the body of a loop and matched nothing. + Opcode jumped to should be an on_failure_jump. + Just treat it like an ordinary jump. + For a * loop, it has pushed its failure point already; + If so, discard that as redundant. */ + + if ((enum regexpcode)*p != on_failure_jump + && (enum regexpcode)*p != try_next + && (enum regexpcode)*p != succeed_n + && (enum regexpcode)*p != finalize_push + && (enum regexpcode)*p != finalize_push_n) + continue; + p++; + EXTRACT_NUMBER_AND_INCR(j, p); + p += j; + if (stackp != stackb && *stackp == p) + stackp--; /* pop */ + continue; + + case start_nowidth: + case stop_nowidth: + case finalize_push: + p += 2; + continue; + + case finalize_push_n: + p += 4; + continue; + + case try_next: + case on_failure_jump: + handle_on_failure_jump: + EXTRACT_NUMBER_AND_INCR(j, p); + if (p + j < pend) { + if (stackp == stacke) { + unsigned char **stackx; + unsigned int len = stacke - stackb; + + EXPAND_FAIL_STACK(stackx, stackb, len); + } + *++stackp = p + j; /* push */ + } + else { + bufp->can_be_null = 1; + } + if (is_a_succeed_n) + EXTRACT_NUMBER_AND_INCR(k, p); /* Skip the n. */ + continue; + + case succeed_n: + is_a_succeed_n = 1; + /* Get to the number of times to succeed. */ + EXTRACT_NUMBER(k, p + 2); + /* Increment p past the n for when k != 0. */ + if (k == 0) { + p += 4; + } + else { + goto handle_on_failure_jump; + } + continue; + + case set_number_at: + p += 4; + continue; + + case start_memory: + case stop_memory: + p += 2; + continue; + + case duplicate: + bufp->can_be_null = 1; + fastmap['\n'] = 1; + case anychar: + for (j = 0; j < (1 << BYTEWIDTH); j++) + if (j != '\n') + fastmap[j] = 1; + if (bufp->can_be_null) + { + FREE_AND_RETURN_VOID(stackb); + } + /* Don't return; check the alternative paths + so we can set can_be_null if appropriate. */ + break; + + case wordchar: + for (j = 0; j < 0x80; j++) { + if (SYNTAX(j) == Sword) + fastmap[j] = 1; + } + switch (current_mbctype) { + case MBCTYPE_ASCII: + for (j = 0x80; j < (1 << BYTEWIDTH); j++) { + if (SYNTAX(j) == Sword2) + fastmap[j] = 1; + } + break; + case MBCTYPE_EUC: + case MBCTYPE_SJIS: + case MBCTYPE_UTF8: + for (j = 0x80; j < (1 << BYTEWIDTH); j++) { + if (re_mbctab[j]) + fastmap[j] = 1; + } + break; + } + break; + + case notwordchar: + for (j = 0; j < 0x80; j++) + if (SYNTAX(j) != Sword) + fastmap[j] = 1; + switch (current_mbctype) { + case MBCTYPE_ASCII: + for (j = 0x80; j < (1 << BYTEWIDTH); j++) { + if (SYNTAX(j) != Sword2) + fastmap[j] = 1; + } + break; + case MBCTYPE_EUC: + case MBCTYPE_SJIS: + case MBCTYPE_UTF8: + for (j = 0x80; j < (1 << BYTEWIDTH); j++) { + if (!re_mbctab[j]) + fastmap[j] = 1; + } + break; + } + break; + + case charset: + /* NOTE: Charset for single-byte chars never contain + multi-byte char. See set_list_bits(). */ + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) + if (p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH))) + { + if (TRANSLATE_P()) + j = translate[j]; + fastmap[j] = (j>0x7f?(ismbchar(j)?0:2):1); + } + { + unsigned short size; + unsigned int c, beg, end; + + p += p[-1] + 2; + size = EXTRACT_UNSIGNED(&p[-2]); + for (j = 0; j < (int)size; j++) { + c = EXTRACT_MBC(&p[j*8]); + beg = WC2MBC1ST(c); + c = EXTRACT_MBC(&p[j*8+4]); + end = WC2MBC1ST(c); + /* set bits for 1st bytes of multi-byte chars. */ + while (beg <= end) { + /* NOTE: Charset for multi-byte chars might contain + single-byte chars. We must reject them. */ + if (ismbchar(beg)) + fastmap[beg] = 1; + beg++; + } + } + } + break; + + case charset_not: + /* S: set of all single-byte chars. + M: set of all first bytes that can start multi-byte chars. + s: any set of single-byte chars. + m: any set of first bytes that can start multi-byte chars. + + We assume S+M = U. + ___ _ _ + s+m = (S*s+M*m). */ + /* Chars beyond end of map must be allowed */ + /* NOTE: Charset_not for single-byte chars might contain + multi-byte chars. See set_list_bits(). */ + for (j = *p * BYTEWIDTH; j < (1 << BYTEWIDTH); j++) + if (!ismbchar(j)) + fastmap[j] = 1; + + for (j = *p++ * BYTEWIDTH - 1; j >= 0; j--) + if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) + { + if (!ismbchar(j)) + fastmap[j] = 1; + } + if (current_mbctype) { + for (j = 0x80; j < (1 << BYTEWIDTH); j++) + if (!(p[j / BYTEWIDTH] & (1 << (j % BYTEWIDTH)))) + fastmap[j] = 2; + } + { + unsigned short size; + unsigned int c, beg, end; + + p += p[-1] + 2; + size = EXTRACT_UNSIGNED(&p[-2]); + if (size == 0) { + for (j = 0x80; j < (1 << BYTEWIDTH); j++) + if (ismbchar(j)) + fastmap[j] = 1; + break; + } + for (j = 0,c = 0x80;j < (int)size; j++) { + int cc = EXTRACT_MBC(&p[j*8]); + beg = WC2MBC1ST(cc); + while (c < beg) { + if (ismbchar(c)) + fastmap[c] = 1; + c++; + } + + cc = EXTRACT_MBC(&p[j*8+4]); + c = WC2MBC1ST(cc) + 1; + } + + for (j = c; j < (1 << BYTEWIDTH); j++) + if (ismbchar(j)) + fastmap[j] = 1; + } + break; + + case unused: /* pacify gcc -Wall */ + break; + } + + /* Get here means we have successfully found the possible starting + characters of one path of the pattern. We need not follow this + path any farther. Instead, look at the next alternative + remembered in the stack. */ + if (stackp != stackb) + p = *stackp--; /* pop */ + else + break; + } + FREE_AND_RETURN_VOID(stackb); +} + + +/* Using the compiled pattern in BUFP->buffer, first tries to match + STRING, starting first at index STARTPOS, then at STARTPOS + 1, and + so on. RANGE is the number of places to try before giving up. If + RANGE is negative, it searches backwards, i.e., the starting + positions tried are STARTPOS, STARTPOS - 1, etc. STRING is of SIZE. + In REGS, return the indices of STRING that matched the entire + BUFP->buffer and its contained subexpressions. + + The value returned is the position in the strings at which the match + was found, or -1 if no match was found, or -2 if error (such as + failure stack overflow). */ + +int +re_search(bufp, string, size, startpos, range, regs) + struct re_pattern_buffer *bufp; + char *string; + int size, startpos, range; + struct re_registers *regs; +{ + register char *fastmap = bufp->fastmap; + int val, anchor = 0; + + /* Check for out-of-range starting position. */ + if (startpos < 0 || startpos > size) + return -1; + + /* Update the fastmap now if not correct already. */ + if (fastmap && !bufp->fastmap_accurate) { + re_compile_fastmap(bufp); + } + + /* If the search isn't to be a backwards one, don't waste time in a + search for a pattern that must be anchored. */ + if (bufp->used>0) { + switch ((enum regexpcode)bufp->buffer[0]) { + case begbuf: + if (range > 0) { + if (startpos > 0) + return -1; + else if (re_match(bufp, string, size, 0, regs) >= 0) + return 0; + return -1; + } + break; + + case begline: + anchor = 1; + break; + + default: + break; + } + } + if (bufp->options & RE_OPTIMIZE_ANCHOR) { + anchor = 1; + } + + if (bufp->must) { + int len = ((unsigned char*)bufp->must)[0]; + int pos, pbeg, pend; + + pbeg = startpos; + pend = startpos + range; + if (pbeg > pend) { /* swap pbeg,pend */ + pos = pend; pend = pbeg; pbeg = pos; + } + if (pend > size) pend = size; + if (bufp->options & RE_OPTIMIZE_NO_BM) { + pos = slow_search(bufp->must+1, len, + string+pbeg, pend-pbeg, + MAY_TRANSLATE()?translate:0); + } + else { + pos = bm_search(bufp->must+1, len, + string+pbeg, pend-pbeg, + bufp->must_skip, + MAY_TRANSLATE()?translate:0); + } + if (pos == -1) return -1; + if (range > 0 && (bufp->options & RE_OPTIMIZE_EXACTN)) { + startpos += pos; + range -= pos; + } + } + + for (;;) + { + /* If a fastmap is supplied, skip quickly over characters that + cannot possibly be the start of a match. Note, however, that + if the pattern can possibly match the null string, we must + test it at each starting point so that we take the first null + string we get. */ + + if (fastmap && startpos < size + && bufp->can_be_null != 1 && !(anchor && startpos == 0)) + { + if (range > 0) /* Searching forwards. */ + { + register unsigned char *p, c; + int irange = range; + + p = (unsigned char*)string+startpos; + + while (range > 0) { + c = *p++; + if (ismbchar(c)) { + int len = mbclen(c) - 1; + if (fastmap[c]) + break; + p += len; + range -= len + 1; + c = *p; + if (fastmap[c] == 2) + break; + } + else { + if (fastmap[MAY_TRANSLATE() ? translate[c] : c]) + break; + range--; + } + } + startpos += irange - range; + } + else /* Searching backwards. */ + { + register unsigned char c; + + c = string[startpos]; + c &= 0xff; + if (MAY_TRANSLATE() ? !fastmap[translate[c]] : !fastmap[c]) + goto advance; + } + } + + if (startpos > size) return -1; + if (anchor && size > 0 && startpos == size) return -1; + if (fastmap && startpos == size && range >= 0 + && (bufp->can_be_null == 0 || + (bufp->can_be_null && size > 0 + && string[startpos-1] == '\n'))) + return -1; + + val = re_match(bufp, string, size, startpos, regs); + if (val >= 0) + return startpos; + if (val == -2) + return -2; + +#ifndef NO_ALLOCA +#ifdef C_ALLOCA + alloca(0); +#endif /* C_ALLOCA */ +#endif /* NO_ALLOCA */ + + if (range > 0) { + if (anchor && startpos < size && startpos > 0 && string[startpos-1] != '\n') { + while (range > 0 && string[startpos] != '\n') { + range--; + startpos++; + } + } + else if (fastmap && (bufp->stclass)) { + register unsigned char *p; + unsigned int c; + int irange = range; + + p = (unsigned char*)string+startpos; + while (range > 0) { + c = *p++; + if (ismbchar(c) && fastmap[c] != 2) { + MBC2WC(c, p); + } + else if (MAY_TRANSLATE()) + c = translate[c]; + if (*bufp->stclass == charset) { + if (!is_in_list(c, bufp->stclass+1)) break; + } + else { + if (is_in_list(c, bufp->stclass+1)) break; + } + range--; + if (c > 256) range--; + } + startpos += irange - range; + } + } + + advance: + if (!range) + break; + else if (range > 0) { + const char *d = string + startpos; + + if (ismbchar(*d)) { + int len = mbclen(*d) - 1; + range-=len, startpos+=len; + if (!range) + break; + } + range--, startpos++; + } + else { + range++, startpos--; + { + const char *s, *d, *p; + + s = string; d = string + startpos; + for (p = d; p-- > s && ismbchar(*p); ) + /* --p >= s would not work on 80[12]?86. + (when the offset of s equals 0 other than huge model.) */ + ; + if (!((d - p) & 1)) { + if (!range) + break; + range++, startpos--; + } + } + } + } + return -1; +} + + + + +/* The following are used for re_match, defined below: */ + +/* Routine used by re_match. */ + +/* Structure and accessing macros used in re_match: */ + +typedef union +{ + unsigned char *word; + struct + { + /* This field is one if this group can match the empty string, + zero if not. If not yet determined, `MATCH_NULL_UNSET_VALUE'. */ +#define MATCH_NULL_UNSET_VALUE 3 + unsigned match_null_string_p : 2; + unsigned is_active : 1; + unsigned matched_something : 1; + unsigned ever_matched_something : 1; + } bits; +} register_info_type; + +#define REG_MATCH_NULL_STRING_P(R) ((R).bits.match_null_string_p) +#define IS_ACTIVE(R) ((R).bits.is_active) +#define MATCHED_SOMETHING(R) ((R).bits.matched_something) +#define EVER_MATCHED_SOMETHING(R) ((R).bits.ever_matched_something) + + +/* Macros used by re_match: */ + +/* I.e., regstart, regend, and reg_info. */ +#define NUM_REG_ITEMS 3 + +/* Individual items aside from the registers. */ +#define NUM_NONREG_ITEMS 3 + +/* We push at most this many things on the stack whenever we + fail. The `+ 2' refers to PATTERN_PLACE and STRING_PLACE, which are + arguments to the PUSH_FAILURE_POINT macro. */ +#define MAX_NUM_FAILURE_ITEMS (num_regs * NUM_REG_ITEMS + NUM_NONREG_ITEMS) + +/* We push this many things on the stack whenever we fail. */ +#define NUM_FAILURE_ITEMS (last_used_reg * NUM_REG_ITEMS + NUM_REG_ITEMS) + + +/* This pushes most of the information about the current state we will want + if we ever fail back to it. */ + +#define PUSH_FAILURE_POINT(pattern_place, string_place) \ + do { \ + long last_used_reg, this_reg; \ + \ + /* Find out how many registers are active or have been matched. \ + (Aside from register zero, which is only set at the end.) */ \ + for (last_used_reg = num_regs - 1; last_used_reg > 0; last_used_reg--)\ + if (!REG_UNSET(regstart[last_used_reg])) \ + break; \ + \ + if (stacke - stackp <= NUM_FAILURE_ITEMS) \ + { \ + unsigned char **stackx; \ + unsigned int len = stacke - stackb; \ + /* if (len > re_max_failures * MAX_NUM_FAILURE_ITEMS) \ + { \ + FREE_VARIABLES(); \ + FREE_AND_RETURN(stackb,(-2)); \ + }*/ \ + \ + /* Roughly double the size of the stack. */ \ + EXPAND_FAIL_STACK(stackx, stackb, len); \ + } \ + \ + /* Now push the info for each of those registers. */ \ + for (this_reg = 1; this_reg <= last_used_reg; this_reg++) \ + { \ + *stackp++ = regstart[this_reg]; \ + *stackp++ = regend[this_reg]; \ + *stackp++ = reg_info[this_reg].word; \ + } \ + \ + /* Push how many registers we saved. */ \ + *stackp++ = (unsigned char*)last_used_reg; \ + \ + *stackp++ = pattern_place; \ + *stackp++ = string_place; \ + *stackp++ = (unsigned char*)0; /* non-greedy flag */ \ + } while(0) + + +/* This pops what PUSH_FAILURE_POINT pushes. */ + +#define POP_FAILURE_POINT() \ + do { \ + int temp; \ + stackp -= NUM_NONREG_ITEMS; /* Remove failure points (and flag). */ \ + temp = (int)*--stackp; /* How many regs pushed. */ \ + temp *= NUM_REG_ITEMS; /* How much to take off the stack. */ \ + stackp -= temp; /* Remove the register info. */ \ + } while(0) + +/* Registers are set to a sentinel when they haven't yet matched. */ +#define REG_UNSET_VALUE ((unsigned char*)-1) +#define REG_UNSET(e) ((e) == REG_UNSET_VALUE) + +#define PREFETCH if (d == dend) goto fail + +/* Call this when have matched something; it sets `matched' flags for the + registers corresponding to the subexpressions of which we currently + are inside. */ +#define SET_REGS_MATCHED \ + do { unsigned this_reg; \ + for (this_reg = 0; this_reg < num_regs; this_reg++) \ + { \ + if (IS_ACTIVE(reg_info[this_reg])) \ + MATCHED_SOMETHING(reg_info[this_reg]) \ + = EVER_MATCHED_SOMETHING (reg_info[this_reg]) \ + = 1; \ + else \ + MATCHED_SOMETHING(reg_info[this_reg]) = 0; \ + } \ + } while(0) + +#define AT_STRINGS_BEG(d) ((d) == string) +#define AT_STRINGS_END(d) ((d) == dend) + +#define IS_A_LETTER(d) (SYNTAX(*(d)) == Sword || \ + (current_mbctype ? \ + re_mbctab[*(d)] : \ + SYNTAX(*(d)) == Sword2)) + +#define PREV_IS_A_LETTER(d) ((current_mbctype == MBCTYPE_SJIS)? \ + IS_A_LETTER((d)-(!AT_STRINGS_BEG((d)-1)&& \ + ismbchar((d)[-2])?2:1)): \ + ((d)[-1] >= 0x80 || IS_A_LETTER((d)-1))) + +static void +init_regs(regs, num_regs) + struct re_registers *regs; + unsigned int num_regs; +{ + int i; + + regs->num_regs = num_regs; + if (num_regs < RE_NREGS) + num_regs = RE_NREGS; + + if (regs->allocated == 0) { + regs->beg = TMALLOC(num_regs, int); + regs->end = TMALLOC(num_regs, int); + regs->allocated = num_regs; + } + else if (regs->allocated < num_regs) { + TREALLOC(regs->beg, num_regs, int); + TREALLOC(regs->end, num_regs, int); + } + for (i=0; ibeg[i] = regs->end[i] = -1; + } +} + +/* Match the pattern described by BUFP against STRING, which is of + SIZE. Start the match at index POS in STRING. In REGS, return the + indices of STRING that matched the entire BUFP->buffer and its + contained subexpressions. + + If bufp->fastmap is nonzero, then it had better be up to date. + + The reason that the data to match are specified as two components + which are to be regarded as concatenated is so this function can be + used directly on the contents of an Emacs buffer. + + -1 is returned if there is no match. -2 is returned if there is an + error (such as match stack overflow). Otherwise the value is the + length of the substring which was matched. */ + +int +re_match(bufp, string_arg, size, pos, regs) + struct re_pattern_buffer *bufp; + char *string_arg; + int size, pos; + struct re_registers *regs; +{ + register unsigned char *p = (unsigned char*)bufp->buffer; + unsigned char *p1; + + /* Pointer to beyond end of buffer. */ + register unsigned char *pend = p + bufp->used; + + unsigned num_regs = bufp->re_nsub; + + unsigned char *string = (unsigned char*)string_arg; + + register unsigned char *d, *dend; + register int mcnt; /* Multipurpose. */ + int options = bufp->options; + + /* Failure point stack. Each place that can handle a failure further + down the line pushes a failure point on this stack. It consists of + restart, regend, and reg_info for all registers corresponding to the + subexpressions we're currently inside, plus the number of such + registers, and, finally, two char *'s. The first char * is where to + resume scanning the pattern; the second one is where to resume + scanning the strings. If the latter is zero, the failure point is a + ``dummy''; if a failure happens and the failure point is a dummy, it + gets discarded and the next next one is tried. */ + + unsigned char **stackb; + unsigned char **stackp; + unsigned char **stacke; + + + /* Information on the contents of registers. These are pointers into + the input strings; they record just what was matched (on this + attempt) by a subexpression part of the pattern, that is, the + regnum-th regstart pointer points to where in the pattern we began + matching and the regnum-th regend points to right after where we + stopped matching the regnum-th subexpression. (The zeroth register + keeps track of what the whole pattern matches.) */ + + unsigned char **regstart = RE_TALLOC(num_regs, unsigned char*); + unsigned char **regend = RE_TALLOC(num_regs, unsigned char*); + + /* If a group that's operated upon by a repetition operator fails to + match anything, then the register for its start will need to be + restored because it will have been set to wherever in the string we + are when we last see its open-group operator. Similarly for a + register's end. */ + unsigned char **old_regstart = RE_TALLOC(num_regs, unsigned char*); + unsigned char **old_regend = RE_TALLOC(num_regs, unsigned char*); + + /* The is_active field of reg_info helps us keep track of which (possibly + nested) subexpressions we are currently in. The matched_something + field of reg_info[reg_num] helps us tell whether or not we have + matched any of the pattern so far this time through the reg_num-th + subexpression. These two fields get reset each time through any + loop their register is in. */ + + register_info_type *reg_info = RE_TALLOC(num_regs, register_info_type); + + /* The following record the register info as found in the above + variables when we find a match better than any we've seen before. + This happens as we backtrack through the failure points, which in + turn happens only if we have not yet matched the entire string. */ + + unsigned best_regs_set = 0; + unsigned char **best_regstart = RE_TALLOC(num_regs, unsigned char*); + unsigned char **best_regend = RE_TALLOC(num_regs, unsigned char*); + + if (regs) { + init_regs(regs, num_regs); + } + + /* Initialize the stack. */ + stackb = RE_TALLOC(MAX_NUM_FAILURE_ITEMS * NFAILURES, unsigned char*); + stackp = stackb; + stacke = &stackb[MAX_NUM_FAILURE_ITEMS * NFAILURES]; + +#ifdef DEBUG_REGEX + fprintf(stderr, "Entering re_match(%s%s)\n", string1_arg, string2_arg); +#endif + + /* Initialize subexpression text positions to -1 to mark ones that no + ( or ( and ) or ) has been seen for. Also set all registers to + inactive and mark them as not having matched anything or ever + failed. */ + for (mcnt = 0; mcnt < num_regs; mcnt++) { + regstart[mcnt] = regend[mcnt] + = old_regstart[mcnt] = old_regend[mcnt] + = best_regstart[mcnt] = best_regend[mcnt] = REG_UNSET_VALUE; +#ifdef __CHECKER__ + reg_info[mcnt].word = 0; +#endif + REG_MATCH_NULL_STRING_P (reg_info[mcnt]) = MATCH_NULL_UNSET_VALUE; + IS_ACTIVE (reg_info[mcnt]) = 0; + MATCHED_SOMETHING (reg_info[mcnt]) = 0; + EVER_MATCHED_SOMETHING (reg_info[mcnt]) = 0; + } + + /* Set up pointers to ends of strings. + Don't allow the second string to be empty unless both are empty. */ + + + /* `p' scans through the pattern as `d' scans through the data. `dend' + is the end of the input string that `d' points within. `d' is + advanced into the following input string whenever necessary, but + this happens before fetching; therefore, at the beginning of the + loop, `d' can be pointing at the end of a string, but it cannot + equal string2. */ + + d = string + pos, dend = string + size; + + + /* This loops over pattern commands. It exits by returning from the + function if match is complete, or it drops through if match fails + at this starting point in the input data. */ + + for (;;) + { +#ifdef DEBUG_REGEX + fprintf(stderr, + "regex loop(%d): matching 0x%02d\n", + p - (unsigned char*)bufp->buffer, + *p); +#endif + /* End of pattern means we might have succeeded. */ + if (p == pend) + { + /* If not end of string, try backtracking. Otherwise done. */ + if (d != dend) + { + while (stackp != stackb && (int)stackp[-1] == 1) + POP_FAILURE_POINT(); + if (stackp != stackb) + { + /* More failure points to try. */ + + /* If exceeds best match so far, save it. */ + if (! best_regs_set || (d > best_regend[0])) + { + best_regs_set = 1; + best_regend[0] = d; /* Never use regstart[0]. */ + + for (mcnt = 1; mcnt < num_regs; mcnt++) + { + best_regstart[mcnt] = regstart[mcnt]; + best_regend[mcnt] = regend[mcnt]; + } + } + goto fail; + } + /* If no failure points, don't restore garbage. */ + else if (best_regs_set) + { + restore_best_regs: + /* Restore best match. */ + d = best_regend[0]; + + for (mcnt = 0; mcnt < num_regs; mcnt++) + { + regstart[mcnt] = best_regstart[mcnt]; + regend[mcnt] = best_regend[mcnt]; + } + } + } + + /* If caller wants register contents data back, convert it + to indices. */ + if (regs) + { + regs->beg[0] = pos; + regs->end[0] = d - string; + for (mcnt = 1; mcnt < num_regs; mcnt++) + { + if (REG_UNSET(regend[mcnt])) + { + regs->beg[mcnt] = -1; + regs->end[mcnt] = -1; + continue; + } + regs->beg[mcnt] = regstart[mcnt] - string; + regs->end[mcnt] = regend[mcnt] - string; + } + } + FREE_VARIABLES(); + FREE_AND_RETURN(stackb, (d - pos - string)); + } + + /* Otherwise match next pattern command. */ +#ifdef SWITCH_ENUM_BUG + switch ((int)((enum regexpcode)*p++)) +#else + switch ((enum regexpcode)*p++) +#endif + { + + /* ( [or `(', as appropriate] is represented by start_memory, + ) by stop_memory. Both of those commands are followed by + a register number in the next byte. The text matched + within the ( and ) is recorded under that number. */ + case start_memory: + /* Find out if this group can match the empty string. */ + p1 = p; /* To send to group_match_null_string_p. */ + if (REG_MATCH_NULL_STRING_P (reg_info[*p]) == MATCH_NULL_UNSET_VALUE) + REG_MATCH_NULL_STRING_P (reg_info[*p]) + = group_match_null_string_p (&p1, pend, reg_info); + + /* Save the position in the string where we were the last time + we were at this open-group operator in case the group is + operated upon by a repetition operator, e.g., with `(a*)*b' + against `ab'; then we want to ignore where we are now in + the string in case this attempt to match fails. */ + old_regstart[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) + ? REG_UNSET (regstart[*p]) ? d : regstart[*p] + : regstart[*p]; + regstart[*p] = d; + IS_ACTIVE(reg_info[*p]) = 1; + MATCHED_SOMETHING(reg_info[*p]) = 0; + p += 2; + continue; + + case stop_memory: + /* We need to save the string position the last time we were at + this close-group operator in case the group is operated + upon by a repetition operator, e.g., with `((a*)*(b*)*)*' + against `aba'; then we want to ignore where we are now in + the string in case this attempt to match fails. */ + old_regend[*p] = REG_MATCH_NULL_STRING_P (reg_info[*p]) + ? REG_UNSET (regend[*p]) ? d : regend[*p] + : regend[*p]; + + regend[*p] = d; + IS_ACTIVE(reg_info[*p]) = 0; + + /* If just failed to match something this time around with a sub- + expression that's in a loop, try to force exit from the loop. */ + if ((p + 1) != pend && + (! MATCHED_SOMETHING(reg_info[*p]) + || (enum regexpcode)p[-3] == start_memory)) + { + p1 = p + 2; + mcnt = 0; + switch (*p1++) + { + case jump_n: + case finalize_push_n: + case finalize_jump: + case maybe_finalize_jump: + case jump: + case dummy_failure_jump: + EXTRACT_NUMBER_AND_INCR(mcnt, p1); + break; + } + p1 += mcnt; + + /* If the next operation is a jump backwards in the pattern + to an on_failure_jump, exit from the loop by forcing a + failure after pushing on the stack the on_failure_jump's + jump in the pattern, and d. */ + if (mcnt < 0 && (enum regexpcode)*p1 == on_failure_jump + && (enum regexpcode)p1[3] == start_memory && p1[4] == *p) + { + /* If this group ever matched anything, then restore + what its registers were before trying this last + failed match, e.g., with `(a*)*b' against `ab' for + regstart[1], and, e.g., with `((a*)*(b*)*)*' + against `aba' for regend[3]. + + Also restore the registers for inner groups for, + e.g., `((a*)(b*))*' against `aba' (register 3 would + otherwise get trashed). */ + + if (EVER_MATCHED_SOMETHING (reg_info[*p])) + { + unsigned r; + + EVER_MATCHED_SOMETHING (reg_info[*p]) = 0; + + /* Restore this and inner groups' (if any) registers. */ + for (r = *p; r < *p + *(p + 1); r++) + { + regstart[r] = old_regstart[r]; + + /* xx why this test? */ + if ((int)old_regend[r] >= (int)regstart[r]) + regend[r] = old_regend[r]; + } + } + p1++; + EXTRACT_NUMBER_AND_INCR(mcnt, p1); + PUSH_FAILURE_POINT(p1 + mcnt, d); + goto fail; + } + } + p += 2; + continue; + + case stop_paren: + break; + + /* \ has been turned into a `duplicate' command which is + followed by the numeric value of as the register number. */ + case duplicate: + { + int regno = *p++; /* Get which register to match against */ + register unsigned char *d2, *dend2; + + if (IS_ACTIVE(reg_info[regno])) break; + + /* Where in input to try to start matching. */ + d2 = regstart[regno]; + if (REG_UNSET(d2)) break; + + /* Where to stop matching; if both the place to start and + the place to stop matching are in the same string, then + set to the place to stop, otherwise, for now have to use + the end of the first string. */ + + dend2 = regend[regno]; + if (REG_UNSET(dend2)) break; + for (;;) + { + /* At end of register contents => success */ + if (d2 == dend2) break; + + /* If necessary, advance to next segment in data. */ + PREFETCH; + + /* How many characters left in this segment to match. */ + mcnt = dend - d; + + /* Want how many consecutive characters we can match in + one shot, so, if necessary, adjust the count. */ + if (mcnt > dend2 - d2) + mcnt = dend2 - d2; + + /* Compare that many; failure if mismatch, else move + past them. */ + if ((options & RE_OPTION_IGNORECASE) + ? memcmp_translate(d, d2, mcnt) + : memcmp((char*)d, (char*)d2, mcnt)) + goto fail; + d += mcnt, d2 += mcnt; + } + } + break; + + case start_nowidth: + PUSH_FAILURE_POINT(0, d); + EXTRACT_NUMBER_AND_INCR(mcnt, p); + STORE_NUMBER(p+mcnt, stackp - stackb); + continue; + + case stop_nowidth: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + stackp = stackb + mcnt; + d = stackp[-2]; + POP_FAILURE_POINT(); + continue; + + case pop_and_fail: + EXTRACT_NUMBER(mcnt, p+1); + stackp = stackb + mcnt; + POP_FAILURE_POINT(); + goto fail; + + case anychar: + PREFETCH; + /* Match anything but a newline, maybe even a null. */ + if (ismbchar(*d)) { + if (d + mbclen(*d) > dend || d[1] == '\n' || d[1] == '\0') + goto fail; + SET_REGS_MATCHED; + d += mbclen(*d); + break; + } + if (((TRANSLATE_P()) ? translate[*d] : *d) == '\n') + goto fail; + SET_REGS_MATCHED; + d++; + break; + + case charset: + case charset_not: + { + int not; /* Nonzero for charset_not. */ + int part; /* 2 if matched part of mbc */ + unsigned char *dsave = d + 1; + int cc, c; + + PREFETCH; + cc = c = (unsigned char)*d++; + if (ismbchar(c)) { + if (d + mbclen(c) - 1 <= dend) { + MBC2WC(c, d); + } + } + else if (TRANSLATE_P()) + cc = c = (unsigned char)translate[c]; + + part = not = is_in_list(c, p); + if (*(p - 1) == (unsigned char)charset_not) { + not = !not; + } + if (!not) goto fail; + + p += 1 + *p + 2 + EXTRACT_UNSIGNED(&p[1 + *p])*8; + SET_REGS_MATCHED; + + if (part == 2) d = dsave; + break; + } + + case begline: + if (size == 0 + || AT_STRINGS_BEG(d) + || (d && d[-1] == '\n')) + break; + else + goto fail; + + case endline: + if (AT_STRINGS_END(d) || *d == '\n') + break; + goto fail; + + /* Match at the very beginning of the string. */ + case begbuf: + if (AT_STRINGS_BEG(d)) + break; + goto fail; + + /* Match at the very end of the data. */ + case endbuf: + if (AT_STRINGS_END(d)) + break; + goto fail; + + /* Match at the very end of the data. */ + case endbuf2: + if (AT_STRINGS_END(d)) + break; + /* .. or newline just before the end of the data. */ + if (*d == '\n' && AT_STRINGS_END(d+1)) + break; + goto fail; + + /* `or' constructs are handled by starting each alternative with + an on_failure_jump that points to the start of the next + alternative. Each alternative except the last ends with a + jump to the joining point. (Actually, each jump except for + the last one really jumps to the following jump, because + tensioning the jumps is a hassle.) */ + + /* The start of a stupid repeat has an on_failure_jump that points + past the end of the repeat text. This makes a failure point so + that on failure to match a repetition, matching restarts past + as many repetitions have been found with no way to fail and + look for another one. */ + + /* A smart repeat is similar but loops back to the on_failure_jump + so that each repetition makes another failure point. */ + + case on_failure_jump: + on_failure: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + PUSH_FAILURE_POINT(p + mcnt, d); + continue; + + /* The end of a smart repeat has a maybe_finalize_jump back. + Change it either to a finalize_jump or an ordinary jump. */ + case maybe_finalize_jump: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + { + register unsigned char *p2 = p; + + /* Compare the beginning of the repeat with what in the + pattern follows its end. If we can establish that there + is nothing that they would both match, i.e., that we + would have to backtrack because of (as in, e.g., `a*a') + then we can change to pop_failure_jump, because we'll + never have to backtrack. + + This is not true in the case of alternatives: in + `(a|ab)*' we do need to backtrack to the `ab' alternative + (e.g., if the string was `ab'). But instead of trying to + detect that here, the alternative has put on a dummy + failure point which is what we will end up popping. */ + + /* Skip over open/close-group commands. */ + while (p2 + 2 < pend) { + if ((enum regexpcode)*p2 == stop_memory || + (enum regexpcode)*p2 == start_memory) + p2 += 3; /* Skip over args, too. */ + else if ((enum regexpcode)*p2 == stop_paren) + p2 += 1; + else + break; + } + + if (p2 == pend) + p[-3] = (unsigned char)finalize_jump; + else if (*p2 == (unsigned char)exactn + || *p2 == (unsigned char)endline) + { + register int c = *p2 == (unsigned char)endline ? '\n' : p2[2]; + register unsigned char *p1 = p + mcnt; + /* p1[0] ... p1[2] are an on_failure_jump. + Examine what follows that. */ + if (p1[3] == (unsigned char)exactn && p1[5] != c) + p[-3] = (unsigned char)finalize_jump; + else if (p1[3] == (unsigned char)charset + || p1[3] == (unsigned char)charset_not) { + int not; + if (ismbchar(c)) { + unsigned char *pp = p2+3; + MBC2WC(c, pp); + } + /* `is_in_list()' is TRUE if c would match */ + /* That means it is not safe to finalize. */ + not = is_in_list(c, p1 + 4); + if (p1[3] == (unsigned char)charset_not) + not = !not; + if (!not) + p[-3] = (unsigned char)finalize_jump; + } + } + } + p -= 2; /* Point at relative address again. */ + if (p[-1] != (unsigned char)finalize_jump) + { + p[-1] = (unsigned char)jump; + goto nofinalize; + } + /* Note fall through. */ + + /* The end of a stupid repeat has a finalize_jump back to the + start, where another failure point will be made which will + point to after all the repetitions found so far. */ + + /* Take off failure points put on by matching on_failure_jump + because didn't fail. Also remove the register information + put on by the on_failure_jump. */ + case finalize_jump: + if (stackp[-2] == d) { + p = stackp[-3]; + POP_FAILURE_POINT(); + continue; + } + POP_FAILURE_POINT(); + /* Note fall through. */ + + /* Jump without taking off any failure points. */ + case jump: + nofinalize: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + p += mcnt; + continue; + + /* We need this opcode so we can detect where alternatives end + in `group_match_null_string_p' et al. */ + case jump_past_alt: + goto nofinalize; + + case dummy_failure_jump: + /* Normally, the on_failure_jump pushes a failure point, which + then gets popped at finalize_jump. We will end up at + finalize_jump, also, and with a pattern of, say, `a+', we + are skipping over the on_failure_jump, so we have to push + something meaningless for finalize_jump to pop. */ + PUSH_FAILURE_POINT(0, 0); + goto nofinalize; + + /* At the end of an alternative, we need to push a dummy failure + point in case we are followed by a `finalize_jump', because + we don't want the failure point for the alternative to be + popped. For example, matching `(a|ab)*' against `aab' + requires that we match the `ab' alternative. */ + case push_dummy_failure: + /* See comments just above at `dummy_failure_jump' about the + two zeroes. */ + PUSH_FAILURE_POINT(0, 0); + break; + + /* Have to succeed matching what follows at least n times. Then + just handle like an on_failure_jump. */ + case succeed_n: + EXTRACT_NUMBER(mcnt, p + 2); + /* Originally, this is how many times we HAVE to succeed. */ + if (mcnt > 0) + { + mcnt--; + p += 2; + STORE_NUMBER_AND_INCR(p, mcnt); + PUSH_FAILURE_POINT(0, 0); + } + else if (mcnt == 0) + { + p[2] = unused; + p[3] = unused; + goto on_failure; + } + continue; + + case jump_n: + EXTRACT_NUMBER(mcnt, p + 2); + /* Originally, this is how many times we CAN jump. */ + if (mcnt) + { + mcnt--; + STORE_NUMBER(p + 2, mcnt); + goto nofinalize; /* Do the jump without taking off + any failure points. */ + } + /* If don't have to jump any more, skip over the rest of command. */ + else + p += 4; + continue; + + case set_number_at: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + p1 = p + mcnt; + EXTRACT_NUMBER_AND_INCR(mcnt, p); + STORE_NUMBER(p1, mcnt); + continue; + + case try_next: + EXTRACT_NUMBER_AND_INCR(mcnt, p); + if (p + mcnt < pend) { + PUSH_FAILURE_POINT(p, d); + stackp[-1] = (unsigned char*)1; + } + p += mcnt; + continue; + + case finalize_push: + POP_FAILURE_POINT(); + EXTRACT_NUMBER_AND_INCR(mcnt, p); + PUSH_FAILURE_POINT(p + mcnt, d); + stackp[-1] = (unsigned char*)1; + continue; + + case finalize_push_n: + EXTRACT_NUMBER(mcnt, p + 2); + /* Originally, this is how many times we CAN jump. */ + if (mcnt) { + int pos, i; + + mcnt--; + STORE_NUMBER(p + 2, mcnt); + EXTRACT_NUMBER(pos, p); + EXTRACT_NUMBER(i, p+pos+5); + if (i > 0) goto nofinalize; + POP_FAILURE_POINT(); + EXTRACT_NUMBER_AND_INCR(mcnt, p); + PUSH_FAILURE_POINT(p + mcnt, d); + stackp[-1] = (unsigned char*)1; + p += 2; /* skip n */ + } + /* If don't have to push any more, skip over the rest of command. */ + else + p += 4; + continue; + + /* Ignore these. Used to ignore the n of succeed_n's which + currently have n == 0. */ + case unused: + continue; + + case casefold_on: + options |= RE_OPTION_IGNORECASE; + continue; + + case casefold_off: + options &= ~RE_OPTION_IGNORECASE; + continue; + + case wordbound: + if (AT_STRINGS_BEG(d)) { + if (IS_A_LETTER(d)) break; + else goto fail; + } + if (AT_STRINGS_BEG(d)) { + if (PREV_IS_A_LETTER(d)) break; + else goto fail; + } + if (PREV_IS_A_LETTER(d) != IS_A_LETTER(d)) + break; + goto fail; + + case notwordbound: + if (AT_STRINGS_BEG(d)) { + if (IS_A_LETTER(d)) goto fail; + else break; + } + if (AT_STRINGS_END(d)) { + if (PREV_IS_A_LETTER(d)) goto fail; + else break; + } + if (PREV_IS_A_LETTER(d) != IS_A_LETTER(d)) + goto fail; + break; + + case wordbeg: + if (IS_A_LETTER(d) && (AT_STRINGS_BEG(d) || !PREV_IS_A_LETTER(d))) + break; + goto fail; + + case wordend: + if (!AT_STRINGS_BEG(d) && PREV_IS_A_LETTER(d) + && (!IS_A_LETTER(d) || AT_STRINGS_END(d))) + break; + goto fail; + + case wordchar: + PREFETCH; + if (!IS_A_LETTER(d)) + goto fail; + if (ismbchar(*d) && d + mbclen(*d) - 1 < dend) + d += mbclen(*d) - 1; + d++; + SET_REGS_MATCHED; + break; + + case notwordchar: + PREFETCH; + if (IS_A_LETTER(d)) + goto fail; + if (ismbchar(*d) && d + mbclen(*d) - 1 < dend) + d += mbclen(*d) - 1; + d++; + SET_REGS_MATCHED; + break; + + case exactn: + /* Match the next few pattern characters exactly. + mcnt is how many characters to match. */ + mcnt = *p++; + /* This is written out as an if-else so we don't waste time + testing `translate' inside the loop. */ + if (TRANSLATE_P()) + { + do + { + unsigned char c; + + PREFETCH; + c = *d++; + if (*p == 0xff) { + p++; + if (!--mcnt + || AT_STRINGS_END(d) + || (unsigned char)*d++ != (unsigned char)*p++) + goto fail; + continue; + } + if (ismbchar(c)) { + 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 */ + if ((unsigned char)translate[c] + != (unsigned char)translate[*p++]) + goto fail; + } + while (--mcnt); + } + else + { + do + { + PREFETCH; + if (*p == 0xff) {p++; mcnt--;} + if (*d++ != *p++) goto fail; + } + while (--mcnt); + } + 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. */ + fail: + if (stackp != stackb) + /* A restart point is known. Restart there and pop it. */ + { + short last_used_reg, this_reg; + + /* If this failure point is from a dummy_failure_point, just + skip it. */ + if (stackp[-3] == 0) { + POP_FAILURE_POINT(); + goto fail; + } + stackp--; /* discard flag */ + d = *--stackp; + p = *--stackp; + /* Restore register info. */ + last_used_reg = (long)*--stackp; + + /* Make the ones that weren't saved -1 or 0 again. */ + for (this_reg = num_regs - 1; this_reg > last_used_reg; this_reg--) + { + regend[this_reg] = REG_UNSET_VALUE; + regstart[this_reg] = REG_UNSET_VALUE; + IS_ACTIVE(reg_info[this_reg]) = 0; + MATCHED_SOMETHING(reg_info[this_reg]) = 0; + } + + /* And restore the rest from the stack. */ + for ( ; this_reg > 0; this_reg--) + { + reg_info[this_reg].word = *--stackp; + regend[this_reg] = *--stackp; + regstart[this_reg] = *--stackp; + } + if (p < pend) + { + int is_a_jump_n = 0; + int failed_paren = 0; + + p1 = p; + /* If failed to a backwards jump that's part of a repetition + loop, need to pop this failure point and use the next one. */ + pop_loop: + switch ((enum regexpcode)*p1) { + case stop_paren: + failed_paren = 1; + p1++; + goto pop_loop; + + case jump_n: + case finalize_push_n: + is_a_jump_n = 1; + case maybe_finalize_jump: + case finalize_jump: + case finalize_push: + case jump: + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + + if (p1 >= pend) break; + if (( is_a_jump_n && (enum regexpcode)*p1 == succeed_n) || + (!is_a_jump_n && (enum regexpcode)*p1 == on_failure_jump)) { + if (failed_paren) { + p1++; + EXTRACT_NUMBER_AND_INCR(mcnt, p1); + PUSH_FAILURE_POINT(p1 + mcnt, d); + } + goto fail; + } + break; + default: + /* do nothing */ ; + } + } + } + else + break; /* Matching at this starting point really fails. */ + } + + if (best_regs_set) + goto restore_best_regs; + + FREE_AND_RETURN(stackb,(-1)); /* Failure to match. */ +} + + +/* We are passed P pointing to a register number after a start_memory. + + Return true if the pattern up to the corresponding stop_memory can + match the empty string, and false otherwise. + + If we find the matching stop_memory, sets P to point to one past its number. + Otherwise, sets P to an undefined byte less than or equal to END. + + We don't handle duplicates properly (yet). */ + +static int +group_match_null_string_p (p, end, reg_info) + unsigned char **p, *end; + register_info_type *reg_info; +{ + int mcnt; + /* Point to after the args to the start_memory. */ + unsigned char *p1 = *p + 2; + + while (p1 < end) + { + /* Skip over opcodes that can match nothing, and return true or + false, as appropriate, when we get to one that can't, or to the + matching stop_memory. */ + + switch ((enum regexpcode)*p1) + { + /* Could be either a loop or a series of alternatives. */ + case on_failure_jump: + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + + /* If the next operation is not a jump backwards in the + pattern. */ + + if (mcnt >= 0) + { + /* Go through the on_failure_jumps of the alternatives, + seeing if any of the alternatives cannot match nothing. + The last alternative starts with only a jump, + whereas the rest start with on_failure_jump and end + with a jump, e.g., here is the pattern for `a|b|c': + + /on_failure_jump/0/6/exactn/1/a/jump_past_alt/0/6 + /on_failure_jump/0/6/exactn/1/b/jump_past_alt/0/3 + /exactn/1/c + + So, we have to first go through the first (n-1) + alternatives and then deal with the last one separately. */ + + + /* Deal with the first (n-1) alternatives, which start + with an on_failure_jump (see above) that jumps to right + past a jump_past_alt. */ + + while ((enum regexpcode)p1[mcnt-3] == jump_past_alt) + { + /* `mcnt' holds how many bytes long the alternative + is, including the ending `jump_past_alt' and + its number. */ + + if (!alt_match_null_string_p (p1, p1 + mcnt - 3, + reg_info)) + return 0; + + /* Move to right after this alternative, including the + jump_past_alt. */ + p1 += mcnt; + + /* Break if it's the beginning of an n-th alternative + that doesn't begin with an on_failure_jump. */ + if ((enum regexpcode)*p1 != on_failure_jump) + break; + + /* Still have to check that it's not an n-th + alternative that starts with an on_failure_jump. */ + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if ((enum regexpcode)p1[mcnt-3] != jump_past_alt) + { + /* Get to the beginning of the n-th alternative. */ + p1 -= 3; + break; + } + } + + /* Deal with the last alternative: go back and get number + of the `jump_past_alt' just before it. `mcnt' contains + the length of the alternative. */ + EXTRACT_NUMBER (mcnt, p1 - 2); +#if 0 + if (!alt_match_null_string_p (p1, p1 + mcnt, reg_info)) + return 0; +#endif + p1 += mcnt; /* Get past the n-th alternative. */ + } /* if mcnt > 0 */ + break; + + + case stop_memory: + *p = p1 + 2; + return 1; + + + default: + if (!common_op_match_null_string_p (&p1, end, reg_info)) + return 0; + } + } /* while p1 < end */ + + return 0; +} /* group_match_null_string_p */ + + +/* Similar to group_match_null_string_p, but doesn't deal with alternatives: + It expects P to be the first byte of a single alternative and END one + byte past the last. The alternative can contain groups. */ + +static int +alt_match_null_string_p (p, end, reg_info) + unsigned char *p, *end; + register_info_type *reg_info; +{ + int mcnt; + unsigned char *p1 = p; + + while (p1 < end) + { + /* Skip over opcodes that can match nothing, and break when we get + to one that can't. */ + + switch ((enum regexpcode)*p1) + { + /* It's a loop. */ + case on_failure_jump: + p1++; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + break; + + default: + if (!common_op_match_null_string_p (&p1, end, reg_info)) + return 0; + } + } /* while p1 < end */ + + return 1; +} /* alt_match_null_string_p */ + + +/* Deals with the ops common to group_match_null_string_p and + alt_match_null_string_p. + + Sets P to one after the op and its arguments, if any. */ + +static int +common_op_match_null_string_p (p, end, reg_info) + unsigned char **p, *end; + register_info_type *reg_info; +{ + int mcnt; + int ret; + int reg_no; + unsigned char *p1 = *p; + + switch ((enum regexpcode)*p1++) + { + case unused: + case begline: + case endline: + case begbuf: + case endbuf: + case endbuf2: + case wordbeg: + case wordend: + case wordbound: + case notwordbound: +#ifdef emacs + case before_dot: + case at_dot: + case after_dot: +#endif + break; + + case start_memory: + reg_no = *p1; + ret = group_match_null_string_p (&p1, end, reg_info); + + /* Have to set this here in case we're checking a group which + contains a group and a back reference to it. */ + + if (REG_MATCH_NULL_STRING_P (reg_info[reg_no]) == MATCH_NULL_UNSET_VALUE) + REG_MATCH_NULL_STRING_P (reg_info[reg_no]) = ret; + + if (!ret) + return 0; + break; + + /* If this is an optimized succeed_n for zero times, make the jump. */ + case jump: + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + if (mcnt >= 0) + p1 += mcnt; + else + return 0; + break; + + case succeed_n: + /* Get to the number of times to succeed. */ + p1 += 2; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + + if (mcnt == 0) + { + p1 -= 4; + EXTRACT_NUMBER_AND_INCR (mcnt, p1); + p1 += mcnt; + } + else + return 0; + break; + + case duplicate: + if (!REG_MATCH_NULL_STRING_P (reg_info[*p1])) + return 0; + break; + + case set_number_at: + p1 += 4; + + default: + /* All other opcodes mean we cannot match the empty string. */ + return 0; + } + + *p = p1; + return 1; +} /* common_op_match_null_string_p */ + + +static int +memcmp_translate(s1, s2, len) + unsigned char *s1, *s2; + register int len; +{ + register unsigned char *p1 = s1, *p2 = s2, c; + while (len) + { + c = *p1++; + if (ismbchar(c)) { + int n; + + if (c != *p2++) return 1; + for (n = mbclen(c) - 1; n > 0; n--) + if (!--len || *p1++ != *p2++) + return 1; + } + else + if (translate[c] != translate[*p2++]) + return 1; + len--; + } + return 0; +} + +void +re_copy_registers(regs1, regs2) + struct re_registers *regs1, *regs2; +{ + int i; + + if (regs1 == regs2) return; + if (regs1->allocated == 0) { + regs1->beg = TMALLOC(regs2->num_regs, int); + regs1->end = TMALLOC(regs2->num_regs, int); + regs1->allocated = regs2->num_regs; + } + else if (regs1->allocated < regs2->num_regs) { + TREALLOC(regs1->beg, regs2->num_regs, int); + TREALLOC(regs1->end, regs2->num_regs, int); + regs1->allocated = regs2->num_regs; + } + for (i=0; inum_regs; i++) { + regs1->beg[i] = regs2->beg[i]; + regs1->end[i] = regs2->end[i]; + } + regs1->num_regs = regs2->num_regs; +} + +void +re_free_registers(regs) + struct re_registers *regs; +{ + if (regs->allocated == 0) return; + if (regs->beg) free(regs->beg); + if (regs->end) free(regs->end); +} + +/* Functions for multi-byte support. + Created for grep multi-byte extension Jul., 1993 by t^2 (Takahiro Tanimoto) + Last change: Jul. 9, 1993 by t^2 */ +static const unsigned char mbctab_ascii[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +}; + +static const unsigned char mbctab_euc[] = { /* 0xA1-0xFE */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0 +}; + +static const unsigned char mbctab_sjis[] = { /* 0x80-0x9f,0xE0-0xFF */ + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + +static const unsigned char mbctab_utf8[] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 5, 5, 0, 0 +}; + +const unsigned char *re_mbctab = mbctab_ascii; + +void +re_mbcinit(mbctype) + int mbctype; +{ + switch (mbctype) { + case MBCTYPE_ASCII: + re_mbctab = mbctab_ascii; + current_mbctype = MBCTYPE_ASCII; + break; + case MBCTYPE_EUC: + re_mbctab = mbctab_euc; + current_mbctype = MBCTYPE_EUC; + break; + case MBCTYPE_SJIS: + re_mbctab = mbctab_sjis; + current_mbctype = MBCTYPE_SJIS; + break; + case MBCTYPE_UTF8: + re_mbctab = mbctab_utf8; + current_mbctype = MBCTYPE_UTF8; + break; + } +} diff --git a/regex.h b/regex.h index f61b980648..66ee23aa5a 100644 --- a/regex.h +++ b/regex.h @@ -17,11 +17,24 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto) Last change: May 21, 1993 by t^2 */ -/* modifis for Ruby by matz@caelum.co.jp */ +/* modified for Ruby by matz@netlab.co.jp */ #ifndef __REGEXP_LIBRARY #define __REGEXP_LIBRARY +/* symbol mangling for ruby */ +#ifdef RUBY +# 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 /* Define number of parens for which we record the beginnings and ends. @@ -76,8 +89,8 @@ void re_mbcinit (); struct re_pattern_buffer { char *buffer; /* Space holding the compiled pattern commands. */ - size_t allocated; /* Size of space that `buffer' points to. */ - size_t used; /* Length of portion of buffer actually occupied */ + int allocated; /* Size of space that `buffer' points to. */ + int used; /* Length of portion of buffer actually occupied */ char *fastmap; /* Pointer to fastmap, if any, or zero if none. */ /* re_search uses the fastmap, if there is one, to skip over totally implausible characters. */ @@ -113,8 +126,8 @@ typedef struct re_pattern_buffer regex_t; struct re_registers { - size_t allocated; - size_t num_regs; + int allocated; + int num_regs; int *beg; int *end; }; @@ -138,13 +151,13 @@ typedef struct #ifdef __STDC__ -extern char *re_compile_pattern (char *, size_t, struct re_pattern_buffer *); +extern char *re_compile_pattern (char *, int, struct re_pattern_buffer *); void re_free_pattern (struct re_pattern_buffer *); /* Is this really advertised? */ extern void re_compile_fastmap (struct re_pattern_buffer *); -extern int re_search (struct re_pattern_buffer *, char*, size_t, size_t, size_t, +extern int re_search (struct re_pattern_buffer *, char*, int, int, int, struct re_registers *); -extern int re_match (struct re_pattern_buffer *, char *, size_t, size_t, +extern int re_match (struct re_pattern_buffer *, char *, int, int, struct re_registers *); extern void re_set_casetable (char *table); extern void re_copy_registers (struct re_registers*, struct re_registers*); diff --git a/ruby.1 b/ruby.1 index 8665ca79bb..ffc9337a53 100644 --- a/ruby.1 +++ b/ruby.1 @@ -161,8 +161,7 @@ OK" to the standard output. .B -Kc specifies KANJI (Japanese) code-set. .TP -.B --d --debug +.B -d --debug turns on debug mode. $DEBUG will set TRUE. .TP .B -e script @@ -172,6 +171,9 @@ search argv for script filenames. .B -F regexp specifies input field separator ($;). .TP +.B -h --help +prints a summary of the options. +.TP .B -i extension specifies in-place-edit mode. The extension, if specified, is added to old filename to make a backup copy. diff --git a/ruby.c b/ruby.c index 9bf28022e8..4f2ed550e1 100644 --- a/ruby.c +++ b/ruby.c @@ -6,7 +6,7 @@ $Date$ created at: Tue Aug 10 12:47:31 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -47,9 +47,8 @@ char *getenv(); static int version, copyright; -VALUE rb_debug = Qfalse; -VALUE rb_verbose = Qfalse; -int rb_tainting = Qfalse; +VALUE ruby_debug = Qfalse; +VALUE ruby_verbose = Qfalse; static int sflag = Qfalse; char *ruby_inplace_mode = Qfalse; @@ -71,6 +70,46 @@ static char *script; static int origargc; static char **origargv; +static void +usage(name) + char *name; +{ + /* This message really ought to be max 23 lines. + * Removed -h because the user already knows that opton. Others? */ + + static char *usage_msg[] = { +"-0[octal] specify record separator (\\0, if no argument)", +"-a autosplit mode with -n or -p (splits $_ into $F)", +"-c check syntax only", +"-d set debugging flags (set $DEBUG to true)", +"-e 'command' one line of script. Several -e's allowed. Omit [programfile]", +"-Fpattern split() pattern for autosplit (-a)", +"-i[extension] edit ARGV files in place (make backup if extension supplied)", +"-Idirectory specify $LOAD_PATH directory (may be used more than once)", +"-K[kcode] specifies KANJI (Japanese) code-set", +"-l enable line ending processing", +"-n assume 'while gets; ...; end' loop around your script", +"-p assume loop like -n but print line also like sed", +"-rlibrary require the library, before executing your script", +"-s enable some switch parsing for switches after script name", +"-S look for the script using PATH environment variable", +"-T[level] turn on tainting checks", +"-v enables verbose mode", +"-w turn warnings on for compilation of your script", +"-x[directory] strip off text before #!ruby line and perhaps cd to directory", +"-X[directory] cd to directory, before executing your script", +"--copyright print the copyright", +"--version print the version", +"\n", +NULL +}; + char **p = usage_msg; + + printf("\nUsage: %s [switches] [--] [programfile] [arguments]", name); + while (*p) + printf("\n %s", *p++); +} + #ifndef RUBY_LIB #define RUBY_LIB "/usr/local/lib/ruby" #endif @@ -193,8 +232,8 @@ proc_options(argcp, argvp) goto reswitch; case 'd': - rb_debug = Qtrue; - rb_verbose |= 1; + ruby_debug = Qtrue; + ruby_verbose |= 1; s++; goto reswitch; @@ -205,9 +244,9 @@ proc_options(argcp, argvp) case 'v': ruby_show_version(); - rb_verbose = 2; + ruby_verbose = 2; case 'w': - rb_verbose |= 1; + ruby_verbose |= 1; s++; goto reswitch; @@ -222,6 +261,10 @@ proc_options(argcp, argvp) s++; goto reswitch; + case 'h': + usage(origargv[0]); + exit(0); + case 'l': do_line = Qtrue; rb_output_rs = rb_rs; @@ -236,6 +279,14 @@ proc_options(argcp, argvp) case 'e': forbid_setid("-e"); + if (!*++s) { + s = argv[1]; + argc--,argv++; + } + if (!s) { + fprintf(stderr, "%s: no code specified for -e\n", origargv[0]); + exit(2); + } if (!e_fp) { e_tmpname = ruby_mktemp(); if (!e_tmpname) rb_fatal("Can't mktemp"); @@ -245,10 +296,7 @@ proc_options(argcp, argvp) } if (script == 0) script = e_tmpname; } - if (argv[1]) { - fputs(argv[1], e_fp); - argc--, argv++; - } + fputs(s, e_fp); putc('\n', e_fp); break; @@ -308,7 +356,6 @@ proc_options(argcp, argvp) if (numlen == 0) v = 1; } rb_set_safe_level(v); - rb_tainting = Qtrue; } break; @@ -350,15 +397,21 @@ proc_options(argcp, argvp) if (strcmp("copyright", s) == 0) copyright = 1; else if (strcmp("debug", s) == 0) - rb_debug = 1; + ruby_debug = 1; else if (strcmp("version", s) == 0) version = 1; else if (strcmp("verbose", s) == 0) - rb_verbose = 2; + ruby_verbose = 2; else if (strcmp("yydebug", s) == 0) yydebug = 1; + else if (strcmp("help", s) == 0) { + usage(origargv[0]); + exit(0); + } else { - rb_fatal("Unrecognized long option: --%s",s); + fprintf(stderr, "%s: invalid option --%s (-h will show valid options)\n", + origargv[0], s); + exit(2); } break; @@ -368,7 +421,9 @@ proc_options(argcp, argvp) break; default: - rb_fatal("Unrecognized switch: -%s",s); + fprintf(stderr, "%s: invalid option -%c (-h will show valid options)\n", + origargv[0], *s); + exit(2); case 0: break; @@ -397,7 +452,7 @@ proc_options(argcp, argvp) Init_ext(); /* should be called here for some reason :-( */ if (script_given == Qfalse) { if (argc == 0) { /* no more args */ - if (rb_verbose == 3) exit(0); + if (ruby_verbose == 3) exit(0); script = "-"; load_stdin(); } @@ -425,8 +480,8 @@ proc_options(argcp, argvp) argc--; argv++; } } - if (rb_verbose) rb_verbose = Qtrue; - if (rb_debug) rb_debug = Qtrue; + if (ruby_verbose) ruby_verbose = Qtrue; + if (ruby_debug) ruby_debug = Qtrue; xflag = Qfalse; *argvp = argv; @@ -728,10 +783,10 @@ ruby_prog_init() init_ids(); ruby_sourcefile = "ruby"; - rb_define_variable("$VERBOSE", &rb_verbose); - rb_define_variable("$-v", &rb_verbose); - rb_define_variable("$DEBUG", &rb_debug); - rb_define_variable("$-d", &rb_debug); + rb_define_variable("$VERBOSE", &ruby_verbose); + rb_define_variable("$-v", &ruby_verbose); + rb_define_variable("$DEBUG", &ruby_debug); + rb_define_variable("$-d", &ruby_debug); rb_define_readonly_variable("$-p", &do_print); rb_define_readonly_variable("$-l", &do_line); @@ -743,9 +798,6 @@ ruby_prog_init() #if defined(_WIN32) || defined(DJGPP) addpath(ruby_libpath()); #endif -#ifdef __MACOS__ - setup_macruby_libpath(); -#endif #ifdef RUBY_ARCHLIB addpath(RUBY_ARCHLIB); diff --git a/ruby.h b/ruby.h index 44c1abd2c6..49169d94cb 100644 --- a/ruby.h +++ b/ruby.h @@ -3,10 +3,9 @@ ruby.h - $Author$ - $Date$ created at: Thu Jun 10 14:26:32 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto *************************************************/ @@ -40,10 +39,11 @@ extern "C" { #include /* need to include 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)) @@ -245,21 +245,21 @@ struct RFloat { struct RString { struct RBasic basic; - size_t len; + int len; char *ptr; VALUE orig; }; struct RArray { struct RBasic basic; - size_t len, capa; + int len, capa; VALUE *ptr; }; struct RRegexp { struct RBasic basic; struct re_pattern_buffer *ptr; - size_t len; + int len; char *str; }; @@ -304,14 +304,14 @@ VALUE rb_data_object_alloc _((VALUE,void*,void (*)(),void (*)())); struct RStruct { struct RBasic basic; - size_t len; + int len; VALUE *ptr; }; struct RBignum { struct RBasic basic; char sign; - size_t len; + int len; unsigned short *digits; }; @@ -415,7 +415,7 @@ void rb_const_set _((VALUE, ID, VALUE)); VALUE rb_equal _((VALUE,VALUE)); -EXTERN VALUE rb_verbose, rb_debug; +EXTERN VALUE ruby_verbose, ruby_debug; int rb_safe_level _((void)); void rb_set_safe_level _((int)); @@ -447,6 +447,7 @@ void ruby_run _((void)); EXTERN VALUE rb_mKernel; EXTERN VALUE rb_mComparable; EXTERN VALUE rb_mEnumerable; +EXTERN VALUE rb_mPrecision; EXTERN VALUE rb_mErrno; EXTERN VALUE rb_mFileTest; EXTERN VALUE rb_mGC; @@ -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)); @@ -525,7 +529,11 @@ rb_type(VALUE obj) extern __inline__ int rb_special_const_p(VALUE obj) { - return (FIXNUM_P(obj)||obj == Qnil||obj == Qfalse||obj == Qtrue)?Qtrue:Qfalse; + if (FIXNUM_P(obj)) return Qtrue; + if (obj == Qnil) return Qtrue; + if (obj == Qfalse) return Qtrue; + if (obj == Qtrue) return Qtrue;; + return Qfalse; } extern __inline__ int diff --git a/rubyio.h b/rubyio.h index 5b8baf0f15..036f24426c 100644 --- a/rubyio.h +++ b/rubyio.h @@ -7,7 +7,7 @@ $Date$ created at: Fri Nov 12 16:47:09 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ diff --git a/rubytest.rb b/rubytest.rb index cf583c1dfb..3bf11b3ba5 100644 --- a/rubytest.rb +++ b/rubytest.rb @@ -1,11 +1,15 @@ #! ./miniruby -I. +x = ENV["LD_LIBRARY_PATH"] +x = x ? x+":." : "." +ENV["LD_LIBRARY_PATH"] = x + require 'rbconfig' include Config $stderr.reopen($stdout) error = '' -`./ruby #{CONFIG["srcdir"]}/sample/test.rb`.each do |line| +`./#{CONFIG["ruby_install_name"]} #{CONFIG["srcdir"]}/sample/test.rb`.each do |line| if line =~ /^end of test/ print "test succeeded\n" exit 0 diff --git a/sample/biorhythm.rb b/sample/biorhythm.rb index 50ad1f2ef7..d2cbb113ec 100644 --- a/sample/biorhythm.rb +++ b/sample/biorhythm.rb @@ -19,11 +19,11 @@ def usage() print "Usage:\n" print "biorhythm.rb [options]\n" print " options...\n" - print " -D YYYYMMDD(birthday) : すべて default 値を使う. \n" - print " --sdate | --date YYYYMMDD : system date もしくは指定した日付を使う.\n" - print " --birthday YYYYMMDD : 誕生日の指定をする. \n" - print " -v | -g : Values or Graph の指定. \n" - print " --days DAYS : 期間の指定をする(Graph の時のみ有効). \n" + print " -D YYYYMMDD(birthday) : use default values.\n" + print " --sdate | --date YYYYMMDD : use system date; use specified date.\n" + print " --birthday YYYYMMDD : specifies your birthday.\n" + print " -v | -g : show values or graph.\n" + print " --days DAYS : graph range (only in effect for graphs).\n" print " --help : help\n" end $USAGE = 'usage' diff --git a/sample/cal.rb b/sample/cal.rb index a5f4b4db18..50865dbb8f 100644 --- a/sample/cal.rb +++ b/sample/cal.rb @@ -1,7 +1,7 @@ #! /usr/local/bin/ruby -# cal.rb (bsd compatible version): Written by Tadayoshi Funaba 1998 -# $Id: bsdcal.rb,v 1.2 1998/12/01 13:47:40 tadf Exp $ +# cal.rb (bsd compatible version): Written by Tadayoshi Funaba 1998, 1999 +# $Id: bsdcal.rb,v 1.3 1999/02/06 08:52:21 tadf Exp $ require 'date2' @@ -68,7 +68,7 @@ def zip(xs) yr end -while /^-(.*)$/no =~ $*[0] +while /^-([^-].*)$/no =~ $*[0] a = $1 if /^c(.+)?$/no =~ a then if $1 then @@ -90,6 +90,7 @@ while /^-(.*)$/no =~ $*[0] end $*.shift end +$*.shift if /^--/no =~ $*[0] usage if (gs = $tab[$cc]).nil? case $*.length when 0 diff --git a/sample/io.rb b/sample/io.rb deleted file mode 100644 index 0b38d2112d..0000000000 --- a/sample/io.rb +++ /dev/null @@ -1,44 +0,0 @@ -# IO test -# usage: ruby io.rb file.. - -home = ENV["HOME"] -home.sub("m", "&&") -print(home, "\n") -print(home.reverse, "\n") - -if File.s("io.rb") - print(File.s("io.rb"), ": io.rb\n") -end - -$/="f\n" -for i in "abc\n\ndef\nghi\n" - print("tt: ", i) -end - -printf("%s:(%d)%s\n", $0, ARGV.length, ARGV[0]) -passwd = open(ARGV[0], "r") -#printf("%s", passwd.find{i|i =~ /\*/}) - -n = 1 -for i in passwd #.grep(/^\*/) - printf("%6d: %s", n, i) - n = n + 1; -end - -fp = open("|-", "r") - -if fp == nil - for i in 1..5 - print(i, "\n") - end -else - for line in fp - print(line) - end -end - -def printUsage() - if $USAGE - apply($USAGE); - end -end diff --git a/sample/list.rb b/sample/list.rb index 76035e67d6..17eefae85a 100644 --- a/sample/list.rb +++ b/sample/list.rb @@ -1,8 +1,8 @@ # Linked list example class MyElem - # オブジェクト生成時に自動的に呼ばれるメソッド + # object initializer called from Class#new def initialize(item) - # @変数はインスタンス変数(宣言は要らない) + # @variables are instance variable, no declaration needed @data = item @succ = nil end @@ -15,7 +15,7 @@ class MyElem @succ end - # 「obj.data = val」としたときに暗黙に呼ばれるメソッド + # the method invoked by ``obj.data = val'' def succ=(new) @succ = new end @@ -40,12 +40,12 @@ class MyList end end - # オブジェクトを文字列に変換するメソッド - # これを再定義するとprintでの表現が変わる + # the method to convert object into string. + # redefining this will affect print. def to_s str = "= @wi then 0 elsif y < 0 then 0 @@ -83,13 +83,13 @@ class Board end end def count(x,y) - # (x,y)$B$KNY@\$9$kGzCF$N?t$rJV$9(B + # (x,y)に隣接する爆弾の数を返す fetch(x-1,y-1)+fetch(x,y-1)+fetch(x+1,y-1)+ fetch(x-1,y) + fetch(x+1,y)+ fetch(x-1,y+1)+fetch(x,y+1)+fetch(x+1,y+1) end def over(win) - # $B%2!<%`$N=*N;(B + # ゲームの終了 quit unless win pos(@cx,@cy); print CHR[11] @@ -100,8 +100,8 @@ class Board end end def over? - # $B%2!<%`$N=*N;%A%'%C%/(B - # $B=*N;=hM}$b8F$S=P$9(B + # ゲームの終了チェック + # 終了処理も呼び出す remain = (@mc+@total == 0) if @over || remain over(remain) @@ -111,8 +111,8 @@ class Board end end def quit - # $B%2!<%`$NCfCG(B($B$^$?$O=*N;(B) - # $BHWLL$rA4$F8+$;$k(B + # ゲームの中断(または終了) + # 盤面を全て見せる @hi.times do|y| pos(0,y) @wi.times do|x| @@ -122,19 +122,19 @@ class Board end end def down - # $B%+!<%=%k$r2<$K(B + # カーソルを下に if @cy < @hi-1 then @cy=@cy+1; pos(@cx, @cy) end end def up - # $B%+!<%=%k$r>e$K(B + # カーソルを上に if @cy > 0 then @cy=@cy-1; pos(@cx, @cy) end end def left - # $B%+!<%=%k$r:8$K(B + # カーソルを左に if @cx > 0 then @cx=@cx-1; pos(@cx, @cy) end end def right - # $B%+!<%=%k$r1&$K(B + # カーソルを右に if @cx < @wi-1 then @cx=@cx+1; pos(@cx, @cy) end end end @@ -143,7 +143,7 @@ bd=Board.new(10,10,10) system("stty raw -echo") begin loop do - case getc + case STDIN.getc when ?n # new game bd.reset when ?m # mark @@ -163,7 +163,7 @@ begin break end if bd.over? - if getc == ?q then break end + if STDIN.getc == ?q then break end bd.reset end end diff --git a/sample/rbc.rb b/sample/rbc.rb index 83796255cc..9f1ab9443d 100644 --- a/sample/rbc.rb +++ b/sample/rbc.rb @@ -273,7 +273,7 @@ module BC_APPLICATION__ rests.unshift op identify_number(rests) else - # obj.if などの対応 + # handle ``obj.if'' and such identify_identifier(rests, TRUE) @lex_state = EXPR_ARG end @@ -344,7 +344,7 @@ module BC_APPLICATION__ @lex_state = EXPR_BEG end end - @OP.def_rule('$') do + @OP.def_rule('$') do #' |op, rests| identify_gvar(rests) end @@ -466,7 +466,7 @@ module BC_APPLICATION__ print token, "\n" if CONFIG[:DEBUG] if state = CLAUSE_STATE_TRANS[token] if @lex_state != EXPR_BEG and token =~ /^(if|unless|while|until)/ - # 修飾子 + # modifiers else if ENINDENT_CLAUSE.include?(token) @indent += 1 @@ -640,7 +640,7 @@ module BC_APPLICATION__ def_exception :ErrNodeAlreadyExists, "node already exists" class Node - # postprocがなければ抽象ノード, nilじゃなければ具象ノード + # abstract node if postproc is nil. def initialize(preproc = nil, postproc = nil) @Tree = {} @preproc = preproc diff --git a/sample/rcs.rb b/sample/rcs.rb index 3f74da9ef2..7c091936f3 100644 --- a/sample/rcs.rb +++ b/sample/rcs.rb @@ -1,12 +1,12 @@ # random dot steraogram # usage: rcs.rb rcs.dat -sw = 40.0 # p^[ -dw = 78.0 # Random Character Streogram +sw = 40.0 # width of original pattern +dw = 78.0 # width of generating Random Character Streogram hdw = dw / 2.0 -w = 20.0 # -h =1.0 # -d = 0.2 # P +w = 20.0 # distance between eyes +h =1.0 # distance from screen and base plane +d = 0.2 # z value unit ss="abcdefghijklmnopqrstuvwxyz0123456789#!$%^&*()-=\\[];'`,./" rnd = srand() diff --git a/sample/rename.rb b/sample/rename.rb index 9abea7e327..4174c382c4 100644 --- a/sample/rename.rb +++ b/sample/rename.rb @@ -283,8 +283,8 @@ gsub!(/\bobj_instance_variables\b/,"rb_obj_instance_variables") gsub!(/\bobj_remove_instance_variable\b/,"rb_obj_remove_instance_variable") gsub!(/\bshow_copyright\b/,"ruby_show_copyright") gsub!(/\bshow_version\b/,"ruby_show_version") -gsub!(/\bdebug\b/,"rb_debug") -gsub!(/\bverbose\b/,"rb_verbose") +gsub!(/\bdebug\b/,"ruby_debug") +gsub!(/\bverbose\b/,"ruby_verbose") gsub!(/\bFail\(/,"rb_raise(rb_eRuntimeError, ") gsub!(/\bArgError\(/,"rb_raise(rb_eArgError, ") gsub!(/\bTypeError\(/,"rb_raise(rb_eTypeError, ") @@ -294,4 +294,4 @@ gsub!(/\bError\b/,"rb_compile_error") gsub!(/\bErrorAppend\b/,"rb_compile_error_append") gsub!(/\bTRUE\b/,"Qtrue") gsub!(/\bFALSE\b/,"Qfalse") -gsub!(/\berrinfo\b/,"rb_errinfo") +gsub!(/\berrinfo\b/,"ruby_errinfo") diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el deleted file mode 100644 index 0f56477ea0..0000000000 --- a/sample/ruby-mode.el +++ /dev/null @@ -1,649 +0,0 @@ -;;; -;;; ruby-mode.el - -;;; -;;; $Author$ -;;; Time-stamp: <97/03/21 01:16:05 matz> -;;; created at: Fri Feb 4 14:49:13 JST 1994 -;;; - -(defconst ruby-mode-version "1.0.7") - -(defconst ruby-block-beg-re - "class\\|module\\|def\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin\\|do" - ) - -(defconst ruby-indent-beg-re - "\\(\\s *\\(class\\|module\\|def\\)\\)\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin" - ) - -(defconst ruby-modifier-re - "if\\|unless\\|while\\|until" - ) - -(defconst ruby-block-mid-re - "then\\|else\\|elsif\\|when\\|rescue\\|ensure" - ) - -(defconst ruby-block-op-re - "and\\|or\\|not" - ) - -(defconst ruby-block-end-re "end") - -(defconst ruby-delimiter - (concat "[?$/%(){}#\"'`]\\|\\[\\|\\]\\|\\<\\(" - ruby-block-beg-re - "\\|" ruby-block-end-re - "\\)\\>\\|^=begin") - ) - -(defconst ruby-negative - (concat "^[ \t]*\\(\\(" ruby-block-mid-re "\\)\\>\\|\\(" - ruby-block-end-re "\\)\\>\\|\\}\\|\\]\\)") - ) - -(defconst ruby-operator-chars "[,.+*/%-&|^~=<>:]") -(defconst ruby-symbol-chars "[a-zA-Z0-9_]") - -(defvar ruby-mode-abbrev-table nil - "Abbrev table in use in ruby-mode buffers.") - -(define-abbrev-table 'ruby-mode-abbrev-table ()) - -(defvar ruby-mode-map nil "Keymap used in ruby mode.") - -(if ruby-mode-map - nil - (setq ruby-mode-map (make-sparse-keymap)) - (define-key ruby-mode-map "{" 'ruby-electric-brace) - (define-key ruby-mode-map "}" 'ruby-electric-brace) - (define-key ruby-mode-map "\e\C-a" 'ruby-beginning-of-defun) - (define-key ruby-mode-map "\e\C-e" 'ruby-end-of-defun) - (define-key ruby-mode-map "\e\C-b" 'ruby-beginning-of-block) - (define-key ruby-mode-map "\e\C-f" 'ruby-end-of-block) - (define-key ruby-mode-map "\e\C-p" 'ruby-beginning-of-block) - (define-key ruby-mode-map "\e\C-n" 'ruby-end-of-block) - (define-key ruby-mode-map "\t" 'ruby-indent-command) - (define-key ruby-mode-map "\C-c\C-e" 'ruby-insert-end) - (define-key ruby-mode-map "\C-j" 'ruby-reindent-then-newline-and-indent) - (define-key ruby-mode-map "\C-m" 'newline)) - -(defvar ruby-mode-syntax-table nil - "Syntax table in use in ruby-mode buffers.") - -(if ruby-mode-syntax-table - () - (setq ruby-mode-syntax-table (make-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 ?\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) - (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) - (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) - (modify-syntax-entry ?\} "){" ruby-mode-syntax-table) - (modify-syntax-entry ?\[ "(]" ruby-mode-syntax-table) - (modify-syntax-entry ?\] ")[" ruby-mode-syntax-table) - ) - -(defvar ruby-indent-level 2 - "*Indentation of ruby statements.") - -(defun ruby-mode () - "Major mode for editing ruby scripts. -\\[ruby-indent-command] properly indents subexpressions of multi-line -class, module, def, if, while, for, do, and case statements, taking -nesting into account. - -The variable ruby-indent-level controls the amount of indentation. -\\{ruby-mode-map}" - (interactive) - (kill-all-local-variables) - (use-local-map ruby-mode-map) - (setq mode-name "ruby") - (setq major-mode 'ruby-mode) - (set-syntax-table ruby-mode-syntax-table) - (setq local-abbrev-table ruby-mode-abbrev-table) - (make-local-variable 'indent-line-function) - (setq indent-line-function 'ruby-indent-line) - (make-local-variable 'require-final-newline) - (setq require-final-newline t) - (make-variable-buffer-local 'comment-start) - (setq comment-start "# ") - (make-variable-buffer-local 'comment-end) - (setq comment-end "") - (make-variable-buffer-local 'comment-column) - (setq comment-column 32) - (make-variable-buffer-local 'comment-start-skip) - (setq comment-start-skip "\\(^\\|\\s-\\);?#+ *") - (make-local-variable 'parse-sexp-ignore-comments) - (setq parse-sexp-ignore-comments t) - (run-hooks 'ruby-mode-hook)) - -(defun ruby-current-indentation () - (save-excursion - (beginning-of-line) - (back-to-indentation) - (current-column))) - -(defun ruby-indent-line (&optional flag) - "Correct indentation of the current ruby line." - (ruby-indent-to (ruby-calculate-indent))) - -(defun ruby-indent-command () - (interactive) - (ruby-indent-line t)) - -(defun ruby-indent-to (x) - (if x - (let (shift top beg) - (and (< x 0) - (error "invalid nest")) - (setq shift (current-column)) - (beginning-of-line) - (setq beg (point)) - (back-to-indentation) - (setq top (current-column)) - (skip-chars-backward " \t") - (cond - ((>= x shift) - (setq shift 0)) - ((>= shift top) - (setq shift (- shift top))) - (t (setq shift 0))) - (if (and (bolp) - (= x top)) - (move-to-column (+ x shift)) - (move-to-column top) - (delete-region beg (point)) - (beginning-of-line) - (indent-to x) - (move-to-column (+ x shift)))))) - -(defun ruby-expr-beg (&optional modifier) - (save-excursion - (if (looking-at "\\?") - (progn - (or (bolp) (forward-char -1)) - (not (looking-at "\\sw"))) - (skip-chars-backward " \t") - (or (bolp) (forward-char -1)) - (or (looking-at ruby-operator-chars) - (looking-at "[\\[({!?]") - (bolp) - (and (looking-at ruby-symbol-chars) - (forward-word -1) - (or - (and modifier (bolp)) - (looking-at ruby-block-beg-re) - (looking-at ruby-block-op-re) - (looking-at ruby-block-mid-re) - (and modifier - (save-excursion - (forward-char -1) - (let ((c (char-after (point)))) - (or (eq c ?.) - (eq c ? ) - (eq c ?\t)))))) - (goto-char (match-end 0)) - (looking-at "[^_]")))))) - -(defun ruby-parse-region (start end) - (let ((indent-point end) - (indent 0) - (in-string nil) - (in-paren nil) - (depth 0) - (nest nil) - (pcol nil)) - (save-excursion - (if start - (goto-char start) - (ruby-beginning-of-indent)) - (save-restriction - (narrow-to-region (point) end) - (while (and (> indent-point (point)) - (re-search-forward ruby-delimiter indent-point t)) - (let ((pnt (point)) w) - (goto-char (match-beginning 0)) - (cond - ((or (looking-at "\"") ;skip string - (looking-at "'") - (looking-at "`")) - (setq w (char-after (point))) - (cond - ((and (not (eobp)) - (re-search-forward (format "[^\\]%c" w) indent-point t)) - nil) - (t - (setq in-string (point)) - (goto-char indent-point)))) - ((looking-at "/") - (cond - ((and (not (eobp)) (ruby-expr-beg)) - (if (re-search-forward "[^\\]/" indent-point t) - nil - (setq in-string (point)) - (goto-char indent-point))) - (t - (goto-char pnt)))) - ((looking-at "%") - (cond - ((and (not (eobp)) (ruby-expr-beg) - (looking-at "%[Qqrx]?\\(.\\)")) - (setq w (buffer-substring (match-beginning 1) - (match-end 1))) - (cond - ((string= w "[") (setq w "]")) - ((string= w "{") (setq w "}")) - ((string= w "(") (setq w ")")) - ((string= w "<") (setq w ">"))) - (goto-char (match-end 0)) - (if (search-forward w indent-point t) - nil - (setq in-string (point)) - (goto-char indent-point))) - (t - (goto-char pnt)))) - ((looking-at "\\?") ;skip ?char - (cond - ((ruby-expr-beg) - (looking-at "?\\(\\\\C-\\|\\\\M-\\)*.") - (goto-char (match-end 0))) - (t - (goto-char pnt)))) - ((looking-at "\\$") ;skip $char - (goto-char pnt) - (forward-char 1)) - ((looking-at "#") ;skip comment - (forward-line 1) - (goto-char (point)) - ) - ((looking-at "(") - (setq nest (cons (cons (char-after (point)) pnt) nest)) - (setq pcol (cons (cons pnt depth) pcol)) - (setq depth 0) - (goto-char pnt) - ) - ((looking-at "[\\[{]") - (setq nest (cons (cons (char-after (point)) pnt) nest)) - (setq depth (1+ depth)) - (goto-char pnt) - ) - ((looking-at ")") - (setq nest (cdr nest)) - (setq depth (cdr (car pcol))) - (setq pcol (cdr pcol)) - (goto-char pnt)) - ((looking-at "[])}]") - (setq nest (cdr nest)) - (setq depth (1- depth)) - (goto-char pnt)) - ((looking-at ruby-block-end-re) - (if (or (and (not (bolp)) - (progn - (forward-char -1) - (eq ?_ (char-after (point))))) - (progn - (goto-char pnt) - (setq w (char-after (point))) - (or (eq ?_ w) - (eq ?! w) - (eq ?? w)))) - nil - (setq nest (cdr nest)) - (setq depth (1- depth))) - (goto-char pnt)) - ((looking-at ruby-block-beg-re) - (and - (or (bolp) - (progn - (forward-char -1) - (not (eq ?_ (char-after (point)))))) - (progn - (goto-char pnt) - (setq w (char-after (point))) - (and (not (eq ?_ w)) - (not (eq ?! w)) - (not (eq ?? w)))) - (progn - (goto-char (match-beginning 0)) - (if (looking-at ruby-modifier-re) - (ruby-expr-beg) - t)) - (progn - (setq nest (cons (cons nil pnt) nest)) - (setq depth (1+ depth)))) - (if (looking-at "def\\s *[/`]") - (goto-char (match-end 0)) - (goto-char pnt))) - ((looking-at "^=begin") - (if (re-search-forward "^=end" indent-point t) - (forward-line 1) - (setq in-string (match-end 0)) - (goto-char indent-point))) - (t - (error (format "bad string %s" - (buffer-substring (point) pnt) - ))))))) - (list in-string (car nest) depth (car (car pcol)))))) - -(defun ruby-calculate-indent (&optional parse-start) - (save-excursion - (beginning-of-line) - (let ((indent-point (point)) - (case-fold-search nil) - state bol eol - (indent 0)) - (if parse-start - (goto-char parse-start) - (ruby-beginning-of-indent) - (setq parse-start (point))) - (back-to-indentation) - (setq indent (current-column)) - (setq state (ruby-parse-region parse-start indent-point)) - (cond - ((nth 0 state) ; within string - (setq indent nil)) ; do nothing - - ((car (nth 1 state)) ; in paren - (goto-char (cdr (nth 1 state))) - (if (eq (car (nth 1 state)) ?\( ) - (let ((column (current-column)) - (s (ruby-parse-region (point) indent-point))) - (cond - ((and (nth 2 s) (> (nth 2 s) 0)) - (goto-char (cdr (nth 1 s))) - (forward-word -1) - (setq indent (+ (current-column) ruby-indent-level))) - (t - (setq indent (current-column))))) - (cond - ((nth 3 state) - (goto-char (nth 3 state)) - (setq indent (+ (current-column) ruby-indent-level))) - (t - (goto-char parse-start) - (back-to-indentation) - (setq indent (+ (current-column) (* (nth 2 state) ruby-indent-level))))) - )) - - ((and (nth 2 state)(> (nth 2 state) 0)) ; in nest - (if (null (cdr (nth 1 state))) - (error "invalid nest")) - (goto-char (cdr (nth 1 state))) - (forward-word -1) ; skip back a keyword - (cond - ((looking-at "do") ; iter block is a special case - (cond - ((nth 3 state) - (goto-char (nth 3 state)) - (setq indent (+ (current-column) ruby-indent-level))) - (t - (goto-char parse-start) - (back-to-indentation) - (setq indent (+ (current-column) (* (nth 2 state) ruby-indent-level)))))) - (t - (setq indent (+ (current-column) ruby-indent-level))))) - - ((and (nth 2 state) (< (nth 2 state) 0)) ; in negative nest - (setq indent (+ (current-column) (* (nth 2 state) ruby-indent-level))))) - - (cond - (indent - (goto-char indent-point) - (end-of-line) - (setq eol (point)) - (beginning-of-line) - (cond - ((re-search-forward ruby-negative eol t) - (and (not (eq ?_ (char-after (match-end 0)))) - (setq indent (- indent ruby-indent-level)))) - ;;operator terminated lines - ((and - (save-excursion - (beginning-of-line) - (not (bobp))) - (or (null (car (nth 1 state))) ;not in parens - (and (eq (car (nth 1 state)) ?\{) - (save-excursion ;except non-block braces - (goto-char (cdr (nth 1 state))) - (or (bobp) (forward-char -1)) - (not (ruby-expr-beg)))))) - ;; goto beginning of non-empty no-comment line - (let (end done) - (while (not done) - (skip-chars-backward " \t\n") - (setq end (point)) - (beginning-of-line) - (if (re-search-forward "^\\s *#" end t) - (beginning-of-line) - (setq done t)))) - (setq bol (point)) - (end-of-line) - (skip-chars-backward " \t") - (or (bobp) (forward-char -1)) - (and - (or (and (looking-at ruby-symbol-chars) - (skip-chars-backward ruby-symbol-chars) - (looking-at ruby-block-op-re) - (save-excursion - (goto-char (match-end 0)) - (not (looking-at "[a-z_]")))) - (and (looking-at ruby-operator-chars) - (or (not (or (eq ?/ (char-after (point))))) - (null (nth 0 (ruby-parse-region parse-start (point))))) - (not (eq (char-after (1- (point))) ?$)) - (or (not (eq ?| (char-after (point)))) - (save-excursion - (or (eolp) (forward-char -1)) - (and (search-backward "|") - (skip-chars-backward " \t\n") - (and (not (eolp)) - (progn - (forward-char -1) - (not (looking-at "\\{"))) - (progn - (forward-word -1) - (not (looking-at "do\\>[^_]"))))))))) - (setq indent (+ indent ruby-indent-level))))))) - indent))) - -(defun ruby-electric-brace (arg) - (interactive "P") - (self-insert-command (prefix-numeric-value arg)) - (ruby-indent-line t)) - -(defun ruby-beginning-of-defun (&optional arg) - "Move backward to next beginning-of-defun. -With argument, do this that many times. -Returns t unless search stops due to end of buffer." - (interactive "p") - (and (re-search-backward (concat "^\\(" ruby-block-beg-re "\\)\\b") - nil 'move (or arg 1)) - (progn (beginning-of-line) t))) - -(defun ruby-beginning-of-indent () - (and (re-search-backward (concat "^\\(" ruby-indent-beg-re "\\)\\b") - nil 'move) - (progn - (beginning-of-line) - t))) - -(defun ruby-end-of-defun (&optional arg) - "Move forward to next end of defun. -An end of a defun is found by moving forward from the beginning of one." - (interactive "p") - (and (re-search-forward (concat "^\\(" ruby-block-end-re "\\)\\b[^_]") - nil 'move (or arg 1)) - (progn (beginning-of-line) t)) - (forward-line 1)) - -(defun ruby-move-to-block (n) - (let (start pos done down) - (setq start (ruby-calculate-indent)) - (if (eobp) - nil - (while (and (not (bobp)) (not done)) - (forward-line n) - (cond - ((looking-at "^$")) - ((looking-at "^\\s *#")) - (t - (setq pos (current-indentation)) - (cond - ((< start pos) - (setq down t)) - ((and down (= pos start)) - (setq done t)) - ((> start pos) - (setq done t))))) - (if done - (progn - (back-to-indentation) - (if (looking-at ruby-block-mid-re) - (setq done nil))))))) - (back-to-indentation)) - -(defun ruby-beginning-of-block () - "Move backward to next beginning-of-block" - (interactive) - (ruby-move-to-block -1)) - -(defun ruby-end-of-block () - "Move forward to next beginning-of-block" - (interactive) - (ruby-move-to-block 1)) - -(defun ruby-reindent-then-newline-and-indent () - (interactive "*") - (save-excursion - (delete-region (point) (progn (skip-chars-backward " \t") (point)))) - (newline) - (save-excursion - (forward-line -1) - (indent-according-to-mode)) - (indent-according-to-mode)) - -(fset 'ruby-encomment-region (symbol-function 'comment-region)) - -(defun ruby-decomment-region (beg end) - (interactive "r") - (save-excursion - (goto-char beg) - (while (re-search-forward "^\\([ \t]*\\)#" end t) - (replace-match "\\1" nil nil) - (save-excursion - (ruby-indent-line))))) - -(defun ruby-insert-end () - (interactive) - (insert "end") - (ruby-indent-line t) - (end-of-line)) - -(cond - ((featurep 'hilit19) - (hilit-set-mode-patterns - 'ruby-mode - '(("[^$\\?]\\(\"[^\\\"]*\\(\\\\\\(.\\|\n\\)[^\\\"]*\\)*\"\\)" 1 string) - ("[^$\\?]\\('[^\\']*\\(\\\\\\(.\\|\n\\)[^\\']*\\)*'\\)" 1 string) - ("[^$\\?]\\(`[^\\`]*\\(\\\\\\(.\\|\n\\)[^\\`]*\\)*`\\)" 1 string) - ("^\\s *#.*$" nil comment) - ("[^$@?\\]\\(#[^$@{].*$\\)" 1 comment) - ("[^a-zA-Z_]\\(\\?\\(\\\\[CM]-\\)*.\\)" 1 string) - ("^\\s *\\(require\\|load\\).*$" nil include) - ("^\\s *\\(include\\|alias\\|undef\\).*$" nil decl) - ("^\\s *\\<\\(class\\|def\\|module\\)\\>" "[)\n;]" defun) - ("[^_]\\<\\(begin\\|case\\|else\\|elsif\\|end\\|ensure\\|for\\|if\\|unless\\|rescue\\|then\\|when\\|while\\|until\\|do\\)\\>[^_]" 1 defun) - ("[^_]\\<\\(and\\|break\\|next\\|raise\\|fail\\|in\\|not\\|or\\|redo\\|retry\\|return\\|super\\|yield\\|self\\|nil\\)\\>[^_]" 1 keyword) - ("\\$\\(.\\|\\sw+\\)" nil type) - ("[$@].[a-zA-Z_0-9]*" nil struct) - ("^__END__" nil label)))) - - ((featurep 'font-lock) - (or (boundp 'font-lock-variable-name-face) - (setq font-lock-variable-name-face font-lock-type-face)) - (defvar ruby-font-lock-keywords - (list - (cons (concat - "\\(^\\|[^_]\\)\\b\\(" - (mapconcat - 'identity - '("alias" - "and" - "begin" - "break" - "case" - "class" - "do" - "elsif" - "else" - "fail" - "ensure" - "for" - "end" - "if" - "in" - "module" - "next" - "not" - "or" - "raise" - "redo" - "rescue" - "retry" - "return" - "then" - "self" - "super" - "unless" - "undef" - "until" - "when" - "while" - ) - "\\|") - "\\)[ \n\t()]") - 2) - ;; variables - '("\\(^\\|[^_]\\)\\b\\(nil\\|self\\|true\\|false\\)\\b[^_]" - 2 font-lock-variable-name-face) - ;; variables - '("\\[$@].\\([a-zA-Z0-9_]\\)" - 0 font-lock-variable-name-face) - ;; constants - '("\\(^\\|[^_]\\)\\b\\([A-Z]+[a-zA-Z0-9_]*\\)" - 2 font-lock-type-face) - ;; functions - '("^\\s *def[ \t]+.*$" - 0 font-lock-function-name-face)) - "*Additional expressions to highlight in ruby mode.") - (if (and (>= (string-to-int emacs-version) 20) - (not (featurep 'xemacs))) - (add-hook - 'ruby-mode-hook - (lambda () - (make-local-variable 'font-lock-defaults) - (setq font-lock-defaults - '((ruby-font-lock-keywords) nil nil ((?\_ . "w")))))) - (add-hook 'ruby-mode-hook - (lambda () - (setq font-lock-keywords ruby-font-lock-keywords) - (font-lock-mode 1)))))) diff --git a/sample/rubydb2x.el b/sample/rubydb2x.el deleted file mode 100644 index a74265fb0e..0000000000 --- a/sample/rubydb2x.el +++ /dev/null @@ -1,104 +0,0 @@ -(require 'gud) -(provide 'rubydb) - -;; ====================================================================== -;; rubydb functions - -;;; History of argument lists passed to rubydb. -(defvar gud-rubydb-history nil) - -(defun gud-rubydb-massage-args (file args) - (cons "-I" (cons "." (cons "-r" (cons "debug" (cons file args)))))) - -;; There's no guarantee that Emacs will hand the filter the entire -;; marker at once; it could be broken up across several strings. We -;; might even receive a big chunk with several markers in it. If we -;; receive a chunk of text which looks like it might contain the -;; beginning of a marker, we save it here between calls to the -;; filter. -(defvar gud-rubydb-marker-acc "") - -(defun gud-rubydb-marker-filter (string) - (save-match-data - (setq gud-marker-acc (concat gud-marker-acc string)) - (let ((output "")) - - ;; Process all the complete markers in this chunk. - (while (string-match "\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n" - gud-marker-acc) - (setq - - ;; Extract the frame position from the marker. - gud-last-frame - (cons (substring gud-marker-acc (match-beginning 1) (match-end 1)) - (string-to-int (substring gud-marker-acc - (match-beginning 2) - (match-end 2)))) - - ;; Append any text before the marker to the output we're going - ;; to return - we don't include the marker in this text. - output (concat output - (substring gud-marker-acc 0 (match-beginning 0))) - - ;; Set the accumulator to the remaining text. - gud-marker-acc (substring gud-marker-acc (match-end 0)))) - - ;; Does the remaining text look like it might end with the - ;; beginning of another marker? If it does, then keep it in - ;; gud-marker-acc until we receive the rest of it. Since we - ;; know the full marker regexp above failed, it's pretty simple to - ;; test for marker starts. - (if (string-match "\032.*\\'" gud-marker-acc) - (progn - ;; Everything before the potential marker start can be output. - (setq output (concat output (substring gud-marker-acc - 0 (match-beginning 0)))) - - ;; Everything after, we save, to combine with later input. - (setq gud-marker-acc - (substring gud-marker-acc (match-beginning 0)))) - - (setq output (concat output gud-marker-acc) - gud-marker-acc "")) - - output))) - -(defun gud-rubydb-find-file (f) - (find-file-noselect f)) - -(defvar rubydb-command-name "ruby" - "File name for executing ruby.") - -;;;###autoload -(defun rubydb (command-line) - "Run rubydb on program FILE in buffer *gud-FILE*. -The directory containing FILE becomes the initial working directory -and source-file directory for your debugger." - (interactive - (list (read-from-minibuffer "Run rubydb (like this): " - (if (consp gud-rubydb-history) - (car gud-rubydb-history) - (concat rubydb-command-name " ")) - nil nil - '(gud-rubydb-history . 1)))) - - (gud-overload-functions '((gud-massage-args . gud-rubydb-massage-args) - (gud-marker-filter . gud-rubydb-marker-filter) - (gud-find-file . gud-rubydb-find-file) - )) - (gud-common-init command-line) - - (gud-def gud-break "b %l" "\C-b" "Set breakpoint at current line.") -; (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line") - (gud-def gud-step "s" "\C-s" "Step one source line with display.") - (gud-def gud-next "n" "\C-n" "Step one line (skip functions).") - (gud-def gud-cont "c" "\C-r" "Continue with display.") - (gud-def gud-finish "finish" "\C-f" "Finish executing current function.") - (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).") - (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).") - (gud-def gud-print "p %e" "\C-p" "Evaluate ruby expression at point.") - - (setq comint-prompt-regexp "^(rdb:-) ") - (setq paragraph-start comint-prompt-regexp) - (run-hooks 'rubydb-mode-hook) - ) diff --git a/sample/rubydb3x.el b/sample/rubydb3x.el deleted file mode 100644 index 9d4e31f90e..0000000000 --- a/sample/rubydb3x.el +++ /dev/null @@ -1,104 +0,0 @@ -(require 'gud) -(provide 'rubydb) - -;; ====================================================================== -;; rubydb functions - -;;; History of argument lists passed to rubydb. -(defvar gud-rubydb-history nil) - -(defun gud-rubydb-massage-args (file args) - (cons "-r" (cons "debug" args))) - -;; There's no guarantee that Emacs will hand the filter the entire -;; marker at once; it could be broken up across several strings. We -;; might even receive a big chunk with several markers in it. If we -;; receive a chunk of text which looks like it might contain the -;; beginning of a marker, we save it here between calls to the -;; filter. -(defvar gud-rubydb-marker-acc "") - -(defun gud-rubydb-marker-filter (string) - (setq gud-marker-acc (concat gud-marker-acc string)) - (let ((output "")) - - ;; Process all the complete markers in this chunk. - (while (string-match "\032\032\\([^:\n]*\\):\\([0-9]*\\):.*\n" - gud-marker-acc) - (setq - - ;; Extract the frame position from the marker. - gud-last-frame - (cons (substring gud-marker-acc (match-beginning 1) (match-end 1)) - (string-to-int (substring gud-marker-acc - (match-beginning 2) - (match-end 2)))) - - ;; Append any text before the marker to the output we're going - ;; to return - we don't include the marker in this text. - output (concat output - (substring gud-marker-acc 0 (match-beginning 0))) - - ;; Set the accumulator to the remaining text. - gud-marker-acc (substring gud-marker-acc (match-end 0)))) - - ;; Does the remaining text look like it might end with the - ;; beginning of another marker? If it does, then keep it in - ;; gud-marker-acc until we receive the rest of it. Since we - ;; know the full marker regexp above failed, it's pretty simple to - ;; test for marker starts. - (if (string-match "\032.*\\'" gud-marker-acc) - (progn - ;; Everything before the potential marker start can be output. - (setq output (concat output (substring gud-marker-acc - 0 (match-beginning 0)))) - - ;; Everything after, we save, to combine with later input. - (setq gud-marker-acc - (substring gud-marker-acc (match-beginning 0)))) - - (setq output (concat output gud-marker-acc) - gud-marker-acc "")) - - output)) - -(defun gud-rubydb-find-file (f) - (save-excursion - (let ((buf (find-file-noselect f))) - (set-buffer buf) - (gud-make-debug-menu) - buf))) - -(defvar rubydb-command-name "ruby" - "File name for executing ruby.") - -;;;###autoload -(defun rubydb (command-line) - "Run rubydb on program FILE in buffer *gud-FILE*. -The directory containing FILE becomes the initial working directory -and source-file directory for your debugger." - (interactive - (list (read-from-minibuffer "Run rubydb (like this): " - (if (consp gud-rubydb-history) - (car gud-rubydb-history) - (concat rubydb-command-name " ")) - nil nil - '(gud-rubydb-history . 1)))) - - (gud-common-init command-line 'gud-rubydb-massage-args - 'gud-rubydb-marker-filter 'gud-rubydb-find-file) - - (gud-def gud-break "b %l" "\C-b" "Set breakpoint at current line.") -; (gud-def gud-remove "clear %l" "\C-d" "Remove breakpoint at current line") - (gud-def gud-step "s" "\C-s" "Step one source line with display.") - (gud-def gud-next "n" "\C-n" "Step one line (skip functions).") - (gud-def gud-cont "c" "\C-r" "Continue with display.") - (gud-def gud-finish "finish" "\C-f" "Finish executing current function.") - (gud-def gud-up "up %p" "<" "Up N stack frames (numeric arg).") - (gud-def gud-down "down %p" ">" "Down N stack frames (numeric arg).") - (gud-def gud-print "p %e" "\C-p" "Evaluate ruby expression at point.") - - (setq comint-prompt-regexp "^(rdb:-) ") - (setq paragraph-start comint-prompt-regexp) - (run-hooks 'rubydb-mode-hook) - ) diff --git a/sample/test.rb b/sample/test.rb index f28327659e..ad4cf20269 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -183,7 +183,7 @@ ok(i>4) check "exception"; begin - fail "this must be handled" + raise "this must be handled" ok(false) rescue ok(true) @@ -191,7 +191,7 @@ end $bad = true begin - fail "this must be handled no.2" + raise "this must be handled no.2" rescue if $bad $bad = false @@ -205,9 +205,9 @@ ok(true) $string = "this must be handled no.3" begin begin - fail "exception in rescue clause" + raise "exception in rescue clause" rescue - fail $string + raise $string end ok(false) rescue @@ -217,9 +217,9 @@ end # exception in ensure clause begin begin - fail "this must be handled no.4" + raise "this must be handled no.4" ensure - fail "exception in ensure clause" + raise "exception in ensure clause" end ok(false) rescue @@ -229,7 +229,7 @@ end $bad = true begin begin - fail "this must be handled no.5" + raise "this must be handled no.5" ensure $bad = false end @@ -240,7 +240,7 @@ ok(!$bad) $bad = true begin begin - fail "this must be handled no.6" + raise "this must be handled no.6" ensure $bad = false end @@ -355,7 +355,7 @@ ok($x[1] == 2) ok(begin for k,v in $y - fail if k*2 != v + raise if k*2 != v end true rescue @@ -746,7 +746,7 @@ if defined? Process.kill sleep 0.1 ok($x == 2) - trap "SIGINT", proc{fail "Interrupt"} + trap "SIGINT", proc{raise "Interrupt"} x = false begin @@ -867,21 +867,21 @@ ok(i6 == nil) check "system" ok(`echo foobar` == "foobar\n") -ok(`./ruby -e 'print "foobar"'` == 'foobar') +ok(`./miniruby -e 'print "foobar"'` == 'foobar') tmp = open("script_tmp", "w") tmp.print "print $zzz\n"; tmp.close -ok(`./ruby -s script_tmp -zzz` == 'true') -ok(`./ruby -s script_tmp -zzz=555` == '555') +ok(`./miniruby -s script_tmp -zzz` == 'true') +ok(`./miniruby -s script_tmp -zzz=555` == '555') tmp = open("script_tmp", "w") tmp.print "#! /usr/local/bin/ruby -s\n"; tmp.print "print $zzz\n"; tmp.close -ok(`./ruby script_tmp -zzz=678` == '678') +ok(`./miniruby script_tmp -zzz=678` == '678') tmp = open("script_tmp", "w") tmp.print "this is a leading junk\n"; @@ -891,8 +891,8 @@ tmp.print "__END__\n"; tmp.print "this is a trailing junk\n"; tmp.close -ok(`./ruby -x script_tmp` == 'nil') -ok(`./ruby -x script_tmp -zzz=555` == '555') +ok(`./miniruby -x script_tmp` == 'nil') +ok(`./miniruby -x script_tmp -zzz=555` == '555') tmp = open("script_tmp", "w") for i in 1..5 @@ -900,7 +900,7 @@ for i in 1..5 end tmp.close -`./ruby -i.bak -pe 'sub(/^[0-9]+$/){$&.to_i * 5}' script_tmp` +`./miniruby -i.bak -pe 'sub(/^[0-9]+$/){$&.to_i * 5}' script_tmp` done = true tmp = open("script_tmp", "r") while tmp.gets @@ -917,7 +917,7 @@ File.unlink "script_tmp.bak" or `/bin/rm -f "script_tmp.bak"` $bad = false for script in Dir["{lib,sample}/*.rb"] - unless `./ruby -c #{script}`.chomp == "Syntax OK" + unless `./miniruby -c #{script}`.chomp == "Syntax OK" $bad = true end end diff --git a/sample/tkbiff.rb b/sample/tkbiff.rb deleted file mode 100644 index d2d7bf7beb..0000000000 --- a/sample/tkbiff.rb +++ /dev/null @@ -1,149 +0,0 @@ -#! /usr/local/bin/ruby - -if ARGV[0] != '-d' - unless $DEBUG - exit if fork - end -else - ARGV.shift -end - -if ARGV.length == 0 - if ENV['MAIL'] - $spool = ENV['MAIL'] - else - $spool = '/usr/spool/mail/' + ENV['USER'] - end -else - $spool = ARGV[0] -end - -require "parsedate" -require "base64" - -include ParseDate - -class Mail - def Mail.new(f) - if !f.kind_of?(IO) - f = open(f, "r") - me = super - f.close - else - me = super - end - return me - end - - def initialize(f) - @header = {} - @body = [] - while f.gets() - $_.chop! - next if /^From / # skip From-line - break if /^$/ # end of header - if /^(\S+):\s*(.*)/ - @header[attr = $1.capitalize] = $2 - elsif attr - sub(/^\s*/, '') - @header[attr] += "\n" + $_ - end - end - - return if ! $_ - - while f.gets() - break if /^From / - @body.push($_) - end - end - - def header - return @header - end - - def body - return @body - end - -end - -require "tkscrollbox" - -$top = TkRoot.new -$top.withdraw -$list = TkScrollbox.new($top) { - relief 'raised' - width 80 - height 8 - setgrid 'yes' - pack -} -TkButton.new($top) { - text 'Dismiss' - command proc {$top.withdraw} - pack('fill'=>'both','expand'=>'yes') -} -$top.bind "Control-c", proc{exit} -$top.bind "Control-q", proc{exit} -$top.bind "space", proc{exit} - -$spool_size = 0 -$check_time = Time.now - -def check - $check_time = Time.now - size = File.size($spool) - if size and size != $spool_size - $spool_size = size - pop_up if size > 0 - end - Tk.after 5000, proc{check} -end - -if defined? Thread - Thread.start do - loop do - sleep 600 - if Time.now - $check_time > 200 - Tk.after 5000, proc{check} - end - end - end -end - -def pop_up - outcount = 0; - $list.delete 0, 'end' - f = open($spool, "r") - while !f.eof? - mail = Mail.new(f) - date, from, subj = mail.header['Date'], mail.header['From'], mail.header['Subject'] - next if !date - y = m = d = 0 - y, m, d = parsedate(date) if date - from = "sombody@somewhere" if ! from - subj = "(nil)" if ! subj - from = decode_b(from) - subj = decode_b(subj) - $list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj) - outcount += 1 - end - f.close - if outcount == 0 - $list.insert 'end', "You have no mail." - else - $list.see 'end' - end - $top.deiconify - Tk.after 2000, proc{$top.withdraw} -end - -$list.insert 'end', "You have no mail." -check -Tk.after 2000, proc{$top.withdraw} -begin - Tk.mainloop -rescue - `echo #$! > /tmp/tkbiff` -end diff --git a/sample/tkbrowse.rb b/sample/tkbrowse.rb deleted file mode 100644 index d127996173..0000000000 --- a/sample/tkbrowse.rb +++ /dev/null @@ -1,69 +0,0 @@ -#!/usr/local/bin/ruby -# -# This script generates a directory browser, which lists the working -# directory and allows you to open files or subdirectories by -# double-clicking. - -# Create a scrollbar on the right side of the main window and a listbox -# on the left side. - -require "tkscrollbox" - -list = TkScrollbox.new { - relief 'raised' - width 20 - height 20 - setgrid 'yes' - pack -} - -# The procedure below is invoked to open a browser on a given file; if the -# file is a directory then another instance of this program is invoked; if -# the file is a regular file then the Mx editor is invoked to display -# the file. - -def browse (dir, file) - if dir != "." - file="#{dir}/#{file}" - if File.directory? file - system "browse #{file} &" - else - if File.file? file - if ENV['EDITOR'] - system format("%s %s&", ENV['EDITOR'], file) - else - sysmte "xedit #{file}&" - end - else - STDERR.print "\"#{file}\" isn't a directory or regular file" - end - end - end -end - -# Fill the listbox with a list of all the files in the directory (run -# the "ls" command to get that information). - -if ARGV.length>0 - dir = ARGV[0] -else - dir="." -end -list.insert 'end', *`ls #{dir}`.split - -# Set up bindings for the browser. - -list.focus -list.bind "Control-q", proc{exit} -list.bind "Control-c", proc{exit} -list.bind "Control-p", proc{ - print "selection <", TkSelection.get, ">\n" -} - -list.bind "Double-Button-1", proc{ - for i in TkSelection.get.split - print "clicked ", i, "\n" - browse dir, i - end -} -Tk.mainloop diff --git a/sample/tkdialog.rb b/sample/tkdialog.rb deleted file mode 100644 index e83e16d0a8..0000000000 --- a/sample/tkdialog.rb +++ /dev/null @@ -1,62 +0,0 @@ -#! /usr/local/bin/ruby -require "tk" - -root = TkFrame.new -top = TkFrame.new(root) { - relief 'raised' - border 1 -} -msg = TkMessage.new(top) { - text "File main.c hasn't been saved to disk since \ -it was last modified. What should I do?" - justify 'center' - aspect 200 - font '-Adobe-helvetica-medium-r-normal--*-240*' - pack('padx'=>5, 'pady'=>5, 'expand'=>'yes') -} -top.pack('fill'=>'both') -root.pack - -bot = TkFrame.new(root) { - relief 'raised' - border 1 -} - -TkFrame.new(bot) { |left| - relief 'sunken' - border 1 - pack('side'=>'left', 'expand'=>'yes', 'padx'=>10, 'pady'=> 10) - TkButton.new(left) { - text "Save File" - command "quit 'save'" - pack('expand'=>'yes','padx'=>6,'pady'=> 6) - top.bind "Enter", proc{state 'active'} - msg.bind "Enter", proc{state 'active'} - bot.bind "Enter", proc{state 'active'} - top.bind "Leave", proc{state 'normal'} - msg.bind "Leave", proc{state 'normal'} - bot.bind "Leave", proc{state 'normal'} - Tk.root.bind "ButtonRelease-1", proc{quit 'save'} - Tk.root.bind "Return", proc{quit 'save'} - } -} -TkButton.new(bot) { - text "Quit Anyway" - command "quit 'quit'" - pack('side'=>'left', 'expand'=>'yes', 'padx'=>10) -} -TkButton.new(bot) { - text "Return To Editor" - command "quit 'return'" - pack('side'=>'left', 'expand'=>'yes', 'padx'=>10) -} -bot.pack -root.pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes') - -def quit(button) - print "aaa\n" - print "You pressed the \"#{button}\" button; bye-bye!\n" - exit -end - -Tk.mainloop diff --git a/sample/tkfrom.rb b/sample/tkfrom.rb deleted file mode 100644 index b0ef8995ca..0000000000 --- a/sample/tkfrom.rb +++ /dev/null @@ -1,126 +0,0 @@ -#! /usr/local/bin/ruby - -require "parsedate" -require "base64" - -include ParseDate - -class Mail - def Mail.new(f) - if !f.kind_of?(IO) - f = open(f, "r") - me = super(f) - f.close - else - me = super - end - return me - end - - def initialize(f) - @header = {} - @body = [] - while f.gets() - $_.chop! - next if /^From / # skip From-line - break if /^$/ # end of header - if /^(\S+):\s*(.*)/ - @header[attr = $1.capitalize] = $2 - elsif attr - sub(/^\s*/, '') - @header[attr] += "\n" + $_ - end - end - - return if ! $_ - - while f.gets() - break if /^From / - @body.push($_) - end - end - - def header - return @header - end - - def body - return @body - end - -end - -if ARGV.length == 0 - if ENV['MAIL'] - ARGV[0] = ENV['MAIL'] - elsif ENV['USER'] - ARGV[0] = '/usr/spool/mail/' + ENV['USER'] - elsif ENV['LOGNAME'] - ARGV[0] = '/usr/spool/mail/' + ENV['LOGNAME'] - end -end - -require "tk" -list = scroll = nil -TkFrame.new{|f| - list = TkListbox.new(f) { - yscroll proc{|idx| - scroll.set *idx - } - relief 'raised' -# geometry "80x5" - width 80 - height 5 - setgrid 'yes' - pack('side'=>'left','fill'=>'both','expand'=>'yes') - } - scroll = TkScrollbar.new(f) { - command proc{|idx| - list.yview *idx - } - pack('side'=>'right','fill'=>'y') - } - pack -} -root = Tk.root -TkButton.new(root) { - text 'Dismiss' - command proc {exit} - pack('fill'=>'both','expand'=>'yes') -} -root.bind "Control-c", proc{exit} -root.bind "Control-q", proc{exit} -root.bind "space", proc{exit} - -$outcount = 0; -for file in ARGV - next if !File.exist?(file) - f = open(file, "r") - while !f.eof - mail = Mail.new(f) - date = mail.header['Date'] - next if !date - from = mail.header['From'] - subj = mail.header['Subject'] - y = m = d = 0 - y, m, d = parsedate(date) if date - from = "sombody@somewhere" if ! from - subj = "(nil)" if ! subj - from = decode_b(from) - subj = decode_b(subj) - list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj) - $outcount += 1 - end - f.close - list.see 'end' -end - -limit = 10000 -if $outcount == 0 - list.insert 'end', "You have no mail." - limit = 2000 -end -Tk.after limit, proc{ - exit -} -Tk.mainloop diff --git a/sample/tkhello.rb b/sample/tkhello.rb deleted file mode 100644 index 5188fe1c8c..0000000000 --- a/sample/tkhello.rb +++ /dev/null @@ -1,10 +0,0 @@ -require "tk" - -TkButton.new(nil, - 'text' => 'hello', - 'command' => proc{print "hello\n"}).pack('fill'=>'x') -TkButton.new(nil, - 'text' => 'quit', - 'command' => 'exit').pack('fill'=>'x') - -Tk.mainloop diff --git a/sample/tkline.rb b/sample/tkline.rb deleted file mode 100644 index 63d763a680..0000000000 --- a/sample/tkline.rb +++ /dev/null @@ -1,46 +0,0 @@ - -$tk_thread_safe = TRUE -require "tkclass" - -$tkline_init = FALSE -def start_random - return if $tkline_init - $tkline_init = TRUE - if defined? Thread - Thread.start do - loop do - sleep 2 - Line.new($c, rand(400), rand(200), rand(400), rand(200)) - end - end - end -end - -$c = Canvas.new -$c.pack -$start_x = start_y = 0 - -def do_press(x, y) - $start_x = x - $start_y = y - $current_line = Line.new($c, x, y, x, y) - start_random -end -def do_motion(x, y) - if $current_line - $current_line.coords $start_x, $start_y, x, y - end -end - -def do_release(x, y) - if $current_line - $current_line.coords $start_x, $start_y, x, y - $current_line.fill 'black' - $current_line = nil - end -end - -$c.bind("1", proc{|e| do_press e.x, e.y}) -$c.bind("B1-Motion", proc{|x, y| do_motion x, y}, "%x %y") -$c.bind("ButtonRelease-1", proc{|x, y| do_release x, y}, "%x %y") -Tk.mainloop diff --git a/sample/tktimer.rb b/sample/tktimer.rb deleted file mode 100644 index 34377e2f39..0000000000 --- a/sample/tktimer.rb +++ /dev/null @@ -1,50 +0,0 @@ -#!/usr/local/bin/ruby -# This script generates a counter with start and stop buttons. - -require "tk" -$label = TkLabel.new { - text '0.00' - relief 'raised' - width 10 - pack('side'=>'bottom', 'fill'=>'both') -} - -TkButton.new { - text 'Start' - command proc { - if $stopped - $stopped = FALSE - tick - end - } - pack('side'=>'left','fill'=>'both','expand'=>'yes') -} -TkButton.new { - text 'Stop' - command proc{ - exit if $stopped - $stopped = TRUE - } - pack('side'=>'right','fill'=>'both','expand'=>'yes') -} - -$seconds=0 -$hundredths=0 -$stopped=TRUE - -def tick - if $stopped then return end - Tk.after 50, proc{tick} - $hundredths+=5 - if $hundredths >= 100 - $hundredths=0 - $seconds+=1 - end - $label.text format("%d.%02d", $seconds, $hundredths) -end - -root = Tk.root -root.bind "Control-c", proc{root.destroy} -root.bind "Control-q", proc{root.destroy} -Tk.root.focus -Tk.mainloop diff --git a/sample/uumerge.rb b/sample/uumerge.rb index 26f28923d5..418323c439 100644 --- a/sample/uumerge.rb +++ b/sample/uumerge.rb @@ -1,4 +1,4 @@ -#!/usr/local/bin/ruby +#!/usr/bin/env ruby if ARGV[0] == "-c" out_stdout = 1 @@ -18,7 +18,7 @@ while gets() out = open($file, "w") if $file != "" end out.binmode - next + break end end diff --git a/sig.h b/sig.h deleted file mode 100644 index ac4a4787f4..0000000000 --- a/sig.h +++ /dev/null @@ -1,53 +0,0 @@ -/************************************************ - - sig.h - - - $Author$ - $Date$ - created at: Wed Aug 16 01:15:38 JST 1995 - -************************************************/ -#ifndef SIG_H -#define SIG_H - -extern int trap_immediate; -#define TRAP_BEG (trap_immediate=1) -#define TRAP_END (trap_immediate=0) - -extern int prohibit_interrupt; -#define DEFER_INTS {prohibit_interrupt++;} -#define ALLOW_INTS {prohibit_interrupt--; CHECK_INTS;} -#define ENABLE_INTS {prohibit_interrupt--;} - -extern int trap_pending; -#ifdef THREAD -extern int thread_critical; -#if defined(HAVE_SETITIMER) && !defined(__BOW__) -extern int thread_pending; -void thread_schedule(); -# define CHECK_INTS if (!prohibit_interrupt) {\ - if (trap_pending) rb_trap_exec();\ - if (thread_pending && !thread_critical) thread_schedule();\ -} -# else -/* pseudo preemptive thread switching */ -extern int thread_tick; -#define THREAD_TICK 500 -void thread_schedule(); -# define CHECK_INTS if (!prohibit_interrupt) {\ - if (trap_pending) rb_trap_exec();\ - if (!thread_critical) {\ - if (thread_tick-- <= 0) {\ - thread_tick = THREAD_TICK;\ - thread_schedule();\ - }\ - }\ -} -# endif -#else -# define CHECK_INTS if (!prohibit_interrupt) {\ - if (trap_pending) rb_trap_exec();\ -} -#endif - -#endif diff --git a/signal.c b/signal.c index d7ce4921b2..285cf07405 100644 --- a/signal.c +++ b/signal.c @@ -200,7 +200,7 @@ rb_f_kill(argc, argv) sig = FIX2UINT(argv[0]); if (sig >= NSIG) { s = rb_id2name(sig); - if (!s) rb_raise(rb_eArgError, "Bad signal"); + if (!s) rb_raise(rb_eArgError, "bad signal"); goto str_signal; } break; @@ -216,7 +216,7 @@ rb_f_kill(argc, argv) if (strncmp("SIG", s, 3) == 0) s += 3; if((sig = signm2signo(s)) == 0) - rb_raise(rb_eArgError, "Unrecognized signal name `%s'", s); + rb_raise(rb_eArgError, "unrecognized signal name `%s'", s); if (negative) sig = -sig; @@ -438,13 +438,13 @@ trap(arg) s += 3; sig = signm2signo(s); if (sig == 0 && strcmp(s, "EXIT") != 0) - rb_raise(rb_eArgError, "Invalid signal SIG%s", s); + rb_raise(rb_eArgError, "invalid signal SIG%s", s); } else { sig = NUM2INT(arg->sig); } if (sig < 0 || sig > NSIG) { - rb_raise(rb_eArgError, "Invalid signal no %d", sig); + rb_raise(rb_eArgError, "invalid signal number (%d)", sig); } #if defined(USE_THREAD) && defined(HAVE_SETITIMER) && !defined(__BOW__) if (sig == SIGVTALRM) { @@ -507,7 +507,7 @@ trap_ensure(arg) void rb_trap_restore_mask() { -#ifndef NT +#if !defined(NT) && !defined(USE_CWGUSI) # ifdef HAVE_SIGPROCMASK sigprocmask(SIG_SETMASK, &trap_last_mask, NULL); # else diff --git a/sprintf.c b/sprintf.c index 3c09a8ed2a..71e5488bce 100644 --- a/sprintf.c +++ b/sprintf.c @@ -6,14 +6,22 @@ $Date$ created at: Fri Oct 15 10:39:26 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ #include "ruby.h" #include +#ifndef atof +double strtod(); +#endif + +#ifdef USE_CWGUSI +static void fmt_setup(); +#else static void fmt_setup _((char*,char,int,int,int)); +#endif static char* remove_sign_bits(str, base) @@ -548,6 +556,7 @@ rb_f_sprintf(argc, argv) case 'f': case 'g': + case 'G': case 'e': case 'E': { @@ -566,7 +575,7 @@ rb_f_sprintf(argc, argv) fval = rb_big2dbl(val); break; case T_STRING: - fval = atof(RSTRING(val)->ptr); + fval = strtod(RSTRING(val)->ptr, 0); break; default: Check_Type(val, T_FLOAT); @@ -585,7 +594,7 @@ rb_f_sprintf(argc, argv) } sprint_exit: - if (RTEST(rb_verbose) && argc > 1) { + if (RTEST(ruby_verbose) && argc > 1) { rb_raise(rb_eArgError, "too many argument for format string"); } result = rb_str_new(buf, blen); diff --git a/st.c b/st.c new file mode 100644 index 0000000000..8c0a3861f5 --- /dev/null +++ b/st.c @@ -0,0 +1,483 @@ +/* This is a general purpose hash table package written by Peter Moore @ UCB. */ + +static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible"; + +#include "config.h" +#include +#include "st.h" + +#ifdef USE_CWGUSI +#include +#endif + +typedef struct st_table_entry st_table_entry; + +struct st_table_entry { + unsigned int hash; + char *key; + char *record; + st_table_entry *next; +}; + +#define ST_DEFAULT_MAX_DENSITY 5 +#define ST_DEFAULT_INIT_TABLE_SIZE 11 + + /* + * DEFAULT_MAX_DENSITY is the default for the largest we allow the + * average number of items per bin before increasing the number of + * bins + * + * DEFAULT_INIT_TABLE_SIZE is the default for the number of bins + * allocated initially + * + */ +static int numcmp(); +static int numhash(); +static struct st_hash_type type_numhash = { + numcmp, + numhash, +}; + +extern int strcmp(); +static int strhash(); +static struct st_hash_type type_strhash = { + strcmp, + strhash, +}; + +void *xmalloc(); +void *xcalloc(); +void *xrealloc(); +static void rehash(); + +#define alloc(type) (type*)xmalloc((unsigned)sizeof(type)) +#define Calloc(n,s) (char*)xcalloc((n),(s)) + +#define EQUAL(table, x, y) ((*table->type->compare)(x, y) == 0) + +#define do_hash(key, table) (unsigned int)(*(table)->type->hash)((key)) +#define do_hash_bin(key, table) (do_hash(key, table)%(table)->num_bins) + +/* + * MINSIZE is the minimum size of a dictionary. + */ + +#define MINSIZE 8 + +/* +Table of prime numbers 2^n+a, 2<=n<=30. +*/ +static long primes[] = { + 8 + 3, + 16 + 3, + 32 + 5, + 64 + 3, + 128 + 3, + 256 + 29, + 512 + 17, + 1024 + 9, + 2048 + 5, + 4096 + 83, + 8192 + 27, + 16384 + 43, + 32768 + 3, + 65536 + 45, + 131072 + 9, + 262144 + 39, + 524288 + 39, + 1048576 + 9, + 2097152 + 5, + 4194304 + 3, + 8388608 + 33, + 16777216 + 27, + 33554432 + 9, + 67108864 + 71, + 134217728 + 39, + 268435456 + 9, + 536870912 + 5, + 1073741824 + 83, + 0 +}; + +static int +new_size(size) + int size; +{ + int i, newsize; + + for (i = 0, newsize = MINSIZE; + i < sizeof(primes)/sizeof(primes[0]); + i++, newsize <<= 1) + { + if (newsize > size) return primes[i]; + } + /* Ran out of polynomials */ + return -1; /* should raise exception */ +} + +st_table* +st_init_table_with_size(type, size) + struct st_hash_type *type; + int size; +{ + st_table *tbl; + + size = new_size(size); /* round up to prime number */ + + tbl = alloc(st_table); + tbl->type = type; + tbl->num_entries = 0; + tbl->num_bins = size; + tbl->bins = (st_table_entry **)Calloc(size, sizeof(st_table_entry*)); + + return tbl; +} + +st_table* +st_init_table(type) + struct st_hash_type *type; +{ + return st_init_table_with_size(type, 0); +} + +st_table* +st_init_numtable() +{ + return st_init_table(&type_numhash); +} + +st_table* +st_init_numtable_with_size(size) + int size; +{ + return st_init_table_with_size(&type_numhash, size); +} + +st_table* +st_init_strtable() +{ + return st_init_table(&type_strhash); +} + +st_table* +st_init_strtable_with_size(size) + int size; +{ + return st_init_table_with_size(&type_strhash, size); +} + +void +st_free_table(table) + st_table *table; +{ + register st_table_entry *ptr, *next; + int i; + + for(i = 0; i < table->num_bins ; i++) { + ptr = table->bins[i]; + while (ptr != 0) { + next = ptr->next; + free(ptr); + ptr = next; + } + } + free(table->bins); + free(table); +} + +#define PTR_NOT_EQUAL(table, ptr, hash_val, key) \ +((ptr) != 0 && ptr->hash != (hash_val) && !EQUAL((table), (key), (ptr)->key)) + +#define FIND_ENTRY(table, ptr, hash_val, bin_pos) \ +bin_pos = hash_val%(table)->num_bins;\ +ptr = (table)->bins[bin_pos];\ +if (PTR_NOT_EQUAL(table, ptr, hash_val, key)) {\ + while (PTR_NOT_EQUAL(table, ptr->next, hash_val, key)) {\ + ptr = ptr->next;\ + }\ + ptr = ptr->next;\ +} + +int +st_lookup(table, key, value) + st_table *table; + register char *key; + char **value; +{ + unsigned int hash_val, bin_pos; + register st_table_entry *ptr; + + hash_val = do_hash(key, table); + FIND_ENTRY(table, ptr, hash_val, bin_pos); + + if (ptr == 0) { + return 0; + } else { + if (value != 0) *value = ptr->record; + return 1; + } +} + +#define ADD_DIRECT(table, key, value, hash_val, bin_pos)\ +{\ + st_table_entry *tbl;\ + if (table->num_entries/table->num_bins > ST_DEFAULT_MAX_DENSITY) {\ + rehash(table);\ + bin_pos = hash_val % table->num_bins;\ + }\ + \ + tbl = alloc(st_table_entry);\ + \ + tbl->hash = hash_val;\ + tbl->key = key;\ + tbl->record = value;\ + tbl->next = table->bins[bin_pos];\ + table->bins[bin_pos] = tbl;\ + table->num_entries++;\ +} + +int +st_insert(table, key, value) + register st_table *table; + register char *key; + char *value; +{ + unsigned int hash_val, bin_pos; + register st_table_entry *ptr; + + hash_val = do_hash(key, table); + FIND_ENTRY(table, ptr, hash_val, bin_pos); + + if (ptr == 0) { + ADD_DIRECT(table, key, value, hash_val, bin_pos); + return 0; + } else { + ptr->record = value; + return 1; + } +} + +void +st_add_direct(table, key, value) + st_table *table; + char *key; + char *value; +{ + unsigned int hash_val, bin_pos; + + hash_val = do_hash(key, table); + bin_pos = hash_val % table->num_bins; + ADD_DIRECT(table, key, value, hash_val, bin_pos); +} + +static void +rehash(table) + register st_table *table; +{ + register st_table_entry *ptr, *next, **new_bins; + int i, old_num_bins = table->num_bins, new_num_bins; + unsigned int hash_val; + + new_num_bins = new_size(old_num_bins); + new_bins = (st_table_entry**)Calloc(new_num_bins, sizeof(st_table_entry*)); + + for(i = 0; i < old_num_bins ; i++) { + ptr = table->bins[i]; + while (ptr != 0) { + next = ptr->next; + hash_val = ptr->hash % new_num_bins; + ptr->next = new_bins[hash_val]; + new_bins[hash_val] = ptr; + ptr = next; + } + } + free(table->bins); + table->num_bins = new_num_bins; + table->bins = new_bins; +} + +st_table* +st_copy(old_table) + st_table *old_table; +{ + st_table *new_table; + st_table_entry *ptr, *tbl; + int i, num_bins = old_table->num_bins; + + new_table = alloc(st_table); + if (new_table == 0) { + return 0; + } + + *new_table = *old_table; + new_table->bins = (st_table_entry**) + Calloc((unsigned)num_bins, sizeof(st_table_entry*)); + + if (new_table->bins == 0) { + free(new_table); + return 0; + } + + for(i = 0; i < num_bins ; i++) { + new_table->bins[i] = 0; + ptr = old_table->bins[i]; + while (ptr != 0) { + tbl = alloc(st_table_entry); + if (tbl == 0) { + free(new_table->bins); + free(new_table); + return 0; + } + *tbl = *ptr; + tbl->next = new_table->bins[i]; + new_table->bins[i] = tbl; + ptr = ptr->next; + } + } + return new_table; +} + +int +st_delete(table, key, value) + register st_table *table; + register char **key; + char **value; +{ + unsigned int hash_val; + st_table_entry *tmp; + register st_table_entry *ptr; + + hash_val = do_hash_bin(*key, table); + ptr = table->bins[hash_val]; + + if (ptr == 0) { + if (value != 0) *value = 0; + return 0; + } + + if (EQUAL(table, *key, ptr->key)) { + table->bins[hash_val] = ptr->next; + table->num_entries--; + if (value != 0) *value = ptr->record; + *key = ptr->key; + free(ptr); + return 1; + } + + for(; ptr->next != 0; ptr = ptr->next) { + if (EQUAL(table, ptr->next->key, *key)) { + tmp = ptr->next; + ptr->next = ptr->next->next; + table->num_entries--; + if (value != 0) *value = tmp->record; + *key = tmp->key; + free(tmp); + return 1; + } + } + + return 0; +} + +int +st_delete_safe(table, key, value, never) + register st_table *table; + register char **key; + char **value; + char *never; +{ + unsigned int hash_val; + register st_table_entry *ptr; + + hash_val = do_hash_bin(*key, table); + ptr = table->bins[hash_val]; + + if (ptr == 0) { + if (value != 0) *value = 0; + return 0; + } + + if (EQUAL(table, *key, ptr->key)) { + table->num_entries--; + *key = ptr->key; + if (value != 0) *value = ptr->record; + ptr->key = ptr->record = never; + return 1; + } + + for(; ptr->next != 0; ptr = ptr->next) { + if (EQUAL(table, ptr->next->key, *key)) { + table->num_entries--; + *key = ptr->key; + if (value != 0) *value = ptr->record; + ptr->key = ptr->record = never; + return 1; + } + } + + return 0; +} + +void +st_foreach(table, func, arg) + st_table *table; + enum st_retval (*func)(); + char *arg; +{ + st_table_entry *ptr, *last, *tmp; + enum st_retval retval; + int i; + + for(i = 0; i < table->num_bins; i++) { + last = 0; + for(ptr = table->bins[i]; ptr != 0;) { + retval = (*func)(ptr->key, ptr->record, arg); + switch (retval) { + case ST_CONTINUE: + last = ptr; + ptr = ptr->next; + break; + case ST_STOP: + return; + case ST_DELETE: + tmp = ptr; + if (last == 0) { + table->bins[i] = ptr->next; + } else { + last->next = ptr->next; + } + ptr = ptr->next; + free(tmp); + table->num_entries--; + } + } + } +} + +static int +strhash(string) + register char *string; +{ + register int val = 0; + register int c; + + while ((c = *string++) != '\0') { + val = val*997 + c; + } + + return val; +} + +static int +numcmp(x, y) + int x, y; +{ + return x != y; +} + +static int +numhash(n) + int n; +{ + return n; +} diff --git a/st.h b/st.h new file mode 100644 index 0000000000..ce87df6011 --- /dev/null +++ b/st.h @@ -0,0 +1,46 @@ +/* This is a general purpose hash table package written by Peter Moore @ UCB. */ + +/* @(#) st.h 5.1 89/12/14 */ + +#ifndef ST_INCLUDED + +#define ST_INCLUDED + +typedef struct st_table st_table; + +struct st_hash_type { + int (*compare)(); + int (*hash)(); +}; + +struct st_table { + struct st_hash_type *type; + int num_bins; + int num_entries; + struct st_table_entry **bins; +}; + +#define st_is_member(table,key) st_lookup(table,key,(char **)0) + +enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE}; + +st_table *st_init_table(); +st_table *st_init_table_with_size(); +st_table *st_init_numtable(); +st_table *st_init_numtable_with_size(); +st_table *st_init_strtable(); +st_table *st_init_strtable_with_size(); +int st_delete(), st_delete_safe(); +int st_insert(), st_lookup(); +void st_foreach(), st_add_direct(), st_free_table(); +st_table *st_copy(); + +#define ST_NUMCMP ((int (*)()) 0) +#define ST_NUMHASH ((int (*)()) -2) + +#define st_numcmp ST_NUMCMP +#define st_numhash ST_NUMHASH + +int st_strhash(); + +#endif /* ST_INCLUDED */ diff --git a/string.c b/string.c index e5f0dd2a63..e8afb55ff0 100644 --- a/string.c +++ b/string.c @@ -6,7 +6,7 @@ $Date$ created at: Mon Aug 9 17:12:58 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -22,6 +22,10 @@ #include #endif +#ifndef atof +double strtod(); +#endif + VALUE rb_cString; #define STR_FREEZE FL_USER1 @@ -32,7 +36,7 @@ extern VALUE rb_rs; VALUE rb_str_new(ptr, len) char *ptr; - size_t len; + int len; { NEWOBJ(str, struct RString); OBJSETUP(str, rb_cString, T_STRING); @@ -58,16 +62,22 @@ rb_str_new2(ptr) VALUE rb_tainted_str_new(ptr, len) char *ptr; - size_t len; + int len; { - return rb_obj_taint(rb_str_new(ptr, len)); + VALUE str = rb_str_new(ptr, len); + + FL_SET(str, FL_TAINT); + return str; } VALUE rb_tainted_str_new2(ptr) char *ptr; { - return rb_obj_taint(rb_str_new2(ptr)); + VALUE str = rb_str_new2(ptr); + + FL_SET(str, FL_TAINT); + return str; } VALUE @@ -102,7 +112,7 @@ rb_str_new4(orig) str->ptr = RSTRING(orig)->ptr; RSTRING(orig)->orig = (VALUE)str; str->orig = 0; - if (rb_safe_level() >= 3) { + if (FL_TEST(str, FL_TAINT)) { FL_SET(str, FL_TAINT); } return (VALUE)str; @@ -204,7 +214,7 @@ rb_str_s_new(klass, orig) if (rb_safe_level() >= 3) { FL_SET(str, FL_TAINT); } - rb_obj_call_init((VALUE)str); + rb_obj_call_init((VALUE)str, 1, &orig); return (VALUE)str; } @@ -249,7 +259,7 @@ rb_str_times(str, times) VALUE times; { VALUE str2; - size_t i, len; + int i, len; len = NUM2INT(times); if (len < 0) { @@ -292,14 +302,18 @@ rb_str_format(str, arg) VALUE rb_str_substr(str, start, len) VALUE str; - size_t start, len; + int 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) { @@ -315,35 +329,29 @@ rb_str_substr(str, start, len) static VALUE rb_str_subseq(str, beg, end) VALUE str; - size_t beg, end; + int beg, end; { - size_t 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); } @@ -355,7 +363,7 @@ rb_str_modify(str) if (FL_TEST(str, STR_FREEZE)) rb_raise(rb_eTypeError, "can't modify frozen string"); - if (rb_safe_level() >= 4 && !FL_TEST(str, FL_TAINT)) + if (!FL_TEST(str, FL_TAINT) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't modify string"); if (!RSTRING(str)->orig || FL_TEST(str, STR_NO_ORIG)) return; ptr = RSTRING(str)->ptr; @@ -399,7 +407,7 @@ rb_str_dup_frozen(str) VALUE rb_str_resize(str, len) VALUE str; - size_t len; + int len; { rb_str_modify(str); @@ -417,7 +425,7 @@ VALUE rb_str_cat(str, ptr, len) VALUE str; char *ptr; - size_t len; + int len; { if (len > 0) { rb_str_modify(str); @@ -449,7 +457,7 @@ int rb_str_hash(str) VALUE str; { - register size_t len = RSTRING(str)->len; + register int len = RSTRING(str)->len; register char *p = RSTRING(str)->ptr; register int key = 0; @@ -482,8 +490,7 @@ int rb_str_cmp(str1, str2) VALUE str1, str2; { - size_t len; - int retval; + int len, retval; if (ruby_ignorecase) { return rb_str_cicmp(str1, str2); @@ -531,7 +538,7 @@ rb_str_match(x, y) VALUE x, y; { VALUE reg; - size_t start; + int start; switch (TYPE(y)) { case T_REGEXP: @@ -557,13 +564,13 @@ rb_str_match2(str) return rb_reg_match2(rb_reg_regcomp(str)); } -static size_t +static int rb_str_index(str, sub, offset) VALUE str, sub; - size_t offset; + int offset; { char *s, *e, *p; - size_t len; + int len; if (RSTRING(str)->len - offset < RSTRING(sub)->len) return -1; s = RSTRING(str)->ptr+offset; @@ -576,7 +583,7 @@ rb_str_index(str, sub, offset) } s++; } - return (size_t)-1; + return -1; } static VALUE @@ -587,10 +594,10 @@ rb_str_index_method(argc, argv, str) { VALUE sub; VALUE initpos; - size_t pos; + int pos; if (rb_scan_args(argc, argv, "11", &sub, &initpos) == 2) { - pos = NUM2UINT(initpos); + pos = NUM2INT(initpos); } else { pos = 0; @@ -608,7 +615,7 @@ rb_str_index_method(argc, argv, str) case T_FIXNUM: { int c = FIX2INT(sub); - size_t len = RSTRING(str)->len; + int len = RSTRING(str)->len; char *p = RSTRING(str)->ptr; for (;pos= RSTRING(str)->len) pos = RSTRING(str)->len; } else { @@ -677,7 +684,7 @@ rb_str_rindex(argc, argv, str) } default: - rb_raise(rb_eTypeError, "Type mismatch: %s given", + rb_raise(rb_eTypeError, "type mismatch: %s given", rb_class2name(CLASS_OF(sub))); } return Qnil; @@ -780,7 +787,7 @@ rb_str_aref(str, indx) VALUE str; VALUE indx; { - size_t idx; + int idx; switch (TYPE(indx)) { case T_FIXNUM: @@ -800,18 +807,18 @@ rb_str_aref(str, indx) return Qnil; case T_STRING: - if (rb_str_index(str, indx, 0) != (size_t)-1) return indx; + if (rb_str_index(str, indx, 0) != -1) return indx; return Qnil; default: /* check if indx is Range */ { - size_t beg, end; + int beg, end; if (rb_range_beg_end(indx, &beg, &end)) { return rb_str_subseq(str, beg, end); } } - rb_raise(rb_eIndexError, "Invalid index for string"); + rb_raise(rb_eIndexError, "invalid index for string"); } return Qnil; /* not reached */ } @@ -833,7 +840,8 @@ rb_str_aref_method(argc, argv, str) static void rb_str_replace(str, beg, len, val) VALUE str, val; - size_t beg, len; + int beg; + int len; { if (len < RSTRING(val)->len) { /* expand string */ @@ -853,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; - size_t beg, end; + int beg, end; { - size_t 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); } @@ -898,11 +899,12 @@ rb_str_aset(str, indx, val) VALUE str; VALUE indx, val; { - size_t idx, beg, end; + int idx; + int beg, end; switch (TYPE(indx)) { case T_FIXNUM: - idx = NUM2UINT(indx); + idx = NUM2INT(indx); if (idx < 0) { idx = RSTRING(str)->len + idx; } @@ -929,7 +931,7 @@ rb_str_aset(str, indx, val) case T_STRING: beg = rb_str_index(str, indx, 0); - if (beg != (size_t)-1) { + if (beg != -1) { end = beg + RSTRING(indx)->len - 1; rb_str_replace2(str, beg, end, val); } @@ -938,14 +940,14 @@ rb_str_aset(str, indx, val) default: /* check if indx is Range */ { - size_t beg, end; + int beg, end; if (rb_range_beg_end(indx, &beg, &end)) { if (TYPE(val) != T_STRING) val = rb_str_to_str(val); rb_str_replace2(str, beg, end, val); return val; } } - rb_raise(rb_eIndexError, "Invalid index for string"); + rb_raise(rb_eIndexError, "invalid index for string"); } } @@ -960,15 +962,16 @@ rb_str_aset_method(argc, argv, str) rb_str_modify(str); if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) { - size_t beg, len; + int beg; + int len; if (TYPE(arg3) != T_STRING) arg3 = rb_str_to_str(arg3); - beg = NUM2UINT(arg1); + beg = NUM2INT(arg1); if (beg < 0) { beg = RSTRING(str)->len + beg; if (beg < 0) beg = 0; } - len = NUM2UINT(arg2); + len = NUM2INT(arg2); if (len < 0) rb_raise(rb_eIndexError, "negative length %d", len); if (beg + len > RSTRING(str)->len) { len = RSTRING(str)->len - beg; @@ -1007,7 +1010,7 @@ rb_str_sub_bang(argc, argv, str) VALUE pat, repl, match; struct re_registers *regs; int iter = 0; - size_t plen; + int plen; if (argc == 1 && rb_iterator_p()) { iter = 1; @@ -1016,7 +1019,7 @@ rb_str_sub_bang(argc, argv, str) repl = rb_obj_as_string(argv[1]);; } else { - rb_raise(rb_eArgError, "Wrong # of arguments(%d for 2)", argc); + rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc); } pat = get_pat(argv[0]); @@ -1026,7 +1029,10 @@ rb_str_sub_bang(argc, argv, str) regs = RMATCH(match)->regs; if (iter) { + rb_match_busy(match, Qtrue); repl = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match))); + rb_match_busy(match, Qfalse); + rb_backref_set(match); } else { repl = rb_reg_regsub(repl, str, regs); @@ -1070,10 +1076,10 @@ rb_str_gsub_bang(argc, argv, str) { VALUE pat, val, repl, match; struct re_registers *regs; - int beg, offset, n; + int beg, n; int iter = 0; char *buf, *bp, *cp; - size_t blen, len; + int offset, blen, len; if (argc == 1 && rb_iterator_p()) { iter = 1; @@ -1082,7 +1088,7 @@ rb_str_gsub_bang(argc, argv, str) repl = rb_obj_as_string(argv[1]);; } else { - rb_raise(rb_eArgError, "Wrong # of arguments(%d for 2)", argc); + rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)", argc); } pat = get_pat(argv[0]); @@ -1100,7 +1106,10 @@ rb_str_gsub_bang(argc, argv, str) match = rb_backref_get(); regs = RMATCH(match)->regs; if (iter) { + rb_match_busy(match, Qtrue); val = rb_obj_as_string(rb_yield(rb_reg_nth_match(0, match))); + rb_match_busy(match, Qfalse); + rb_backref_set(match); } else { val = rb_reg_regsub(repl, str, regs); @@ -1138,7 +1147,7 @@ rb_str_gsub_bang(argc, argv, str) } if (RSTRING(str)->len > offset) { len = bp - buf; - if (blen - len < RSTRING(str)->len - offset) { + if (blen - len < RSTRING(str)->len - offset + 1) { REALLOC_N(buf, char, len + RSTRING(str)->len - offset + 1); bp = buf + len; } @@ -1278,11 +1287,11 @@ static VALUE rb_str_include(str, arg) VALUE str, arg; { - size_t i; + int i; if (FIXNUM_P(arg)) { int c = FIX2INT(arg); - size_t len = RSTRING(str)->len; + int len = RSTRING(str)->len; char *p = RSTRING(str)->ptr; for (i=0; iptr); + double f = strtod(RSTRING(str)->ptr, 0); return rb_float_new(f); } @@ -1347,11 +1356,11 @@ rb_str_inspect(str) while (p < pend) { char c = *p++; if (ismbchar(c) && p < pend) { - int len = mbclen(c)-1; + int len = mbclen(c); CHECK(len); *b++ = c; - while (len--) { + while (--len) { *b++ = *p++; } } @@ -1418,7 +1427,7 @@ static VALUE rb_str_dump(str) VALUE str; { - size_t len; + int len; char *p, *pend; char *q, *qend; VALUE result; @@ -1511,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); @@ -1545,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); @@ -1583,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); @@ -1615,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); @@ -1990,7 +1999,7 @@ rb_str_split_method(argc, argv, str) beg = 0; if (char_sep >= 0) { char *ptr = RSTRING(str)->ptr; - size_t len = RSTRING(str)->len; + int len = RSTRING(str)->len; char *eptr = ptr + len; if (char_sep == ' ') { /* AWK emulation */ @@ -2031,9 +2040,9 @@ rb_str_split_method(argc, argv, str) } } else { - size_t start = beg; + int start = beg; int last_null = 0; - size_t idx; + int idx; struct re_registers *regs; while ((end = rb_reg_search(spat, str, start, 0)) >= 0) { @@ -2109,7 +2118,7 @@ rb_str_each_line(argc, argv, str) int rslen; char *p = RSTRING(str)->ptr, *pend = p + RSTRING(str)->len, *s; char *ptr = p; - size_t len = RSTRING(str)->len; + int len = RSTRING(str)->len; VALUE line; if (rb_scan_args(argc, argv, "01", &rs) == 0) { @@ -2158,7 +2167,7 @@ static VALUE rb_str_each_byte(str) struct RString* str; { - size_t i; + int i; for (i=0; ilen; i++) { rb_yield(INT2FIX(RSTRING(str)->ptr[i] & 0xff)); @@ -2223,7 +2232,7 @@ rb_str_chomp_bang(argc, argv, str) int newline; int rslen; char *p = RSTRING(str)->ptr; - size_t len = RSTRING(str)->len; + int len = RSTRING(str)->len; if (rb_scan_args(argc, argv, "01", &rs) == 0) { rs = rb_rs; @@ -2335,11 +2344,11 @@ rb_str_strip(str) static VALUE scan_once(str, pat, start) VALUE str, pat; - size_t *start; + int *start; { VALUE result, match; struct re_registers *regs; - size_t i; + int i; if (rb_reg_search(pat, str, *start, 0) >= 0) { match = rb_backref_get(); @@ -2371,7 +2380,7 @@ rb_str_scan(str, pat) VALUE str, pat; { VALUE result; - size_t start = 0; + int start = 0; pat = get_pat(pat); if (!rb_iterator_p()) { @@ -2484,7 +2493,7 @@ rb_str_ljust(str, w) VALUE str; VALUE w; { - size_t width = NUM2UINT(w); + int width = NUM2INT(w); VALUE res; char *p, *pend; @@ -2503,7 +2512,7 @@ rb_str_rjust(str, w) VALUE str; VALUE w; { - size_t width = NUM2UINT(w); + int width = NUM2INT(w); VALUE res; char *p, *pend; @@ -2522,10 +2531,10 @@ rb_str_center(str, w) VALUE str; VALUE w; { - size_t width = NUM2UINT(w); + int width = NUM2INT(w); VALUE res; char *p, *pend; - size_t n; + int n; if (width < 0 || RSTRING(str)->len >= width) return str; res = rb_str_new(0, width); diff --git a/struct.c b/struct.c index 7aaf4e8d25..ccdaa3aed4 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; @@ -94,7 +96,7 @@ static VALUE rb_struct_ref7(obj) VALUE obj; {return RSTRUCT(obj)->ptr[7];} static VALUE rb_struct_ref8(obj) VALUE obj; {return RSTRUCT(obj)->ptr[8];} static VALUE rb_struct_ref9(obj) VALUE obj; {return RSTRUCT(obj)->ptr[9];} -VALUE (*ref_func[10])() = { +static VALUE (*ref_func[10])() = { rb_struct_ref0, rb_struct_ref1, rb_struct_ref2, @@ -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]); @@ -216,15 +218,16 @@ rb_struct_s_def(argc, argv, klass) RARRAY(rest)->ptr[i] = INT2FIX(id); } st = make_struct(name, rest, klass); - rb_obj_call_init(st); + rb_obj_call_init(st, argc, argv); 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_init((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 -#ifdef USE_CWGUSI -int gettimeofday(struct timeval*, struct timezone*); -int strcasecmp(char*, char*); -#endif - #include #ifndef NT #ifdef HAVE_SYS_TIME_H # include #else +#define time_t long struct timeval { - long tv_sec; /* seconds */ - long tv_usec; /* and microseconds */ + time_t tv_sec; /* seconds */ + time_t tv_usec; /* and microseconds */ }; #endif #endif /* NT */ @@ -33,7 +29,16 @@ struct timeval { #ifdef HAVE_SYS_TIMES_H #include #endif + +#ifdef USE_CWGUSI +#define time_t long +int gettimeofday(struct timeval*, struct timezone*); +int strcasecmp(char*, char*); +#endif + +#if 0 #include +#endif VALUE rb_cTime; #if defined(HAVE_TIMES) || defined(NT) @@ -63,10 +68,10 @@ 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); + rb_obj_call_init(obj, 0, 0); return obj; } @@ -74,13 +79,15 @@ 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; +#ifndef USE_CWGUSI if (sec < 0 || (sec == 0 && usec < 0)) rb_raise(rb_eArgError, "time must be positive"); +#endif obj = Data_Make_Struct(klass, struct time_object, 0, free, tobj); tobj->tm_got = 0; tobj->tv.tv_sec = sec; @@ -91,7 +98,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); } @@ -105,7 +112,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; @@ -114,12 +121,12 @@ rb_time_timeval(time) case T_FLOAT: if (RFLOAT(time)->value < 0.0) rb_raise(rb_eArgError, "time must be positive"); - t.tv_sec = (long)floor(RFLOAT(time)->value); - t.tv_usec = (long)((RFLOAT(time)->value - t.tv_sec) * 1000000.0); + t.tv_sec = (time_t)RFLOAT(time)->value; + t.tv_usec = (time_t)((RFLOAT(time)->value - (double)t.tv_sec)*1e6); 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; @@ -127,7 +134,7 @@ rb_time_timeval(time) default: if (!rb_obj_is_kind_of(time, rb_cTime)) { - rb_raise(rb_eTypeError, "Can't convert %s into Time", + rb_raise(rb_eTypeError, "can't convert %s into Time", rb_class2name(CLASS_OF(time))); } GetTimeval(time, tobj); @@ -152,22 +159,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; @@ -184,108 +191,121 @@ 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"); + if (guess < 0) goto too_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; + if (guess < 0) goto too_future; 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) goto too_future; - time = time_new_internal(klass, guess, 0); - if (gm_or_local) return time_gmtime(time); - return time_localtime(time); + return guess; + + too_future: + rb_raise(rb_eArgError, "too far future"); error: rb_raise(rb_eArgError, "gmtime/localtime error"); return Qnil; /* not reached */ } +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; @@ -311,7 +331,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 @@ -331,7 +351,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 @@ -339,12 +359,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); @@ -353,10 +373,13 @@ time_cmp(time1, time2) { double t; - if (tobj1->tv.tv_sec == (int)RFLOAT(time2)->value) return INT2FIX(0); + if (tobj1->tv.tv_sec == (time_t)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); + if (tobj1->tv.tv_sec == (time_t)RFLOAT(time2)->value) + return INT2FIX(0); + if (tobj1->tv.tv_sec > (time_t)RFLOAT(time2)->value) + return INT2FIX(1); return FIX2INT(-1); } } @@ -371,7 +394,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); @@ -398,7 +421,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; @@ -461,7 +484,7 @@ time_to_s(time) VALUE time; { struct time_object *tobj; - char buf[64]; + char buf[128]; int len; GetTimeval(time, tobj); @@ -470,12 +493,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); } @@ -485,23 +508,20 @@ time_plus(time1, time2) VALUE time1, time2; { struct time_object *tobj1, *tobj2; - long sec, usec; + time_t 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; + +#if 0 + if (rb_obj_is_kind_of(time2, rb_cTime)) { + rb_raise(rb_eTypeError, "time + time?"); } +#endif + f = NUM2DBL(time2); + sec = (time_t)f; + usec = tobj1->tv.tv_usec + (time_t)((f - (double)sec)*1e6); + sec = tobj1->tv.tv_sec + sec; if (usec >= 1000000) { /* usec overflow */ sec++; @@ -515,26 +535,23 @@ time_minus(time1, time2) VALUE time1, time2; { struct time_object *tobj1, *tobj2; - int sec, usec; + time_t 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 = (time_t)f; + usec = tobj1->tv.tv_usec - (time_t)((f - (double)sec)*1e6); + sec = tobj1->tv.tv_sec - sec; } if (usec < 0) { /* usec underflow */ @@ -645,7 +662,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 @@ -666,7 +683,7 @@ time_zone(time) VALUE time; { struct time_object *tobj; - char buf[10]; + char buf[64]; int len; GetTimeval(time, tobj); @@ -674,7 +691,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); } @@ -696,7 +713,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)); } @@ -708,23 +725,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 @@ -743,6 +768,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; @@ -752,6 +780,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; @@ -797,26 +827,41 @@ 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; + struct tm *tm; + unsigned long p, s; unsigned char buf[8]; int i; + rb_scan_args(argc, argv, "01", &dummy); GetTimeval(time, tobj); - sec = tobj->tv.tv_sec; - usec = tobj->tv.tv_usec; + + tm = gmtime(&tobj->tv.tv_sec); + + p = 0x1 << 31 | /* 1 */ + tm->tm_year << 14 | /* 17 */ + tm->tm_mon << 10 | /* 4 */ + tm->tm_mday << 5 | /* 5 */ + tm->tm_hour; /* 5 */ + s = tm->tm_min << 26 | /* 6 */ + tm->tm_sec << 20 | /* 6 */ + tobj->tv.tv_usec; /* 20 */ for (i=0; i<4; i++) { - buf[i] = sec & 0xff; - sec = RSHIFT(sec, 8); + buf[i] = p & 0xff; + p = RSHIFT(p, 8); } for (i=4; i<8; i++) { - buf[i] = usec & 0xff; - usec = RSHIFT(usec, 8); + buf[i] = s & 0xff; + s = RSHIFT(s, 8); } + return rb_str_new(buf, 8); } @@ -824,8 +869,10 @@ static VALUE time_load(klass, str) VALUE klass, str; { - int sec, usec; + unsigned long p, s; + time_t sec, usec; unsigned char *buf; + struct tm tm; int i; buf = str2cstr(str, &i); @@ -833,14 +880,28 @@ time_load(klass, str) rb_raise(rb_eTypeError, "marshaled time format differ"); } - sec = usec = 0; + p = s = 0; for (i=0; i<4; i++) { - sec |= buf[i]<<(8*i); + p |= buf[i]<<(8*i); } for (i=4; i<8; i++) { - usec |= buf[i]<<(8*(i-4)); + s |= buf[i]<<(8*(i-4)); } + if ((p & (1<<31)) == 0) { + return time_new_internal(klass, sec, usec); + } + p &= ~(1<<31); + tm.tm_year = (p >> 14) & 0x3ffff; + tm.tm_mon = (p >> 10) & 0xf; + tm.tm_mday = (p >> 5) & 0x1f; + tm.tm_hour = p & 0x1f; + tm.tm_min = (s >> 26) & 0x3f; + tm.tm_sec = (s >> 20) & 0x3f; + + sec = make_time_t(&tm, gmtime); + usec = (time_t) s & 0xfffff; + return time_new_internal(klass, sec, usec); } @@ -900,6 +961,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 ae0914d217..33d9b3d6f1 100644 --- a/util.c +++ b/util.c @@ -6,7 +6,7 @@ $Date$ created at: Fri Mar 10 17:22:34 JST 1995 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -19,6 +19,10 @@ #define RUBY_NO_INLINE #include "ruby.h" +#ifdef USE_CWGUSI +extern char* mktemp(char*); +#endif + VALUE rb_class_of(obj) VALUE obj; @@ -757,7 +761,7 @@ void ruby_qsort (base, nel, size, cmp) void* base; int nel; int size; int (*cmp) if (t < 0) {mmswap(L,l); l = L; goto loopB;} /*535-5*/ } - loopA: eq_l = 1; eq_r = 1; /* splitting type A */ /* left <= median < right右*/ + loopA: eq_l = 1; eq_r = 1; /* splitting type A */ /* left <= median < right */ for (;;) { for (;;) { if ((l += size) == r) @@ -805,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 756daeeac6..675df9aaa7 100644 --- a/util.h +++ b/util.h @@ -6,7 +6,7 @@ $Date$ created at: Thu Mar 9 11:55:53 JST 1995 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ #ifndef UTIL_H @@ -35,4 +35,7 @@ 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_unsetenv _((char*)); + #endif /* UTIL_H */ diff --git a/variable.c b/variable.c index 03262c5d83..348b4d5989 100644 --- a/variable.c +++ b/variable.c @@ -106,7 +106,7 @@ find_class_path(klass) st_foreach(rb_class_tbl, fc_i, &arg); } if (arg.name) { - rb_iv_set(klass, "__classpath__", arg.path); + st_insert(ROBJECT(klass)->iv_tbl,rb_intern("__classpath__"),arg.path); return arg.path; } return Qnil; @@ -116,22 +116,20 @@ 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)) { klass = (VALUE)RCLASS(klass)->super; } if (!klass) klass = rb_cObject; - if (!ROBJECT(klass)->iv_tbl || - !st_lookup(ROBJECT(klass)->iv_tbl, classpath, &path)) { + if (!ROBJECT(klass)->iv_tbl) + ROBJECT(klass)->iv_tbl = st_init_numtable(); + else if (!st_lookup(ROBJECT(klass)->iv_tbl, classpath, &path)) { ID classid = rb_intern("__classid__"); - path = rb_ivar_get(klass, classid); - if (!NIL_P(path)) { + if (st_lookup(ROBJECT(klass)->iv_tbl, classid, &path)) { path = rb_str_new2(rb_id2name(FIX2INT(path))); - if (!ROBJECT(klass)->iv_tbl) - ROBJECT(klass)->iv_tbl = st_init_numtable(); st_insert(ROBJECT(klass)->iv_tbl, classpath, path); st_delete(RCLASS(klass)->iv_tbl, &classid, 0); } @@ -248,6 +246,9 @@ char * rb_class2name(klass) VALUE klass; { + if (klass == rb_cNilClass) return "nil"; + if (klass == rb_cTrueClass) return "true"; + if (klass == rb_cFalseClass) return "false"; return RSTRING(rb_class_path(klass))->ptr; } @@ -305,7 +306,7 @@ static VALUE undef_getter(id) ID id; { - if (rb_verbose) { + if (ruby_verbose) { rb_warning("global variable `%s' not initialized", rb_id2name(id)); } return Qnil; @@ -386,7 +387,7 @@ readonly_setter(val, id, var) ID id; void *var; { - rb_raise(rb_eNameError, "Can't set variable %s", rb_id2name(id)); + rb_raise(rb_eNameError, "can't set variable %s", rb_id2name(id)); } static int @@ -716,9 +717,11 @@ generic_ivar_set(obj, id, val) VALUE val; { st_table *tbl; + int special = Qfalse; if (rb_special_const_p(obj)) { special_generic_ivar = 1; + special = Qtrue; } if (!generic_iv_tbl) { generic_iv_tbl = st_init_numtable(); @@ -824,6 +827,8 @@ rb_ivar_get(obj, id) { VALUE val; + if (!FL_TEST(obj, FL_TAINT) && rb_safe_level() >= 4) + rb_raise(rb_eSecurityError, "Insecure: can't access instance variable"); switch (TYPE(obj)) { case T_OBJECT: case T_CLASS: @@ -837,7 +842,7 @@ rb_ivar_get(obj, id) return generic_ivar_get(obj, id); break; } - if (rb_verbose) { + if (ruby_verbose) { rb_warning("instance var %s not initialized", rb_id2name(id)); } return Qnil; @@ -849,13 +854,13 @@ rb_ivar_set(obj, id, val) ID id; VALUE val; { + if (!FL_TEST(obj, FL_TAINT) && rb_safe_level() >= 4) + rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable"); switch (TYPE(obj)) { case T_OBJECT: case T_CLASS: case T_MODULE: case T_FILE: - if (rb_safe_level() >= 4 && !FL_TEST(obj, FL_TAINT)) - rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable"); if (!ROBJECT(obj)->iv_tbl) ROBJECT(obj)->iv_tbl = st_init_numtable(); st_insert(ROBJECT(obj)->iv_tbl, id, val); break; @@ -871,8 +876,6 @@ rb_ivar_defined(obj, id) VALUE obj; ID id; { - if (!rb_is_instance_id(id)) return Qfalse; - switch (TYPE(obj)) { case T_OBJECT: case T_CLASS: @@ -907,6 +910,8 @@ rb_obj_instance_variables(obj) { VALUE ary; + if (!FL_TEST(obj, FL_TAINT) && rb_safe_level() >= 4) + rb_raise(rb_eSecurityError, "Insecure: can't get metainfo"); switch (TYPE(obj)) { case T_OBJECT: case T_CLASS: @@ -938,6 +943,8 @@ rb_obj_remove_instance_variable(obj, name) VALUE val = Qnil; ID id = rb_to_id(name); + if (!FL_TEST(obj, FL_TAINT) && rb_safe_level() >= 4) + rb_raise(rb_eSecurityError, "Insecure: can't modify instance variable"); if (!rb_is_instance_id(id)) { rb_raise(rb_eNameError, "`%s' is not an instance variable", rb_id2name(id)); @@ -973,7 +980,7 @@ rb_const_get_at(klass, id) if (klass == rb_cObject) { return rb_const_get(klass, id); } - rb_raise(rb_eNameError, "Uninitialized constant %s::%s", + rb_raise(rb_eNameError, "uninitialized constant %s::%s", RSTRING(rb_class_path(klass))->ptr, rb_id2name(id)); return Qnil; /* not reached */ @@ -1016,11 +1023,11 @@ rb_const_get(klass, id) /* Uninitialized constant */ if (klass && klass != rb_cObject) - rb_raise(rb_eNameError, "Uninitialized constant %s::%s", + rb_raise(rb_eNameError, "uninitialized constant %s::%s", RSTRING(rb_class_path(klass))->ptr, rb_id2name(id)); else { - rb_raise(rb_eNameError, "Uninitialized constant %s",rb_id2name(id)); + rb_raise(rb_eNameError, "uninitialized constant %s",rb_id2name(id)); } return Qnil; /* not reached */ } @@ -1080,6 +1087,8 @@ VALUE rb_mod_const_at(mod, ary) VALUE mod, ary; { + if (!FL_TEST(mod, FL_TAINT) && rb_safe_level() >= 4) + rb_raise(rb_eSecurityError, "Insecure: can't get metainfo"); if (RCLASS(mod)->iv_tbl) { st_foreach(RCLASS(mod)->iv_tbl, const_i, ary); } @@ -1163,7 +1172,7 @@ rb_const_set(klass, id, val) ID id; VALUE val; { - if (rb_safe_level() >= 4 && !FL_TEST(klass, FL_TAINT)) + if (!FL_TEST(klass, FL_TAINT) && rb_safe_level() >= 4) rb_raise(rb_eSecurityError, "Insecure: can't set constant"); if (!RCLASS(klass)->iv_tbl) { RCLASS(klass)->iv_tbl = st_init_numtable(); diff --git a/version.c b/version.c index 22393f0f4a..0e21322ab4 100644 --- a/version.c +++ b/version.c @@ -7,7 +7,7 @@ $Date$ created at: Thu Sep 30 20:08:01 JST 1993 - Copyright (C) 1993-1998 Yukihiro Matsumoto + Copyright (C) 1993-1999 Yukihiro Matsumoto ************************************************/ @@ -31,6 +31,6 @@ ruby_show_version() void ruby_show_copyright() { - fprintf(stderr, "ruby - Copyright (C) 1993-1998 Yukihiro Matsumoto\n"); + fprintf(stderr, "ruby - Copyright (C) 1993-1999 Yukihiro Matsumoto\n"); exit(0); } diff --git a/version.h b/version.h index 3b291392b3..7d3f771002 100644 --- a/version.h +++ b/version.h @@ -1,2 +1,2 @@ #define RUBY_VERSION "1.3.1" -#define VERSION_DATE "99/01/20" +#define VERSION_DATE "99/02/25" diff --git a/win32/Makefile b/win32/Makefile index 152bdc88ea..b0d6ffe723 100644 --- a/win32/Makefile +++ b/win32/Makefile @@ -20,7 +20,7 @@ LDFLAGS = $(CFLAGS) -Fm #CFLAGS = -nologo -DNT=1 -Zi -MD #LDFLAGS = $(CFLAGS) -Fm -MD LIBS = $(EXTLIBS) advapi32.lib wsock32.lib -MISSING = crypt.obj alloca.obj win32.obj +MISSING = crypt.obj alloca.obj win32.obj fnmatch.obj isinf.obj isnan.obj prefix = binprefix = @@ -50,7 +50,6 @@ OBJS = array.obj \ error.obj \ eval.obj \ file.obj \ - fnmatch.obj \ gc.obj \ glob.obj \ hash.obj \ @@ -62,6 +61,7 @@ OBJS = array.obj \ object.obj \ pack.obj \ parse.obj \ + prec.obj \ process.obj \ random.obj \ range.obj \ @@ -174,6 +174,15 @@ strtol.obj: missing/strtol.c strtoul.obj: missing/strtoul.c $(CC) $(CFLAGS) $(CPPFLAGS) -c missing/strtoul.c +fnmatch.obj: missing/fnmatch.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c missing/fnmatch.c + +isinf.obj: missing/isinf.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c missing/isinf.c + +isnan.obj: missing/isnan.c + $(CC) $(CFLAGS) $(CPPFLAGS) -c missing/isnan.c + # when I use -I., there is confliction at "OpenFile" # so, set . into environment varible "include" win32.obj: win32/win32.c @@ -201,9 +210,8 @@ enum.obj: enum.c ruby.h config.h defines.h error.obj: error.c ruby.h config.h defines.h env.h eval.obj: eval.c ruby.h config.h defines.h env.h node.h rubysig.h st.h dln.h file.obj: file.c ruby.h config.h defines.h rubyio.h rubysig.h -fnmatch.obj: fnmatch.c config.h fnmatch.h gc.obj: gc.c ruby.h config.h defines.h env.h rubysig.h st.h node.h re.h regex.h -glob.obj: glob.c config.h fnmatch.h +glob.obj: glob.c config.h missing/fnmatch.h hash.obj: hash.c ruby.h config.h defines.h st.h inits.obj: inits.c ruby.h config.h defines.h io.obj: io.c ruby.h config.h defines.h rubyio.h rubysig.h @@ -228,3 +236,4 @@ util.obj: util.c defines.h config.h util.h variable.obj: variable.c ruby.h config.h defines.h env.h st.h version.obj: version.c ruby.h config.h defines.h version.h director.obj : director.c dir.h +prec.obj: prec.c ruby.h config.h defines.h diff --git a/win32/config.h b/win32/config.h index 8385154cd5..a4de1bfd70 100644 --- a/win32/config.h +++ b/win32/config.h @@ -27,7 +27,7 @@ #define vfork fork #define HAVE_FMOD 1 /* #define HAVE_RANDOM 1 */ -/* #define HAVE_WAITPID 1 */ +#define HAVE_WAITPID 1 #define HAVE_GETCWD 1 /* #define HAVE_TRUNCATE 1 */ #define HAVE_CHSIZE 1 @@ -37,6 +37,8 @@ /* #define HAVE_SETITIMER 1 */ #define HAVE_GETGROUPS 1 /* #define HAVE_SIGPROCMASK 1 */ +#define HAVE_GETLOGIN 1 + #define RSHIFT(x,y) ((x)>>y) #define FILE_COUNT _cnt #define DLEXT ".dll" @@ -44,27 +46,9 @@ #define RUBY_ARCHLIB "/usr/local/lib/ruby/i386-mswin32" #define RUBY_PLATFORM "i386-mswin32" -/* NNN */ -#define strcasecmp _strcmpi -#define popen _popen -#define pclose _pclose -#define pipe _pipe -#define bzero(x, y) memset(x, 0, y) -#define snprintf _snprintf -#define vsnprintf _vsnprintf - - -#define S_IFMT _S_IFMT -#define S_IFDIR _S_IFDIR -#define S_IFCHR _S_IFCHR -#define S_IFREG _S_IFREG -#define S_IREAD _S_IREAD -#define S_IWRITE _S_IWRITE -#define S_IEXEC _S_IEXEC -#define S_IFIFO _S_IFIFO - -#define UIDTYPE int -#define GIDTYPE int -#define pid_t int -#define WNOHANG -1 -//#define NT +#define SIZEOF_INT 4 +#define SIZEOF_SHORT 2 +#define SIZEOF_LONG 4 +#define SIZEOF_VOIDP 4 +#define SIZEOF_FLOAT 4 +#define SIZEOF_DOUBLE 8 diff --git a/win32/ruby.def b/win32/ruby.def index dfe63e5ba6..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: @@ -272,11 +275,9 @@ EXPORTS rb_io_fptr_finalize rb_io_close rb_io_binmode - rb_io_mode_flags rb_fopen rb_fdopen rb_io_unbuffered - rb_io_reopen rb_str_setter ; numeric.c rb_num_zerodiv @@ -401,7 +402,6 @@ EXPORTS rb_test_false_or_nil ruby_scan_oct ruby_scan_hex - rb_add_suffix ;variable.c rb_class_path rb_set_class_path diff --git a/win32/win32.c b/win32/win32.c index 46489c4e08..54e7e7f7af 100644 --- a/win32/win32.c +++ b/win32/win32.c @@ -23,7 +23,7 @@ #include #include #include -#include "nt.h" +#include "win32.h" #include "dir.h" #ifndef index #define index(x, y) strchr((x), (y)) diff --git a/win32/win32.h b/win32/win32.h index a3d1f21aa5..8304946eaf 100644 --- a/win32/win32.h +++ b/win32/win32.h @@ -95,9 +95,10 @@ #include #include -// -// Grrr... -// +#define UIDTYPE int +#define GIDTYPE int +#define pid_t int +#define WNOHANG -1 #define access _access #define chmod _chmod @@ -113,6 +114,7 @@ #define lseek _lseek #define mktemp _mktemp #define open _open +#define perror _perror #define read _read #define setmode _setmode #define sopen _sopen @@ -129,6 +131,7 @@ #define execvp _execvp #define execvpe _execvpe #define getpid _getpid +#define sleep(x) Sleep((x)*1000) #define spawnl _spawnl #define spawnle _spawnle #define spawnlp _spawnlp @@ -141,9 +144,11 @@ #define fileno _fileno #endif #define utime _utime -//#define pipe _pipe -#define perror _perror - +#define vsnprintf _vsnprintf +#define snprintf _snprintf +#define popen _popen +#define pclose _pclose +#define strcasecmp _strcmpi /* these are defined in nt.c */ @@ -186,14 +191,7 @@ extern struct servent * mygetservbyport(int, char *); // // stubs // -// extern int ioctl (int, unsigned int, char *); extern int ioctl (int, unsigned int, long); -#if 0 -extern void sleep (unsigned int); -#else -#define sleep(x) Sleep(x*1000) -#endif - extern UIDTYPE getuid (void); extern UIDTYPE geteuid (void); extern GIDTYPE getgid (void); @@ -202,8 +200,6 @@ extern int setuid (int); extern int setgid (int); -#undef IN /* confict in parse.c */ - #if 0 extern int sys_nerr; extern char *sys_errlist[]; @@ -214,11 +210,6 @@ extern char *mystrerror(int); #define PIPE_BUF 1024 -#define HAVE_STDLIB_H 1 -#define HAVE_GETLOGIN 1 -#define HAVE_WAITPID 1 -#define HAVE_GETCWD 1 - #define LOCK_SH 1 #define LOCK_EX 2 #define LOCK_NB 4 @@ -227,8 +218,6 @@ extern char *mystrerror(int); #define EWOULDBLOCK 10035 /* EBASEERR + 35 (winsock.h) */ #endif -#define O_BINARY 0x8000 - #ifdef popen #undef popen #define popen mypopen -- cgit v1.2.3