summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog1799
-rw-r--r--MANIFEST30
-rw-r--r--Makefile.in30
-rw-r--r--README182
-rw-r--r--README.EXT973
-rw-r--r--README.jp159
-rw-r--r--ToDo8
-rw-r--r--array.c459
-rw-r--r--bignum.c440
-rw-r--r--class.c45
-rw-r--r--compar.c10
-rw-r--r--config.dj35
-rwxr-xr-xconfig.guess139
-rwxr-xr-xconfig.sub177
-rw-r--r--configure.bat5
-rw-r--r--configure.in242
-rw-r--r--defines.h13
-rw-r--r--dir.c64
-rw-r--r--dln.c161
-rw-r--r--enum.c100
-rw-r--r--env.h7
-rw-r--r--error.c714
-rw-r--r--eval.c3252
-rw-r--r--ext/Setup4
-rw-r--r--ext/Setup.dj8
-rw-r--r--ext/dbm/MANIFEST1
-rw-r--r--ext/dbm/dbm.c188
-rw-r--r--ext/dbm/dbm.doc107
-rw-r--r--ext/dbm/extconf.rb2
-rw-r--r--ext/etc/etc.c36
-rw-r--r--ext/extmk.rb.in148
-rw-r--r--ext/kconv/MANIFEST2
-rw-r--r--ext/kconv/kconv.c1934
-rw-r--r--ext/marshal/MANIFEST1
-rw-r--r--ext/marshal/extconf.rb2
-rw-r--r--ext/marshal/marshal.c519
-rw-r--r--ext/marshal/marshal.doc5
-rw-r--r--ext/md5/MANIFEST6
-rw-r--r--ext/md5/depend2
-rw-r--r--ext/md5/md5.doc36
-rw-r--r--ext/md5/md5.h86
-rw-r--r--ext/md5/md5c.c337
-rw-r--r--ext/md5/md5init.c90
-rw-r--r--ext/socket/MANIFEST1
-rw-r--r--ext/socket/extconf.rb7
-rw-r--r--ext/socket/socket.c426
-rw-r--r--ext/socket/socket.doc227
-rw-r--r--ext/tkutil/MANIFEST2
-rw-r--r--ext/tkutil/depend1
-rw-r--r--ext/tkutil/extconf.rb11
-rw-r--r--ext/tkutil/tkutil.c1
-rw-r--r--file.c403
-rw-r--r--gc.c171
-rw-r--r--glob.c8
-rw-r--r--hash.c137
-rw-r--r--inits.c8
-rw-r--r--io.c885
-rw-r--r--io.h14
-rw-r--r--lib/base64.rb2
-rw-r--r--lib/cgi-lib.rb56
-rw-r--r--lib/complex.rb490
-rw-r--r--lib/find.rb47
-rw-r--r--lib/getopts.rb173
-rw-r--r--lib/jcode.rb174
-rw-r--r--lib/mailread.rb19
-rw-r--r--lib/mathn.rb307
-rw-r--r--lib/observer.rb40
-rw-r--r--lib/parsearg.rb103
-rw-r--r--lib/rational.rb361
-rw-r--r--lib/safe.rb78
-rw-r--r--lib/thread.rb153
-rw-r--r--lib/tk.rb557
-rw-r--r--lib/tkcanvas.rb47
-rw-r--r--lib/tkcore.rb521
-rw-r--r--lib/tkentry.rb2
-rw-r--r--lib/tkscrollbox.rb27
-rw-r--r--lib/tktext.rb18
-rw-r--r--lib/tkthcore.rb546
-rw-r--r--main.c4
-rw-r--r--math.c9
-rw-r--r--missing/flock.c90
-rw-r--r--missing/mkdir.c4
-rw-r--r--missing/setenv.c4
-rw-r--r--missing/strftime.c1094
-rw-r--r--node.h84
-rw-r--r--numeric.c417
-rw-r--r--object.c384
-rw-r--r--pack.c74
-rw-r--r--parse.y1586
-rw-r--r--process.c386
-rw-r--r--random.c28
-rw-r--r--range.c153
-rw-r--r--re.c247
-rw-r--r--re.h2
-rw-r--r--regex.c76
-rw-r--r--regex.h2
-rw-r--r--ruby.c239
-rw-r--r--ruby.h123
-rw-r--r--ruby.texi5044
-rw-r--r--sample/clnt.rb6
-rw-r--r--sample/dir.rb4
-rw-r--r--sample/eval.rb41
-rw-r--r--sample/evaldef.rb26
-rw-r--r--sample/export.rb2
-rw-r--r--sample/fact.rb8
-rwxr-xr-xsample/from.rb14
-rw-r--r--sample/fullpath.pl22
-rw-r--r--sample/fullpath.rb6
-rwxr-xr-xsample/getopts.test25
-rw-r--r--sample/io.rb4
-rwxr-xr-xsample/less.rb4
-rw-r--r--sample/list.rb14
-rwxr-xr-xsample/mpart.rb6
-rw-r--r--sample/observ.rb31
-rw-r--r--sample/philos.rb54
-rw-r--r--sample/pi.rb18
-rw-r--r--sample/rcs.rb2
-rw-r--r--sample/regx.rb23
-rw-r--r--sample/ruby-mode.el575
-rw-r--r--sample/sieve.rb2
-rw-r--r--sample/svr.rb2
-rw-r--r--sample/test.rb981
-rwxr-xr-xsample/time.rb2
-rw-r--r--sample/tkbiff.rb46
-rw-r--r--sample/tkbrowse.rb8
-rw-r--r--sample/tkfrom.rb13
-rw-r--r--sample/tkline.rb25
-rw-r--r--sample/trojan.pl12
-rw-r--r--sample/tsvr.rb23
-rwxr-xr-xsample/uumerge.rb8
-rw-r--r--sig.h46
-rw-r--r--signal.c161
-rw-r--r--sprintf.c72
-rw-r--r--st.c202
-rw-r--r--st.h22
-rw-r--r--string.c674
-rw-r--r--struct.c95
-rw-r--r--time.c251
-rw-r--r--top.sed37
-rw-r--r--util.c2
-rw-r--r--util.h2
-rw-r--r--variable.c206
-rw-r--r--version.c8
-rw-r--r--version.h4
144 files changed, 20373 insertions, 12047 deletions
diff --git a/ChangeLog b/ChangeLog
index 9a7479823d..78867f67d9 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,1771 @@
+Tue Dec 24 15:20:58 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.4-961224
+
+ * configure.in: char¤¬unsigned¤«¤É¤¦¤«¤â¥Á¥§¥Ã¥¯
+
+ * regex.c (SIGN_EXTEND_CHAR): __CHAR_UNSIGNED__¤Ë¤âÂбþ
+
+ * pack.c (pack_unpack): ÌÀ¼¨Åª¤Ësigned char¤ò»ØÄê¡¥
+
+Mon Dec 23 14:41:23 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ruby.c (load_file): ɸ½àÆþÎϤ«¤é¤Î¥¹¥¯¥ê¥×¥È¤Ç°ì»þ¥Õ¥¡¥¤¥ë¤ò»È¤ï
+ ¤Ê¤¤¤è¤¦¤Ë
+
+ * object.c (f_integer): `0x', `0'¤Ê¤É¤Çbase¤ò²ò¼á¤¹¤ë¤è¤¦¤Ë¡¥
+
+Fri Dec 20 01:44:39 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * Makefile.in (flock.o): flock¤ËÂбþ
+
+Thu Dec 19 20:13:32 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.4-961219
+
+Wed Dec 18 00:06:48 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * glob.c (glob_filename): strrchr¤¬¥Þ¥¯¥í¤Î¾ì¹ç¤ËÂбþ
+
+ * configure.in: <sys/select.h>¤ò¥Á¥§¥Ã¥¯
+
+ * ext/kconv/kconv.c: 1.62¥Ù¡¼¥¹¤Ë
+
+ * ext/kconv/kconv.c: Kconv¥â¥¸¥å¡¼¥ë
+
+ * string.c (str_substr): len¤¬¸µ¤Îʸ»úÎó¤è¤êŤ¤»þ¤ËÂбþ
+
+ * parse.y (iterator): ¡Ö$bar do .. end¡×¤Ê¤É¤Ïµö¤µ¤Ê¤¤¤è¤¦¤Ë
+
+ * parse.y (iterator): FID(foo!,foo?)¤òdo·Á¼°¤Î¥¤¥Æ¥ì¡¼¥¿¤Ë¤Ç¤­¤ë¡¥
+
+ * missing/flock.c (flock): lockf()¤ò»È¤Ã¤ÆÂåÂØ
+
+ * file.c (file_flock): flock¤ò¼ÂÁõ
+
+Tue Dec 17 12:13:38 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.4-961217
+
+Fri Dec 13 02:05:03 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * configure.in: RUBYLIB¤Î¥«¥ì¥ó¥È¤ò¸å²ó¤·(@mix/awk offline)
+
+ * dln.c: AIX¤ËÂбþ¤·¤¿¡©(@mix/awk offline)
+
+ * eval.c (thread_schedule): critical section¤Ç¤âÌÀ¼¨Åª¤Ê¥³¥ó¥Æ¥­¥¹
+ ¥È¥¹¥¤¥Ã¥Á¤Ïµ¯¤­¤Ê¤¤¤È¤Þ¤º¤¤
+
+ * re.c (reg_search): match¤Ë¼ºÇÔ¤·¤¿»þ¤Ë$~¤ònil¤Ë¡¥
+
+ * re.c (reg_search): Ëè²ómatch¤òÀ¸À®¤¹¤ë¤è¤¦¤Ë
+
+Thu Dec 12 17:03:30 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * numeric.c (flo_to_s): 2.0.to_s -> 2.0¤Ë
+
+ * eval.c (thread_save_context): $_, $~¤òthreadËè¤ËÊݸ
+
+ * eval.c (thread_kill): main thread¤Ç¤Ïexit(0)
+
+ * string.c (str_split_method): ´Ö°ã¤Ã¤¿·ë²Ì¤òÊÖ¤·¤Æ¤¤¤¿
+
+Thu Dec 12 15:32:48 1996 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
+
+ * dir.c: CYGWIN32Âбþ
+
+ * ext/socket/socket.c: CYGWIN32Âбþ
+
+ * io.c: CYGWIN32Âбþ
+
+Thu Dec 12 14:43:51 1996 Jun Kuroda <j_kuro@pluto.ai.kutech.ac.jp>
+
+ * lib/tk.rb: wish4.2¤âõº÷¸õÊä¤Ë´Þ¤á¤ë
+
+ * config.guess: JCCÂбþ
+
+Thu Dec 12 00:41:17 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.4-961212
+
+ * parse.y (parse_string): """..."""¤Ï¤ä¤Ï¤ê̵¤¯¤¹¤³¤È¤Ë¤·¤¿
+
+ * parse.y (parse_regx): %r|...|¤Çterminator¤ò \ ¤Ç¥¨¥¹¥±¡¼¥×¤Ç¤­¤ë
+ ¤è¤¦¤Ë
+
+ * signal.c (posix_signal): sigaction¤ò»È¤¦signal
+
+ * configure.in: posix signal/bsd signal¤Î¸¡½Ð
+
+Wed Dec 11 17:47:35 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (thread_schedule): critical section¤Ç¤Ï¥³¥ó¥Æ¥­¥¹¥È¥¹¥¤¥Ã
+ ¥Á¤¬µ¯¤­¤Ê¤¤¤è¤¦¤Ë
+
+ * lib/thread.rb: SharedMutex¥¯¥é¥¹
+
+ * lib/jcode.rb: String#scan¤ò»È¤¦¤è¤¦¤Ë
+
+Tue Dec 10 12:21:28 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961210
+
+ * string.c (str_split_method): Àµµ¬É½¸½¤Ë()¤ò´Þ¤à»þ¤Ë¥Ð¥°
+
+ * lib/jcode.rb: ¤Á¤ç¤Ã¤È¤Þ¤·¤Ë¤Ê¤Ã¤¿
+
+ * string.c (tr_setup_table): ÃÖ´¹Ê¸»ú¤¬Ã»¤¹¤®¤ë(2ʸ»ú)¤Î¤È¤­¤Î¥Ð¥°
+
+Mon Dec 9 11:38:04 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * string.c (str_scan): ʸ»úÎó¤Î¥Þ¥Ã¥Á¤ò¹Ô¤¦¡¥¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¤âư
+ ºî¤¹¤ë
+
+ * regex.c (re_copy_registers): allocated¤¬½é´ü²½¤µ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿
+
+ * re.c (match_to_s): $~¤Îʸ»úÎó²½
+
+ * re.c (match_to_a): $~¤òÇÛÎ󲽤Ǥ­¤ë¤è¤¦¤Ë
+
+ * re.c (match_getter): ¥ì¥¸¥¹¥¿¤¬½é´ü²½¤µ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿
+
+Thu Dec 5 11:06:10 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * string.c (str_split_method): ¥Þ¥Ã¥Á¤·¤Ê¤«¤Ã¤¿³ç¸Ì¤Ï¶õʸ»úÎó¤ò
+ push¤¹¤ë¤Ù¤­¤Ç¤Ï¤Ê¤¤
+
+ * string.c (str_succ): ¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤ò´Þ¤Þ¤Ê¤¤Ê¸»ú¤ËÂбþ
+
+Wed Dec 4 10:48:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961204
+
+ * io.c (io_binmode): DJGPP¤Ç¤ÎbinmodeÂбþ
+
+ * sprintf.c (f_sprintf): int¤ÎÈϰϤοôÃͤÏľÀÜsprintf¤ÇÊÑ´¹¤¹¤ë
+
+ * sprintf.c (f_sprintf): "%02s"¤ËÍê¤é¤Ê¤¤
+
+ * re.c (reg_search): index¤ÇSEGV
+
+Tue Dec 3 10:09:36 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961203
+
+ * ext/extmk.rb.in (install): INSTALL_DATA¤«¤éINSTALL¤ËÊѹ¹
+
+ * dln.c: hpuxÂбþ
+
+ * string.c (str_aset_method): Éé¤ÎÃͤò´Þ¤àÈϰϤǤâÎã³°¤òµ¯¤³¤µ¤Ê¤¤
+
+ * array.c (ary_replace): Éé¤ÎÃͤò´Þ¤àÈϰϤǤâÎã³°¤òµ¯¤³¤µ¤Ê¤¤
+
+ * array.c (beg_len): beg==end¤Î»þ¡¤Ä¹¤µ0¤Ë
+
+Mon Dec 2 14:07:12 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * configure.in: HP shlÂбþ
+
+ * string.c (str_upto): beg > end¤Î»þ̵¸Â¥ë¡¼¥×¤ËÍî¤Á¤ë¤Î¤ò»ß¤á¤¿
+
+ * range.c (range_each): String#upto¤¬ºÆÄêµÁ¤µ¤ì¤¿¾ì¹ç¤ËÂбþ
+
+ * string.c (str_split_method): "ABC".split(/(B)/)¤¬¸íưºî
+
+Sat Nov 30 01:43:52 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (rb_eval): undef¤ÇSEGV
+
+Fri Nov 29 12:17:59 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * sample/ruby-mode.el (ruby-parse-region): %Q#..#¤Ê¤É¤ËÂбþ¡¥¤·¤«
+ ¤·¡¤¶èÀÚ¤êʸ»ú¤¬±é»»»Ò¤Ç¹ÔËö¤Ë¤¢¤ë¾ì¹ç¤Ë¤ÏÂбþ¤Ç¤­¤Ê¤«¤Ã¤¿¡¥
+
+ * re.c (reg_raise): Îã³°¤Ç¤â¥¹¥é¥Ã¥·¥å¤ò¥¨¥¹¥±¡¼¥×
+
+ * re.c (reg_inspect): ¥¹¥é¥Ã¥·¥å¤ò¥¨¥¹¥±¡¼¥×
+
+ * parse.y (parse_string): `%[QqXxRr](.)..\1'¤Ê¤ëʸ»úÎó·Á¼°(¥Æ¥¹¥È
+ ºÎÍÑ)
+
+ * parse.y (parse_qstring): '''...'''¤Î·Á¼°
+
+ * ext/dbm/dbm.c (Init_dbm): ½Ò¸ìkey?,value?¤ÎÄɲÃ
+
+ * ext/dbm/dbm.c (Init_dbm): includes->include?
+
+ * hash.c (Init_Hash): ½Ò¸ìkey?,value?,include?¤ÎÄɲÃ
+
+ * eval.c (rb_eval): elseÀ᤬¼Â¹Ô¤µ¤ì¤Ê¤¤(¤¦¡¼¤ó)
+
+ * string.c (str_sub_iter_s): ¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯Æâ¤Ç¥Þ¥Ã¥Á¤¬¹Ô¤ï¤ì
+ ¤ë¤È°ÌÃÖ¤¬¤º¤ì¤ë(»þ¤Ë̵¸Â¥ë¡¼¥×¤ËÍî¤Á¤ë)
+
+ * string.c (str_resize): len¤¬0¤Î»þsize¤ÎÄ´À°¤¬¹Ô¤ï¤ì¤Ê¤«¤Ã¤¿
+
+Thu Nov 28 00:59:54 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961128
+
+ * parse.y (parse_string): 3-quote style¤Îʸ»úÎó(Îã:"""abc"d"e""")
+
+ * configure.in (EXTSTATIC): ext¤òÀÅŪ¤Ë¥ê¥ó¥¯¤¹¤ë»þ¤Ë¤Ïruby¤Ïdll¤ò
+ »È¤¦¤è¤¦¤Ë
+
+ * io.c (Init_IO): gets¤Î°ú¿ô¤¬´Ö°ã¤Ã¤Æ¤¤¤¿
+
+ * string.c (str_each_line): RS¤òÌÀ¼¨Åª¤Ë»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë
+
+Wed Nov 27 12:37:46 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961127
+
+ * eval.c (rb_eval): iver defined? ¤Çself¤ò»ØÄꤹ¤ë¤Î¤ò˺¤ì¤¿
+
+ * io.c: getsÅù¤ÇRS¤òÌÀ¼¨Åª¤Ë»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë
+
+ * ext/extmk.rb.in (install): static link¤Ë¼ºÇÔ
+
+Tue Nov 26 10:33:04 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961126
+
+ * string.c (str_sub_s): ÃÖ´¹¸å¤Îʸ»úÎ󍵤¬´Ö°ã¤Ã¤Æ¤¤¤¿
+
+Mon Nov 25 09:11:22 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * numeric.c (fix_rshift): 32°Ê¾å¤Î±¦¥·¥Õ¥È¤Ç0¤òÊÖ¤¹¤è¤¦¤Ë(C¤Î
+ rshift¤Ï(x>>(y%32))¤òÊÖ¤·¤Æ¤¤¤¿)¡¥
+
+ * string.c (str_gsub): ÃÖ´¹¤¬¹Ô¤ï¤ì¤Ê¤¤¾ì¹ç¤¬¤¢¤Ã¤¿
+
+ * string.c (str_resize): ËÜÅö¤ËɬÍפʻþ¤À¤±realloc
+
+Thu Nov 21 04:13:21 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * configure.in (EXTSTATIC): --with-static-linked-ext¤ÇÁ´¤Æ¤Î¥â¥¸¥å¡¼
+ ¥ë¤òÀÅŪ¥ê¥ó¥¯¤¹¤ë¤è¤¦¤Ë
+
+ * pack.c (pack_unpack): ¹ÔËö¤Î²þ¹Ô¤¬¤Ê¤¤»þ¤Ë¤â¥Á¥§¥Ã¥¯¥µ¥à¤ò¥¹¥­¥Ã
+ ¥×¤¹¤ë¤è¤¦¤Ë
+
+Wed Nov 20 96 21:42:51 1996 Yasuo OHBA <jammy@shljapan.co.jp>
+
+ * configure.in: freebsdÂбþ
+
+Wed Nov 20 10:24:24 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ext/extmk.rb.in (install): Ä̾ï¥ê¥ó¥¯ÍѤÎLDFLAGS¤È¥À¥¤¥Ê¥ß¥Ã¥¯¥ê
+ ¥ó¥¯ÍѤÎDLDFALGS¤òʬΥ
+
+ * ext/extmk.rb.in (install): ¥³¥ó¥Ñ¥¤¥ë¤ÎÀ®¸ù¤·¤¿¤â¤Î¤òÀÅŪ¥ê¥ó¥¯
+ ¤Î¥ê¥¹¥È¤ËÄɲ乤ë
+
+ * eval.c (f_missing): ¥ª¥Ö¥¸¥§¥¯¥È¤Îʸ»úÎóɽ¸½¤¬Ä¹¤¹¤®¤ë»þ¥Ð¥Ã¥Õ¥¡
+ ¤ò½ñ¤­ÄÙ¤·¤Æ¤¤¤¿
+
+ * process.c (proc_exec_v): fork¤·¤¿¸åÎã³°¤òȯÀ¸¤µ¤»¤Æ¤Ï¤¤¤±¤Ê¤¤
+
+Tue Nov 19 13:28:15 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961119
+
+ * eval.c (mod_method_defined): Module#method_defined? ¤ÎÄɲÃ
+
+ * parse.y (call_args): °ú¿ô¤¬Í£°ì¤Î¥³¥Þ¥ó¥É¥³¡¼¥ë¤Ç¤¢¤ë»þ¤Î¥Ð¥°(Ìá
+ ¤êÃͤ¬Å¸³«¤µ¤ì¤Æ¤·¤Þ¤¦)
+
+Mon Nov 18 13:28:18 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * string.c (str_sub): ¼ºÇÔ¤·¤¿»þ¤Ënil¤òÊÖ¤·¤Æ¤¤¤¿
+
+ * string.c (str_split_method): ¸¡º÷³«»Ï°ÌÃÖ¤¬°Üư¤·¤Æ¤Ê¤«¤Ã¤¿
+
+ * ext/socket/socket.c (sock_s_getservbyaname): ¤Þ¤À´Ö°ã¤Ã¤Æ¤¤¤¿
+
+ * version 0.99.3-961118
+
+ * string.c (str_sub_s): ¸µ¤Îʸ»úÎó¤òÃÖ´¹¤¹¤ë¤Î¤ò»ß¤á¤¿
+
+ * pack.c (encodes): Îΰ賰¤ò¥¢¥¯¥»¥¹¤·¤Æ¤¤¤¿
+
+Fri Nov 15 17:10:35 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * bignum.c (big_divmod): Bignum¤¬°ú¿ô¤Î¾ì¹ç¤ÎÂбþ˺¤ì
+
+ * sample/ruby-mode.el (ruby-expr-beg): word?·Á¼°¤Ø¤ÎÂбþ¤¬ÉÔ´°Á´
+
+Wed Nov 13 15:42:40 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * string.c (str_tr_s_bang): tr_s¤Çtr¤¬¹Ô¤ï¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿
+
+ * eval.c (rb_eval): autoload¥¯¥é¥¹¤Î¥Á¥§¥Ã¥¯
+
+ * string.c (f_sub): sub¤¬sub!¤ÈƱ¤¸Æ°ºî¤Ë¤Ê¤Ã¤Æ¤¤¤¿
+
+ * eval.c (thread_sleep): stop¤Èsleep¤ÎʬΥ
+
+Mon Nov 11 13:53:19 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961111
+
+ * numeric.c (fix_step): to, step¤¬À°¿ô°Ê³°¤Î¾ì¹ç¤ËÂбþ
+
+ * eval.c (rb_call): dynamic var¤¬dynamic scoping¤Ë¤Ê¤Ã¤Æ¤¤¤¿(¤³¤ì
+ ¤Ï¤Þ¤º¤¤)
+
+ * string.c (str_chop_bang): Ťµ0¤Îʸ»úÎó¤Îchop¤Ç¡¤Îΰ賰¤Î¥¢¥¯¥»
+ ¥¹¤¬È¯À¸¤·¤Æ¤¤¤¿¡¥
+
+ * parse.y (yyerror): ³ä¤êÅö¤Æ¤¿Îΰ賰¤ò¥¢¥¯¥»¥¹¤·¤Æ¤¤¤¿
+
+Fri Nov 8 11:54:46 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (thread_yield): scope¤òheap¤Ë¥³¥Ô¡¼
+
+Thu Nov 7 09:56:53 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * numeric.c (num_coerce): ¤È¤ê¤¢¤¨¤ºÎ¾ÊÕ¤òFloat¤ËÊÑ´¹¤¹¤ë¤³¤È¤Ë
+
+Wed Nov 6 10:45:13 1996 Yasuo OHBA <jammy@shljapan.co.jp>
+
+ * lib/parsearg.rb: Âè2°ú¿ô¤òÊѹ¹¡¥
+
+Tue Nov 5 14:21:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961105
+
+Sat Nov 2 01:11:40 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * bignum.c (big_pow): typo (dy -> dx)
+
+ * bignum.c (big_divmod): ÃΤé¤Ê¤¤·¿¤Ïfloat¤ËÊÑ´¹¤·¤Æ¤ß¤ë
+
+ * numeric.c (fix_lshift): ¶­³¦¾ò·ï¤Î¥Ð¥°(Éé¤Ë¤Ê¤Ã¤Æ¤¤¤¿)
+
+ * bignum.c (big_pow): ̵Â̤Êfloat¤Ø¤ÎÊÑ´¹¤ò¤Ê¤¯¤·¤¿
+
+ * math.c (math_atan2): typo(x -> y)
+
+Fri Nov 1 15:30:59 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ext/socket/socket.c (sock_gethostname): gethostname¤¬¤Ê¤¤»þ¤Ë¤Ï
+ uname¤ò»È¤Ã¤Æ¥Û¥¹¥È̾¤òÆÀ¤ë
+
+ * ext/etc/etc.c (etc_getlogin): getlogin¤¬NULL¤òÊÖ¤·¤Æ¤â´Ä¶­ÊÑ¿ô¤ò
+ Ä´¤Ù¤ë¤è¤¦¤Ë
+
+ * object.c (krn_clone): ¥ª¥Ö¥¸¥§¥¯¥È¤Î¥Õ¥é¥°¤â¥³¥Ô¡¼
+
+ * hash.c (rb_cmp): ¥Ï¥Ã¥·¥å¤ÎÈæ³Ó¤ò`=='¤Ç¤Ê¤¯`eql?'¤ËÊѹ¹
+
+ * math.c (Need_Float): Float()¤ò»È¤Ã¤ÆÊÑ´¹¤¹¤ë
+
+ * compar.c (cmp_gt): °ÊÁ°¤Î±¦ÊÕ¤òÊÖ¤¹»ÅÍͤÎ̾»Ä¤¬»Ä¤Ã¤Æ¤¤¤¿
+
+Thu Oct 31 12:55:51 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961031
+
+ * numeric.c (Init_Numeric): typo
+
+ * eval.c (error_print): Ť¹¤®¤ëtrace back¤òÅÓÃæ¾Êά¤¹¤ë
+
+ * regex.c (re_compile_pattern): Á´³Ñ¤Îrange¤ËÂбþ
+
+Wed Oct 30 03:03:18 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.3-961030
+
+ * io.c (f_ungetc): ´Ø¿ô¤òÄɲÃ
+
+ * eval.c (dyna_var_asgn): returnÃÍ˺¤ì
+
+Tue Oct 29 10:05:28 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * string.c (f_split): ´Ø¿ôsplit¤òÄɲÃ
+
+ * eval.c (rb_call): ¥Í¥¹¥È¤·¤¿³°Â¦¤Î¥¯¥é¥¹/¥â¥¸¥å¡¼¥ë¤ÎÄê¿ô¤ò»²¾È
+ ¤Ç¤­¤ë¤è¤¦¤Ë
+
+Mon Oct 28 09:51:03 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * string.c (str_sub): offset¤¬Ê¸»ú¤ÎËöÈø¤Ë¤¢¤ë»þ¤Î¥Á¥§¥Ã¥¯
+
+ * regex.c (re_match): ³ä¤êÅö¤Æ¤ë¥ì¥¸¥¹¥¿¤Î¿ô¤¬1¿¤«¤Ã¤¿
+
+ * io.c (io_gets): $/ = ""¤Îưºî¤òperl¤Ë¹ç¤ï¤»¤ë(awk¤È¤Ï¤Á¤ç¤Ã¤È°ã
+ ¤¦¤é¤·¤¤)
+
+ * io.c (io_gets): $/ = nil¤Î»þ¾¯¤·¹â®²½
+
+ * string.c (str_split_method): ³ç¸Ì¤¬null¤Ë¥Þ¥Ã¥Á¤·¤¿»þ¤Ë¤â̵»ë¤·
+ ¤Ê¤¤¤è¤¦¤Ë
+
+ * string.c (str_split_method): ³ç¸Ì¤Ë¥Þ¥Ã¥Á¤·¤¿Ê¬¤Ïlimit¤Î¿ô¤Ë´Þ¤á
+ ¤Ê¤¤¤è¤¦¤Ë¡¥
+
+ * numeric.c (num_coerce_bin): coerce¤ÎÄêµÁ¤òÊѹ¹¡¤2Í×ÁǤÎÇÛÎó
+ [x,y]¤òÊÖ¤¹¤è¤¦¤Ë
+
+ * sample/ruby-mode.el (ruby-calculate-indent): "do |aa|"¤ÎÂбþ¤ò²þ
+ Á±¤·¤¿¡¥
+
+Sat Oct 26 01:43:51 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ext/marshal/marshal.c (w_object): ¥Ó¥ë¥È¥¤¥ó¥¯¥é¥¹¤Î¥µ¥Ö¥¯¥é¥¹¤ò
+ Àµ¤·¤¯Éüµì¤Ç¤­¤ë¤è¤¦¤Ë
+
+ * ext/marshal/marshal.c (w_object): ¥æ¡¼¥¶ÄêµÁdump¤ÎÍ¥Àè
+
+ * numeric.c (flo_coerce): Float()¤ò»È¤Ã¤ÆÄêµÁ
+
+ * numeric.c (Init_Numeric): Numeric¤Înew¤Îundef¤Ï¤Þ¤º¤¤
+
+ * ext/marshal/marshal.c (w_symbol): ¥·¥ó¥Ü¥ë¤ÎÆâÍÆ(ʸ»úÎó)¤Ï°ìÅÙ¤·
+ ¤«¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤µ¤Ê¤¤¡¥
+
+ * sample/ruby-mode.el (ruby-parse-region): if/while½¤¾þ»Ò¤ËÂбþ¤·
+ ¤Ê¤¯¤Ê¤Ã¤Æ¤¤¤¿
+
+ * bignum.c (Init_Bignum): Bignum.new¤ò½ü¤¯
+
+ * eval.c (rb_eval): °ú¿ôɾ²Á¸å¤Ë¥Õ¥¡¥¤¥ë̾¤È¹ÔÈÖ¹æ¤òºÆÀßÄê
+
+ * numeric.c (flo_div): typo
+
+ * sample/ruby-mode.el (ruby-parse-region): def /, def `¤ËÂбþ
+
+Fri Oct 25 09:26:29 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * sample/ruby-mode.el (ruby-calculate-indent): "do |aa|"¤ËÂбþ
+
+ * array.c (ary_aset): index¤¬fixnum¤Î¾ì¹ç¤Á¤ç¤Ã¤È¹â®²½
+
+ * eval.c (thread_fd_writable): ½ñ¤­¹þ¤ßÁ°¤Îselect¥Á¥§¥Ã¥¯
+
+ * array.c (ary_assoc): ̵¸Â¥ë¡¼¥×¤ËÍî¤Á¤¿
+
+ * eval.c (thread_wait_for): select¤¬¥¨¥é¡¼½ªÎ»¤·¤¿»þ¡¤linux°Ê³°¤Ç
+ ¤Îưºî¤¬Àµ¤·¤¯¤Ê¤«¤Ã¤¿¡¥
+
+Thu Oct 24 08:26:48 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (backtrace): `$@'¤òʸ»úÎ󤫤éÇÛÎó¤ËÊѹ¹¤·¤¿¡¥
+
+ * eval.c (eval): evalÃæ¤ÎÎ㳰ȯÀ¸°ÌÃÖ¤òÊݸ¤¹¤ë
+
+ * bignum.c (bigsub): ¥ª¥Ú¥é¥ó¥É¤ÎÂç¾®Èæ³Ó¤Î¼ºÇÔ
+
+ * re.c (reg_search): ľÀÜ»²¾È¤¬¤Ê¤¤»þ¤Ë¤â`$~'¤¬¥»¥Ã¥È¤µ¤ì¤ë¤è¤¦¤Ë
+
+Wed Oct 23 10:40:10 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.2-961023
+
+ * ext/marshal/marshal.c (r_bytes): malloc¤ò¤ä¤á¡¤alloca¤ò»È¤¦
+
+ * sample/ruby-mode.el (ruby-calculate-indent): ³ç¸Ì¤ÎÂбþ¤òÊѹ¹¡¥
+ ()Æâ¤Ç¤Ï¥¤¥ó¥Ç¥ó¥È¤ò¥ì¥Ù¥ë¤ò¹ç¤ï¤»¤ë¤è¤¦¤Ë
+
+Tue Oct 22 12:59:11 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * hash.c (hash_s_new): size¤ò»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë
+
+ * ext/marshal/marshal.c (w_object): dump¤¹¤ë¿¼¤µÀ©¸Â¤ò»ØÄê¤Ç¤­¤ë¤è
+ ¤¦¤Ë
+
+ * array.c (ary_s_new): size¤ò»ØÄꤷ¤¿»þ¤Î½é´ü²½Ëº¤ì
+
+ * object.c (f_float): big2dbl¤ÎÀë¸À˺¤ì¡¥
+
+ * bignum.c (bigsub): Â礭¤µ¤Î¶á¤¤BignumƱ»Î¤Î±é»»¤Ç·ë²Ì¤¬Éé¤Ë¤Ê¤ë
+ ¾ì¹ç¤Ë´Ö°ã¤¤¤¬¤¢¤Ã¤¿¡¥
+
+ * array.c (ary_aset): ÃÖ´¹Àè¤ÈÃÖ´¹¸µ¤¬Æ±¤¸Ä¹¤µ¤Î»þÆâÍÆ¤ò
+ shift(memmove)¤·¤Ê¤¤¤è¤¦¤Ë¡¥
+
+ * ext/marshal/marshal.c (marshal_dump): ¥Õ¥¡¥¤¥ë¥Õ¥©¡¼¥Þ¥Ã¥È¤Ë¥Ð¡¼
+ ¥¸¥ç¥ó¤òËä¤á¹þ¤à¤è¤¦¤Ë
+
+ * ext/marshal/marshal.c (tmpnam): linux-aout-dlnÍѤËÄêµÁ
+
+Mon Oct 21 08:40:20 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ext/socket/socket.c (sock_s_gethostbyname): hostent¹½Â¤ÂΤξðÊó
+ ¤òÊÖ¤¹
+ (sock_s_gethostbyaddr): IP¥¢¥É¥ì¥¹¤«¤éhostent¹½Â¤ÂΤòÆÀ¤ë
+ (sock_s_getservbyaname): getservbyname(3)
+
+Fri Oct 18 10:37:36 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * sample/ruby-mode.el (ruby-indent-to): °ÜưÀ襫¥é¥à¤¬Éé¤Ë¤Ê¤ë¥Ð¥°
+
+ * eval.c (compile): eval¤Ç¸µ¥½¡¼¥¹¤Î¹ÔÈÖ¹æ¤Ç¥¨¥é¡¼¤òɽ¼¨¤¹¤ë
+
+Thu Oct 17 09:52:28 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (eval): eval¤Çʸˡ¥¨¥é¡¼¤¬¤¢¤Ã¤¿»þ¤ËSEGV
+
+ * lib/safe.rb: Restricted.eval¤ÎÃæ¤À¤±À©¸Â¤ò²Ã¤¨¤ë¡¥
+
+ * eval.c (error_print): ¥Ð¥Ã¥¯¥È¥ì¡¼¥¹¤Î½ÐÎÏ¡¥caller¤ÇÎ㳰ȯÀ¸°ÌÃÖ
+ ¤òÄ´À°¤·¤¿»þ¤ËÌäÂ꤬½Ð¤ë(¤½¤ó¤Ê¤³¤È¤ò¤·¤Ê¤±¤ì¤ÐÎɤ¤¤Î¤À¤¬¡Ä)
+
+ * eval.c (make_backtrace): ¥Ð¥Ã¥¯¥È¥ì¡¼¥¹¤ÎÀ¸À®
+
+Wed Oct 16 12:56:22 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ruby-man-0.99.2-jp/index.html: ÆüËܸìÈǥɥ­¥å¥á¥ó¥È¤Î´°À®(Ť«¤Ã¤¿¡Ä)
+
+ * re.c (reg_regcomp): $=¤¬nil¤Î»þ¤Î½èÍý
+
+ * string.c (f_chop): $_¤ËÂФ¹¤ëchop
+
+Tue Oct 15 11:04:23 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.2-961015
+
+Mon Oct 14 18:22:38 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (thread_schedule): BOWÂбþ¡¥select¤¬-1¤òÊÖ¤·¤¿»þ¤Ë¥Ð¥°(¼Â
+ ¤Ïdo .. while¤¬continue¤ÇÀèÆ¬¤Ë¥¸¥ã¥ó¥×¤¹¤ë¤È»×¤¤¹þ¤ó¤Ç¤¤¤¿¡¥¾ò
+ ·ï¤ÎľÁ°¤À¤Ã¤¿¤Î¤Í ^^);;;;;
+
+ * sample/ruby-mode.el (ruby-mode-syntax-table): ?¤Îsyntax¤¬"/"¤Ç¤Ï
+ ¤Þ¤º¤¤¤é¤·¤¤
+
+ * hash.c (rb_hash): name conflict
+
+Fri Oct 11 00:23:05 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.2-961011
+
+ * ext/marshal/marshal.c (w_object): ·ë¶Éư¤¤¤Æ¤¤¤Ê¤«¤Ã¤¿½Û´Ä¥ª¥Ö¥¸¥§
+ ¥¯¥ÈÂбþ¤ò³°¤·¤¿¡¥
+
+ * hash.c (rb_hash): Fixnum¤Èʸ»úÎó¤Î¹â®²½
+
+ * ext/marshal/marshal.c (w_object): ̵Â̤ʥǡ¼¥¿¤Îºï½ü(¥Õ¥©¡¼¥Þ¥Ã
+ ¥È¤ÎÈó¸ß´¹À­)
+
+ * io.c (io_readline): Ìá¤êÃͤÎÉÔÈ÷
+
+ * ext/marshal/marshal.c (marshal_dumps): MSDOSÂбþ
+
+ * ruby.c (load_file): MSDOSÂбþ
+
+Wed Oct 9 17:46:27 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ext/extmk.rb.in (install): ̵Â̤ʥ³¥Ô¡¼¤òÈò¤±¤ë
+
+ * string.c (str_sub_method): ¥Þ¥Ã¥Á¤¬¤Ê¤«¤Ã¤¿»þ¤ÎString#sub¤ÎÃͤ¬
+ °ã¤Ã¤Æ¤¤¤¿¡¥
+
+ * eval.c (obj_extend): extend¤·¤¿»þ¤Ëobject_extended¤ò¸Æ¤Ö¤è¤¦¤Ë
+
+Tue Oct 8 00:55:38 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (thread_alloc): ³äÅö¤ÎÊ¿¶Ñ²½
+
+ * eval.c (thread_schedule): join¤Î¥Ð¥°¤ò½¤Àµ
+
+ * eval.c (thread_wait_for): select¤Ø¤Î³ä¹þ¤ß¤Ê¤É¤ËÂбþ
+
+ * eval.c (thread_select): linux¤Îselect¤Îµóư¤ËÂбþ(timeout¤¬ÊѲ½
+ ¤¹¤ë)
+
+Mon Oct 7 09:47:19 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.2-961007
+
+ * eval.c (PUSH_BLOCK): the_class¤ÎÊݸ¤ò˺¤ì¤Æ¤¤¤¿¡¥
+
+ * ext/dbm/dbm.c (fdbm_store): size¤ÎÊݸ¤¹¤ë¾ì½ê¤¬´Ö°ã¤Ã¤Æ¤¤¤¿
+
+ * ext/socket/socket.c (s_accept): threadÂбþ¤·¤Æ¤¤¤Ê¤«¤Ã¤¿
+
+Sat Oct 5 01:32:27 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * io.c (io_readchar): EOF¤ÇÎã³°¤òȯÀ¸¤µ¤»¤ë
+
+Fri Oct 4 11:59:54 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ext/marshal/marshal.c (w_object): Hash¤ÈObject¤ÎÉüµì¤ËɬÍפʥϥÃ
+ ¥·¥å¥Æ¡¼¥Ö¥ë¤¬ÅϤµ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿¡¥
+
+ * variable.c (rb_path2class): ¥æ¡¼¥¶ÄêµÁ¥¯¥é¥¹¤ÎÉüµì¤Ë¼ºÇÔ¤·¤Æ¤¤¤¿
+
+ * variable.c (rb_path2class): ¥¯¥é¥¹¤¬Â¸ºß¤·¤Ê¤¤»þ¤Î¥¨¥é¡¼¤òFatal
+ ¤«¤éNameError¤Ø¡¥
+
+ * range.c (range_s_new): first,last¤¬Î¾ÊýNumeric¤Î»þ¥¨¥é¡¼¤Ë¤Ê¤Ã¤Æ
+ ¤¤¤¿¡¥
+
+ * range.c: start->first, end->last
+
+Wed Oct 2 02:02:46 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * file.c: DJGPP¤Çchmod,chown¤ò»È¤¨¤ë¤è¤¦¤Ë(¤Ã¤ÆDOS¤Ëchown¤¬¤¢¤ë¤Î¤«?)
+
+ * class.c (rb_singleton_class): ¥Ó¥ë¥È¥¤¥ó¥¯¥é¥¹¤âextend¤·¤¿¤êÆÃ°Û
+ ¥á¥½¥Ã¥É¤òÄɲä·¤¿¤ê¤Ç¤­¤ë¤è¤¦¤Ë
+
+ * variable.c (rb_set_class_path): ¥æ¡¼¥¶ÄêµÁ¤Î¥È¥Ã¥×¥ì¥Ù¥ë¥¯¥é¥¹¤Ë
+ path¤òÀßÄꤷ¤Ê¤¤
+
+ * eval.c (eval): Îã³°¤¬RuntimeError¤Ë²½¤±¤Æ¤¤¤¿
+
+ * eval.c (eval): evalÃæ¤ÎÎã³°¤Îɽ¸½¤Î²þÁ±
+
+ * eval.c (eval): eval_with_binding¤È¤Î°ìËܲ½
+
+ * eval.c (rb_eval): ¥¯¥é¥¹/¥â¥¸¥å¡¼¥ëÄêµÁ¤ÎÃæ¤«¤éÄêµÁÃæ¤Î¥¯¥é¥¹/¥â
+ ¥¸¥å¡¼¥ë¤¬»²¾È¤Ç¤­¤ë¤è¤¦¤Ë
+
+Tue Oct 1 01:40:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.2-961001
+
+ * parse.y: cur_cref¤¬2ÅÙÀë¸À¤µ¤ì¤Æ¤¤¤¿
+
+ * signal.c (trap): SIGSEGV¡¤SIGBUS¤Î¤Ê¤¤µ¡¼ï¤ËÂбþ
+
+ * io.c (Init_IO): °ú¿ô¥¿¥¤¥×¤Î»ØÄê´Ö°ã¤¤
+
+Mon Sep 30 15:28:00 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.2-960930
+
+ * config.guess,config.sub: $host_os¤¬Àµ¤·¤¯ÀßÄꤵ¤ì¤Ê¤¤
+
+ * eval.c (rb_eval): yield¤ÇÀµ¤·¤¯¤Ê¤¤self¤¬ÀßÄꤵ¤ì¤Æ¤¤¤¿
+
+ * eval.c (ruby_run): toplevel¤ÎÎã³°½èÍý¤Î¥Ð¥°
+
+Mon Sep 30 09:13:26 1996 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
+
+ * djgppÂбþ
+
+Sat Sep 28 02:45:10 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.2-960928
+
+ * sample/ruby-mode.el (ruby-beginning-of-block): ¥Ö¥í¥Ã¥¯¤ÎÀèÆ¬¤Ë
+ °Üư(Àµ¤·¤¯¥¤¥ó¥Ç¥ó¥È¤·¤Æ¤¤¤Ê¤¤¤Èưºî¤·¤Ê¤¤)
+ (ruby-end-of-block): Ʊ¾å
+
+ * eval.c (class_s_new): Class#new¤¬¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ð¤ì¤¿»þ¤Ï
+ initialize¤â¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ð¤ì¤ë¤è¤¦¤Ë
+
+ * signal.c (sigsegv): SEGV¤Çbacktrace¤òɽ¼¨¤¹¤ë¤è¤¦¤Ë
+
+Fri Sep 27 09:51:07 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.2-960927
+
+ * eval.c (error_print): °ú¿ô¤Î¤Ê¤¤raise¤Ç¥á¥Ã¥»¡¼¥¸¤¬Àµ¤·¤¯É½¼¨¤µ
+ ¤ì¤ë¤è¤¦¤Ë¡¥
+
+ * eval.c (rb_longjmp): mesg¤¬nil¤Î»þRuntimeError¤òÀ¸À®¤¹¤ë¡¥
+
+ * eval.c (f_raise): °ú¿ô¤¬¤Ê¤¤»þ¤ËÂбþ
+
+ * eval.c (thread_mark): stack¾å¤Ë¤Ê¤¤¥Ç¡¼¥¿¤Î¥¢¥É¥ì¥¹ÊÑ´¹¤ò¹Ô¤Ã¤Æ
+ ¤¤¤¿¡¥
+
+ * eval.c (Init_Thread): ³ä¹þ¤ß¤Î´Ö³Ö¤¬1ÉäÈŤ¹¤®¤¿¡¥
+
+Thu Sep 26 16:02:45 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (thread_schedule): °ìÅÙ¥Ú¥ó¥Ç¥£¥ó¥°¤Ë¤Ê¤ë¤È¥Õ¥é¥°¤¬¥¯¥ê¥¢
+ ¤µ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿¡¥
+
+ * process.c (rb_proc_exec): system/exec¤Î°ú¿ô¤¬¶õʸ»úÎó¤Ç¤¢¤Ã¤¿¾ì
+ ¹ç¡¤Îã³°¤òȯÀ¸¤¹¤Ù¤­¤À¤Ã¤¿¡¥
+
+ * config.sub/config.guess: ¿·¤·¤¤¤â¤Î¤ËÃÖ¤­´¹¤¨
+
+Thu Sep 26 15:41:35 1996 WATANABE Hirofumi <watanabe@ase.ptg.sony.co.jp>
+
+ * io.c (next_argv): -i.bak¤òBOW¤ÈDOS¤ËÂбþ¡¥
+
+Thu Sep 26 01:31:43 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * io.c (io_sysread): EOF¤ÇÎã³°
+
+ * io.c (f_readline): EOF¤ÇÎã³°¤òȯÀ¸¤¹¤ë¤è¤¦¤Ë¡¥gets¤Ï¸ß´¹À­¤Î¤¿¤á
+ nil¤òÊÖ¤¹¤Þ¤Þ¤Ë¤¹¤ë
+
+ * eval.c (proc_call): lambda¤«¤é¤Îreturn¤ÇIN_BLOCK¥Õ¥é¥°¤¬Î©¤Ã¤¿¤Þ
+ ¤Þ¤À¤Ã¤¿
+
+ * eval.c (PUSH_BLOCK2): thread¤ËÂбþ¤¹¤ë¤¿¤áBlock¤ò°ìÅÙstack¤Ë¥³¥Ô¡¼
+
+Wed Sep 25 11:54:11 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (method_call): Const::method()·Á¼°¤ò»È¤¨¤ë¤è¤¦¤Ë¤·¤Æ¤ß¤¿¡¥
+ °ú¿ô³ç¸Ì¤Ï¾Êά¤Ç¤­¤Ê¤¤¡¥
+
+ * sample/test.rb: Process.kill¤Î¸ºß¤ò³Î¤«¤á¤Æ¤«¤é¥Æ¥¹¥È¤ò¹Ô¤¦
+
+ * eval.c (eval_with_binding): Âè2°ú¿ô¤È¤·¤Æbinding(¤Þ¤¿¤Ïlambda)¤ò
+ Í¿¤¨¤ë¤È¤½¤Î´Ä¶­¤Çeval¤ò¼Â¹Ô¤¹¤ë¤è¤¦¤Ë¤·¤¿
+
+ * eval.c (f_binding): ¸½ºß¤Îbinding¤òÊÖ¤¹´Ø¿ô
+
+ * eval.c: block¹½Â¤ÂΤËthe_class¤òÊݸ¤¹¤ë¥á¥ó¥Ð¤òÄɲÃ
+
+ * process.c (Init_process): kill,wait,waitpid¤òProcess¤Ë°Üư
+
+Tue Sep 24 02:44:43 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * sample/ruby-mode.el: ¤¤¤í¤¤¤íÌäÂ꤬¿¤¤¤Î¤Ç°ÊÁ°¤Î¹â®²½¤ÏÇË´þ¡¥
+ Ê̤Υ¢¥×¥í¡¼¥Á¤ò»È¤Ã¤¿¡¥
+
+ * lib/tk.rb (Tk.pack): Ê£¿ô¤Î¥¦¥£¥ó¥É¥¦¤ò¼õ¤±ÉÕ¤±¤ëpack
+
+Sat Sep 21 11:08:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (exprs): ¶õʸ¤â¼õ¤±ÉÕ¤±¤ë¤è¤¦¤Ëʸˡ¤òÊѹ¹¡¥º£¤Þ¤Ç¤Ï²þ¹Ô
+ ¤ÎϢ³¤À¤±¤¬µö¤µ¤ì¤Æ¤¤¤¿¡¥
+
+Fri Sep 20 11:39:18 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * Fail¤ÎÂçȾ¤ò̾Á°¤Ä¤­Îã³°¤ËÊѹ¹¡¥
+
+ * re.c (Init_Regexp): ̾Á°¤Ä¤­Îã³°¤òƳÆþ¡¥
+
+ * eval.c (f_missing): Object¤Ïinspect¤·¤Ê¤¤¡¥
+
+ * object.c (inspect_i): Object#inspect¤Çloop¤ËÂбþ¡¥
+
+ * regex.c (re_search): /^$/¤¬""¤Ë¥Þ¥Ã¥Á¤·¤Ê¤«¤Ã¤¿¡¥
+
+Thu Sep 19 19:25:12 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * regex.c (re_search): /^$/¤¬Èó¶õ¹Ô¤Ë¥Þ¥Ã¥Á¤·¤Æ¤¤¤¿¡¥
+
+Tue Sep 17 10:28:11 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.2-960917
+
+Mon Sep 16 10:47:56 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * sample/ruby-mode.el (ruby-calculate-indent): ±é»»»Ò·Ñ³¤Î¾ì¹ç¤Î
+ ʸ»úÎó¤ÎȽÄê¤Î¥Ð¥°
+
+ * sample/ruby-mode.el (ruby-calculate-indent): else¤Ê¤É¤Î¼¡¤Î¹Ô¤Î
+ ¥¤¥ó¥Ç¥ó¥È·×»»¤òÀµ¤·¤¯¡¥
+
+Sat Sep 14 08:37:19 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.2-960914
+
+Fri Sep 13 08:06:03 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ext/socket/socket.c (tcpaddr): portÈÖ¹æ¤Ëntohs¤ò¤Ä¤±Ëº¤ì
+
+ * dln.c (link_undef): ¥Æ¡¼¥Ö¥ë¤Î¼ïÎब´Ö°ã¤Ã¤Æ¤¤¤¿¡¥
+
+ * bignum.c (bigadd): °ú¤­»»¤¬È¯À¸¤¹¤ë»þ¤Ë·×»»°ã¤¤¤¬µ¯¤­¤Æ¤¤¤¿¡¥
+
+ * parse.y (iter_do_block): do..end¤Ç¤âdynamic variable¤ò¡¥
+
+ * bignum.c (big_pow): ¤è¤êÀµ³Î¤Ê·×»»¤ò(À°¿ôƱ»Î¤Ç¤Ïfloat¤ËÊÑ´¹¤·¤Ê
+ ¤¤)¡¥
+
+Thu Sep 12 13:11:55 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * variable.c (rb_set_class_path): String¥¯¥é¥¹¤¬½é´ü²½¤µ¤ì¤ëÁ°¤Ë
+ String¤òºî¤Ã¤Æ¤¤¤¿¡¥Áȹþ¤ß¥¯¥é¥¹¤Ë¤Ïpath¤Ï¤¤¤é¤Ê¤¤
+
+ * parse.y (yylex): 0.1¤¬0¤Ë¤Ê¤Ã¤Æ¤¤¤¿
+
+ * parse.y (yylex): ¹ÔÈÖ¹æ¤ÎÉÔÀ°¹ç
+
+ * gc.c (oblist_live_obj): º£¡ÖÀ¸¤­¤Æ¤¤¤ë¡×Á´Éô¤Î¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹
+ ¥¤¥Æ¥ì¡¼¥¿¡¥¤½¤Î¥¯¥é¥¹(¤Þ¤¿¤Ï¥µ¥Ö¥¯¥é¥¹)¤ÎÁ´Éô¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤òÊÖ
+ ¤¹each_object_of¤âÄêµÁ¤·¤¿¡¥
+
+ * class.c (rb_define_class_id): ̵Â̤ʥ¯¥é¥¹¤ò³ä¤êÅö¤Æ¤Æ¤¤¤¿¡¥·ë²Ì
+ ¤È¤·¤ÆÌ¤½é´ü²½¤Î¥¯¥é¥¹¥ª¥Ö¥¸¥§¥¯¥È¤¬Â¸ºß¤·¤Æ¤¤¤¿¡¥
+
+Wed Sep 11 00:56:23 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (yylex): octal¤ÎÄê¿ô¤Î¸¡½Ð¤ò¤è¤êÀµ³Î¤Ë(090¤Ï¥¨¥é¡¼¤È¤«)¡¥
+
+ * bignum.c (big_minus): y¤¬x¤è¤êÂ礭¤¤¾ì¹ç¤Ë¥¨¥é¡¼¡¥
+
+ * parse.y (yylex): ¥¨¥é¡¼¹ÔÈÖ¹æ¤Îɽ¼¨¤ò¤è¤êÀµ³Î¤Ë
+
+ * sample/ruby-mode.el (ruby-expr-beg): ÊÑ¿ô̾¤¬1ʸ»ú¤Î»þ¸íưºî¤·¤Æ
+ ¤¤¤¿¡¥
+
+ * sample/ruby-mode.el (ruby-calculate-indent): ?/¤Ç¥ë¡¼¥×¤ËÍî¤Á¤¤
+ ¤¿¥Ð¥°¤ò½¤Àµ¡¥
+
+ * enum.c (enum_min,enum_max): sort¤Î¤è¤¦¤Ë¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¤âưºî¤¹
+ ¤ë¤è¤¦¤Ë¡¥
+
+ * enum.c (enum_find_all): typo
+
+Tue Sep 10 12:07:12 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * node.h (nd_line): NODE¤Îline¤òflags¤Ë²¡¤·¹þ¤á¤Æ¥ª¥Ö¥¸¥§¥¯¥È¥µ¥¤
+ ¥º¤ò¾®¤µ¤¯¤·¤¿¡¥À©¸Â:32bit int¤Î¥Þ¥·¥ó¤Î¾ì¹ç¡¤¥Õ¥¡¥¤¥ë¤Î¹Ô¿ô¤¬
+ 32767¤ò±Û¤¨¤ë¤ÈÀµ¾ï¤Ëɽ¼¨¤µ¤ì¤Ê¤¤¡¥
+
+ * st.c: hash¤Ècompare¤Î´Ø¿ô¥á¥ó¥Ð¤ò¹½Â¤ÂΤ˥ѥ寡¤¥¯¥é¥¹Åª¤Ê»È¤¤
+ Êý¤ò¹Ô¤¦¡¥1 table¤¢¤¿¤ê4 byte¤ÎÀáÌó¡¥
+
+Mon Sep 9 16:35:54 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * file.c (file_truncate): Ä󶡤µ¤ì¤Ê¤¤»þ¤Ë¤ÏÆÃÊ̤ÊÎã³°¤òȯÀ¸¤¹¤ë¤è
+ ¤¦¤Ë¡¥
+
+ * eval.c (Init_Proc): ÉÔŬÀڤʰÌÃÖ¤Îlocal-jump¤òÎã³°¤Ë¡¥
+
+Sat Sep 7 17:06:15 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (proc_call): ¤Þ¤À¥¹¥³¡¼¥×¤¬¥¹¥¿¥Ã¥¯¾å¤Ë¤¢¤ë»þ¤Ë¤Ï¶É½êæ½Ð
+ ¤òÍ­¸ú¤Ë¤¹¤ë¡¥¤³¤ì¤Ç¡¤proc¤òÀ¸À®¤·¤Æcall¤¹¤ë¤³¤È¤Ï¡¤¥¹¥³¡¼¥×¤òæ
+ ½Ð¤·¤Ê¤¤¸Â¤ê¡¤yield¤ÈƱ¤¸°ÕÌ£¤ò»ý¤Ä¤³¤È¤Ë¤Ê¤ë¡¥
+
+Fri Sep 6 13:30:59 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * sample/ruby-mode.el (ruby-indent-to): ¥¤¥ó¥Ç¥ó¥È¤¬ÊѤï¤é¤Ê¤¤»þ¤Ë
+ ¤Ï¥Ð¥Ã¥Õ¥¡¤òÊѹ¹¤·¤Ê¤¤¡¥
+ (ruby-calculate-indent): ¤Þ¤ºÊ¸»úÎó¤ÎÆâÉô¤«È½ÃǤ·¤Æ¤«¤é¡¤Á°¤Î¹Ô
+ ¤«¤é¥Ñ¡¼¥º¤ò¹Ô¤¦¡¥defun¤¬Â礭¤¯¤Ê¤Ã¤¿»þ¤Î¹â®²½¡¥
+ (ruby-in-string-p): ʸ»úÎó¤ÎÆâÉô¤«¤É¤¦¤«¤òȽÃǤ¹¤ë´Ø¿ô(°ÊÁ°¤Î
+ parse¤«¤éʬΥ)
+ (ruby-parse-region): ʸ»úÎó¤ËÂФ¹¤ë½èÍý¤ò¤Ï¤º¤¹¡¥
+ (ruby-beginning-of-block): ¥Ö¥í¥Ã¥¯¤ÎÀèÆ¬¤Ë
+ (ruby-end-of-block): ¥Ö¥í¥Ã¥¯¤ÎËöÈø¤Ë(ÃÙ¤¤¡Ä)
+
+Thu Sep 5 14:23:07 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * file.c (file_s_split): [dirname,basename]¤Ësplit¤¹¤ë¡¥
+
+ * eval.c (rb_eval): eval¤ÎÃæ¤Ç¤âÄê¿ô¤ÎÃͤ¬Àµ¤·¤¯¤Ê¤ë¤è¤¦¤Ë¡¥¤³¤ì¤Ç
+ Äê¿ô¤Ë´Ø¤·¤Æ¤ÏÀÅŪ¤Ê¥¹¥³¡¼¥×¤¬Êݾڤµ¤ì¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¡¥
+
+ * st.c (rehash): ¥Ï¥Ã¥·¥å³ÈÂç¤Î·Ï¿ô¤ò2¤«¤é1.79¤Ë¡¥³ä»»¤¬¤è¤êÎɤ¤ÃÍ
+ ¤òÊÖ¤¹¤è¤¦¤Ë¡¥
+
+Thu Sep 5 00:32:07 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (class_superclass) ¥¯¥é¥¹¤Î¥¹¡¼¥Ñ¡¼¥¯¥é¥¹¤òÊÖ¤¹¥á¥½¥Ã¥É¡¥
+
+Wed Sep 4 16:54:56 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * random.c (f_rand): Bignum¤älong¤ÎÈϰϤò±Û¤¨¤ëFloat¤ËÂФ¹¤ëÍð¿ô¤â
+ ȯÀ¸¤Ç¤­¤ë¤è¤¦¤Ë¡¥
+
+ * struct.c (struct_alloc): Fatal¤Ç¤Ï¤Ê¤¯Îã³°¤òȯÀ¸¤µ¤»¤ë¤è¤¦¤Ë(ÄÌ
+ ¾ï¤Î»ÈÍѤÇȯÀ¸¤·¤¦¤ë)¡¥
+
+ * struct.c (struct_s_members): Struct¤ÎÆÃ°Û¥á¥½¥Ã¥É¤Ç¤Ï¤Ê¤¯¡¤À¸À®
+ ¤µ¤ì¤¿Struct¥¯¥é¥¹¤ÎÆÃ°Û¥á¥½¥Ã¥É¤Ë¤·¤¿¡¥
+
+ * st.c (st_init_table): rubyÀìÍѤ˥ѥé¥á¥¿¤ò¸ÇÄê¤Ë¤·¤¿(¥µ¥¤
+ ¥º¤¬¸º¤Ã¤¿)
+
+Mon Sep 2 11:37:59 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * array.c (ary_shift): capa¤¬¤¢¤Þ¤ê¤Ë¤âÂ礭¤¤»þ¤Ë¤ÏÎΰè¤òREALLOC
+ (ary_pop): Ʊ¾å
+
+ * string.c (str_inspect): multibyte character Âбþ¤Ë¥ß¥¹¡¥
+ (str_inspect): unsigned char¤Ë¤·¤Ê¤¤¤ÈÉ乿ŏ³«¤µ¤ì¤Æ¤·¤Þ¤¦
+
+ * parse.y (primary): `::'¤òprimary¤Ë°Üư Foo::Bar.Baz¤¬¥¨¥é¡¼¤Ë¤Ê
+ ¤é¤Ê¤¤¤è¤¦¤Ë¡¥
+
+ * parse.y (primary): ¥ª¥Ú¥ì¡¼¥¿·Á¼°¤ÎÆÃ°Û¥á¥½¥Ã¥É¤¬ÄêµÁ¤Ç¤­¤Ê¤¤
+
+ * random.c (f_rand): max¤¬0¤Î»þ¤ËÂбþ
+
+ * io.c (io_printf): ´Ø¿ô¤òÄêµÁ¤·¤Æ¤¤¤¿¤¬¥¤¥ó¥¿¥×¥ê¥¿¤ËÅÐÏ¿¤·¤Æ¤¤¤Ê
+ ¤«¤Ã¤¿¡¥
+
+ * file.c (file_s_basename): Âè2°ú¿ô¤¬Ìµ¤¤»þ¤Ë¥¨¥é¡¼¡¥
+
+Thu Aug 29 10:49:40 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (expr): ¥¤¥Æ¥ì¡¼¥¿¤Î¿··Á¼°¤Ë¡Ömethod do .. end¡×·Á¼°¤òºÎ
+ ÍѤ·¤¿¡¥¤â¤Á¤í¤óÀΤηÁ¼°¤âÍ­¸ú¡¥
+
+ * sample/ruby-mode.el (ruby-calculate-indent): end¤Î¿ô¤ÎÊý¤¬Â¿¤¤¾ì
+ ¹ç¤Ë¤â¥¨¥é¡¼¤òµ¯¤³¤µ¤Ê¤¤¤è¤¦¤Ë¡¥
+
+Wed Aug 28 09:41:36 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * numeric.c (upto,downto,step,times): Âоݤ¬fixnum¤ÎÈϰϤò±Û¤¨¤Æ¤â
+ ưºî¤¹¤ë¤è¤¦¤Ë¡¥
+
+Mon Aug 26 10:04:37 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * missing/setenv.c (envix): typo(missing `== 0' for memcmp)
+
+ * dir.c (dir_foreach): foreach(dir open -> read loop -> close¤Þ¤Ç)
+
+ * io.c (io_foreach): foreach(file open -> read loop -> close¤Þ¤Ç)
+
+ * Fatal¤Î¤¦¤ÁÊ᪲Äǽ¤Ê¤¤¤¯¤Ä¤«¤òÎã³°¤Ë¡¥
+
+Sat Aug 24 23:56:37 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * bignum.c (bigdivmod): FIX2INT -> INT2FIX Âç´Ö°ã¤¤
+
+Fri Aug 23 18:13:03 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * regex.c (re_free_registers): allocate¤·¤Æ¤¤¤Ê¤¤»þ¤Ë¤ÏÅöÁ³ free
+ ¤·¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
+
+Thu Aug 22 01:20:35 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (thread_create): ³°Â¦¤«¤é¶¯À©½ªÎ»¤µ¤»¤é¤ì¤¿thread¤Ï
+ cleanup¤¹¤ëɬÍפ¬Ìµ¤¤¡¥
+
+Wed Aug 21 09:57:28 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (thread_create): thread¤ò½ªÎ»¤µ¤»¤¿Âç°èæ½Ð¤Î¾ðÊó¤ò
+ main_thread¤ËÅϤ¹¤è¤¦¤Ë¡¥
+
+ * parse.y (call_args): ºÇ½ª°ú¿ô¤Ë³ç¸Ì¤ò¾Êά¤·¤¿¥á¥½¥Ã¥É¸Æ½Ð¤·¤òÃÖ
+ ¤±¤ë¤è¤¦¤Ë(Îã: print foo bar, baz == print(foo(bar,baz)))
+
+Tue Aug 20 13:37:16 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (masign): ¿½ÅÂåÆþ¤Èrest°ú¿ô¤Îưºî¤ò¹ç¤ï¤»¤Æ¶õ¤ÎÇÛÎó¤òÂå
+ Æþ¤¹¤ë¤è¤¦¤Ë¡¥
+
+ * parse.y (arg): defined?¤Î¶¯ÅÙ¤ò¤â¤¦¤Á¤ç¤Ã¤È¶¯¤¯
+
+ * eval.c (error_print): -w¤ÇÎ㳰̾¤âɽ¼¨¤¹¤ë¤è¤¦¤Ë
+
+ * eval.c (rb_eval): ¿·¹½Ê¸¤ËÂбþ
+ (handle_rescue): Ê᪤¹¤ëÎã³°¤ò kind_of? ¤ÇƱÄê
+
+ * parse.y (primary): rescue¤Î¹½Ê¸¤òÊѹ¹(ƱÄê°ú¿ô¤ÎÄɲá¤Ê£¿ôrescue)
+
+ * Fail()¤Î¤«¤Ê¤ê¤òŬÅö¤ÊÎã³°¤ò»È¤¦¤è¤¦¤Ë
+
+ * eval.c (thread_interrupt): Interrupt(º£¤Ïnon-local jump)¤Ï
+ main-thread¤ËÁ÷¤é¤ì¤ë¤è¤¦¤Ë¡¥
+
+ * eval.c (rb_longjmp): $! ¤ÎÆâÍÆ¤òʸ»úÎ󤫤éÎã³°¥¯¥é¥¹¤ËÊѹ¹
+ (rb_raise): rb_fail ¤«¤é̾¾ÎÊѹ¹
+ (rb_interrupt): Îã³°²½
+ (rb_exit): Îã³°²½
+
+ * error.c (Init_Exception): Îã³°¥¯¥é¥¹¤Î¿·Àß(ʸ»úÎó¤Î¥µ¥Ö¥¯¥é¥¹)
+
+Mon Aug 19 19:40:52 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * signal.c (trap): ¸Å¤¤¥Ï¥ó¥É¥é¤òÊÖ¤¹¤è¤¦¤Ë¡¥
+
+Wed Aug 14 00:07:18 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (rb_trap_eval): ¥Ï¥ó¥É¥é¤Î¤¿¤á¤Ëthread¤òfork¤¹¤ë¤³¤È¤ò»ß
+ ¤á¤¿¡¥
+
+ * eval.c (thread_mark): threadËè¤Î $!, $@ ¤ò¥Þ¡¼¥¯¤·Ëº¤ì
+
+ * ext/dbm/dbm.c (fdbm_delete): ¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ð¤ì¤¿¾ì¹ç¡¤Í×ÁÇ
+ ¤¬Ìµ¤±¤ì¤Ð¥Ö¥í¥Ã¥¯¤òɾ²Á¤¹¤ë¡¥
+
+ * hash.c (hash_delete): ¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ð¤ì¤¿¾ì¹ç¡¤Í×ÁǤ¬Ìµ¤±¤ì
+ ¤Ð¥Ö¥í¥Ã¥¯¤òɾ²Á¤¹¤ë¡¥
+
+ * array.c (ary_delete): ¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ð¤ì¤¿¾ì¹ç¡¤Í×ÁǤ¬Ìµ¤±¤ì
+ ¤Ð¥Ö¥í¥Ã¥¯¤òɾ²Á¤¹¤ë¡¥
+
+ * eval.c (rb_interrupt): SIGINT¤Î¥Ç¥Õ¥©¥ë¥È¤òexit¤«¤éÆÃÊ̤ÊÂç°èæ
+ ½Ð¤Ë¡¥¤ä¤Ï¤ê³ä¤ê¹þ¤Þ¤ì¤¿°ÌÃÖ¤Îɽ¼¨¤¬Ìµ¤¤¤Î¤Ï¼ä¤·¤¤¤Î¤Ç¡¥
+
+Tue Aug 13 01:34:00 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (rb_exit): sub-threadÆâ¤Ç¤Îexit¤âstatus¤òÊݸ¤¹¤ë¤è¤¦¤Ë
+ (thread_create): ¼«threadÆâ¤Îexit¤ËÂбþ
+
+ * signal.c (sighandle): SIGINT¤Î¥Ç¥Õ¥©¥ë¥È¥Ï¥ó¥É¥é¤Ïexit¤¹¤ë¤è¤¦¤Ë
+ (°ÊÁ°¤ÏÎã³°¤òȯÀ¸¤·¤Æ¤¤¤¿)¡¥
+
+ * Îã³°¤Î°ìÉô¤òFatal¤Ë¡¥
+
+ * string.c (str_aset): ʸ»úÎó¤ÎÃÖ´¹¤ÎÂоݤ¬Éôʬʸ»úÎó¤Ç¤Ê¤«¤Ã¤¿»þ¡¤
+ Îã³°¤òȯÀ¸¤µ¤»¤Ê¤¤¤è¤¦¤Ë
+
+ * eval.c (proc_call): Proc¤ÎÃæ¤«¤ébreak/next¤ÏÄ̤·¡¤Â¾¤Î¤â¤Î¤ÏÄ̤µ
+ ¤Ê¤¤¤è¤¦¤Ë
+
+Mon Aug 12 14:15:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * object.c (krn_type): ʸ»úÎó¤òÊÖ¤¹
+
+ * eval.c (thread_create): sub-threadÆâ¤Ç¤Îexit¤ËÂбþ
+
+ * numeric.c (fix_type): ʸ»úÎó¤òÊÖ¤¹
+
+ * io.c (f_p): ¥Ç¥Ð¥Ã¥°Íѥǡ¼¥¿É½¼¨¥á¥½¥Ã¥É
+
+ * eval.c (f_missing): nil/TRUE/FALSE¤òÆÃḚ̂·¤¤
+
+ * string.c (str_inspect): Ť¤Ê¸»úÎó¤òû½Ìɽ¼¨¡¥inspect¤ÎƯ¤­¤ò
+ human readable string¤ÎÀ¸À®¤ËÅý°ì(re-generatable string ¤ÏÀµ¼°¤Ë
+ ̵¤¯¤Ê¤Ã¤¿)¡¥
+
+Sat Aug 10 16:54:21 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * object.c (Init_Object): kernel/nil/false/true¤Î¥¯¥é¥¹Ì¾¤òÊѹ¹(¾®
+ ʸ»ú¤Ë)¡¤ruby¥¹¥¯¥ê¥×¥È¤«¤é¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¤è¤¦¤Ë¡¥
+
+ * eval.c (rb_eval): CONSTANT¤Î¥¢¥¯¥»¥¹Àè¤òñ½ã²½¡¥cref¤ò»È¤ï¤Ê¤¤¡¥
+
+ * eval.c (f_eval): ÆÃ°Û¥á¥½¥Ã¥ÉÆâ¤Ç¤âÄê¿ô¤ÎÃͤ¬Àµ¤·¤¯¤Ê¤ë¤è¤¦¤Ë
+
+Fri Aug 9 12:23:17 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * array.c (ary_concat): append -> concat String¤Ë¹ç¤ï¤»¤¿
+
+ * parse.y (yylex): `$;'¤¬»È¤¨¤Ê¤«¤Ã¤¿¡¥
+
+ * array.c (ary_push_method): Ê£¿ô°ú¿ô¤ò¼õ¤±ÉÕ¤±¤ë¤è¤¦¤Ë¡¥
+ (ary_unshift): Ê£¿ô°ú¿ô¤ò¼õ¤±ÉÕ¤±¤ë¤è¤¦¤Ë¡¥
+
+ * io.c (io_popen): IO.popen¤Çcommand pipe¤¬³«¤±¤ë¤è¤¦¤Ë¡¥
+
+ * object.c (Init_Object): Kernel¤ÈNil¤òruby script¤«¤é¥¢¥¯¥»¥¹¤Ç¤­
+ ¤Ê¤¤¤è¤¦¤Ë¡¥
+
+Thu Aug 8 01:21:47 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * object.c (f_integer): À°¿ô¤Ø¤ÎÊÑ´¹´Ø¿ô
+ (f_float): ¼Â¿ô¤Ø¤ÎÊÑ´¹´Ø¿ô
+ (f_string): ʸ»úÎ󤨤ÎÊÑ´¹´Ø¿ô
+ (f_array): ÇÛÎ󤨤ÎÊÑ´¹´Ø¿ô
+
+ * bignum.c (big_to_i): FIXNUM¤ÎÈϰϤǤʤ¤»þ¤ÏBignum¤Î¤Þ¤ÞÊÖ¤¹¤è¤¦
+ ¤ËÊѹ¹¡¥
+
+Wed Aug 7 09:28:38 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99.1-960807
+
+ * parse.y (mlhs): ¡Ö*foo = 1,2,3¡×¥¿¥¤¥×¤Î¿½ÅÂåÆþ¤â²Äǽ¤Ë¡¥
+
+ * object.c (Init_Object): ¥¯¥é¥¹True/False¤òruby script¤«¤é¥¢¥¯¥»
+ ¥¹¤Ç¤­¤Ê¤¤¤è¤¦¤Ë¡¥
+
+ * object.c (nil_inspect): inspectɽ¸½¤Ï"nil"¤Ë
+
+ * io.c (io_print): nil¤Îprint¤ònil¤Ë¡¥
+
+ * object.c (nil_to_s): nil¤Îʸ»úÎóɽ¸½¤ò""¤Ë¡¥
+
+Tue Aug 6 01:12:32 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * dir.c (dir_s_open): file descripter¤¬Â­¤ê¤Ê¤¤»þ¤Ë¤Ïgc¤·¤Æ¤«¤é¤â
+ ¤¦°ìÅÙopen¤·¤Æ¤ß¤ë¡¥
+
+ * io.c (rb_fopen): ¤¹¤Ù¤Æ¤Îfopen()¤Ë¤Ä¤¤¤Æfile descripter¤¬Â­¤ê¤Ê
+ ¤¤»þ¤Ë¤Ïgc¤·¤Æ¤«¤é¤â¤¦°ìÅÙopen¤·¤Æ¤ß¤ë¡¥
+
+ * ext/socket/socket.c (Init_socket): Äê¿ô¤ÎÄɲá¥
+
+ * sample/ruby-mode.el (ruby-indent-to): ¥¤¥ó¥Ç¥ó¥È¸å¤Î¥«¡¼¥½¥ë°ÌÃÖ
+ ¤ÎÄ´À°¤òÀµ¤·¤¯¡¥
+
+ * gc.c (gc): ³ä¹þ¤ß¥Á¥§¥Ã¥¯¤ò¹Ô¤ï¤Ê¤¤(C¥³¡¼¥É¤ÎÃæ¤Ç°Â¿´¤·¤Æ
+ malloc()¤¬»È¤¨¤Ê¤¯¤Ê¤ë¤Î¤Ç)¡¥
+
+ * st.c (call_hash_func): signal¤Èthread¤Ë¤è¤ë³ä¹þ¤ß¤ËÂбþ¡¥
+
+ * sig.h (DEFER_INTS): ³ä¹þ¤ß¶Ø»ß¶è´Ö¤Î»ØÄê
+
+ * eval.c (f_require): thread¤Ë¤è¤ërequire¤Î¶¥¹ç¤ËÂбþ(ºÇ½é¤Î
+ require¤¬½ªÎ»¤¹¤ë¤Þ¤Ç¾¤Îthread¤ÏÂÔ¤Ä)¡¥
+
+ * bignum.c (str2inum): 0x80000000¤ÎÃͤ¬Éé¤Ë¤Ê¤Ã¤Æ¤¤¤¿
+
+ * sprintf.c (f_sprintf): ʸ»úÎóËöÈø¡¤¹ÔËö¤ÎñÆÈ¤Î`%'¤ËÂбþ
+
+ * bignum.c (big_cmp): Èæ³Ó¤Î·ë²Ì¤¬µÕ¤Ë¤Ê¤ë»þ¤¬¤¢¤Ã¤¿¡¥
+
+Mon Aug 5 10:58:13 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * process.c (proc_exec_v): Îã³°¤Î¥á¥Ã¥»¡¼¥¸¤òʬ¤«¤ê¤ä¤¹¤¯¡¥
+
+ * ext/dbm/dbm.c (fdbm_store): nil¤ò³ÊǼ¤¹¤ë¤ÈÍ×ÁǤκï½ü¤Ë¤Ê¤ë
+
+ * ext/dbm/dbm.c: ¥µ¥¤¥º¤ò¥­¥ã¥Ã¥·¥å¡¥
+
+Sat Aug 3 01:52:52 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (rb_fail): `fail'¤¬°ú¿ô̵¤·¤Ç¸Æ¤Ð¤ì¤¿»þ¤À¤±°ÊÁ°¤Î`$@'¤òÊÝ
+ ¸¤¹¤ë¤è¤¦¤Ë¡¥
+
+ * eval.c (f_fail): frame¤ÎÄ´À°
+
+Fri Aug 2 11:26:21 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ext/socket/socket.c (bsock_setopt): val¤È¤·¤ÆTRUE/FALSE/Fixnum¤â
+ ¼õ¤±ÉÕ¤±¤ë¤è¤¦¤Ë¡¥
+
+ * ext/socket/socket.c (Init_socket): SO_REUSEADDRÅù¤ÎÄê¿ô¤ÎÄɲÃ
+
+ * ext/md5/md5init.c: md5¥â¥¸¥å¡¼¥ë(½é¤ÎÊ£¿ô¥Õ¥¡¥¤¥ë¤«¤é¤Ê¤ë¥â¥¸¥å¡¼
+ ¥ë¤Ç¤â¤¢¤ë)
+
+ * ruby.h (Make_Data_Struct): Data: object¤ÎinstanceÊÑ¿ô¤Ë³ÊǼ ->
+ Data·¿¤ÎObject¤Ë(Dir,Time,Proc,Thread,DBM)
+
+Thu Aug 1 11:38:44 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ext/dbm/dbm.c (fdbm_store): value¤¬Ê¸»ú¤Ç̵¤¤»þ¤ËÂбþ
+
+Wed Jul 31 10:53:42 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ext/socket/socket.c (open_inet): htons¤¬É¬ÍפǤ¢¤Ã¤¿
+ (tcpaddr): ntohl¤ÇÊÑ´¹¤·¤¿
+
+ * process.c (rb_proc_exec): execvp -> execv
+
+Tue Jul 30 17:48:33 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c: `$?'¤òthread local¤Ë
+
+ * Makefile.in (install): install»þ¤Ëstrip¤ò¹Ô¤¦
+
+ * configure.in: install»þ¤Îstrip¤Î¸¡½Ð
+
+ * configure.in: NEXTSTEPÂбþ
+
+ * version 0.99.1-960730
+
+Tue Jul 30 16:40:35 1996 SHIROYAMA Takayuki <psi@fortune.nest.or.jp>
+
+ * dln.c (dln_load): NeXT dln(mach-o)Âбþ¡¥configure¤Ï̤Âбþ
+
+Tue Jul 30 09:46:51 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * process.c (f_system): Ê£¿ô°ú¿ô¤â¤È¤ì¤ë¤è¤¦¤Ë
+
+ * process.c (f_exec): Ê£¿ô°ú¿ô¤â¤È¤ì¤ë¤è¤¦¤Ë
+
+ * array.c (ary_append): ÇÛÎó(¤Þ¤¿¤ÏEnum)¤ÎÍ×ÁǤòÇ˲õŪ¤ËÄɲÃ
+
+ * array.c (ary_plus): Enum¤Ï¤½¤ÎÍ×ÁǤòÄɲÃ
+
+ * file.c (file_s_open): File.open¤òÄɲÃ
+
+ * struct.c (struct_new): FIX2INT¤ò˺¤ì¤Æ¤¤¤¿
+
+ * file.c (Init_File): exists? -> exist?
+
+ * object.c (obj_is_kind_of): is_kind_of? -> kind_of?, is_a?
+
+ * object.c (obj_is_instance_of): is_instance_of? -> instance_of?
+
+Mon Jul 29 16:40:02 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (parse_regx): ¼°Å¸³«¤ò¹Ô¤Ã¤¿¾ì¹ç¡¤casefold¤ÎÀßÄ꤬¤Ç¤­¤Æ
+ ¤¤¤Ê¤«¤Ã¤¿¡¥
+
+ * object.c (true_type): TRUE/FALSE¤Ëtype¤ò¼ÂÁõ¡¥
+
+ * parse.y (read_escape): 3ʸ»ú°ÊÆâ¤Îoctal¤ËÂбþ(\0¤È¤«)
+
+Fri Jul 26 00:31:45 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * array.c (ary_reverse_bang): in-place¤ÇÇÛÎó¤òȿž¤µ¤»¤ë
+ (ary_sort_bang): in-place¤Çsort¤¹¤ë
+ (ary_sort): sort¤·¤¿ÇÛÎó¤òÊÖ¤¹¤è¤¦¤Ë
+ (ary_delete_at): »ØÄꤷ¤¿°ÌÃÖ¤ÎÍ×ÁǤòºï½ü¤¹¤ë
+
+ * eval.c (rb_call): stack¿¼¤µ¥Á¥§¥Ã¥¯¤òËè²ó¤Ï¹Ô¤ï¤Ê¤¤¤è¤¦¤Ë
+
+ * error.c (Warning): ¼Â¹ÔÃæ¤Îwarning¤¬É½¼¨¤µ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿
+
+ * eval.c (compile): Î㳰ȯÀ¸¤òʬΥ¡¥
+
+ * eval.c (f_eval): ÊÑ¿ôrb_in_eval¤òÀµ¤·¤¯´ÉÍý¤¹¤ë¤è¤¦¤Ë
+
+ * ext/dbm/dbm.c (fdbm_store): ³ÊǼ¤¹¤ëkey¤òʸ»úÎó¤ËÊÑ´¹
+
+ * eval.c (rb_call): ̵¸ÂºÆµ¢¤Î¥Á¥§¥Ã¥¯¤òÂç°èæ½Ð¤ò¹Ô¤¦C method¤Ë¤â
+ Âбþ¤µ¤»¤¿¡¥thread¤Îstack¿¼¤µ¥Á¥§¥Ã¥¯¥ë¡¼¥Á¥ó¤òήÍÑ¡¥
+
+ * parse.y (yylex): Âè1°ú¿ô¤Îunary -/+¤ÎȽÄ꤬´Ö°ã¤Ã¤Æ¤¤¤¿¡¥
+
+ * parse.y (yylex): unary +¤Ç¿ô»ú¤ò;·×¤ËÆÉ¤ó¤Ç¤¤¤¿(ex. +5 -> 55)
+
+Thu Jul 25 12:15:04 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (yylex): Û£Ëæ¤Ç¤Ê¤¤°ú¿ô¤ËÂФ·¤Æ·Ù¹ð¤ò½Ð¤·¤Æ¤¤¤¿¡¥
+
+ * eval.c (iterator_p): °ú¿ô¤Ç¸Æ¤ó¤Ç¤âÀµ¤·¤¤·ë²Ì¤òÊÖ¤¹¤è¤¦¤Ë¡¥
+
+ * parse.y: break/next/redo/retry¤Î¥á¥½¥Ã¥É²½¡¥
+
+ * sample/ruby-mode.el (ruby-calculate-indent): nest¤Î¥Á¥§¥Ã¥¯¥ß¥¹
+
+ * sample/ruby-mode.el (ruby-parse-region): ͽÌó¸ì¤Î¥Á¥§¥Ã¥¯¤ò¶¯²½
+
+ * parse.y (primary): unless/until¤ÎÉü³è
+
+Tue Jul 23 18:50:10 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * array.c (Array#empty?), Hash.c (Hash#empty?), ext/dbm/dbm.c (DBM#empty?):
+ ¶õ¤ÎȽÄê½Ò¸ì
+
+ * eval.c (f_unless): if¤ÎµÕ¤ò¤¹¤ë¥¤¥Æ¥ì¡¼¥¿
+
+ * eval.c (f_until): while¤ÎµÕ¤ò¤¹¤ë¥¤¥Æ¥ì¡¼¥¿
+
+ * parse.y: not¤ÎÍ¥Àè½ç°Ì¤òand/or¤è¤ê¹â¤¯
+
+ * parse.y (expr): `!'¤ò°ú¿ô³ç¸Ì¤ò¾Êά¤·¤¿call¤Ç¤âÍ­¸ú¤Ë
+
+Mon Jul 22 10:15:38 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99-960722
+
+ * array.c (ary_print_on): OFS¤ÎNIL¥Á¥§¥Ã¥¯¤¬ÉÔ´°Á´
+
+ * ruby.c (load_file): ɸ½àÆþÎϤ«¤é¤Î¥¹¥¯¥ê¥×¥È¤¬¶õ¤Î»þ¤ËÂбþ¡¥
+
+ * ruby.c (proc_options): -w¤Ç¤Ï°ú¿ô̵¤·¤Î»þ¤Ë¤Ïɸ½àÆþÎϤ«¤é¥¹¥¯¥ê
+ ¥×¥È¤ò¤È¤ë(-v¤Ç¤Ï¤¿¤ó¤Ë½ªÎ»¤¹¤ë)¡¥
+
+ * array.c (ary_compact): nil¤ÎÍ×ÁǤò¼è¤ê½ü¤¯¥á¥½¥Ã¥É
+
+ * array.c (ary_nitems): nil¤Ç¤Ê¤¤Í×ÁǤò¿ô¤¨¤ë¥á¥½¥Ã¥É
+
+Sun Jul 20 00:51:53 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ruby.c (proc_options): -w option¤òÄɲÃ
+
+ * parse.y: {}¤¬ÊĤ¸¤Æ¤¤¤Ê¤¤»þ¤Ë¤ÏŸ³«¤·¤Ê¤¤Ê¸»úÎó¤ò
+
+Fri Jul 19 16:16:05 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99-960719
+
+ * lib/find.rb: ÀÐÄÍÈÇ(prune¤Î³ÈÄ¥ÉÕ¤­)
+
+ * file.c (test_l): lstat¤ÇÄ´¤Ù¤Ê¤¤¤È¤Í¡¥
+
+ * eval.c (f_throw): Âè2°ú¿ô¤ò¾Êά²Äǽ¤Ë¡¥
+
+ * parse.y (str_extend): {}¤Î¥Í¥¹¥È¤ËÂбþ
+
+Thu Jul 18 18:25:46 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99-960718
+
+ * parse.y (str_extend): ʸ»úÎóÃæ¤Î¼°Å¸³«¤Ë \" ' ` / ¤ò´Þ¤à»ö¤¬¤Ç¤­
+ ¤ë¤è¤¦¤Ë¡¥
+
+Tue Jul 16 15:55:31 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * sample/ruby-mode.el (ruby-parse-region): Àµµ¬É½¸½Æâ¤Î¥¨¥¹¥±¡¼¥×
+ ¤ËÂбþ
+
+ * version 0.99-960716
+
+Fri Jul 12 10:06:19 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * io.c (f_select): °ú¿ô¤Îclose check.
+
+ * ruby.c (load_file): #!¹Ô¤Î°ú¿ô¥Á¥§¥Ã¥¯¤òÂè1°ú¿ô¤Ë¸ÂÄê(¼Â¤ò¤¤¤¦¤È
+ DOS²þ¹ÔÂкö)
+
+Wed Jul 10 17:18:35 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99-960710
+
+ * time.c (time_s_timegm/time_s_timelocal): »þ´Ö¤òÀ¸À®¤¹¤ë¥á¥½¥Ã¥É
+
+Mon Jun 17 15:59:20 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99-960617
+
+ * parse.y (yyerror): ¥¨¥é¡¼É½¼¨¤Î´Êά²½¡¥
+
+Wed Jun 12 14:11:01 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * signal.c (rb_trap_exit): trap 0¤Ïthread¤òÀ¸À®¤»¤º¤Ë½èÍý¤¹¤ë¡¥
+
+Fri Jun 7 10:17:01 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * array.c/hash.c (indexes): ÇÛÎó1°ú¿ô¤Î¥Ñ¥¿¡¼¥ó¤ò̵¤¯¤·¤¿¡¥ÇÛÎó¤Î
+ ¾ì¹ç¤Ï`*ary'¤ò»È¤Ã¤Æ¤â¤é¤ª¤¦¡¥
+
+ * eval.c (thread_wait_threads): main_thread¤¬½ªÎ»¤¹¤ëÁ°¤Ë¾¤Î
+ thread¤òÂÔ¤Ä(¶¯À©Åª¤Ë¤Ï½ªÎ»¤µ¤»¤Ê¤¤)¡¥
+ (ruby_run): ¾¤Îthread¤òÂԤäƤ¤¤ë´Ö¤Ë¥·¥°¥Ê¥ë¤¬Í褿¤é¡¤Á´thread
+ ¤ò¶¯À©½ªÎ»¤µ¤»¤ë¡¥
+
+ * eval.c (rb_fail): ¥á¥½¥Ã¥É̾¤ò`$!'¤ËËä¤á¹þ¤à¡¥
+
+ * eval.c (thread_create): main_thread¤Î¥³¥ó¥Æ¥¯¥¹¥È¤¬¥»¡¼¥Ö¤µ¤ì¤Ê
+ ¤¤¾ì¹ç¤¬¤¢¤Ã¤¿¡¥
+
+ * process.c (f_sleep): »þ´Ö¤ò»ØÄꤻ¤º¡¤thread¤¬¤Ò¤È¤Ä¤·¤«¤Ê¤¤¾õ¶·
+ ¤Ë¤âÂбþ¡¥
+
+ * eval.c (thread_create): create¸å¡¤fn¤ò¸Æ¤Ó½Ð¤¹Á°¤Ëcontext switch
+ ¤¬µ¯¤­¤ë¤È°ã¤¦context¤Çfn¤¬¼Â¹Ô¤µ¤ì¤Æ¤·¤Þ¤¦¥Ð¥°¡¥
+
+Mon Jun 3 08:03:17 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * struct.c (struct_s_def): ¥á¥ó¥Ð¤Î»ØÄê¤òʸ»úÎ󡤥·¥ó¥Ü¥ë(FIXNUM)
+ ÁÐÊý¤Ç²Äǽ¤Ë¤·¤¿¡¥
+
+ * ext/etc/etc.c (Init_etc): ¹½Â¤ÂÎ¥ª¥Ö¥¸¥§¥¯¥È¤òGC¤«¤éÊݸ¤¿¡¥
+
+ * error.c (rb_sys_fail): nil/FALSE¤ò°ú¿ô¤È¤·¤Æ¼õ¤±ÉÕ¤±¤ë¤è¤¦¤Ë¡¥
+
+Thu May 30 16:19:08 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (thread_select): EINTR¤ËÂбþ¡¥
+
+Wed May 29 11:04:51 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (f_catch): catch/throw¤ò¼ÂÁõ¤·¤¿¡¥
+
+Tue May 28 13:30:52 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99-960528
+
+ * eval.c (thread_cleanup): main thread¤¬½ªÎ»¤¹¤ë¤È¾¤Îthread¤â½ªÎ»
+ ¤¹¤ë¤³¤È¤ÎÌÀ³Î²½¡¥
+
+ * signal.c (trap): SIGINT¤Î¥Ç¥Õ¥©¥ë¥È¤ÎÀßÄê¥ß¥¹(ËÜÅö¤ËSIG_DFL¤Ç¤Ï
+ ¤Þ¤º¤«¤Ã¤¿)¡¥ruby¤Ç¤Ï¤Á¤ã¤ó¤È¥Ï¥ó¥É¥ë¤·¤Ê¤¤¤È¡¥
+
+ * eval.c (thread_interrupt): SIGINT¤Ïmain_thread¤ËÎã³°¤òȯÀ¸¤µ¤»¤ë
+ ¤è¤¦¤Ë¡¥
+
+Mon May 27 15:13:31 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (thread_status): thread¤Î¾õÂÖ¤òÊÖ¤¹¥á¥½¥Ã¥É¡¥thread¤Î½ªÎ»
+ ¤òÂÔ¤¿¤Ê¤¤¡¥
+
+ * eval.c (thread_value): °ì¼ï¤Îpromise¤ò¼ÂÁõ¤¹¤ë¤¿¤á¤Î¥á¥½¥Ã¥É¡¥
+
+ * eval.c (thread_join): ÂԤäƤ¤¤ëthread¤¬Îã³°¤òµ¯¤³¤·¤¿»þ¤Ë¤Ï¡¤
+ join¤¬¤½¤ÎÎã³°¤òȯÀ¸¤¹¤ë¤è¤¦¤Ë¡¥
+
+ * eval.c (thread_create): thread¤Ç¤ÎÎã³°¤òpropagate¤·¤Ê¤¤¤è¤¦¤Ë¡¥
+
+Fri May 24 10:47:53 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * enum.c (Init_Enumerable): `size' as alias to the `length'
+
+ * eval.c (thread_save_context): `$@', `$!'¤ò¥¹¥ì¥Ã¥ÉËè¤Ë¥»¡¼¥Ö¡¥
+
+ * eval.c (superclass): ¥¨¥é¡¼É½¼¨¤ò¤è¤ê¿ÆÀڤˡ¥
+
+Thu May 23 10:38:41 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.99-960523
+
+ * eval.c (superclass): ¥¨¥é¡¼»þ¤Ë¥¹¡¼¥Ñ¡¼¥¯¥é¥¹Ì¾¤ò(ʬ¤«¤ì¤Ð)ɽ¼¨
+ ¤¹¤ë¤è¤¦¤Ë¡¥
+
+Wed May 22 19:48:42 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (superclass): ¥¹¡¼¥Ñ¡¼¥¯¥é¥¹¤Î»ØÄê»Ò¤ò`:'¤«¤é`<'¤ËÊѹ¹¡¥
+
+Tue May 21 09:27:59 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * lib/thread.rb: thread¤ò¥µ¥Ý¡¼¥È¤¹¤ë¥¯¥é¥¹(Mutex, Queue)¡¥
+
+Mon May 20 09:39:49 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * time.c (time_cmp): ÉâÆ°¾®¿ôÅÀ¿ô¤â°·¤¨¤ë¤è¤¦¤Ë¡¥
+ (time_minus): Time - Time¤¬ÉâÆ°¾®¿ôÅÀ¿ô¤òÊÖ¤¹¤è¤¦¤Ë¡¥
+
+Fri May 17 15:40:10 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * process.c (rb_proc_exec): ThreadÂбþ»þ¤Ëexec¤ÎľÁ°¤Ë
+ ITIMER_VIRTUAL¤ò¥ê¥»¥Ã¥È¤¹¤ë¡¥
+
+Tue May 14 02:12:44 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * signal.c (sighandle): SIGINT¤ËÂФ·¤Æ¥Ç¥Õ¥©¥ë¥È¤ÇÎã³°¤òȯÀ¸¤µ¤»¤ë
+ ¤Î¤ò¤ä¤á¡¤status 130¤Çexit¤¹¤ë¤è¤¦¤Ë¤·¤¿¡¥
+
+ * eval.c (thread_schedule): Thread¤Î¥Ð¥°¤Ï¤Û¤È¤ó¤É¤È¤ì¤¿¤è¤¦¤À¡¥
+
+Fri May 10 11:21:08 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (thread_schedule): ¥æ¡¼¥¶¥ì¥Ù¥ëThreadµ¡Ç½¡¥¸úΨ¤Ï¤È¤â¤«¤¯
+ °Ü¿¢À­¤Ï¤¢¤ë¡¥º£¸å¡¤thread´Ö¤ÎÄÌ¿®µ¡Ç½¤ò¼ÂÁõ¤¹¤ëͽÄê¡¥
+
+Thu May 2 21:22:31 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * time.c (time_timeval): struct timeval¤òľÀÜÊÖ¤¹¤è¤¦¤Ë(staticÊÑ¿ô
+ ¤ò»È¤ï¤Ê¤¤)¡¥
+
+Wed May 1 17:27:32 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * process.c (f_sleep): À°¿ô°Ê³°¤Îtime¤ò»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë¡¥
+
+Thu Apr 25 08:19:15 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * file.c (file_s_dirname): ¥Õ¥¡¥¤¥ë̾¤¬"/"¤ò´Þ¤Þ¤Ê¤¤»þ¡¤"."¤òÊÖ¤¹
+ ¤è¤¦¤Ë(GNU dirname¤Î»ÅÍÍ)¡¥
+
+ * file.c (file_s_basename): ¤Þ¤Ànil¤È0¤òº®Æ±¤·¤Æ¤¤¤ë¥½¡¼¥¹¤¬»Ä¤Ã¤Æ
+ ¤¤¤¿¡¥
+
+ * parse.y (exprs): ¥¨¥é¡¼¥ê¥«¥Ð¥ê¤òÄɲá¥
+
+Wed Apr 24 15:51:05 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * string.c (str_chop_bang): CRLF¤Î¾ì¹ç2 bytes¤òchop!¤¹¤ë¤è¤¦¤Ë¡¥
+
+ * ext/socket/socket.c (tcp_svr_s_open): ¤Þ¤Ànil¤È0¤òº®Æ±¤·¤Æ¤¤¤ë¥½¡¼
+ ¥¹¤¬»Ä¤Ã¤Æ¤¤¤¿¡¥
+
+Tue Apr 23 18:14:25 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * pack.c (pack_pack): "A/a"¤Î¥Ð¥°¡¥Í¾·×¤Êpadding¤¬Æþ¤Ã¤Æ¤¤¤¿¡¥
+
+Thu Apr 18 13:02:11 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * configure.in: ¥¢¡¼¥­¥Æ¥¯¥Á¥ã°Í¸Éô¤òÊ̥ǥ£¥ì¥¯¥È¥ê¤Ë¥¤¥ó¥¹¥È¡¼¥ë
+ ¤¹¤ë¤è¤¦¤Ë¡¥
+
+ * parse.y (yyerror): ¥¨¥é¡¼È¯À¸»þ¤Ë¥¨¥é¡¼¹Ô¤È¤½¤Î°ÌÃÖ¤òɽ¼¨¤¹¤ë¤è
+ ¤¦¤Ë¡¥
+
+Wed Apr 17 14:22:42 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * defines.h: SAFE_SIGHANDLE¤ò̵¤¯¤·¡¤´í¸±¤ÊÁªÂò¤Ï¤Ç¤­¤Ê¤¤¤è¤¦¤Ë¡¥
+
+ * io.c (io_ungetc): ¿·µ¡Ç½¡¥
+
+ * ruby.c (load_file): ¥Õ¥¡¥¤¥ë¤«¤é¤ÎÆÉ¤ß¹þ¤ßÊý¼°¤¬ÊѤï¤Ã¤¿¤Î¤ËÂбþ¡¥
+
+ * parse.y (compile_file): ¥Õ¥¡¥¤¥ë¤«¤é¤ÎÆþÎϤò°ìÅÙÁ´ÉôÆÉ¤ß¹þ¤à¤Î¤ò
+ »ß¤á¤Æ¡¤gets¤ò»È¤¦¤³¤È¤Ë¤·¤¿¡¥
+
+Wed Apr 10 17:40:11 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.98
+
+Tue Apr 9 09:54:30 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (iter_block): ¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤Î»ØÄê¤ò¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·
+ ¤Ë¸ÂÄꡥʸˡ¤ÎÌÀ³Î²½¡¥
+
+ * eval.c (rb_eval): ¾ò·ï¼°¤ÎÀµµ¬É½¸½¤ÎÈæ³Ó¤òinline²½¡¥
+
+ * eval.c (rb_eval): defined? ¤Î ÄêµÁ¾ðÊó(¼ïÊÌ)¤òʸ»úÎó¤ÇÊÖ¤¹¡¥
+
+ * node.h: NODE_BEGIN -> NODE_RESCUE, NODE_ENSURE¤ËʬΥ¡¥
+
+ * eval.c (rb_eval): option -n/-p¤Î¥È¥Ã¥×¥ì¥Ù¥ë¥ë¡¼¥×¤ÎinlineŸ³«¡¥
+
+ * parse.y (cond0): ¾ò·ï¼°Ãæ¤Îʸ»úÎó¤ÏÈæ³Ó¤ÎÂоݤȤ·¤Ê¤¤
+
+Wed Mar 27 12:33:54 1996 Tairo Nomura <tairo@hucom.tp.titech.ac.jp>
+
+ * defines.h: NeXTÂбþ
+
+Wed Mar 27 10:02:44 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y: ͽÌó¸ì¤ÎÊѹ¹ continue -> next
+
+Mon Mar 25 07:34:37 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (parse_regx): o(once)¥ª¥×¥·¥ç¥ó¤òÄɲá¥
+
+Fri Mar 22 14:25:35 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.97d
+
+ * eval.c (dyna_var_defined): ưŪ¥í¡¼¥«¥ëÊÑ¿ô¤ÎÄêµÁ¥Á¥§¥Ã¥¯Íѥ롼
+ ¥Á¥ó¡¥
+
+ * parse.y (gettable): eval()¤ÎÃæ¤Ç¤ÎưŪ¥í¡¼¥«¥ëÊÑ¿ô(´û¤ËÃͤò»ý¤Ã
+ ¤Æ¤¤¤ë¤â¤Î)¤Î¸¡½Ð¤Ë¼ºÇÔ¤·¤Æ¤¤¤¿¡¥
+
+Tue Mar 19 10:46:47 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.97c
+
+ * re.c (reg_s_new): compile»þ¤Ësegmentation fault¡¥
+
+ * parse.y (str_extend): ¤¤¤Ä¤âeval¤¹¤ë¤è¤¦¤Ë¡¥
+
+Wed Mar 13 11:00:42 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (str_extend): ʸ»úÎóÃæ¤Î¼°Å¸³«¤ÎÉÔÈ÷¤ò̵¤¯¤·¤¿¡¥
+
+ * parse.y: ²¼¼ê¤Ê¥¨¥é¡¼¥ê¥«¥Ð¥ê¤ò³°¤·¤¿¡¥
+
+Tue Mar 12 12:30:20 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (rescue): ´Ö°ã¤Ã¤Æensure¤Ç¤âÎã³°¤òÊ᪤·¤Æ¤¤¤¿¡¥
+
+Wed Mar 6 12:11:03 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * parse.y (var_extend): ÊÑ¿ôŸ³«"#{}"¤Ç¡¤Ç¤°Õ¤Î¼°¤ò½ñ¤±¤ë¤è¤¦¤Ë¤·
+ ¤¿¡¤¤³¤ì¤Ç¡ÖÊÑ¿ô¡×Ÿ³«¤Ç¤Ï̵¤¯¤Ê¤Ã¤Á¤ã¤Ã¤¿¤Ê¤¢¡¥
+
+ * regex.c (init_syntax_once): `_'¤òword¤ËÄɲá¥
+
+ * regex.c (re_compile_pattern): `\w',`\W'¤ÎȽÄê¤òsyntax table¤ò»È
+ ¤¦¤è¤¦¤Ë¡¥
+
+Tue Feb 27 10:15:32 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * object.c (obj_inspect): ɽ¼¨¤¹¤ë¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤¬Ìµ¤¤»þ¤Ë¤Ï¡¤
+ to_s¤ò»È¤¦¡¥
+
+ * configure.in: dln¤Î¸¡½Ð¤ò¼«Æ°Åª¤Ë¡¥
+
+Mon Feb 26 19:55:33 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ruby.c (readin): read(2)¤Ç°ìÅ٤˥ե¡¥¤¥ë¤¬ÆÉ¤ß¹þ¤á¤Ê¤¤¾ì¹ç¤ËÂбþ¡¥
+
+Sat Feb 24 14:47:18 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.97b
+
+Fri Feb 23 11:26:02 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * class.c (rb_define_module): C¸À¸ì¤ÇÄêµÁ¤µ¤ì¤¿¥â¥¸¥å¡¼¥ë¤ÎPATH¤Î
+ ÀßÄê˺¤ì¡¥Ê¸»úÎ󲽤Çcore dump¡¥
+
+ * eval.c (mod_include): Ìá¤êÃͤònil¤Ë¡¥
+
+ * version 0.97a
+
+Thu Feb 22 21:03:42 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * array.c (ary_times): ¡ÖÇÛÎó*ʸ»úÎó¡×¤¬join¤ÈƱ¤¸Æ¯¤­¤ò¤¹¤ë¤è¤¦¤Ë¡¥
+
+Wed Feb 21 11:18:09 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * configure.in : fileCount¤òcache¡¥
+
+ * configure.in : Linux¤ÇELF´Ä¶­¤ò¼«Æ°Åª¤Ë¸¡½Ð¤Ç¤­¤ë¤è¤¦¡¥
+
+Tue Feb 20 11:18:09 1996 Mitsuhide Satou <mit-sato@aries.bekkoame.or.jp>
+
+ * FreeBSD dynamic linkÂбþ¡¥
+
+Fri Feb 16 08:50:01 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * object.c (obj_inspect): ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ò»ý¤¿¤Ê¤¤¥ª¥Ö¥¸¥§¥¯¥È¤â
+ Àµ¤·¤¯É½¼¨¤µ¤ì¤ë¤è¤¦¤Ë¡¥
+
+Wed Feb 14 16:56:44 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (rb_eval): ¾ò·ï¼°¤Î`2..2'¤Ê¤Éº¸ÊÕÀ®Î©Ä¾¸å¤Ë±¦ÊÕ¤¬À®Î©¤¹¤ë
+ ¥Ñ¥¿¡¼¥ó¤Ë¥Ð¥°¡¥
+
+Tue Feb 13 18:22:22 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.97
+
+Fri Feb 9 21:32:55 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * lib/tkscrollbox.rb: ¥¹¥¯¥í¡¼¥ë¤Çtcl¤ÎÀßÄê¤ò¹Ô¤¤¡¤ruby<->wish¤ÎÉÔ
+ ÍפÊÄÌ¿®¤ò̵¤¯¤·¤¿¡¥
+
+Wed Feb 7 10:26:52 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * string.c (str_aref): index¤òunsigned int¤Ç¤È¤Ã¤Æ¤¤¤¿¡¥
+
+ * string.c (str_aref): Èϰϳ°¤Îindex¤ËÂФ·¤Ænil¤òÊÖ¤¹¡¥
+
+ * parse.y (special_local_set): `$_'¤¬Àë¸À̵¤·¤Ë»È¤ï¤ì¤¿¾ì¹ç¤ËÂбþ¡¥
+ ´Ø¿ô¤òvariable.c¤«¤é°Üư¡¥
+
+ * string.c (str_sub): ÃÖ´¹³«»Ï°ÌÃÖ¤¬´Ö°ã¤Ã¤Æ¤¤¤¿¡¥
+
+Tue Feb 6 16:17:31 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * sample/ruby-mode.el (ruby-parse-region): ¥³¥á¥ó¥È¤ÎÆÉ¤ßÈô¤Ð¤·¤Î
+ ¥Ð¥°¡¥
+
+Fri Feb 2 18:35:28 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * variable.c (lastline_get): `$_'¤ò`$~'¤ÈƱ¤¸¤è¤¦¤ËSCOPE¥í¡¼¥«¥ë¤Ê
+ ÊÑ¿ô¤Ë¤·¤¿¡¥
+
+Thu Feb 1 14:14:07 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * file.c: stat¤Îcache¤ò¤ä¤á¤¿¡¥
+
+Wed Jan 31 07:13:08 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (proc_s_new): proc¤ÎÃæ¤Çyield¤ò¸Æ¤Ð¤ì¤¿»þ¤Ëcore dump¤·¤Æ
+ ¤¤¤¿¡¥¤È¤ê¤¢¤¨¤ºÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥
+
+ * variable.c (rb_class2path): singleton class¤ËÂбþ¡¥
+
+ * ext/etc/etc.c (Init_etc): struct_define¤Î¥¿¡¼¥ß¥Í¡¼¥¿¤¬nil¤À¤Ã¤¿
+ (0¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤)¡¥
+
+ * ext/marshal/marshal.c: TRUE/FALSE¤òÅǤ­½Ð¤»¤ë¤è¤¦¤Ë¡¥
+
+ * eval.c (rb_get_method_body): ¥­¥ã¥Ã¥·¥å¤ÎaliasÂбþ¡¤¤¤¤Þ¤Þ¤Ç¤Ï
+ alias¤Ï¥­¥ã¥Ã¥·¥å¤ËÆþ¤Ã¤Æ¤¤¤Ê¤«¤Ã¤¿¡¥
+
+Tue Jan 30 09:55:13 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (rb_eval): NODE_BLOCK - tail recursive(¤È¤¤¤¦¤Û¤É¤Ç¤â¤Ê¤¤
+ ¤¬)¡¥
+
+ * io.c (io_pipe): pipe(2)¤ò¼ÂÁõ¤·¤¿¡¥
+
+ * eval.c (rb_eval): Qself¤ò¤Ê¤¯¤·¤¿¡¥threadÂбþ¤Ø¤ÎÂè°ìÊâ¡¥Àè¤Ï±ó
+ ¤¤¤¬¡Ä¡¥
+
+ * eval.c (proc_call): proc¤ÎÃæ¤Ç¤Îreturn¤Ïproc¤Î½ªÎ»¤ò°ÕÌ£¤¹¤ë¤è¤¦
+ ¤Ë¡¥¤¿¤À¤·¡¤proc¤«¤é¤Îyield¤ÎÃæ¤Ç¤Îreturn¤ÏÎã³°¤òȯÀ¸¤¹¤ë¡¥
+
+Wed Jan 24 11:33:48 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.96a
+
+ * dir.c (dir_each): `$_'¤ÎÃͤòÊѹ¹¤¹¤ë¤Î¤ò¤ä¤á¤¿¡¥
+
+ * io.c (f_readlines): nil¤ÈFALSE¤ÎʬΥ¤Î¤¢¤ª¤ê¤Ç̵¸Â¥ë¡¼¥×¤ËÍî¤Á¤Æ
+ ¤¤¤¿¡¥
+
+ * ruby.c (ruby_options): $0¤ÎÀßÄê¥ß¥¹¡¥
+
+Tue Jan 23 15:28:21 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (rb_eval): ``¤Ïʸ»úÎó¤ò°ú¿ô¤È¤¹¤ë¥á¥½¥Ã¥É(`)¸Æ¤Ó½Ð¤·¤Î¥·
+ ¥ó¥¿¥Ã¥¯¥¹¥·¥å¥¬¡¼¤Ç¤¢¤ë¤È¤·¤¿¡¥
+
+ * ruby.c (addpath): `-I'¥ª¥×¥·¥ç¥ó¤Ç¥Ç¥£¥ì¥¯¥È¥ê¤¬¡ÖÁ°¤Ë¡×Äɲ䵤ì
+ ¤ë¤è¤¦¤ËÊѹ¹¡¥
+
+Fri Jan 19 11:23:12 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * dln.c (load_1): N_INDRÂбþ(½ÐÍ褿¤è¤¦¤Êµ¤¤¬¤¹¤ë)¡¥
+
+Thu Jan 18 18:14:20 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * ruby.texi: FALSE¤Ènil¤ÎʬΥ¤òÈ¿±Ç¤·¤¿¡¥
+
+Tue Jan 16 17:39:23 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.96 - ¤È¤ê¤¢¤¨¤ºnil¤ÈFALSE¤ò¶èÊ̤¹¤ëÈÇ
+
+Wed Jan 10 15:31:48 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * re.c (reg_match): ¥Þ¥Ã¥Á¤·¤Ê¤«¤Ã¤¿»þ¤ÎÌá¤êÃͤÏFALSE¡¥
+
+ * object.c (rb_equal): `0 == nil'¤¬TRUE¤Ë¤Ê¤ë¥Ð¥°¡¥
+
+Tue Jan 9 00:44:58 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * nil¤ÈFALSE¤¬Ê¬Î¥²Äǽ¤ËÊѹ¹¡¥
+
+ * nil¤ÈFALSE¤È0¤Î¶èÊ̤ò¸·Ì©¤Ë¡¥
+
+ * struct.c (struct_new): °ú¿ô¤ò0¤Ç½ª¤ëɬÍפ¬Ìµ¤¯¤Ê¤Ã¤¿¡¥
+
+ * object.c (inspect_i): ¥ª¥Ö¥¸¥§¥¯¥È¤Î¥Á¥§¥Ã¥¯¤Î¥Ð¥°(Fixnum¤Çcore
+ dump¤·¤Æ¤¤¤¿)¡¥
+
+ * range.c (range_to_s): Range¤Îɽ¼¨¤ò²þÁ±¡¥
+
+ * object.c (true_inspect): TRUE¤Îɽ¼¨¤ò`TRUE'¤Ë¡¥
+
+Mon Jan 8 15:02:33 1996 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * numeric.c (fix_mul): divide by zero error¤¬È¯À¸¤·¤¿(¥ª¡¼¥Ð¡¼¥Õ¥í¡¼
+ ¸¡½Ð¤Î¥Ð¥°)
+
+ * texinfo.tex¤ò¥Ñ¥Ã¥±¡¼¥¸¤Ë´Þ¤á¤¿¡¥
+
+Sun Dec 31 00:08:49 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (rb_eval): `::'¤Ç¤Ï¡¤¤½¤Î¥¯¥é¥¹¤ÇÄêµÁ¤µ¤ì¤¿Äê¿ô¤ò»²¾È¤¹¤ë
+ ¤è¤¦¤ËÊѹ¹¡¥
+
+ * string.c (Init_String): each¤òeach_line¤ËÌᤷ¤¿¡¥
+
+Thu Dec 28 12:31:55 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * eval.c (rb_eval): case¤Î±é»»»Ò¤ò`=~'¤«¤é`==='¤Ë¡¥
+
+ * variable.c (rb_const_set): ¥¯¥é¥¹Äê¿ô¤ÎºÆÄêµÁ¤òµö¤¹(Ʊ¤¸¥¯¥é¥¹¤Ç
+ ¤ÏÉÔ²Ä)¡¥·Ù¹ð¤Ï½Ð¤¹¡¥
+
+Wed Dec 27 13:27:52 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.95c
+
+ * ext/tkutil/tkutil.c: wish¤¬¤¢¤Ã¤Æ¤â¤Ê¤¯¤Æ¤â°ì±þ¥³¥ó¥Ñ¥¤¥ë¤À¤±¤Ï
+ ¤¹¤ë¤è¤¦¤Ë¡¥
+
+ * lib/tk.rb: ´Ä¶­ÊÑ¿ôPATH¤«¤é{wish|wish4.0}¤òõ¤¹¤è¤¦¤Ë¡¥
+
+Tue Dec 26 01:03:42 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * sample/ruby-mode.el (ruby-parse-region): Àµµ¬É½¸½¤Î¸¡½Ð¶¯²½¡¥
+
+ * numeric.c (fix_mul): ¾è»»¤Î¥ª¡¼¥Ð¡¼¥Õ¥í¡¼¸¡½Ð¥¢¥ë¥´¥ê¥º¥à¤Î¥Ð¥°¡¥
+
+ * ext/extmk.rb.in: ./install-sh¤ò»È¤¦¾ì¹ç¤ÎPATH¤òÄ´À°¡¥
+
+ * Makefile.in (install): lib/*.rb¤ò°ì¤Ä¤º¤Ä¥¤¥ó¥¹¥È¡¼¥ë¡¥
+
+ * io.c (io_each_line): ¥¤¥Æ¥ì¡¼¥¿¤ÎÌá¤êÃͤònil¤ÇÅý°ì¡¥
+
+Fri Dec 22 10:34:32 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+
+ * version 0.95b
+
+ * variable.c (f_untrace_var): Âè2°ú¿ô¤ò»ØÄꤹ¤ë¤ÈÆÃÄê¤Îtrace¤òºï½ü
+ ¤Ç¤­¤ë¤è¤¦¤Ë¡¥
+
+ * variable.c (f_trace_var): Âè2°ú¿ô¤¬nil¤Î»þ¡¤trace¤òºï½ü¤¹¤ë¡¥
+
+ * lib/tk.rb (file_readable/file_writable): Âè2°ú¿ô¤ònil¤Ë¤¹¤ë¤³¤È
+ ¤Ë¤è¤ëevent handler¤Îºï½ü¡¥
+
+ * parse.y (variable): ¥É¥­¥å¥á¥ó¥È¤Ë`__FILE__'¤È`__LINE__'¤¬»Ä¤Ã¤Æ
+ ¤¤¤¿¡¥`caller(0)'¤ÇÂåÍѤ·¤¿¤Ï¤º¤À¤Ã¤¿¤Î¤Ë¡¥
+
+ * eval.c (f_eval): $!¤Î¥ê¥»¥Ã¥È¡¥
+
+ * error.c (err_sprintf): ¾¡¼ê¤Ë"\n"¤òÉղ乤ë¤Î¤ò»ß¤á¤¿¡¥
+
+ * parse.y (f_arglist): °ú¿ô¥ê¥¹¥Èľ¸å¤Îif/while¤ÎÆÉ¤ß´Ö°ã¤¤¡¥
+ lex_state¤ÎÃͤ¬ÀßÄꤵ¤ì¤Æ¤¤¤Ê¤«¤Ã¤¿¡¥
+
Thu Dec 21 00:56:57 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+ * version 0.95a - ^^;;;
+
+ * lib/tkscrollbox.rb: ¥Ñ¥Ã¥±¡¼¥¸¤ËÆþ¤Ã¤Æ¤Ê¤«¤Ã¤¿¡¥
+
+ * configure.in: FILE structure¤Î¥Á¥§¥Ã¥¯¤Ë¥Ð¥°¡¥
+
+ * Makefile.in (clean): ext°Ê²¼¤òinstall¤·¤Æ¤¤¤¿¡¥
+
+ * ext/socket/extconf.rb: Solaris¤Ë¤ª¤±¤ë-lnls¤Î¥Á¥§¥Ã¥¯¡¥
+
+ * array.c (beg_len): ¥Ð¥°¤¬¤¢¤Ã¤¿¡Ä¡¥Èᤷ¤¤¡¥
+
* version 0.95 - fj.sources¤Ë
* eval.c (rb_eval): rescue¤Î¥í¥¸¥Ã¥¯¤òrb_rescue()¤Ë°ì¸µ²½¡¥
@@ -204,8 +1970,8 @@ Fri Oct 13 13:19:19 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
* string.c (str_strip_bang): ʸ»úÎó¤Î¸å¤í¤ÎŤµ¤ÎÄ´À°¤¬¹Ô¤ï¤ì¤Æ¤¤
¤Ê¤«¤Ã¤¿¡¥
- * re.c (reg_search): $&, $1...¤Î¤Ï¥í¡¼¥«¥ë¤Ë«Çû¤¹¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¡¥
- ¸Æ¤Ó½Ð¤·¤¿¥á¥½¥Ã¥É¤Ç¤Î¥Þ¥Ã¥Á¤Ï¸½¥¹¥³¡¼¥×¤Î$&¤Ê¤É¤ÎÃͤ˱ƶÁ¤·¤Ê¤¤¡¥
+ * re.c (reg_search): $&, $1...¤Ï¥í¡¼¥«¥ë¤Ë«Çû¤¹¤ë¤è¤¦¤Ë¤Ê¤Ã¤¿¡¥¸Æ
+ ¤Ó½Ð¤·¤¿¥á¥½¥Ã¥É¤Ç¤Î¥Þ¥Ã¥Á¤Ï¸½¥¹¥³¡¼¥×¤Î$&¤Ê¤É¤ÎÃͤ˱ƶÁ¤·¤Ê¤¤¡¥
¥Þ¥Ã¥Á¤Î¾ðÊó¤ò¥¹¥³¡¼¥×³°¤ÇÆÀ¤¿¤¤¤È¤­¤Ë¤Ï$~¤ò»È¤Ã¤ÆÂ«Çû¾ðÊó¤ò»ý¤Á
½Ð¤¹É¬Íפ¬¤¢¤ë¡¥
@@ -352,7 +2118,7 @@ Thu Sep 14 18:00:59 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
* object.c (obj_is_instance_of): is_member_of¤«¤é̾¾ÎÊѹ¹¡¥
-Wed Sep 13 15:44:35 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
+ Wed Sep 13 15:44:35 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
* string.c (Fstr_tr_bang): Èϰϳ°¤Îʸ»ú¤ËÂФ¹¤ëÊÑ´¹¥Ð¥°¡¥
@@ -441,7 +2207,7 @@ Fri Aug 11 14:37:03 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
* io.c: ¥Þ¥¯¥íREAD_DATA_PENDING¤ÎÄêµÁ¤òÊѹ¹(LinuxÂбþ)
- * io.c (io_fptr_finalize): ftpr¤Î³«Êü»þ¤Î½èÍý¤ò»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë¡¥
+ * io.c (io_fptr_finalize): fptr¤Î³«Êü»þ¤Î½èÍý¤ò»ØÄê¤Ç¤­¤ë¤è¤¦¤Ë¡¥
Wed Aug 9 16:52:41 1995 Yukihiro Matsumoto <matz@caelum.co.jp>
@@ -722,8 +2488,8 @@ Thu May 18 12:27:23 1995 Yukihiro Matsumoto <matz@ix-02>
¤¤ÌäÂê¤â¤¢¤Ã¤¿¡¥·ë²Ì¤È¤·¤Ætr¤ò½ñ¤­´¹¤¨¤¿¤Î¤Ç¡¤copyright¤ÎÌäÂê¤Ï
̵¤¯¤Ê¤Ã¤¿(¤È»×¤¦)¡¥
- * gc.c (gc): the_scope¤ò¥Þ¡¼¥¯¤·¤Æ¤¤¤Ê¤«¤Ã¤¿¤Î¤Ç¡¤¥í¡¼¥«¥ëÊÑ¿ô¤¬´Ö
- °ã¤Ã¤Æ³«Êü¤µ¤ì¤ë¾ì¹ç¤¬¤¢¤Ã¤¿¡¥
+ * gc.c (gc): the_scope¤ò¥Þ¡¼¥¯¤·¤Æ¤¤¤Ê¤«¤Ã¤¿¤Î¤Ç¡¤¥í¡¼¥«¥ëÊÑ¿ô¤Î»Ø
+ ¤·¤Æ¤¤¤ë¥ª¥Ö¥¸¥§¥¯¥È¤¬´Ö°ã¤Ã¤Æ³«Êü¤µ¤ì¤ë¾ì¹ç¤¬¤¢¤Ã¤¿¡¥
* gc.c (mark_locations_array): ¼ã´³¤Î¹â®²½¡¥
@@ -789,8 +2555,8 @@ Thu Apr 20 12:31:24 1995 Yukihiro Matsumoto (matz@ix-02)
* env.h, gc.c, regex.c: IRIX¤Ø¤Î°Ü¿¢Âбþ
- * configure: pic¤òÀ¸À®¤¹¤ëoption¤Î¸¡½Ð¤Î¤¿¤á¡¤¥·¥¹¥Æ¥à¥¿¥¤¥×¤ò¥Á¥§¥Ã
- ¥¯¤¹¤ë¤è¤¦¤Ë¡¥
+ * configure: dlopenÍѤËpic¤òÀ¸À®¤¹¤ëoption¤Î¸¡½Ð¤Î¤¿¤á¡¤¥·¥¹¥Æ¥à¥¿
+ ¥¤¥×¤ò¥Á¥§¥Ã¥¯¤¹¤ë¤è¤¦¤Ë¡¥
Tue Apr 18 19:08:17 1995 Yukihiro Matsumoto (matz@ix-02)
@@ -808,7 +2574,7 @@ Mon Apr 10 18:36:06 1995 Yukihiro Matsumoto (matz@ix-02)
Fri Apr 7 13:51:08 1995 Yukihiro Matsumoto (matz@ix-02)
* cons.c->assoc.c: cons¤Î;·×¤Êµ¡Ç½¤Ï³°¤·¤Æpair¤È¤·¤Æ¤Îµ¡Ç½¤À¤±¤ò
- »Ä¤·¤¿¡¥enumerable¤òinclude¤¹¤ë¤Î¤â¤ä¤á¤¿¡¥
+ »Ä¤·¤¿¡¥Enumerable¤òinclude¤¹¤ë¤Î¤â¤ä¤á¤¿¡¥
* string.c(esub): ʸ»úÎóÃÖ´¹¥¤¥Æ¥ì¡¼¥¿¡¥perl¤Îs///e¤ÎÁêÅö¤¹¤ë¡¥
@@ -885,8 +2651,8 @@ Fri Mar 10 18:35:46 1995 Yukihiro Matsumoto (matz@ix-02)
* eval.c: Math¤Î¤è¤¦¤Ê¥â¥¸¥å¡¼¥ë¤Ï¼«Ê¬¼«¿È¤Çextend¤¹¤ë¡¥
- * eval.c: ¥¯¥é¥¹¤ä¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤·¤¿´û¤ËƱ̾¤Î¤â¤Î¤¬¤¢¤ì¤ÐÄɲÃÄê
- µÁ¤È¤Ê¤ë¤è¤¦¤Ë¡¥¤¿¤À¤·¡¥super¥¯¥é¥¹¤Î°ã¤¤¤Ê¤É¤Ï¥Á¥§¥Ã¥¯¤¹¤ë¡¥
+ * eval.c: ¥¯¥é¥¹¤ä¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤¹¤ë»þ¡¤´û¤ËƱ̾¤Î¤â¤Î¤¬¤¢¤ì¤ÐÄÉ
+ ²ÃÄêµÁ¤È¤Ê¤ë¤è¤¦¤Ë¡¥¤¿¤À¤·¡¥super¥¯¥é¥¹¤Î°ã¤¤¤Ê¤É¤Ï¥Á¥§¥Ã¥¯¤¹¤ë¡¥
* regex.c: debug.
@@ -933,8 +2699,8 @@ Thu Feb 23 11:19:19 1995 Yukihiro Matsumoto (matz@ix-02)
* eval.c(rb_clear_cache): ¥­¥ã¥Ã¥·¥å¤Î¥¯¥ê¥¢¤·Ëº¤ì¤¬¤¢¤Ã¤¿¡¥
* eval.c: Äê¿ô¤Î¥¹¥³¡¼¥×¤ò¥¯¥é¥¹Æâ¤ÎÀÅŪ¥¹¥³¡¼¥×¤ËÊѹ¹¤·¤¿¡¥¤³¤ì¤Ë
- ¤è¤Ã¤Æ¡¤ÆÃ°Û¥á¥½¥Ã¥É¤«¤é¤Ï»²¾È¤µ¤ì¤ëÄê¿ô¤Ï¡¤¥ì¥·¡¼¥Ð¤Î¥¯¥é¥¹¤Ç¤Ï
- ¤Ê¤¯¡¤ÄêµÁ¤µ¤ì¤¿¥¹¥³¡¼¥×¤Î¥¯¥é¥¹¤ÎÄê¿ô¤È¤Ê¤ë¡¥
+ ¤è¤Ã¤Æ¡¤ÆÃ°Û¥á¥½¥Ã¥É¤«¤é»²¾È¤µ¤ì¤ëÄê¿ô¤Ï¡¤¥ì¥·¡¼¥Ð¤Î¥¯¥é¥¹¤Ç¤Ï¤Ê
+ ¤¯¡¤ÄêµÁ¤µ¤ì¤¿¥¹¥³¡¼¥×¤Î¥¯¥é¥¹¤ÎÄê¿ô¤È¤Ê¤ë¡¥
Wed Feb 22 00:51:38 1995 Yukihiro Matsumoto (matz@dyna)
@@ -985,8 +2751,9 @@ Fri Feb 10 16:30:00 1995 Yukihiro Matsumoto (matz@ix-02)
* ruby.c(load_file): script¤òÆÉ¤ß¹þ¤à»þ¤À¤±"#!"¤Î²òÀϤò¹Ô¤¦¤è¤¦¤Ë¡¥
- * ruby.c(readin): ¥Õ¥¡¥¤¥ëÆÉ¤ß¹þ¤ß»þ¤ËÀèÆ¬¤Ë"#!"¤¬¤¢¤ê¡¤ruby¤Ë°ú¿ô
- ¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤ì¤Ð¡¤¤½¤Î°ú¿ô¤âÍ­¸ú¤Ë¤Ê¤ë¡¥
+ * ruby.c(readin): ¥Õ¥¡¥¤¥ëÆÉ¤ß¹þ¤ß»þ¤ËÀèÆ¬¤Ë"#!"¤¬¤¢¤ê¡¤¤½¤Î¹Ô¤¬
+ "ruby"¤È¤¤¤¦Ê¸»úÎó¤ò´Þ¤à»þ¡¤ruby¤Ë°ú¿ô¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤ì¤Ð¡¤¤½¤Î°ú
+ ¿ô¤âÍ­¸ú¤Ë¤Ê¤ë¡¥
* parse.y(yylex): ¥³¥á¥ó¥È¹Ô¤Î½ª¤ê¤¬`\'¤Ç¤¢¤Ã¤¿»þ¡¤¼¡¤Î¹Ô¤Ë·Ñ³¤·
¤Æ¤¤¤ë¤È¤ß¤Ê¤¹¤è¤¦¤Ë¤·¤¿¡¥
@@ -1056,7 +2823,7 @@ Tue Jan 17 11:11:27 1995 Yukihiro Matsumoto (matz@ix-02)
À­¤ò·Ñ¾µ¤¹¤ë¡¥ºÇ½é¤ÎÄêµÁ¤Î»þ¤Ïº£¤Þ¤Ç¤ÈƱ¤¸¥Ç¥Õ¥©¥ë¥È(¥È¥Ã¥×¥ì¥Ù
¥ë¤Ç´Ø¿ôŪ¡¤¥¯¥é¥¹ÄêµÁÆâ¤ÇÄ̾ï¥á¥½¥Ã¥É)¡¥
- * object.c(Class::new): ¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®»þ¤Ë´Ø¿ôŪ¥á¥½¥Ã¥É
+ * object.c(Class#new): ¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®»þ¤Ë´Ø¿ôŪ¥á¥½¥Ã¥É
init_object¤¬É¬¤º¸Æ¤Ð¤ì¤ë¤è¤¦¤ËÊѹ¹¡¥
* eval.c: ̤ÄêµÁ¤Î¥á¥½¥Ã¥É¤ËÂФ·¤Æunknown¥á¥½¥Ã¥É¤¬¸Æ¤Ð¤ì¤ë¤è¤¦¤Ë
diff --git a/MANIFEST b/MANIFEST
index 81c7a3a646..3b0ba3e0d0 100644
--- a/MANIFEST
+++ b/MANIFEST
@@ -2,6 +2,7 @@ ChangeLog
MANIFEST
Makefile.in
README
+README.jp
README.EXT
ToDo
array.c
@@ -9,7 +10,9 @@ bignum.c
class.c
compar.c
configure
+configure.bat
configure.in
+config.dj
config.guess
config.sub
defines.h
@@ -47,7 +50,6 @@ regex.c
regex.h
ruby.c
ruby.h
-ruby.texi
sig.h
signal.c
sprintf.c
@@ -56,27 +58,41 @@ st.h
string.c
struct.c
time.c
+top.sed
util.h
util.c
variable.c
version.c
version.h
ext/Setup
+ext/Setup.dj
ext/extmk.rb.in
lib/base64.rb
+lib/cgi-lib.rb
+lib/complex.rb
lib/find.rb
lib/getopts.rb
+lib/jcode.rb
lib/mailread.rb
+lib/mathn.rb
+lib/observer.rb
lib/parsearg.rb
lib/parsedate.rb
+lib/rational.rb
+lib/safe.rb
+lib/thread.rb
lib/tk.rb
+lib/tkcore.rb
lib/tkcanvas.rb
+lib/tkclass.rb
lib/tkentry.rb
+lib/tkscrollbox.rb
lib/tktext.rb
-lib/tkclass.rb
+lib/tkthcore.rb
missing/alloca.c
missing/crypt.c
missing/dup2.c
+missing/flock.c
missing/memmove.c
missing/mkdir.c
missing/nt.c
@@ -93,16 +109,16 @@ sample/cbreak.rb
sample/clnt.rb
sample/dbm.rb
sample/dir.rb
-sample/evaldef.rb
+sample/eval.rb
sample/export.rb
sample/exyacc.rb
+sample/fact.rb
sample/fib.awk
sample/fib.pl
sample/fib.rb
sample/fib.scm
sample/freq.rb
sample/from.rb
-sample/fullpath.pl
sample/fullpath.rb
sample/getopts.test
sample/io.rb
@@ -113,12 +129,16 @@ sample/list3.rb
sample/marshal.rb
sample/mkproto.rb
sample/mpart.rb
+sample/observ.rb
sample/occur.pl
sample/occur.rb
sample/occur2.rb
+sample/philos.rb
+sample/pi.rb
sample/rcs.awk
sample/rcs.dat
sample/rcs.rb
+sample/regx.rb
sample/ruby-mode.el
sample/sieve.rb
sample/svr.rb
@@ -131,6 +151,6 @@ sample/tkfrom.rb
sample/tkhello.rb
sample/tkline.rb
sample/tktimer.rb
-sample/trojan.pl
sample/trojan.rb
+sample/tsvr.rb
sample/uumerge.rb
diff --git a/Makefile.in b/Makefile.in
index 81e3feca79..aa018968ff 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -77,30 +77,30 @@ extruby: miniruby ext/Setup
@if test -z "$$UNDER_EXTMAKE_RB"; \
then echo "Compiling ext modules"; \
UNDER_EXTMAKE_RB=yes; export UNDER_EXTMAKE_RB; \
- cd ext; ../miniruby ./extmk.rb; fi
+ cd ext; ../miniruby ./extmk.rb @EXTSTATIC@; fi
$(PROGRAM): $(OBJS)
@rm -f $(PROGRAM)
$(PURIFY) $(CC) $(STATIC) $(LDFLAGS) $(OBJS) $(LIBS) -o $(PROGRAM)
-$(bindir)/ruby: extruby
- $(INSTALL_PROGRAM) ruby $(bindir)/ruby
- strip $(bindir)/ruby
-
-install: $(bindir)/ruby
+install:; $(INSTALL_PROGRAM) ruby $(bindir)/ruby
+ @-@STRIP@ $(bindir)/ruby
+ @test -d $(libdir) || mkdir $(libdir)
cd ext; ../miniruby ./extmk.rb install
- $(INSTALL_DATA) lib/*.rb $(libdir)
+ @for rb in `grep '^lib/' MANIFEST`; do \
+ $(INSTALL_DATA) $$rb $(libdir); \
+ done
clean:; @rm -f $(OBJS)
@rm -f ext/extinit.c ext/extinit.o
- cd ext; ../ruby ./extmk.rb install
+ cd ext; ../miniruby ./extmk.rb clean
realclean: clean
@rm -f Makefile ext/extmk.rb
@rm -f config.cache config.h config.log config.status
@rm -f core ruby miniruby *~
-test:; @-./ruby sample/test.rb > ./ruby_test 2>&1;\
+test:; @-./ruby sample/test.rb > ./ruby_test 2>&1; \
if grep '^end of test' ./ruby_test > /dev/null; then \
echo "test succeeded"; \
else \
@@ -122,6 +122,9 @@ crypt.o: missing/crypt.c
dup2.o: missing/dup2.c
$(CC) -I. $(CFLAGS) $(CPPFLAGS) -c missing/dup2.c
+flock.o: missing/flock.c
+ $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c missing/flock.c
+
memmove.o: missing/memmove.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c missing/memmove.c
@@ -162,22 +165,21 @@ bignum.o: bignum.c ruby.h config.h defines.h
class.o: class.c ruby.h config.h defines.h node.h st.h
compar.o: compar.c ruby.h config.h defines.h
dir.o: dir.c ruby.h config.h defines.h
-dln.o: dln.c config.h defines.h dln.h
+dln.o: dln.c config.h defines.h dln.h st.h
dmyext.o: dmyext.c
-dummy.o: dummy.c config.h dln.c defines.h dln.h
enum.o: enum.c ruby.h config.h defines.h
error.o: error.c ruby.h config.h defines.h env.h
eval.o: eval.c ruby.h config.h defines.h env.h node.h sig.h st.h dln.h
file.o: file.c ruby.h config.h defines.h io.h sig.h
fnmatch.o: fnmatch.c config.h fnmatch.h
-gc.o: gc.c ruby.h config.h defines.h env.h st.h node.h re.h regex.h
+gc.o: gc.c ruby.h config.h defines.h env.h sig.h st.h node.h re.h regex.h
glob.o: glob.c config.h fnmatch.h
hash.o: hash.c ruby.h config.h defines.h st.h
inits.o: inits.c ruby.h config.h defines.h
io.o: io.c ruby.h config.h defines.h io.h sig.h
main.o: main.c
math.o: math.c ruby.h config.h defines.h
-numeric.o: numeric.c ruby.h config.h defines.h env.h
+numeric.o: numeric.c ruby.h config.h defines.h
object.o: object.c ruby.h config.h defines.h st.h
pack.o: pack.c ruby.h config.h defines.h
process.o: process.c ruby.h config.h defines.h sig.h st.h
@@ -190,7 +192,7 @@ signal.o: signal.c ruby.h config.h defines.h sig.h
sprintf.o: sprintf.c ruby.h config.h defines.h
st.o: st.c config.h st.h
string.o: string.c ruby.h config.h defines.h re.h regex.h
-struct.o: struct.c ruby.h config.h defines.h env.h
+struct.o: struct.c ruby.h config.h defines.h
time.o: time.c ruby.h config.h defines.h
util.o: util.c defines.h config.h util.h
variable.o: variable.c ruby.h config.h defines.h env.h st.h
diff --git a/README b/README
index ad239f98d2..debf3e4b1c 100644
--- a/README
+++ b/README
@@ -1,151 +1,115 @@
-* Ruby¤È¤Ï
+* What's Ruby
-Ruby¤Ï¥·¥ó¥×¥ë¤«¤Ä¶¯ÎϤʥª¥Ö¥¸¥§¥¯¥È»Ø¸þ¥¹¥¯¥ê¥×¥È¸À¸ì¤Ç¤¹¡¥
-Ruby¤ÏºÇ½é¤«¤é½ã¿è¤Ê¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¸À¸ì¤È¤·¤ÆÀ߷פµ¤ì¤Æ¤¤¤Þ
-¤¹¤«¤é¡¤¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¥×¥í¥°¥é¥ß¥ó¥°¤ò¼ê·Ú¤Ë¹Ô¤¦»ö¤¬½ÐÍè¤Þ
-¤¹¡¥¤â¤Á¤í¤óÄ̾ï¤Î¼ê³¤­·¿¤Î¥×¥í¥°¥é¥ß¥ó¥°¤â²Äǽ¤Ç¤¹¡¥
+Ruby is the interpreted scripting language for quick and
+easy object-oriented programming. It has many features to
+process text files and to do system management tasks (as in
+perl). It is simple, straight-forward, and extensible.
-Ruby¤Ï¥Æ¥­¥¹¥È½èÍý´Ø·¸¤ÎǽÎϤʤɤËÍ¥¤ì¡¤perl¤ÈƱ¤¸¤¯¤é¤¤¶¯ÎÏ
-¤Ç¤¹¡¥¤µ¤é¤Ë¥·¥ó¥×¥ë¤Êʸˡ¤È¡¤Îã³°½èÍý¤ä¥¤¥Æ¥ì¡¼¥¿¤Ê¤É¤Îµ¡¹½
-¤Ë¤è¤Ã¤Æ¡¤¤è¤êʬ¤«¤ê¤ä¤¹¤¤¥×¥í¥°¥é¥ß¥ó¥°¤¬½ÐÍè¤Þ¤¹¡¥
+* Features of ruby
-* Ruby¤ÎÆÃĹ¡¥
+ + Simple Syntax
+ + *Normal* Object-Oriented features(ex. class, method calls)
+ + *Advanced* Object-Oriented features(ex. Mix-in, Singleton-method)
+ + Operator Overloading
+ + Exception Handling
+ + Iterators and Closures
+ + Garbage Collection
+ + Dynamic Loading of Object files(on some architecture)
+ + Highly Portable(works on many UNIX machines)
- + ¥·¥ó¥×¥ë¤Êʸˡ
- + ÉáÄ̤Υª¥Ö¥¸¥§¥¯¥È»Ø¸þµ¡Ç½(¥¯¥é¥¹¡¤¥á¥½¥Ã¥É¥³¡¼¥ë¤Ê¤É)
- + ÆÃ¼ì¤Ê¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þµ¡Ç½(Mixin, ÆÃ°Û¥á¥½¥Ã¥É¤Ê¤É)
- + ±é»»»Ò¥ª¡¼¥Ð¡¼¥í¡¼¥É
- + Îã³°½èÍýµ¡Ç½
- + ¥¤¥Æ¥ì¡¼¥¿¤È¥¯¥í¡¼¥¸¥ã
- + ¥¬¡¼¥Ù¡¼¥¸¥³¥ì¥¯¥¿
- + ¥À¥¤¥Ê¥ß¥Ã¥¯¥í¡¼¥Ç¥£¥ó¥° (¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ë¤è¤ë)
- + °Ü¿¢À­¤¬¹â¤¤¡¥Â¿¤¯¤ÎUNIX¾å¤Çư¤¯
+* How to get ruby
-* Æþ¼êË¡
+** by ftp
-** ftp¤Ç
+The ruby distribution can be found on
-°Ê²¼¤Î¾ì½ê¤Ë¤ª¤¤¤Æ¤¢¤ê¤Þ¤¹¡¥
+ ftp://ftp.caelum.co.jp/pub/lang/ruby/
- ftp://ftp.kk.info.kanagawa-u.ac.jp/pub/languages/ruby/
+** by mail
-** ¥á¥¤¥ë¤Ç
-
-°Ê²¼¤Î¥¢¥É¥ì¥¹¤Ë`send'¤È¤¤¤¦Subject¤Î¥á¥¤¥ë¤òÁ÷¤Ã¤Æ²¼¤µ¤¤¡¥
+Send the mail which subject is 'send' to the address below.
ruby-archive@caelum.co.jp
-ËÜʸ¤Ë¤Ï²¿¤ò½ñ¤¤¤Æ¤â¹½¤¤¤Þ¤»¤ó¡¥ÀÞ¤êÊÖ¤·¡¤ºÇ¿·ÈǤÎruby¤¬Á÷¤Ã
-¤ÆÍè¤Þ¤¹¡¥
-
-* ¥á¥¤¥ê¥ó¥°¥ê¥¹¥È
-
- Ruby¤Ë´Ø¤ï¤ëÏÃÂê¤Î¤¿¤á¤Î¥á¥¤¥ê¥ó¥°¥ê¥¹¥È¤ò²òÀ⤷¤Þ¤·¤¿¡¥¥¢
- ¥É¥ì¥¹¤Ï
-
- ruby-list@caelum.co.jp
-
- ¤Ç¤¹¡¥¤³¤Î¥¢¥É¥ì¥¹¤Ë¥á¥¤¥ë¤òÁ÷¤ì¤Ð¡¤¼«Æ°Åª¤ËÅÐÏ¿¤µ¤ì¤Þ¤¹¡¥
-
-* ¥³¥ó¥Ñ¥¤¥ë¡¦¥¤¥ó¥¹¥È¡¼¥ë
-
-°Ê²¼¤Î¼ê½ç¤Ç¹Ô¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
-
- 1. configure¤ò¼Â¹Ô¤·¤ÆMakefile¤Ê¤É¤òÀ¸À®¤¹¤ë
-
- 2. (ɬÍפʤé¤Ð)defines.h¤òÊÔ½¸¤¹¤ë
-
- ¿ʬ¡¤É¬Í×̵¤¤¤È»×¤¤¤Þ¤¹¡¥
-
- 3. (ɬÍפʤé¤Ð)ext/Setup¤ËÀÅŪ¤Ë¥ê¥ó¥¯¤¹¤ë³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ò
- »ØÄꤹ¤ë
+You will receive the uuencoded gzipped tar file of the newest ruby
+distribution.
- ext/Setup¤Ëµ­½Ò¤·¤¿¥â¥¸¥å¡¼¥ë¤ÏÀÅŪ¤Ë¥ê¥ó¥¯¤µ¤ì¤Þ¤¹¡¥
+* How to compile and install
- ¥À¥¤¥Ê¥ß¥Ã¥¯¥í¡¼¥Ç¥£¥ó¥°¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¥¢¡¼¥­¥Æ¥¯
- ¥Á¥ã¤Ç¤ÏSetup¤Î1¹ÔÌܤΡÖoption nodynamic¡×¤È¤¤¤¦¹Ô¤Î¥³
- ¥á¥ó¥È¤ò³°¤¹É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥¤Þ¤¿¡¤¤³¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ç
- ³ÈÄ¥¥â¥¸¥å¡¼¥ë¤òÍøÍѤ¹¤ë¤¿¤á¤Ë¤Ï¡¤¤¢¤é¤«¤¸¤áÀÅŪ¤Ë¥ê¥ó
- ¥¯¤·¤Æ¤ª¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥
+This is what you need to do to compile and install ruby:
- 4. make¤ò¼Â¹Ô¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¤¹¤ë
+ 1. Run ./configure, which will generate config.h and Makefile.
- 5. make test¤Ç¥Æ¥¹¥È¤ò¹Ô¤¦¡¥
+ 2. Edit defines.h if you need. Probably this step will not need.
- ¡Ötest succeeded¡×¤Èɽ¼¨¤µ¤ì¤ì¤ÐÀ®¸ù¤Ç¤¹¡¥
+ 3. Remove comment mark(#) before the module names from ext/Setup, if
+ you want to link modules statically.
- 6. make install
+ If you want to link all the extension modules, remove comment
+ mark from the line "#option nodynamic".
-¤â¤·¡¤¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤¿¾ì¹ç¤Ë¤Ï¥¨¥é¡¼¤Î¥í¥°¤È¥Þ
-¥·¥ó¡¤OS¤Î¼ïÎà¤ò´Þ¤à¤Ç¤­¤ë¤À¤±¾Ü¤·¤¤¥ì¥Ý¡¼¥È¤òºî¼Ô¤ËÁ÷¤Ã¤Æ¤¯
-¤À¤µ¤ë¤È¾¤ÎÊý¤Î¤¿¤á¤Ë¤â¤Ê¤ê¤Þ¤¹¡¥
+ 4. Run make.
-* °Ü¿¢
+ 5. Optionally, run 'make test' to check that the compiled ruby
+ interpreter works well. If you see the message "test succeeded",
+ your ruby works as it should.
-UNIX¤Ç¤¢¤ì¤Ðconfigure¤¬¤Û¤È¤ó¤É¤Îº¹°Û¤òµÛ¼ý¤·¤Æ¤¯¤ì¤ë¤Ï¤º¤Ç
-¤¹¤¬¡¤»×¤ï¤Ì¸«Íî¤È¤·¤¬¤¢¤Ã¤¿¾ì¹ç(¤¢¤ë¤Ë°ã¤¤¤Ê¤¤)¡¤ºî¼Ô¤Ë¤½¤Î
-¤³¤È¤ò¥ì¥Ý¡¼¥È¤¹¤ì¤Ð¡¤²ò·è¤Ç¤­¤ë¤«¤âÃΤì¤Þ¤»¤ó¡¥
+ 6. Run 'make install'
-¥¢¡¼¥¯¥Æ¥¯¥Á¥ã¤Ë¤â¤Ã¤È¤â°Í¸¤¹¤ë¤Î¤ÏGCÉô¤Ç¤¹¡¥ruby¤ÎGC¤ÏÂоÝ
-¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤¬setjmp()¤Ë¤è¤Ã¤Æ¡¤Á´¤Æ¤Î¥ì¥¸¥¹¥¿¤ò jmp_buf
-¤Ë³ÊǼ¤¹¤ë¤³¤È¤È¡¤jmp_buf¤È¥¹¥¿¥Ã¥¯¤¬32bit¥¢¥é¥¤¥ó¥á¥ó¥È¤µ¤ì
-¤Æ¤¤¤ë¤³¤È¤ò²¾Äꤷ¤Æ¤¤¤Þ¤¹¡¥Á°¼Ô¤¬À®Î©¤·¤Ê¤¤¾ì¹ç¤ÎÂбþ¤Ïº¤Æñ
-¤ò¶Ë¤á¤ë¤Ç¤·¤ç¤¦¡¥¸å¼Ô¤Î²ò·è¤ÏÈæ³ÓŪ´Êñ¤Ç¡¤gc.c¤Ç¥¹¥¿¥Ã¥¯¤ò
-¥Þ¡¼¥¯¤·¤Æ¤¤¤ëÉôʬ¤Ë¥¢¥é¥¤¥ó¥á¥ó¥È¤Î¥Ð¥¤¥È¿ô¤À¤±¤º¤é¤·¤Æ¥Þ¡¼
-¥¯¤¹¤ë¥³¡¼¥É¤òÄɲ乤ë¤À¤±¤ÇºÑ¤ß¤Þ¤¹¡¥¡Ödefined(THINK_C)¡×¤Ç
-³ç¤é¤ì¤Æ¤¤¤ëÉôʬ¤ò»²¹Í¤Ë¤·¤Æ¤¯¤À¤µ¤¤
+If you fail to compile ruby, please send the detailed error report with
+the error log and machine/OS type, to help others.
-# ¼ÂºÝ¤Ë¤Ïruby¤ÏThink C¤Ç¥³¥ó¥Ñ¥¤¥ë¤Ç¤­¤Þ¤»¤ó¡¥
+* Copying
-sparc°Ê³°¤Î¥ì¥¸¥¹¥¿¥¦¥£¥ó¥É¥¦¤ò»ý¤ÄCPU¤Ç¤Ï¡¤¥ì¥¸¥¹¥¿¥¦¥£¥ó¥É
-¥¦¤ò¥Õ¥é¥Ã¥·¥å¤¹¤ë¥³¡¼¥É¤òÄɲ乤ëɬÍפ¬¤¢¤ë¤«¤âÃΤì¤Þ¤»¤ó¡¥
+Ruby is copyrighted by Yukihiro Matsumoto <matz@caelum.co.jp>.
-* ÇÛÉÛ¾ò·ï
+This source is distributed under the conditions blow:
-Ruby¤ÎÇÛÉۤ˴ؤ·¤ÆÃøºî¸¢ÊÝ»ý¼Ô¤Ç¤¢¤ëºî¼Ô<matz@caelum.co.jp>
-¤Ï°Ê²¼¤Î¾ò·ï¤ò¤Ä¤±¤Þ¤¹¡¥
+ 1. You may make and give away verbatim copies of the source form of
+ the software without restriction, provided that you do not modify
+ the original distribution file.
- + ¹¹¿·
+ If you want to distribute the modified version in any way, contact
+ the author.
- ¤¤¤«¤Ê¤ëÌÜŪ¤Ç¤¢¤ì¼«Í³¤Ç¤¹¡¥¤¿¤À¤·¡¤µ¡Ç½³ÈÄ¥¤ä¥Ð¥°½¤Àµ¤Ï
- ºî¼Ô¤Ø¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¤ò´üÂÔ¤·¤Þ¤¹(¤â¤Á¤í¤ó¶¯À©¤Ç¤Ï¤¢¤ê
- ¤Þ¤»¤ó)¡¥
+ 2. You may distribute the software in object code or executable
+ form, provided that you distribute it with instructions on where
+ to get the software.
- + ¾¤Î¥×¥í¥°¥é¥à¤Ø¤Î°úÍÑ
+ 3. You may modify the software in any way, provided that you do not
+ distribute the modified version.
- ¤¤¤«¤Ê¤ëÌÜŪ¤Ç¤¢¤ì¼«Í³¤Ç¤¹¡¥¤¿¤À¤·¡¤ruby¤Ë´Þ¤Þ¤ì¤ë¾¤Îºî
- ¼Ô¤Ë¤è¤ë¥³¡¼¥É¤Ï¡¤¤½¤ì¤¾¤ì¤Îºî¼Ô¤Î°Õ¸þ¤Ë¤è¤ëÀ©¸Â¤¬²Ã¤¨¤é
- ¤ì¤Þ¤¹¡¥¶ñÂÎŪ¤Ë¤Ïgc.c(°ìÉô)¡¤regex.[ch]¡¤fnmatch.[ch]¡¤
- glob.c, st.[ch]¤Èmissing¥Ç¥£¥ì¥¯¥È¥ê²¼¤Î¥Õ¥¡¥¤¥ë·²¤¬³ºÅö
- ¤·¤Þ¤¹¡¥
+ 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)¡¤regex.[ch]¡¤fnmatch.[ch]¡¤
+ glob.c, st.[ch] and somme files under ./missing directory. See
+ each files for the condition.
- + ºÆÇÛÉÛ
+ 5. The scripts and library files supplied as input to or produced as
+ output from the software do not automatically fall under the
+ copyright of the software, but belong to whomever generated them,
+ and may be sold commercially, and may be aggregated with this
+ software.
- ÇÛÉÛ¤·¤¿¾õÂÖ¤ò°Ý»ý¤¹¤ë¸Â¤ê¼«Í³¤Ç¤¹¡¥Êѹ¹¤ò¹Ô¤Ã¤¿¤â¤Î¤òºÆ
- ÇÛÉÛ¤¹¤ë¤³¤È¤ò´õ˾¤¹¤ë»þ¤Ë¤Ïºî¼Ô¤ËÏ¢Íí¤·¤Æ¤¯¤À¤µ¤¤¡¥¥ª¥ê
- ¥¸¥Ê¥ë¤Îruby¤ÈÌÀ³Î¤Ë¶èÊ̤Ǥ­¤ë¤è¤¦¤Ç¤¢¤ì¤Ð¡¤ºÆÇÛÉÛ¤òǧ¤á
- ¤ëÊý¿Ë¤Ç¤¹¡¥
+ 6. THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
+ IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
+ WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR
+ PURPOSE.
- Êѹ¹¤ò¹Ô¤Ê¤ï¤Ê¤¤ruby¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤¿¥Ð¥¤¥Ê¥ê¤ÎÇÛÉۤ϶ػß
- ¤·¤Þ¤»¤ó¤¬¡¤¥³¥ó¥Ñ¥¤¥ë¾ò·ï¤Ëµ¯°ø¤¹¤ë¥È¥é¥Ö¥ë¤ò¸º¤é¤¹¤¿¤á
- ¤Ë¡¤¥³¥ó¥Ñ¥¤¥ë»þ¤Î¾ðÊó¤ò¤Ç¤­¤ë¤À¤±¾Ü¤·¤¯ÌÀµ­¤¹¤ë»ö¤ò´õ˾
- ¤·¤Þ¤¹¡¥
+* ruby home-page
- + Ruby¥¹¥¯¥ê¥×¥È¤Î¸¢Íø
+ The URL of the ruby home-page is:
- Á´¤Æ¤Îruby¥¹¥¯¥ê¥×¥È¤Î¸¢Íø¤Ï¤½¤ì¤¾¤ì¤ÎÃøºî¼Ô¤Ë°¤·¤Þ¤¹¡¥
- ºî¼Ô¤Ï¤³¤ì¤é¤Ë´Ø¤·¤Æ°ìÀڤθ¢Íø¤ò¼çÄ¥¤·¤Þ¤»¤ó¡¥¤Þ¤¿ruby¤Ë
- ÁȤ߹þ¤à¤¿¤á¤Î³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë´Ø¤·¤Æ¤âƱÍͤǤ¹¡¥
+ http://www.caelum.co.jp/~matz/ruby/index-en.html
- + ̵ÊݾÚ
+* The Author
- Ruby¤Ï̵ÊݾڤǤ¹¡¥ºî¼Ô¤Ïruby¤ò¥µ¥Ý¡¼¥È¤¹¤ë°Õ»Ö¤Ï¤¢¤ê¤Þ¤¹
- ¤¬¡¤ruby¼«¿È¤Î¥Ð¥°¤¢¤ë¤¤¤Ïruby¥¹¥¯¥ê¥×¥È¤Î¥Ð¥°¤Ê¤É¤«¤éȯ
- À¸¤¹¤ë¤¤¤«¤Ê¤ë»³²¤ËÂФ·¤Æ¤âÀÕǤ¤ò»ý¤Á¤Þ¤»¤ó¡¥
+Feel free to send comments and bug reports to the author. Here is the
+author's latest mail address:
-* Ãø¼Ô
+ matz@ruby.club.or.jp
-¥³¥á¥ó¥È¡¤¥Ð¥°¥ì¥Ý¡¼¥È¤½¤Î¾¤Ï matz@caelum.co.jp ¤Þ¤Ç¡¥
-------------------------------------------------------
created at: Thu Aug 3 11:57:36 JST 1995
Local variables:
diff --git a/README.EXT b/README.EXT
index efa627a24a..fdf8c96af7 100644
--- a/README.EXT
+++ b/README.EXT
@@ -1,308 +1,1029 @@
.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995
-Ruby¤ò³ÈÄ¥¤¹¤ë¤¿¤á¤ÎÊýË¡¤ò²òÀ⤹¤ë¡¥
+ruby¤Î³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Îºî¤êÊý¤òÀâÌÀ¤·¤Þ¤¹¡¥
+
+1¡¥´ðÁÃÃμ±
+
+C¤ÎÊÑ¿ô¤Ë¤Ï·¿¤¬¤¢¤ê¡¤¥Ç¡¼¥¿¤Ë¤Ï·¿¤¬¤¢¤ê¤Þ¤»¤ó¡¥¤Ç¤¹¤«¤é¡¤¤¿
+¤È¤¨¤Ð¥Ý¥¤¥ó¥¿¤òint¤ÎÊÑ¿ô¤ËÂåÆþ¤¹¤ë¤È¡¤¤½¤ÎÃͤÏÀ°¿ô¤È¤·¤Æ¼è
+¤ê°·¤ï¤ì¤Þ¤¹¡¥µÕ¤Ëruby¤ÎÊÑ¿ô¤Ë¤Ï·¿¤¬¤Ê¤¯¡¤¥Ç¡¼¥¿¤Ë·¿¤¬¤¢¤ê¤Þ
+¤¹¡¥¤³¤Î°ã¤¤¤Î¤¿¤á¡¤C¤Èruby¤ÏÁê¸ß¤ËÊÑ´¹¤·¤Ê¤±¤ì¤Ð¡¤¤ª¸ß¤¤¤Î
+¥Ç¡¼¥¿¤ò¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤»¤ó¡¥
+
+ruby¤Î¥Ç¡¼¥¿¤ÏVALUE¤È¤¤¤¦C¤Î·¿¤Çɽ¸½¤µ¤ì¤Þ¤¹¡¥VALUE·¿¤Î¥Ç¡¼
+¥¿¤Ï¤½¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤ò¼«Ê¬¤ÇÃΤäƤ¤¤Þ¤¹¡¥¤³¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤È
+¤¤¤¦¤Î¤Ï¥Ç¡¼¥¿(¥ª¥Ö¥¸¥§¥¯¥È)¤Î¼ÂºÝ¤Î¹½Â¤¤ò°ÕÌ£¤·¤Æ¤¤¤Æ¡¤ruby
+¤Î¥¯¥é¥¹¤È¤Ï¤Þ¤¿°ã¤Ã¤¿¤â¤Î¤Ç¤¹¡¥
+
+VALUE¤«¤éC¤Ë¤È¤Ã¤Æ°ÕÌ£¤Î¤¢¤ë¥Ç¡¼¥¿¤ò¼è¤ê½Ð¤¹¤¿¤á¤Ë¤Ï
+
+ (1) VALUE¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤òÃΤë
+ (2) VALUE¤òC¤Î¥Ç¡¼¥¿¤ËÊÑ´¹¤¹¤ë
+
+¤ÎξÊý¤¬É¬ÍפǤ¹¡¥(1)¤ò˺¤ì¤ë¤È´Ö°ã¤Ã¤¿¥Ç¡¼¥¿¤ÎÊÑ´¹¤¬¹Ô¤ï¤ì
+¤Æ¡¤ºÇ°­¥×¥í¥°¥é¥à¤¬core dump¤·¤Þ¤¹¡¥
+
+1.1 ¥Ç¡¼¥¿¥¿¥¤¥×
+
+ruby¤Ë¤Ï¥æ¡¼¥¶¤¬»È¤¦²ÄǽÀ­¤Î¤¢¤ë°Ê²¼¤Î¥¿¥¤¥×¤¬¤¢¤ê¤Þ¤¹¡¥
-Ruby¤ÏC¥³¡¼¥É¤ò½ñ¤¯¤³¤È¤Ë¤è¤Ã¤Æ¡¤´Êñ¤Ëµ¡Ç½¤òÄɲäǤ­¤ë¡¥¤ª¤ª¤Þ¤«¤Ê¼ê
-½ç¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
+ T_NIL nil
+ T_OBJECT Ä̾ï¤Î¥ª¥Ö¥¸¥§¥¯¥È
+ T_CLASS ¥¯¥é¥¹
+ T_MODULE ¥â¥¸¥å¡¼¥ë
+ T_FLOAT ÉâÆ°¾®¿ôÅÀ¿ô
+ T_STRING ʸ»úÎó
+ T_REGEXP Àµµ¬É½¸½
+ T_ARRAY ÇÛÎó
+ T_FIXNUM Fixnum(31bitĹÀ°¿ô)
+ T_HASH Ï¢ÁÛÇÛÎó
+ T_STRUCT (ruby¤Î)¹½Â¤ÂÎ
+ T_BIGNUM ¿ÇÜĹÀ°¿ô
+ T_TRUE ¿¿
+ T_FALSE µ¶
+ T_DATA ¥Ç¡¼¥¿
- 1. ¥Õ¥¡¥¤¥ë¤òÍѰդ¹¤ë
+¤½¤Î¾¤ËÆâÉô¤ÇÍøÍѤµ¤ì¤Æ¤¤¤ë°Ê²¼¤Î¥¿¥¤¥×¤¬¤¢¤ê¤Þ¤¹¡¥
- ext¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë³ÈÄ¥¥â¥¸¥å¡¼¥ëÍѤΥǥ£¥ì¥¯¥È¥ê¤òÍѰդ·¤Æ¡¤¤½
- ¤ÎÇÛ²¼¤Ë°Ê²¼¤Î¥Õ¥¡¥¤¥ë¤òÍѰդ¹¤ëɬÍפ¬¤¢¤ë¡¥
+ T_ICLASS
+ T_MATCH
+ T_VARMAP
+ T_SCOPE
+ T_NODE
- + MANIFEST¡¥É¬Íפʥե¡¥¤¥ë¤Î°ìÍ÷¡¥
+¤¤¤¯¤Ä¤«¤Î¥¿¥¤¥×¤ÏC¤Î¹½Â¤ÂΤǼÂÁõ¤µ¤ì¤Æ¤¤¤Þ¤¹¡¥
- ɬ¤ºÉ¬Íס¥°ì»þŪ¤Ê¥Õ¥¡¥¤¥ë°Ê³°¤ÎÁ´¤Æ¤Î¥Õ¥¡¥¤¥ë̾¤ò1¹Ô1¥Õ¥¡¥¤¥ë
- ¤Î·Á¼°¤Çµ­½Ò¤¹¤ë¤³¤È¡¥
+1.2 VALUE¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤ò¥Á¥§¥Ã¥¯¤¹¤ë
- + C¤Î¥½¡¼¥¹¥Õ¥¡¥¤¥ë¡¥
+ruby.h¤Ç¤ÏTYPE()¤È¤¤¤¦¥Þ¥¯¥í¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Æ¡¤VALUE¤Î¥Ç¡¼¥¿
+¥¿¥¤¥×¤òÃΤ뤳¤È¤¬½ÐÍè¤Þ¤¹¡¥TYPE()¥Þ¥¯¥í¤Ï¾å¤Ç¾Ò²ð¤·¤¿T_XXXX
+¤Î·Á¼°¤ÎÄê¿ô¤òÊÖ¤·¤Þ¤¹¡¥VALUE¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤Ë±þ¤¸¤Æ½èÍý¤¹¤ë
+¾ì¹ç¤Ë¤Ï¡¤TYPE()¤ÎÃͤÇʬ´ô¤¹¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡¥
- ¥â¥¸¥å¡¼¥ë¤¬1¥Õ¥¡¥¤¥ë¤À¤±¤«¤é¤Ê¤ë»þ¤Ï¥â¥¸¥å¡¼¥ë̾¤ÈƱ¤¸Ì¾Á°¤Î¥Õ¥¡
- ¥¤¥ë̾(¥â¥¸¥å¡¼¥ë.c)¤ò¤Ä¤±¤ë¡¥µÕ¤Ë¥â¥¸¥å¡¼¥ë¤¬Ê£¿ô¤«¤é¤Ê¤ë»þ¤Ï
- ¥â¥¸¥å¡¼¥ë̾¤Î¤Ä¤¤¤¿¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤ÏÈò¤±¤ë¤³¤È¡¥
+ switch (TYPE(obj)) {
+ case T_FIXNUM:
+ /* FIXNUM¤Î½èÍý */
+ break;
+ case T_STRING:
+ /* ʸ»úÎó¤Î½èÍý */
+ break;
+ case T_ARRAY:
+ /* ÇÛÎó¤Î½èÍý */
+ break;
+ default:
+ /* Îã³°¤òȯÀ¸¤µ¤»¤ë */
+ Fail("not valid value");
+ break;
+ }
- + extconf.rb(optional)¡¥ÀßÄêÍÑ¥Õ¥¡¥¤¥ë¡¥
+¤½¤ì¤È¥Ç¡¼¥¿¥¿¥¤¥×¤ò¥Á¥§¥Ã¥¯¤·¤Æ¡¤Àµ¤·¤¯¤Ê¤±¤ì¤ÐÎã³°¤òȯÀ¸¤¹
+¤ë´Ø¿ô¤¬ÍѰդµ¤ì¤Æ¤¤¤Þ¤¹¡¥
- ´Ø¿ô¤ä¥é¥¤¥Ö¥é¥ê¡¤¥Ø¥Ã¥À¤Î¸ºß¥Á¥§¥Ã¥¯¤ò¤·¤¿¤ê¡¤¥â¥¸¥å¡¼¥ë̾¤Ê
- ¤É¤òÀßÄꤹ¤ë¡¥¤³¤Î¥Õ¥¡¥¤¥ë¤¬Ìµ¤±¤ì¤ÐÁ´¤Æ¥Ç¥Õ¥©¥ë¥È¤Ç¥³¥ó¥Ñ¥¤¥ë
- ¤µ¤ì¤ë¡¥
+ void Check_Type(VALUE value, int type)
- + depend(optional)¡¥Makefile¤Ë¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¤¿¤á¤Î¥Õ¥¡
- ¥¤¥ë¤Î°Í¸´Ø·¸¤òµ­½Ò¤·¤¿¥Õ¥¡¥¤¥ë¡¥
+¤³¤Î´Ø¿ô¤Ïvalue¤¬type¤Ç̵¤±¤ì¤Ð¡¤Îã³°¤òȯÀ¸¤µ¤»¤Þ¤¹¡¥°ú¿ô¤È
+¤·¤ÆÍ¿¤¨¤é¤ì¤¿VALUE¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤¬Àµ¤·¤¤¤«¤É¤¦¤«¥Á¥§¥Ã¥¯¤¹
+¤ë¤¿¤á¤Ë¤Ï¡¤¤³¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
- `gcc -MM *.c > depend'¤È¤¹¤ì¤Ð¼«Æ°Åª¤ËÀ¸À®¤Ç¤­¤ë¡¥
+1.3 VALUE¤òC¤Î¥Ç¡¼¥¿¤ËÊÑ´¹¤¹¤ë
- 2. C¤Î¥½¡¼¥¹¥Õ¥¡¥¤¥ë¤òÍѰդ¹¤ë
+¥Ç¡¼¥¿¥¿¥¤¥×¤¬T_NIL, T_FALSE, T_TRUE¤Ç¤¢¤ë»þ¡¤¥Ç¡¼¥¿¤Ï¤½¤ì¤¾
+¤ìnil, FALSE, TRUE¤Ç¤¹¡¥¤³¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ï¤Ò¤È
+¤Ä¤º¤Ä¤·¤«Â¸ºß¤·¤Þ¤»¤ó¡¥
- ɬ¤º¡ÖInit_¥â¥¸¥å¡¼¥ë̾¡×¤È¤¤¤¦´Ø¿ô¤òÍѰդ·¡¤¤½¤ÎÃæ¤Ç¡¤ÊÑ¿ô¤ä¥¯¥é
- ¥¹¤ÎÄêµÁ¤ä¡¤¥¯¥é¥¹¤Ø¤Î¥á¥½¥Ã¥É¤ÎÅÐÏ¿¤Ê¤É¤Î½é´ü²½¤ò¹Ô¤¦¤³¤È¡¥¤³¤Î
- ´Ø¿ô¤Î¸Æ¤Ó½Ð¤·¤Ï¥¤¥ó¥¿¥×¥ê¥¿¤Î½é´ü²½»þ(ÀÅŪ¥ê¥ó¥¯¤Î¾ì¹ç)¤«¥â¥¸¥å¡¼
- ¥ë¤Î¥í¡¼¥É»þ(ưŪ¥ê¥ó¥¯¤Î¾ì¹ç)¤Ë¼«Æ°Åª¤Ë¹Ô¤ï¤ì¤ë¡¥
+¥Ç¡¼¥¿¥¿¥¤¥×¤¬T_FIXNUM¤Î»þ¡¤¤³¤ì¤Ï31bit¤Î¥µ¥¤¥º¤ò»ý¤ÄÀ°¿ô¤Ç
+¤¹¡¥FIXNUM¤òC¤ÎÀ°¿ô¤ËÊÑ´¹¤¹¤ë¤¿¤á¤Ë¤Ï¥Þ¥¯¥í¡ÖFIX2INT()¡×¤ò»È
+¤¤¤Þ¤¹¡¥¤½¤ì¤«¤é¡¤FIXNUM¤Ë¸Â¤é¤ºruby¤Î¥Ç¡¼¥¿¤òÀ°¿ô¤ËÊÑ´¹¤¹¤ë
+¡ÖNUM2INT()¡×¤È¤¤¤¦¥Þ¥¯¥í¤¬¤¢¤ê¤Þ¤¹¡¥¤³¤Î¥Þ¥¯¥í¤Ï¥Ç¡¼¥¿¥¿¥¤
+¥×¤Î¥Á¥§¥Ã¥¯Ìµ¤·¤Ç»È¤¨¤Þ¤¹(À°¿ô¤ËÊÑ´¹¤Ç¤­¤Ê¤¤¾ì¹ç¤Ë¤ÏÎã³°¤¬
+ȯÀ¸¤¹¤ë)¡¥
-* Ruby API
+¤½¤ì°Ê³°¤Î¥Ç¡¼¥¿¥¿¥¤¥×¤ÏÂбþ¤¹¤ëC¤Î¹½Â¤ÂΤ¬¤¢¤ê¤Þ¤¹¡¥Âбþ¤¹
+¤ë¹½Â¤ÂΤΤ¢¤ëVALUE¤Ï¤½¤Î¤Þ¤Þ¥­¥ã¥¹¥È(·¿ÊÑ´¹)¤¹¤ì¤Ð¹½Â¤ÂΤÎ
+¥Ý¥¤¥ó¥¿¤ËÊÑ´¹¤Ç¤­¤Þ¤¹¡¥
-C¸À¸ì¤«¤éRuby¤Îµ¡Ç½¤òÍøÍѤ¹¤ëAPI¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
+¹½Â¤ÂΤϡÖstruct RXxxxx¡×¤È¤¤¤¦Ì¾Á°¤Çruby.h¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤Þ
+¤¹¡¥Î㤨¤Ðʸ»úÎó¤Ï¡Östruct RString¡×¤Ç¤¹¡¥¼ÂºÝ¤Ë»È¤¦²ÄǽÀ­¤¬
+¤¢¤ë¤Î¤Ïʸ»úÎó¤ÈÇÛÎ󤯤餤¤À¤È»×¤¤¤Þ¤¹¡¥
+
+ruby.h¤Ç¤Ï¹½Â¤ÂΤإ­¥ã¥¹¥È¤¹¤ë¥Þ¥¯¥í¤â¡ÖRXXXXX()¡×(Á´ÉôÂçʸ
+»ú¤Ë¤·¤¿¤â¤Î)¤È¤¤¤¦Ì¾Á°¤ÇÄ󶡤µ¤ì¤Æ¤¤¤Þ¤¹(Îã: RSTRING())¡¥
+
+Î㤨¤Ð¡¤Ê¸»úÎóstr¤ÎŤµ¤òÆÀ¤ë¤¿¤á¤Ë¤Ï¡ÖRSTRING(str)->len¡×¤È
+¤·¡¤Ê¸»úÎóstr¤òchar*¤È¤·¤ÆÆÀ¤ë¤¿¤á¤Ë¤Ï¡ÖRSTRING(str)->ptr¡×
+¤È¤·¤Þ¤¹¡¥ÇÛÎó¤Î¾ì¹ç¤Ë¤Ï¡¤¤½¤ì¤¾¤ì¡ÖRARRAT(str)->len¡×¡¤
+¡ÖRARRAT(str)->ptr¡×¤È¤Ê¤ê¤Þ¤¹¡¥
+
+ruby¤Î¹½Â¤ÂΤòľÀÜ¥¢¥¯¥»¥¹¤¹¤ë»þ¤Ëµ¤¤ò¤Ä¤±¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¤³
+¤È¤Ï¡¤ÇÛÎó¤äʸ»úÎó¤Î¹½Â¤ÂΤÎÃæ¿È¤Ï»²¾È¤¹¤ë¤À¤±¤Ç¡¤Ä¾ÀÜÊѹ¹¤·
+¤Ê¤¤¤³¤È¤Ç¤¹¡¥Ä¾ÀÜÊѹ¹¤·¤¿¾ì¹ç¡¤¥ª¥Ö¥¸¥§¥¯¥È¤ÎÆâÍÆ¤ÎÀ°¹çÀ­¤¬
+¤È¤ì¤Ê¤¯¤Ê¤Ã¤Æ¡¤»×¤ï¤Ì¥Ð¥°¤Î¸¶°ø¤Ë¤Ê¤ê¤Þ¤¹¡¥
+
+1.4 C¤Î¥Ç¡¼¥¿¤òVALUE¤ËÊÑ´¹¤¹¤ë
+
+VALUE¤Î¼ÂºÝ¤Î¹½Â¤¤Ï
+
+ * FIXNUM¤Î¾ì¹ç
+
+ 1bit±¦¥·¥Õ¥È¤·¤Æ¡¤LSB¤òΩ¤Æ¤ë¡¥
+
+ * ¤½¤Î¾¤Î¥Ý¥¤¥ó¥¿¤Î¾ì¹ç
+
+ ¤½¤Î¤Þ¤ÞVALUE¤Ë¥­¥ã¥¹¥È¤¹¤ë¡¥
+
+¤È¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥¤è¤Ã¤Æ¡¤LSB¤ò¥Á¥§¥Ã¥¯¤¹¤ì¤ÐVALUE¤¬FIXNUM¤«¤É
+¤¦¤«¤ï¤«¤ë¤ï¤±¤Ç¤¹(¥Ý¥¤¥ó¥¿¤ÎLSB¤¬Î©¤Ã¤Æ¤¤¤Ê¤¤¤³¤È¤ò²¾Äꤷ¤Æ
+¤¤¤ë)¡¥
+
+¤Ç¤¹¤«¤é¡¤FIXNUM°Ê³°¤Îruby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Î¹½Â¤ÂΤÏñ¤ËVALUE
+¤Ë¥­¥ã¥¹¥È¤¹¤ë¤À¤±¤ÇVALUE¤ËÊÑ´¹½ÐÍè¤Þ¤¹¡¥¤¿¤À¤·¡¤Ç¤°Õ¤Î¹½Â¤
+ÂΤ¬VALUE¤Ë¥­¥ã¥¹¥È½ÐÍè¤ë¤ï¤±¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡¥¥­¥ã¥¹¥È¤¹¤ë¤Î
+¤Ïruby¤ÎÃΤäƤ¤¤ë¹½Â¤ÂÎ(ruby.h¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ëstruct RXxxx
+¤Î¤â¤Î)¤À¤±¤Ë¤·¤Æ¤ª¤¤¤Æ¤¯¤À¤µ¤¤¡¥
+
+FIXNUM¤Ë´Ø¤·¤Æ¤ÏÊÑ´¹¥Þ¥¯¥í¤ò·Ðͳ¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥C¤ÎÀ°¿ô
+¤«¤éVALUE¤ËÊÑ´¹¤¹¤ë¥Þ¥¯¥í¤Ï°Ê²¼¤Î¤â¤Î¤¬¤¢¤ê¤Þ¤¹¡¥É¬Íפ˱þ¤¸
+¤Æ»È¤¤Ê¬¤±¤Æ¤¯¤À¤µ¤¤¡¥
+
+ INT2FIX() ¤â¤È¤ÎÀ°¿ô¤¬31bit°ÊÆâ¤Ë¼ý¤Þ¤ë»þ
+ INT2NUM() Ǥ°Õ¤ÎÀ°¿ô¤«¤éVALUE¤Ø
+
+INT2NUM()¤ÏÀ°¿ô¤¬FIXNUM¤ÎÈϰϤ˼ý¤Þ¤é¤Ê¤¤¾ì¹ç¡¤Bignum¤ËÊÑ´¹
+¤·¤Æ¤¯¤ì¤Þ¤¹(¤¬¡¤¾¯¤·ÃÙ¤¤)¡¥
+
+1.5 ruby¤Î¥Ç¡¼¥¿¤òÁàºî¤¹¤ë
+
+ÀèÄø¤â½Ò¤Ù¤¿Ä̤ꡤruby¤Î¹½Â¤ÂΤò¥¢¥¯¥»¥¹¤¹¤ë»þ¤ËÆâÍÆ¤Î¹¹¿·¤ò
+¹Ô¤¦¤³¤È¤Ï´«¤á¤é¤ì¤Þ¤»¤ó¡¥¤Ç¡¤ruby¤Î¥Ç¡¼¥¿¤òÁàºî¤¹¤ë»þ¤Ë¤Ï
+ruby¤¬ÍѰդ·¤Æ¤¤¤ë´Ø¿ô¤òÍѤ¤¤Æ¤¯¤À¤µ¤¤¡¥
+
+¤³¤³¤Ç¤Ï¤â¤Ã¤È¤â»È¤ï¤ì¤ë¤Ç¤¢¤í¤¦Ê¸»úÎó¤ÈÇÛÎó¤ÎÀ¸À®/Áàºî¤ò¹Ô
+¤¤´Ø¿ô¤ò¤¢¤²¤Þ¤¹(Á´Éô¤Ç¤Ï¤Ê¤¤¤Ç¤¹)¡¥
+
+ ʸ»úÎó¤ËÂФ¹¤ë´Ø¿ô
+
+ str_new(char *ptr, int len)
+
+ ¿·¤·¤¤ruby¤Îʸ»úÎó¤òÀ¸À®¤¹¤ë¡¥
+
+ str_new2(char *ptr)
+
+ C¤Îʸ»úÎ󤫤éruby¤Îʸ»úÎó¤òÀ¸À®¤¹¤ë¡¥¤³¤Î´Ø¿ô¤Îµ¡Ç½¤Ï
+ str_new(ptr, strlen(ptr))¤ÈƱÅù¤Ç¤¢¤ë¡¥
+
+ str_cat(VALUE str, char *ptr, int len)
+
+ ruby¤Îʸ»úÎóstr¤Ëlen¥Ð¥¤¥È¤Îʸ»úÎóptr¤òÄɲ乤롥
+
+ ÇÛÎó¤ËÂФ¹¤ë´Ø¿ô
+
+ ary_new()
+
+ Í×ÁǤ¬0¤ÎÇÛÎó¤òÀ¸À®¤¹¤ë¡¥
+
+ ary_new2(int len)
+
+ Í×ÁǤ¬0¤ÎÇÛÎó¤òÀ¸À®¤¹¤ë¡¥lenÍ×ÁÇʬ¤ÎÎΰè¤ò¤¢¤é¤«¤¸¤á³ä¤ê
+ Åö¤Æ¤Æ¤ª¤¯¡¥
+
+ ary_new3(int n, ...)
+
+ °ú¿ô¤Ç»ØÄꤷ¤¿nÍ×ÁǤò´Þ¤àÇÛÎó¤òÀ¸À®¤¹¤ë¡¥
+
+ ary_new4(int n, VALUE elts[])
+
+ ÇÛÎó¤ÇÍ¿¤¨¤¿nÍ×ÁǤÎÇÛÎó¤òÀ¸À®¤¹¤ë¡¥
+
+ ary_push(VALUE ary)
+ ary_pop(VALUE ary, VALUE val)
+ ary_shift(VALUE ary)
+ ary_unshift(VALUE ary, VALUE val)
+ ary_entry(VALUE ary, int idx)
+
+ Array¤ÎƱ̾¤Î¥á¥½¥Ã¥É¤ÈƱ¤¸Æ¯¤­¤ò¤¹¤ë´Ø¿ô¡¥Âè1°ú¿ô¤Ïɬ¤º
+ ÇÛÎó¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¥
+
+2¡¥ruby¤Îµ¡Ç½¤ò»È¤¦
+
+¸¶ÍýŪ¤Ëruby¤Ç½ñ¤±¤ë¤³¤È¤ÏC¤Ç¤â½ñ¤±¤Þ¤¹¡¥ruby¤½¤Î¤â¤Î¤¬C¤Çµ­
+½Ò¤µ¤ì¤Æ¤¤¤ë¤ó¤Ç¤¹¤«¤é¡¤ÅöÁ³¤È¤¤¤¨¤ÐÅöÁ³¤Ê¤ó¤Ç¤¹¤±¤É¡¥¤³¤³¤Ç
+¤Ïruby¤Î³ÈÄ¥¤Ë»È¤¦¤³¤È¤¬Â¿¤¤¤À¤í¤¦¤Èͽ¬¤µ¤ì¤ëµ¡Ç½¤òÃæ¿´¤Ë¾Ò
+²ð¤·¤Þ¤¹¡¥
+
+2.1 ruby¤Ëµ¡Ç½¤òÄɲ乤ë
+
+ruby¤ÇÄ󶡤µ¤ì¤Æ¤¤¤ë´Ø¿ô¤ò»È¤¨¤Ðruby¥¤¥ó¥¿¥×¥ê¥¿¤Ë¿·¤·¤¤µ¡Ç½
+¤òÄɲ乤뤳¤È¤¬¤Ç¤­¤Þ¤¹¡¥ruby¤Ç¤Ï°Ê²¼¤Îµ¡Ç½¤òÄɲä¹¤ë´Ø¿ô¤¬
+Ä󶡤µ¤ì¤Æ¤¤¤Þ¤¹¡¥
+
+ * ¥¯¥é¥¹¡¤¥â¥¸¥å¡¼¥ë
+ * ¥á¥½¥Ã¥É¡¤ÆÃ°Û¥á¥½¥Ã¥É¤Ê¤É
+ * Äê¿ô
+
+¤Ç¤Ï½ç¤Ë¾Ò²ð¤·¤Þ¤¹¡¥
+
+2.1.1 ¥¯¥é¥¹/¥â¥¸¥å¡¼¥ëÄêµÁ
+
+¥¯¥é¥¹¤ä¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤¹¤ë¤¿¤á¤Ë¤Ï¡¤°Ê²¼¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
+
+ VALUE rb_define_class(char *name, VALUE super)
+ VALUE rb_define_module(char *name)
+
+¤³¤ì¤é¤Î´Ø¿ô¤Ï¿·¤·¤¯ÄêµÁ¤µ¤ì¤¿¥¯¥é¥¹¤ä¥â¥¸¥å¡¼¥ë¤òÊÖ¤·¤Þ¤¹¡¥
+¥á¥½¥Ã¥É¤äÄê¿ô¤ÎÄêµÁ¤Ë¤³¤ì¤é¤ÎÃͤ¬É¬ÍפʤΤǡ¤¤Û¤È¤ó¤É¤Î¾ì¹ç
+¤ÏÌá¤êÃͤòÊÑ¿ô¤Ë³ÊǼ¤·¤Æ¤ª¤¯É¬Íפ¬¤¢¤ë¤Ç¤·¤ç¤¦¡¥
+
+2.1.2 ¥á¥½¥Ã¥É/ÆÃ°Û¥á¥½¥Ã¥ÉÄêµÁ
+
+¥á¥½¥Ã¥É¤äÆÃ°Û¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¤Ë¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
+
+ void rb_define_method(VALUE class, char *name,
+ VALUE (*func)(), int argc)
+
+ void rb_define_sigleton_method(VALUE object, char *name,
+ VALUE (*func)(), int argc)
+
+
+ǰ¤Î¤¿¤áÀâÌÀ¤¹¤ë¤È¡ÖÆÃ°Û¥á¥½¥Ã¥É¡×¤È¤Ï¡¤¤½¤ÎÆÃÄê¤Î¥ª¥Ö¥¸¥§¥¯
+¥È¤ËÂФ·¤Æ¤À¤±Í­¸ú¤Ê¥á¥½¥Ã¥É¤Ç¤¹¡¥ruby¤Ç¤Ï¤è¤¯Smalltalk¤Ë¤ª
+¤±¤ë¥¯¥é¥¹¥á¥½¥Ã¥É¤È¤·¤Æ¡¤¥¯¥é¥¹¤ËÂФ¹¤ëÆÃ°Û¥á¥½¥Ã¥É¤¬»È¤ï¤ì
+¤Þ¤¹¡¥
+
+¤³¤ì¤é¤Î´Ø¿ô¤Î argc¤È¤¤¤¦°ú¿ô¤ÏC¤Î´Ø¿ô¤ØÅϤµ¤ì¤ë°ú¿ô¤Î¿ô(¤È
+·Á¼°)¤ò·è¤á¤Þ¤¹¡¥argc¤¬Àµ¤Î»þ¤Ï´Ø¿ô¤Ë°ú¤­ÅϤ¹°ú¿ô¤Î¿ô¤ò°ÕÌ£
+¤·¤Þ¤¹¡¥16¸Ä°Ê¾å¤Î°ú¿ô¤Ï»È¤¨¤Þ¤»¤ó(¤¬¡¤Íפê¤Þ¤»¤ó¤è¤Í¡¤¤½¤ó
+¤Ê¤Ë)¡¥
+
+argc¤¬Éé¤Î»þ¤Ï°ú¿ô¤Î¿ô¤Ç¤Ï¤Ê¤¯¡¤·Á¼°¤ò»ØÄꤷ¤¿¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡¥
+argc¤¬-1¤Î»þ¤Ï°ú¿ô¤òÇÛÎó¤ËÆþ¤ì¤ÆÅϤµ¤ì¤Þ¤¹¡¥argc¤¬-2¤Î»þ¤Ï°ú
+¿ô¤Ïruby¤ÎÇÛÎó¤È¤·¤ÆÅϤµ¤ì¤Þ¤¹¡¥
+
+¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë´Ø¿ô¤Ï¤â¤¦Æó¤Ä¤¢¤ê¤Þ¤¹¡¥¤Ò¤È¤Ä¤Ïprivate¥á
+¥½¥Ã¥É¤òÄêµÁ¤¹¤ë´Ø¿ô¤Ç¡¤°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¤Ç¤¹¡¥
+
+ void rb_define_private_method(VALUE class, char *name,
+ VALUE (*func)(), int argc)
+
+private¥á¥½¥Ã¥É¤È¤Ï´Ø¿ô·Á¼°¤Ç¤·¤«¸Æ¤Ó½Ð¤¹¤³¤È¤Î½ÐÍè¤Ê¤¤¥á¥½¥Ã
+¥É¤Ç¤¹¡¥
+
+¤â¤¦¤Ò¤È¤Ä¤Ï¥â¥¸¥å¡¼¥ë´Ø¿ô¤òÄêµÁ¤¹¤ë¤â¤Î¤Ç¤¹¡¥¥â¥¸¥å¡¼¥ë´Ø¿ô
+¤È¤Ï¥â¥¸¥å¡¼¥ë¤ÎÆÃ°Û¥á¥½¥Ã¥É¤Ç¤¢¤ê¡¤Æ±»þ¤Ëprivate¥á¥½¥Ã¥É¤Ç
+¤â¤¢¤ë¤â¤Î¤Ç¤¹¡¥Îã¤ò¤¢¤²¤ë¤ÈMath¥â¥¸¥å¡¼¥ë¤Îsqrt()¤Ê¤É¤¬¤¢¤²
+¤é¤ì¤Þ¤¹¡¥¤³¤Î¥á¥½¥Ã¥É¤Ï
+
+ Math.sqrt(4)
+
+¤È¤¤¤¦·Á¼°¤Ç¤â
+
+ include Math
+ sqrt(4)
+
+¤È¤¤¤¦·Á¼°¤Ç¤â»È¤¨¤Þ¤¹¡¥¥â¥¸¥å¡¼¥ë´Ø¿ô¤òÄêµÁ¤¹¤ë´Ø¿ô¤Ï°Ê²¼¤Î
+Ä̤ê¤Ç¤¹¡¥
+
+ void rb_define_module_method(VALUE module, char *name,
+ VALUE (*func)(), int argc)
+
+2.1.3 Äê¿ôÄêµÁ
+
+³ÈÄ¥¥â¥¸¥å¡¼¥ë¤¬É¬ÍפÊÄê¿ô¤Ï¤¢¤é¤«¤¸¤áÄêµÁ¤·¤Æ¤ª¤¤¤¿Êý¤¬Îɤ¤
+¤Ç¤·¤ç¤¦¡¥Äê¿ô¤òÄêµÁ¤¹¤ë´Ø¿ô¤ÏÆó¤Ä¤¢¤ê¤Þ¤¹¡¥
+
+ void rb_define_const(VALUE class, char *name, VALUE val)
+ void rb_define_global_const(char *name, VALUE val)
+
+Á°¼Ô¤ÏÆÃÄê¤Î¥¯¥é¥¹/¥â¥¸¥å¡¼¥ë¤Ë°¤¹¤ëÄê¿ô¤òÄêµÁ¤¹¤ë¤â¤Î¡¤¸å
+¼Ô¤Ï¥°¥í¡¼¥Ð¥ë¤ÊÄê¿ô¤òÄêµÁ¤¹¤ë¤â¤Î¤Ç¤¹¡¥
+
+2.2 ruby¤Îµ¡Ç½¤òC¤«¤é¸Æ¤Ó½Ð¤¹
+
+´û¤Ë¡Ø1.5 ruby¤Î¥Ç¡¼¥¿¤òÁàºî¤¹¤ë¡Ù¤Ç°ìÉô¾Ò²ð¤·¤¿¤è¤¦¤Ê´Ø¿ô¤ò
+»È¤¨¤Ð¡¤ruby¤Îµ¡Ç½¤ò¼Â¸½¤·¤Æ¤¤¤ë´Ø¿ô¤òľÀܸƤӽФ¹¤³¤È¤¬½ÐÍè
+¤Þ¤¹¡¥
+
+# ¤³¤Î¤è¤¦¤Ê´Ø¿ô¤Î°ìÍ÷ɽ¤Ï¤¤¤Þ¤Î¤È¤³¤í¤¢¤ê¤Þ¤»¤ó¡¥¥½¡¼¥¹¤ò¸«
+# ¤ë¤·¤«¤Ê¤¤¤Ç¤¹¤Í¡¥
+
+¤½¤ì°Ê³°¤Ë¤âruby¤Îµ¡Ç½¤ò¸Æ¤Ó½Ð¤¹ÊýË¡¤Ï¤¤¤¯¤Ä¤«¤¢¤ê¤Þ¤¹¡¥
+
+2.2.1 ruby¤Î¥×¥í¥°¥é¥à¤òeval¤¹¤ë
+
+C¤«¤éruby¤Îµ¡Ç½¤ò¸Æ¤Ó½Ð¤¹¤â¤Ã¤È¤â´Êñ¤ÊÊýË¡¤È¤·¤Æ¡¤Ê¸»úÎó¤Ç
+Í¿¤¨¤é¤ì¤¿ruby¤Î¥×¥í¥°¥é¥à¤òɾ²Á¤¹¤ë´Ø¿ô¤¬¤¢¤ê¤Þ¤¹¡¥
+
+ VALUE rb_eval_string(char *str)
+
+¤³¤Îɾ²Á¤Ï¸½ºß¤Î´Ä¶­¤Ç¹Ô¤ï¤ì¤Þ¤¹¡¥¤Ä¤Þ¤ê¡¤¸½ºß¤Î¥í¡¼¥«¥ëÊÑ¿ô
+¤äself¤Ê¤É¤ò¼õ¤±·Ñ¤®¤Þ¤¹¡¥
+
+2.2.2 ID¤Þ¤¿¤Ï¥·¥ó¥Ü¥ë
+
+C¤«¤éʸ»úÎó¤ò·Ðͳ¤»¤º¤Ëruby¤Î¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹¤³¤È¤â¤Ç¤­¤Þ
+¤¹¡¥¤½¤ÎÁ°¤Ë¡¤ruby¥¤¥ó¥¿¥×¥ê¥¿Æâ¤Ç¥á¥½¥Ã¥É¤äÊÑ¿ô̾¤ò»ØÄꤹ¤ë
+»þ¤Ë»È¤ï¤ì¤Æ¤¤¤ëID¤Ë¤Ä¤¤¤ÆÀâÌÀ¤·¤Æ¤ª¤­¤Þ¤·¤ç¤¦¡¥
+
+ID¤È¤ÏÊÑ¿ô̾¡¤¥á¥½¥Ã¥É̾¤òɽ¤¹À°¿ô¤Ç¤¹¡¥ruby¤ÎÃæ¤Ç¤Ï
+
+ :¼±ÊÌ»Ò
+
+¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤Þ¤¹¡¥C¤«¤é¤³¤ÎÀ°¿ô¤òÆÀ¤ë¤¿¤á¤Ë¤Ï´Ø¿ô
+
+ rb_intern(char *name)
+
+¤ò»È¤¤¤Þ¤¹¡¥
+
+2.2.3 C¤«¤éruby¤Î¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹
+
+C¤«¤éʸ»úÎó¤ò·Ðͳ¤»¤º¤Ëruby¤Î¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹¤¿¤á¤Ë¤Ï°Ê²¼
+¤Î´Ø¿ô¤ò»È¤¤¤Þ¤¹¡¥
+
+ VALUE rb_funcall(VALUE recv, ID mid, int argc, ...)
+
+¤³¤Î´Ø¿ô¤Ï¥ª¥Ö¥¸¥§¥¯¥Èrecv¤Îmid¤Ç»ØÄꤵ¤ì¤ë¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð
+¤·¤Þ¤¹¡¥
+
+2.2.4 ÊÑ¿ô/Äê¿ô¤ò»²¾È/¹¹¿·¤¹¤ë
+
+C¤«¤é´Ø¿ô¤ò»È¤Ã¤Æ»²¾È¡¦¹¹¿·¤Ç¤­¤ë¤Î¤Ï¡¤¥¯¥é¥¹Äê¿ô¡¤¥¤¥ó¥¹¥¿
+¥ó¥¹ÊÑ¿ô¤Ç¤¹¡¥Âç°èÊÑ¿ô¤Ï°ìÉô¤Î¤â¤Î¤ÏC¤ÎÂç°èÊÑ¿ô¤È¤·¤Æ¥¢¥¯¥»
+¥¹¤Ç¤­¤Þ¤¹¡¥¥í¡¼¥«¥ëÊÑ¿ô¤ò»²¾È¤¹¤ëÊýË¡¤Ï¸ø³«¤·¤Æ¤¤¤Þ¤»¤ó¡¥
+
+¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ò»²¾È¡¦¹¹¿·¤¹¤ë´Ø¿ô¤Ï°Ê²¼¤ÎÄÌ
+¤ê¤Ç¤¹¡¥
+
+ VALUE rb_ivar_get(VALUE obj, ID id)
+ VALUE rb_ivar_get(VALUE obj, ID id, VALUE val)
+
+id¤Ïrb_intern()¤ÇÆÀ¤é¤ì¤ë¤â¤Î¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
+
+¥¯¥é¥¹Äê¿ô¤ò»²¾È¤¹¤ë¤Ë¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
+
+ VALUE rb_const_get(VALUE obj, ID id)
+
+¥¯¥é¥¹Äê¿ô¤ò¿·¤·¤¯ÄêµÁ¤¹¤ë¤¿¤á¤Ë¤Ï¡Ø2.1.3 Äê¿ôÄêµÁ¡Ù¤Ç¾Ò²ð¤µ
+¤ì¤Æ¤¤¤ë´Ø¿ô¤ò»È¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
+
+3¡¥ruby¤ÈC¤È¤Î¾ðÊó¶¦Í­
+
+C¸À¸ì¤Èruby¤Î´Ö¤Ç¾ðÊó¤ò¶¦Í­¤¹¤ëÊýË¡¤Ë¤Ä¤¤¤Æ²òÀ⤷¤Þ¤¹¡¥
+
+3.1 C¤«¤é»²¾È¤Ç¤­¤ëruby¤ÎÄê¿ô
+
+°Ê²¼¤Îruby¤ÎÄê¿ô¤ÏC¤Î¥ì¥Ù¥ë¤«¤é»²¾È¤Ç¤­¤ë¡¥
+
+ TRUE
+ FALSE
+
+¿¿µ¶ÃÍ¡¥FALSE¤ÏC¸À¸ì¤Ç¤âµ¶¤È¤ß¤Ê¤µ¤ì¤ë¡¥
+
+ Qnil
+
+C¸À¸ì¤«¤é¸«¤¿¡Önil¡×¡¥
+
+3.2 C¤Èruby¤Ç¶¦Í­¤µ¤ì¤ëÂç°èÊÑ¿ô
+
+C¤Èruby¤ÇÂç°èÊÑ¿ô¤ò»È¤Ã¤Æ¾ðÊó¤ò¶¦Í­¤Ç¤­¤Þ¤¹¡¥¶¦Í­¤Ç¤­¤ëÂç°è
+ÊÑ¿ô¤Ë¤Ï¤¤¤¯¤Ä¤«¤Î¼ïÎब¤¢¤ê¤Þ¤¹¡¥¤½¤Î¤Ê¤«¤Ç¤â¤Ã¤È¤âÎɤ¯»È¤ï
+¤ì¤ë¤È»×¤ï¤ì¤ë¤Î¤Ïrb_define_variable()¤Ç¤¹¡¥
+
+ void rb_define_variable(char *name, VALUE *var)
+
+¤³¤Î´Ø¿ô¤Ïruby¤ÈC¤È¤Ç¶¦Í­¤¹¤ëÂç°èÊÑ¿ô¤òÄêµÁ¤·¤Þ¤¹¡¥ÊÑ¿ô̾¤¬
+`$'¤Ç»Ï¤Þ¤é¤Ê¤¤»þ¤Ë¤Ï¼«Æ°Åª¤ËÄɲ䵤ì¤Þ¤¹¡¥¤³¤ÎÊÑ¿ô¤ÎÃͤòÊÑ
+¹¹¤¹¤ë¤È¼«Æ°Åª¤Ëruby¤ÎÂбþ¤¹¤ëÊÑ¿ô¤ÎÃͤâÊѤï¤ê¤Þ¤¹¡¥
+
+¤Þ¤¿ruby¦¤«¤é¤Ï¹¹¿·¤Ç¤­¤Ê¤¤ÊÑ¿ô¤â¤¢¤ê¤Þ¤¹¡¥¤³¤Îread only¤Î
+ÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤ÇÄêµÁ¤·¤Þ¤¹¡¥
+
+ void rb_define_readonly_variable(char *name, VALUE *var)
+
+¤³¤ì¤éÊÑ¿ô¤Î¾¤Ëhook¤ò¤Ä¤±¤¿Âç°èÊÑ¿ô¤òÄêµÁ¤Ç¤­¤Þ¤¹¡¥hookÉÕ¤­
+¤ÎÂç°èÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤òÍѤ¤¤ÆÄêµÁ¤·¤Þ¤¹¡¥
+
+ 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¤ÎÂç°èÊÑ¿ô¤òÄêµÁ¤¹¤ë
+´Ø¿ô¤¬¤¢¤ê¤Þ¤¹¡¥
+
+ void rb_define_virtual_variable(char *name,
+ VALUE (*getter)(), VALUE (*setter)())
+
+¤³¤Î´Ø¿ô¤Ë¤è¤Ã¤ÆÄêµÁ¤µ¤ì¤¿ruby¤ÎÂç°èÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ¤Ë¤Ï
+getter¤¬¡¤ÊÑ¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter¤¬¸Æ¤Ð¤ì¤Þ¤¹¡¥
+
+3.3 C¤Î¥Ç¡¼¥¿¤òruby¥ª¥Ö¥¸¥§¥¯¥È¤Ë¤¹¤ë
+
+C¤ÎÀ¤³¦¤ÇÄêµÁ¤µ¤ì¤¿¥Ç¡¼¥¿(¹½Â¤ÂÎ)¤òruby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æ
+¼è¤ê°·¤¤¤¿¤¤¾ì¹ç¤¬¤¢¤ê¤¨¤Þ¤¹¡¥¤³¤Î¤è¤¦¤Ê¾ì¹ç¤Ë¤Ï¡¤Data¤È¤¤¤¦
+ruby¥ª¥Ö¥¸¥§¥¯¥È¤ËC¤Î¹½Â¤ÂÎ(¤Ø¤Î¥Ý¥¤¥ó¥¿)¤ò¤¯¤ë¤à¤³¤È¤Çruby
+¥ª¥Ö¥¸¥§¥¯¥È¤È¤·¤Æ¼è¤ê°·¤¨¤ë¤è¤¦¤Ë¤Ê¤ê¤Þ¤¹¡¥
+
+Data¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¤Æ¹½Â¤ÂΤòruby¥ª¥Ö¥¸¥§¥¯¥È¤Ë¥«¥×¥»¥ë
+²½¤¹¤ë¤¿¤á¤Ë¤Ï¡¤°Ê²¼¤Î¥Þ¥¯¥í¤ò»È¤¤¤Þ¤¹¡¥
+
+ Make_Data_Struct(class, type, mark, free, sval)
+
+¤³¤³¤Çclass¤Ï¿·¤·¤¯À¸À®¤µ¤ì¤ë¥¤¥ó¥¹¥¿¥ó¥¹¤Î¥¯¥é¥¹¡¤¡¤type¤Ï
+¥«¥×¥»¥ë²½¤¹¤ëC¤Î¥Ç¡¼¥¿¤Î·¿(¹½Â¤ÂÎ)¤Ç¤¹¡¥mark¤Ï¤³¤Î¹½Â¤ÂΤ¬
+ruby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ø¤Î»²¾È¤¬¤¢¤ë»þ¤Ë»È¤¦´Ø¿ô¤Ç¤¹¡¥¤½¤Î¤è¤¦¤Ê
+»²¾È¤ò´Þ¤Þ¤Ê¤¤»þ¤Ë¤Ï0¤ò»ØÄꤷ¤Þ¤¹¡¥free¤Ï¤³¤Î¹½Â¤ÂΤ¬¤â¤¦ÉÔ
+Íפˤʤä¿»þ¤Ë¸Æ¤Ð¤ì¤ë´Ø¿ô¤Ç¤¹¡¥¤³¤Î´Ø¿ô¤¬¥¬¡¼¥Ù¡¼¥¸¥³¥ì¥¯¥¿
+¤«¤é¸Æ¤Ð¤ì¤Þ¤¹¡¥sval¤Ïtype·¿¤ÎÊÑ¿ô¤Ç¡¤Make_Data_Struct¤ÎÃæ¤Ç
+¥¢¥í¥±¡¼¥È¤µ¤ì¤Þ¤¹¡¥
+
+¥Þ¥¯¥íMake_Data_Struct¤ÏData¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤·¤Æ¡¤¤½¤ì¤òÃÍ
+¤È¤·¤ÆÊÖ¤·¤Þ¤¹¡¥
+
+¤³¤Î¥Þ¥¯¥í¤ò¸Æ¤Ó½Ð¤¹¤Èsval¤Ë¹½Â¤ÂΤ¬malloc()¤µ¤ì¤ÆÂåÆþ¤µ¤ì¡¤
+¤«¤Ä¤½¤Î¹½Â¤ÂΤò¥«¥×¥»¥ë²½¤·¤¿Data¥ª¥Ö¥¸¥§¥¯¥È¤¬¥¤¥ó¥¹¥¿¥ó¥¹
+ÊÑ¿ô¤È¤·¤Æobj¤Ë¥»¥Ã¥È¤µ¤ì¤Þ¤¹¡¥
+
+Data¥ª¥Ö¥¸¥§¥¯¥È¤«¤éC¥Ý¥¤¥ó¥¿¤ò¼è¤ê½Ð¤¹¤¿¤á¤Ë¤Ï°Ê²¼¤Î¥Þ¥¯¥í
+¤ò»È¤¤¤Þ¤¹¡¥
+
+ Get_Data_Struct(obj, type, sval)
+
+Data¥ª¥Ö¥¸¥§¥¯¥È¤«¤étype·¿¤ÎC¥Ý¥¤¥ó¥¿¤ò¼è¤ê½Ð¤·¤Æ¡¤sval¤ËÂå
+Æþ¤·¤Þ¤¹¡¥
+
+¤³¤ì¤é¤ÎData¤Î»È¤¤Êý¤Ï¤Á¤ç¤Ã¤Èʬ¤«¤ê¤Ë¤¯¤¤¤Î¤Ç¡¤¸å¤ÇÀâÌÀ¤¹¤ë
+ÎãÂê¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡¥
+
+4¡¥ÎãÂê - dbm¥Ñ¥Ã¥±¡¼¥¸¤òºî¤ë
+
+¤³¤³¤Þ¤Ç¤ÎÀâÌÀ¤Ç¤È¤ê¤¢¤¨¤º³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ïºî¤ì¤ë¤Ï¤º¤Ç¤¹¡¥
+ruby¤Îext¥Ç¥£¥ì¥¯¥È¥ê¤Ë¤¹¤Ç¤Ë´Þ¤Þ¤ì¤Æ¤¤¤ëdbm¥â¥¸¥å¡¼¥ë¤òÎã¤Ë
+¤·¤ÆÃʳ¬Åª¤ËÀâÌÀ¤·¤Þ¤¹¡¥
+
+(1) ¥Ç¥£¥ì¥¯¥È¥ê¤òºî¤ë
+
+ % mkdir ext/dbm
+
+ruby¤òŸ³«¤·¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¡¤ext¥Ç¥£¥ì¥¯¥È¥ê¤ÎÃæ¤Ë³ÈÄ¥¥â
+¥¸¥å¡¼¥ëÍѤΥǥ£¥ì¥¯¥È¥ê¤òºî¤ê¤Þ¤¹¡¥Ì¾Á°¤ÏŬÅö¤ËÁª¤ó¤Ç¹½¤¤¤Þ
+¤»¤ó¡¥
+
+(2) MANIFEST¥Õ¥¡¥¤¥ë¤òºî¤ë
+
+ % cd ext/dbm
+ % touch MANIFEST
+
+³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î²¼¤Ë¤ÏMANIFEST¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬
+ɬÍפʤΤǡ¤¤È¤ê¤¢¤¨¤º¶õ¤Î¥Õ¥¡¥¤¥ë¤òºî¤Ã¤Æ¤ª¤­¤Þ¤¹¡¥¸å¤Ç¤³¤Î
+¥Õ¥¡¥¤¥ë¤Ë¤ÏɬÍפʥե¡¥¤¥ë°ìÍ÷¤¬Æþ¤ë¤³¤È¤Ë¤Ê¤ê¤Þ¤¹¡¥
+
+MANIFEST¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤Ï¡¤make¤Î»þ¤Ë¥Ç¥£¥ì¥¯¥È¥ê¤¬³ÈÄ¥¥â¥¸¥å¡¼
+¥ë¤ò´Þ¤ó¤Ç¤¤¤ë¤«¤É¤¦¤«È½Äꤹ¤ë¤¿¤á¤Ë»È¤ï¤ì¤ì¤Æ¤¤¤Þ¤¹¡¥
+
+(3) À߷פ¹¤ë
+
+¤Þ¤¢¡¤ÅöÁ³¤Ê¤ó¤Ç¤¹¤±¤É¡¤¤É¤¦¤¤¤¦µ¡Ç½¤ò¼Â¸½¤¹¤ë¤«¤É¤¦¤«¤Þ¤ºÀß
+·×¤¹¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥¤É¤ó¤Ê¥¯¥é¥¹¤ò¤Ä¤¯¤ë¤«¡¤¤½¤Î¥¯¥é¥¹¤Ë¤Ï
+¤É¤ó¤Ê¥á¥½¥Ã¥É¤¬¤¢¤ë¤«¡¤¥¯¥é¥¹¤¬Ä󶡤¹¤ëÄê¿ô¤Ê¤É¤Ë¤Ä¤¤¤ÆÀß·×
+¤·¤Þ¤¹¡¥dbm¥¯¥é¥¹¤Ë¤Ä¤¤¤Æ¤Ïext/dbm.doc¤ò»²¾È¤·¤Æ¤¯¤À¤µ¤¤¡¥
+
+(4) C¥³¡¼¥É¤ò½ñ¤¯
+
+³ÈÄ¥¥â¥¸¥å¡¼¥ëËÜÂΤȤʤëC¸À¸ì¤Î¥½¡¼¥¹¤ò½ñ¤­¤Þ¤¹¡¥C¸À¸ì¤Î¥½¡¼
+¥¹¤¬¤Ò¤È¤Ä¤Î»þ¤Ë¤Ï¡Ö¥â¥¸¥å¡¼¥ë̾.c¡×¤òÁª¤Ö¤ÈÎɤ¤¤Ç¤·¤ç¤¦¡¥C
+¸À¸ì¤Î¥½¡¼¥¹¤¬Ê£¿ô¤Î¾ì¹ç¤Ë¤ÏµÕ¤Ë¡Ö¥â¥¸¥å¡¼¥ë̾.c¡×¤È¤¤¤¦¥Õ¥¡
+¥¤¥ë̾¤ÏÈò¤±¤ëɬÍפ¬¤¢¤ê¤Þ¤¹¡¥¥ª¥Ö¥¸¥§¥¯¥È¥Õ¥¡¥¤¥ë¤È¥â¥¸¥å¡¼
+¥ëÀ¸À®»þ¤ËÃæ´ÖŪ¤ËÀ¸À®¤µ¤ì¤ë¡Ö¥â¥¸¥å¡¼¥ë̾.o¡×¤È¤¤¤¦¥Õ¥¡¥¤¥ë
+¤È¤¬¾×ÆÍ¤¹¤ë¤«¤é¤Ç¤¹¡¥
+
+ruby¤Ï³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É¤¹¤ë»þ¤Ë¡ÖInit_¥â¥¸¥å¡¼¥ë̾¡×¤È
+¤¤¤¦´Ø¿ô¤ò¼«Æ°Åª¤Ë¼Â¹Ô¤·¤Þ¤¹¡¥dbm¥â¥¸¥å¡¼¥ë¤Î¾ì¹ç¡ÖInit_dbm¡×
+¤Ç¤¹¡¥¤³¤Î´Ø¿ô¤ÎÃæ¤Ç¥¯¥é¥¹¡¤¥â¥¸¥å¡¼¥ë¡¤¥á¥½¥Ã¥É¡¤Äê¿ô¤Ê¤É¤Î
+ÄêµÁ¤ò¹Ô¤¤¤Þ¤¹¡¥dbm.c¤«¤é°ìÉô°úÍѤ·¤Þ¤¹¡¥
+
+--
+Init_dbm()
+{
+ /* DBM¥¯¥é¥¹¤òÄêµÁ¤¹¤ë */
+ cDBM = rb_define_class("DBM", cObject);
+ /* DBM¤ÏEnumerate¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë */
+ rb_include_module(cDBM, mEnumerable);
+
+ /* DBM¥¯¥é¥¹¤Î¥¯¥é¥¹¥á¥½¥Ã¥Éopen(): °ú¿ô¤ÏC¤ÎÇÛÎó¤Ç¼õ¤±¤ë */
+ rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1);
+
+ /* DBM¥¯¥é¥¹¤Î¥á¥½¥Ã¥Éclose(): °ú¿ô¤Ï¤Ê¤· */
+ rb_define_method(cDBM, "close", fdbm_close, 0);
+ /* DBM¥¯¥é¥¹¤Î¥á¥½¥Ã¥É[]: °ú¿ô¤Ï1¸Ä */
+ rb_define_method(cDBM, "[]", fdbm_fetch, 1);
+ :
+}
+--
+
+DBM¥â¥¸¥å¡¼¥ë¤Ïdbm¤Î¥Ç¡¼¥¿¤ÈÂбþ¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Ë¤Ê¤ë¤Ï¤º¤Ç
+¤¹¤«¤é¡¤C¤ÎÀ¤³¦¤Îdbm¤òruby¤ÎÀ¤³¦¤Ë¼è¤ê¹þ¤àɬÍפ¬¤¢¤ê¤Þ¤¹¡¥
+
+dbm.c¤Ç¤ÏDBM¤Î¥Ç¡¼¥¿¤ò³ÊǼ¤¹¤ë¤¿¤á¤Ë°Ê²¼¤Î¤è¤¦¤Ê¹½Â¤ÂΤò»È¤Ã
+¤Æ¤¤¤Þ¤¹¡¥
+
+struct dbmdata {
+ int di_size;
+ DBM *di_dbm;
+};
+
+Ruby¤ÎDBM¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤¹¤ë¤¿¤á¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤Ê¥³¡¼¥É¤ò
+»È¤Ã¤Æ¤¤¤Þ¤¹¡¥
+
+ obj = Make_Data_Struct(class,struct dbmdata,0,free_dbm,dbmp);
+ dbmp->di_dbm = dbm;
+ dbmp->di_size = -1;
+
+DBM¥ª¥Ö¥¸¥§¥¯¥È¤«¤éC¤ÎDBM¥Ý¥¤¥ó¥¿¤ò¼è¤ê½Ð¤¹¤¿¤á¤Ë¤Ï°Ê²¼¤Î¤è
+¤¦¤Ê¥Þ¥¯¥í¤ò»È¤Ã¤Æ¤¤¤Þ¤¹¡¥
+
+#define GetDBM(obj, dbmp) {\
+ Get_Data_Struct(obj, struct dbmdata, dbmp);\
+ if (dbmp->di_dbm == 0) closeddbm();\
+}
+
+DBM¥¯¥é¥¹¤Ë¤Ï¤¿¤¯¤µ¤ó¥á¥½¥Ã¥É¤¬¤¢¤ê¤Þ¤¹¤¬¡¤Ê¬Îह¤ë¤È3¼ïÎà¤Î
+°ú¿ô¤Î¼õ¤±Êý¤¬¤¢¤ê¤Þ¤¹¡¥¤Ò¤È¤Ä¤Ï°ú¿ô¤Î¿ô¤¬¸ÇÄê¤Î¤â¤Î¤Ç¡¤Îã¤È
+¤·¤Æ¤Ïdelete¥á¥½¥Ã¥É¤¬¤¢¤ê¤Þ¤¹¡¥delete¥á¥½¥Ã¥É¤ò¼ÂÁõ¤·¤Æ¤¤¤ë
+fdbm_delete()¤Ï¤³¤Î¤è¤¦¤Ë¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥
+
+--
+static VALUE
+fdbm_delete(obj, keystr)
+ VALUE obj, keystr;
+{
+ :
+}
+--
+
+°ú¿ô¤Î¿ô¤¬¸ÇÄê¤Î¥¿¥¤¥×¤ÏÂè1°ú¿ô¤¬self¡¤Âè2°ú¿ô°Ê¹ß¤¬¥á¥½¥Ã¥É
+¤Î°ú¿ô¤È¤Ê¤ê¤Þ¤¹¡¥
+
+°ú¿ô¤Î¿ô¤¬ÉÔÄê¤Î¤â¤Î¤ÏC¤ÎÇÛÎó¤Ç¼õ¤±¤ë¤â¤Î¤Èruby¤ÎÇÛÎó¤Ç¼õ¤±
+¤ë¤â¤Î¤È¤¬¤¢¤ê¤Þ¤¹¡¥dbm¥â¥¸¥å¡¼¥ë¤ÎÃæ¤Ç¡¤C¤ÎÇÛÎó¤Ç¼õ¤±¤ë¤â¤Î
+¤ÏDBM¤Î¥¯¥é¥¹¥á¥½¥Ã¥É¤Ç¤¢¤ëopen()¤Ç¤¹¡¥¤³¤ì¤ò¼ÂÁõ¤·¤Æ¤¤¤ë´Ø
+¿ôfdbm_s_open()¤Ï¤³¤¦¤Ê¤Ã¤Æ¤¤¤Þ¤¹¡¥
+
+--
+static VALUE
+fdbm_s_open(argc, argv, class)
+ int argc;
+ VALUE *argv;
+ VALUE class;
+{
+ :
+ if (rb_scan_args(argc, argv, "11", &file, &vmode) == 1) {
+ mode = 0666; /* default value */
+ }
+ :
+}
+--
+
+¤³¤Î¥¿¥¤¥×¤Î´Ø¿ô¤ÏÂè1°ú¿ô¤¬Í¿¤¨¤é¤ì¤¿°ú¿ô¤Î¿ô¡¤Âè2°ú¿ô¤¬Í¿¤¨
+¤é¤ì¤¿°ú¿ô¤ÎÆþ¤Ã¤Æ¤¤¤ëÇÛÎó¤Ë¤Ê¤ê¤Þ¤¹¡¥self¤ÏÂè3°ú¿ô¤È¤·¤ÆÍ¿
+¤¨¤é¤ì¤Þ¤¹¡¥
+
+¤³¤ÎÇÛÎó¤ÇÍ¿¤¨¤é¤ì¤¿°ú¿ô¤ò²òÀϤ¹¤ë¤¿¤á¤Î´Ø¿ô¤¬open()¤Ç¤â»È¤ï
+¤ì¤Æ¤¤¤ërb_scan_args()¤Ç¤¹¡¥Âè3°ú¿ô¤Ë»ØÄꤷ¤¿¥Õ¥©¡¼¥Þ¥Ã¥È¤Ë
+½¾¤¤¡¤Âè4ÊÑ¿ô°Ê¹ß¤Ë»ØÄꤷ¤¿ÊÑ¿ô¤ËÃͤòÂåÆþ¤·¤Æ¤¯¤ì¤Þ¤¹¡¥¤³¤Î
+¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï¡¤Âè1ʸ»úÌܤ¬¾Êά¤Ç¤­¤Ê¤¤°ú¿ô¤Î¿ô¡¤Âè2ʸ»úÌܤ¬
+¾Êά¤Ç¤­¤ë°ú¿ô¤Î¿ô¡¤Âè3ʸ»úÌܤ¬Âбþ¤¹¤ëÁê¼ê¤¬Ìµ¤¤¤¢¤Þ¤ê¤Î°ú
+¿ô¤¬¤¢¤ë¤«¤É¤¦¤«¤ò¼¨¤¹"*"¤Ç¤¹¡¥2ʸ»úÌܤÈ3ʸ»úÌܤϾÊά¤Ç¤­¤Þ
+¤¹¡¥dbm.c¤ÎÎã¤Ç¤Ï¡¤¥Õ¥©¡¼¥Þ¥Ã¥È¤Ï"11"¤Ç¤¹¤«¤é¡¤°ú¿ô¤ÏºÇÄã1¤Ä
+¤Ç¡¤2¤Ä¤Þ¤Çµö¤µ¤ì¤ë¤È¤¤¤¦°ÕÌ£¤Ë¤Ê¤ê¤Þ¤¹¡¥¾Êά¤µ¤ì¤Æ¤¤¤ë»þ¤Î
+ÊÑ¿ô¤ÎÃͤÏnil(C¸À¸ì¤Î¥ì¥Ù¥ë¤Ç¤ÏQnil)¤Ë¤Ê¤ê¤Þ¤¹¡¥
+
+ruby¤ÎÇÛÎó¤Ç°ú¿ô¤ò¼õ¤±¼è¤ë¤â¤Î¤Ïindexes¤¬¤¢¤ê¤Þ¤¹¡¥¼ÂÁõ¤Ï¤³
+¤¦¤Ç¤¹¡¥
+
+--
+static VALUE
+fdbm_indexes(obj, args)
+ VALUE obj;
+ struct RArray *args;
+{
+ :
+}
+--
+
+Âè1°ú¿ô¤Ïself¡¤Âè2°ú¿ô¤Ïruby¤ÎÇÛÎó¤Ç¤¹¡¥¤³¤³¤Ç¤Ï¥­¥ã¥¹¥È¤ò¸º
+¤é¤¹¤¿¤á struct RArray* ¤Ç¼õ¤±¤Æ¤¤¤Þ¤¹¤¬¡¤VALUE¤Ç¤âƱ¤¸¤³¤È
+¤Ç¤¹¡¥
+
+** Ãí°Õ»ö¹à
+
+ruby¤È¶¦Í­¤Ï¤·¤Ê¤¤¤¬ruby¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò³ÊǼ¤¹¤ë²ÄǽÀ­¤Î¤¢¤ë
+C¤ÎÂç°èÊÑ¿ô¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤Ã¤Æruby¥¤¥ó¥¿¥×¥ê¥¿¤ËÊÑ¿ô¤Î¸ºß
+¤ò¶µ¤¨¤Æ¤¢¤²¤Æ¤¯¤À¤µ¤¤¡¥¤Ç¤Ê¤¤¤ÈGC¤Ç¥È¥é¥Ö¥ë¤òµ¯¤³¤¹²ÄǽÀ­¤¬
+¤¢¤ê¤Þ¤¹¡¥
+
+ void rb_global_variable(VALUE *var)
+
+(5) extconf.rb¤òÍѰդ¹¤ë
+
+¤â¤·¥Ç¥£¥ì¥¯¥È¥ê¤Ë¡Öextconf.rb¡×¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ì¤Ð¡¤
+make»þ¤Ë¼Â¹Ô¤µ¤ì¤Þ¤¹¡¥¤Ê¤±¤ì¤ÐŬÅö¤ËMakefile¤¬À¸À®¤µ¤ì¤Þ¤¹¡¥
+
+extconf.rb¤Ï¥â¥¸¥å¡¼¥ë¤Î¥³¥ó¥Ñ¥¤¥ë¤ËɬÍפʾò·ï¤Î¥Á¥§¥Ã¥¯¤Ê¤É
+¤ò¹Ô¤¦¤³¤È¤¬ÌÜŪ¤Ç¤¹¡¥extconf.rb¤ÎÃæ¤Ç¤Ï°Ê²¼¤Îruby´Ø¿ô¤ò»È¤¦
+¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥
+
+ have_library(lib, func): ¥é¥¤¥Ö¥é¥ê¤Î¸ºß¥Á¥§¥Ã¥¯
+ have_func(func): ´Ø¿ô¤Î¸ºß¥Á¥§¥Ã¥¯
+ have_header(header): ¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤Î¸ºß¥Á¥§¥Ã¥¯
+ create_makefile(target): Makefile¤ÎÀ¸À®
+
+¥â¥¸¥å¡¼¥ë¤ò¥³¥ó¥Ñ¥¤¥ë¤¹¤ë¾ò·ï¤¬Â·¤ï¤Ê¤º¡¤¤½¤Î¥â¥¸¥å¡¼¥ë¤Ï¥³
+¥ó¥Ñ¥¤¥ë¤·¤Ê¤¤»þ¤Ë¤Ïcreate_makefile¤ò¸Æ¤Ð¤Ê¤±¤ì¤ÐÎɤ¤¡¥
+
+(6) depend¤òÍѰդ¹¤ë
+
+¤â¤·¡¤¥Ç¥£¥ì¥¯¥È¥ê¤Ëdepend¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ì¤Ð¡¤
+Makefile¤¬°Í¸´Ø·¸¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤¯¤ì¤Þ¤¹¡¥
+
+ % gcc -MM *.c > depend
+
+¤Ê¤É¤Çºî¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥¤¢¤Ã¤ÆÂ»¤Ï̵¤¤¤Ç¤·¤ç¤¦¡¥
+
+(7) MANIFEST¥Õ¥¡¥¤¥ë¤Ë¥Õ¥¡¥¤¥ë̾¤òÆþ¤ì¤ë
+
+ % ls > MANIFEST
+ % vi MANIFEST
+
+*.o, *~¤Ê¤ÉÉÔɬÍפʥե¡¥¤¥ë°Ê³°¤ÏMANIFEST¤ËÄɲ䷤Ƥª¤­¤Þ¤¹¡¥
+make»þ¤Ë¤ÏMANIFEST¤ÎÆâÍÆ¤Ï»²¾È¤·¤Þ¤»¤ó¤Î¤Ç¡¤¶õ¤Î¤Þ¤Þ¤Ç¤âÌäÂê
+¤Ïµ¯¤­¤Ê¤¤¤ó¤Ç¤¹¤±¤É¡¤¥Ñ¥Ã¥±¡¼¥¸¥ó¥°¤Î»þ¤Ë»²¾È¤¹¤ë¤³¤È¤¬¤¢¤ë
+¤·¡¤É¬Íפʥե¡¥¤¥ë¤ò¶èÊ̤Ǥ­¤ë¤ó¤Ç¡¤ÍѰդ·¤Æ¤ª¤¤¤¿Êý¤¬Îɤ¤¤Ç
+¤·¤ç¤¦¡¥
+
+(8) make¤¹¤ë
+
+ruby¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Çmake¤ò¼Â¹Ô¤¹¤ë¤ÈMakefile¤òÀ¸À®¤·¤Æ¤¯¤ì¤Þ
+¤¹¡¥°ìÅÙMakefile¤¬À¸À®¤µ¤ì¤ì¤Ð³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Î
+Ãæ¤Çmake¤¹¤ë¤³¤È¤¬¤Ç¤­¤Þ¤¹¡¥extconf.rb¤ò½ñ¤­´¹¤¨¤ë¤Ê¤É¤·¤Æ
+Makefile¤ÎºÆÀ¸À®¤¬É¬Íפʻþ¤Ï¤Þ¤¿ruby¥Ç¥£¥ì¥¯¥È¥ê¤Çmake¤·¤Æ¤¯
+¤À¤µ¤¤¡¥
+
+(9) ¥Ç¥Ð¥Ã¥°
+
+¤Þ¤¢¡¤¥Ç¥Ð¥Ã¥°¤·¤Ê¤¤¤Èư¤«¤Ê¤¤¤Ç¤·¤ç¤¦¤Í¡¥ext/Setup¤Ë¥Ç¥£¥ì
+¥¯¥È¥ê̾¤ò½ñ¤¯¤ÈÀÅŪ¤Ë¥ê¥ó¥¯¤¹¤ë¤Î¤Ç¥Ç¥Ð¥Ã¥¬¤¬»È¤¨¤ë¤è¤¦¤Ë¤Ê
+¤ê¤Þ¤¹¡¥¤½¤Îʬ¥³¥ó¥Ñ¥¤¥ë¤¬ÃÙ¤¯¤Ê¤ê¤Þ¤¹¤±¤É¡¥
+
+(10) ¤Ç¤­¤¢¤¬¤ê
+
+¸å¤Ï¤³¤Ã¤½¤ê»È¤¦¤Ê¤ê¡¤¹­¤¯¸ø³«¤¹¤ë¤Ê¤ê¡¤Çä¤ë¤Ê¤ê¡¤¤´¼«Í³¤Ë¤ª
+»È¤¤¤¯¤À¤µ¤¤¡¥ruby¤Îºî¼Ô¤Ï³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë´Ø¤·¤Æ°ìÀڤθ¢Íø¤ò
+¼çÄ¥¤·¤Þ¤»¤ó¡¥
+
+Appendix A. ruby¤Î¥½¡¼¥¹¥³¡¼¥É¤ÎʬÎà
+
+ruby¤Î¥½¡¼¥¹¤Ï¤¤¤¯¤Ä¤«¤ËʬÎह¤ë¤³¤È¤¬½ÐÍè¤Þ¤¹¡¥¤³¤Î¤¦¤Á¥¯¥é
+¥¹¥é¥¤¥Ö¥é¥ê¤ÎÉôʬ¤Ï´ðËÜŪ¤Ë³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ÈƱ¤¸ºî¤êÊý¤Ë¤Ê¤Ã
+¤Æ¤¤¤Þ¤¹¡¥¤³¤ì¤é¤Î¥½¡¼¥¹¤Ïº£¤Þ¤Ç¤ÎÀâÌÀ¤Ç¤Û¤È¤ó¤ÉÍý²ò¤Ç¤­¤ë¤È
+»×¤¤¤Þ¤¹¡¥
+
+ruby¸À¸ì¤Î¥³¥¢
+
+ class.c
+ error.c
+ eval.c
+ gc.c
+ object.c
+ parse.y
+ variable.c
+
+¥æ¡¼¥Æ¥£¥ê¥Æ¥£´Ø¿ô
+
+ dln.c
+ fnmatch.c
+ glob.c
+ regex.c
+ st.c
+ util.c
+
+ruby¥³¥Þ¥ó¥É¤Î¼ÂÁõ
+
+ dmyext.c
+ inits.c
+ main.c
+ ruby.c
+ version.c
+
+¥¯¥é¥¹¥é¥¤¥Ö¥é¥ê
+
+ array.c
+ bignum.c
+ compar.c
+ dir.c
+ enum.c
+ file.c
+ hash.c
+ io.c
+ math.c
+ numeric.c
+ pack.c
+ process.c
+ random.c
+ range.c
+ re.c
+ signal.c
+ sprintf.c
+ string.c
+ struct.c
+ time.c
+
+Appendix B. ³ÈÄ¥ÍÑ´Ø¿ô¥ê¥Õ¥¡¥ì¥ó¥¹
+
+C¸À¸ì¤«¤éruby¤Îµ¡Ç½¤òÍøÍѤ¹¤ëAPI¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
** ·¿
VALUE
- Ruby¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¸½¤¹¤ë·¿¡¥É¬Íפ˱þ¤¸¤Æ¥­¥ã¥¹¥È¤·¤ÆÍѤ¤¤ë¡¥ÁȤß
- ¹þ¤ß·¿¤òɽ¸½¤¹¤ëC¤Î·¿¤Ïruby.h¤Ëµ­½Ò¤·¤Æ¤¢¤ëR¤Ç»Ï¤Þ¤ë¹½Â¤ÂΤǤ¢¤ë¡¥
- VALUE·¿¤ò¤³¤ì¤é¤Ë¥­¥ã¥¹¥È¤¹¤ë¤¿¤á¤ËR¤Ç»Ï¤Þ¤ë¹½Â¤ÂÎ̾¤òÁ´¤ÆÂçʸ»ú¤Ë
- ¤·¤¿Ì¾Á°¤Î¥Þ¥¯¥í¤¬ÍѰդµ¤ì¤Æ¤¤¤ë¡¥
+ruby¥ª¥Ö¥¸¥§¥¯¥È¤òɽ¸½¤¹¤ë·¿¡¥É¬Íפ˱þ¤¸¤Æ¥­¥ã¥¹¥È¤·¤ÆÍѤ¤¤ë¡¥
+ÁȤ߹þ¤ß·¿¤òɽ¸½¤¹¤ëC¤Î·¿¤Ïruby.h¤Ëµ­½Ò¤·¤Æ¤¢¤ëR¤Ç»Ï¤Þ¤ë¹½Â¤
+ÂΤǤ¢¤ë¡¥VALUE·¿¤ò¤³¤ì¤é¤Ë¥­¥ã¥¹¥È¤¹¤ë¤¿¤á¤ËR¤Ç»Ï¤Þ¤ë¹½Â¤ÂÎ
+̾¤òÁ´¤ÆÂçʸ»ú¤Ë¤·¤¿Ì¾Á°¤Î¥Þ¥¯¥í¤¬ÍѰդµ¤ì¤Æ¤¤¤ë¡¥
** ÊÑ¿ô¡¦Äê¿ô
Qnil
- Äê¿ô: nil¥ª¥Ö¥¸¥§¥¯¥È
-
- Qself
-
- ÊÑ¿ô: ¸½ºß¤Îself¥ª¥Ö¥¸¥§¥¯¥È¤ÎÃÍ¡¥°ìÈ̤˥᥽¥Ã¥É¤Ë¤Ïself¤ò»Ø¤¹°ú¿ô
- ¤¬Í¿¤¨¤é¤ì¤ë¤Î¤Ç, ¤³¤ÎÊÑ¿ô¤Ë¥¢¥¯¥»¥¹¤¹¤ëɬÍפϤʤ¤¡¥¤³¤ÎÊÑ¿ô¤ÎÃͤò
- Êѹ¹¤¹¤ë»þ¤Ï°Ê¸å¤Îself¤ÎÃͤ½¤Î¤â¤Î¤¬ÊѤï¤Ã¤Æ¤·¤Þ¤¦¤Î¤Ç, ÆÃÊ̤ʻö¾ð
- ¤¬¤Ê¤¤¸Â¤êÂåÆþ¤·¤Æ¤Ï¤Ê¤é¤Ê¤¤¡¥
+Äê¿ô: nil¥ª¥Ö¥¸¥§¥¯¥È
TRUE
- Äê¿ô: t¥ª¥Ö¥¸¥§¥¯¥È(¿¿¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ)
+Äê¿ô: TRUE¥ª¥Ö¥¸¥§¥¯¥È(¿¿¤Î¥Ç¥Õ¥©¥ë¥ÈÃÍ)
FALSE
- Äê¿ô: nil¥ª¥Ö¥¸¥§¥¯¥È
+Äê¿ô: FALSE¥ª¥Ö¥¸¥§¥¯¥È
** C¥Ç¡¼¥¿¤Î¥«¥×¥»¥ë²½
VALUE data_new(void *sval, void (*mark)(), void (*free)())
- C¤ÎǤ°Õ¤Î¥Ý¥¤¥ó¥¿¤ò¥«¥×¥»¥ë²½¤·¤¿ruby¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡¥¤³¤Î¥Ý¥¤¥ó
- ¥¿¤¬ruby¤«¤é¥¢¥¯¥»¥¹¤µ¤ì¤Ê¤¯¤Ê¤Ã¤¿»þ¡¤free¤Ç»ØÄꤷ¤¿´Ø¿ô¤¬¸Æ¤Ð¤ì¤ë¡¥
- ¤Þ¤¿¡¤¤³¤Î¥Ý¥¤¥ó¥¿¤Î»Ø¤¹¥Ç¡¼¥¿¤¬Â¾¤Îruby¥ª¥Ö¥¸¥§¥¯¥È¤ò»Ø¤·¤Æ¤¤¤ë¾ì
- ¹ç¡¤mark¤Ë»ØÄꤹ¤ë´Ø¿ô¤Ç¥Þ¡¼¥¯¤¹¤ëɬÍפ¬¤¢¤ë¡¥
+C¤ÎǤ°Õ¤Î¥Ý¥¤¥ó¥¿¤ò¥«¥×¥»¥ë²½¤·¤¿ruby¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡¥¤³
+¤Î¥Ý¥¤¥ó¥¿¤¬ruby¤«¤é¥¢¥¯¥»¥¹¤µ¤ì¤Ê¤¯¤Ê¤Ã¤¿»þ¡¤free¤Ç»ØÄꤷ¤¿
+´Ø¿ô¤¬¸Æ¤Ð¤ì¤ë¡¥¤Þ¤¿¡¤¤³¤Î¥Ý¥¤¥ó¥¿¤Î»Ø¤¹¥Ç¡¼¥¿¤¬Â¾¤Îruby¥ª¥Ö
+¥¸¥§¥¯¥È¤ò»Ø¤·¤Æ¤¤¤ë¾ì¹ç¡¤mark¤Ë»ØÄꤹ¤ë´Ø¿ô¤Ç¥Þ¡¼¥¯¤¹¤ëɬÍ×
+¤¬¤¢¤ë¡¥
Make_Data_Struct(obj, iv, type, mark, free, sval)
- type·¿¤Î¥á¥â¥ê¤òmalloc¤·¡¤ÊÑ¿ôsval¤ËÂåÆþ¤·¤¿¸å¡¤¤½¤ì¤ò¥«¥×¥»¥ë²½¤·
- ¤¿¥Ç¡¼¥¿¤òobj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ôiv¤ËÂåÆþ¤¹¤ë¥Þ¥¯¥í¡¥
+type·¿¤Î¥á¥â¥ê¤òmalloc¤·¡¤ÊÑ¿ôsval¤ËÂåÆþ¤·¤¿¸å¡¤¤½¤ì¤ò¥«¥×¥»
+¥ë²½¤·¤¿¥Ç¡¼¥¿¤òobj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ôiv¤ËÂåÆþ¤¹¤ë¥Þ¥¯¥í¡¥
Get_Data_Struct(obj, iv, type, sval)
- obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ôiv¤¬»Ø¤¹¥Ç¡¼¥¿¤«¤étype·¿¤Î¥Ý¥¤¥ó¥¿¤ò¼è¤ê½Ð¤·
- ÊÑ¿ôsval¤ËÂåÆþ¤¹¤ë¥Þ¥¯¥í¡¥
+obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ôiv¤¬»Ø¤¹¥Ç¡¼¥¿¤«¤étype·¿¤Î¥Ý¥¤¥ó¥¿¤ò¼è
+¤ê½Ð¤·ÊÑ¿ôsval¤ËÂåÆþ¤¹¤ë¥Þ¥¯¥í¡¥
** ¥¯¥é¥¹/¥â¥¸¥å¡¼¥ëÄêµÁ
VALUE rb_define_class(char *name, VALUE super)
- super¤Î¥µ¥Ö¥¯¥é¥¹¤È¤·¤Æ¿·¤·¤¤Ruby¥¯¥é¥¹¤òÄêµÁ¤¹¤ë¡¥
+super¤Î¥µ¥Ö¥¯¥é¥¹¤È¤·¤Æ¿·¤·¤¤ruby¥¯¥é¥¹¤òÄêµÁ¤¹¤ë¡¥
+
+ VALUE rb_define_class_under(VALUE module, char *name, VALUE super)
+
+super¤Î¥µ¥Ö¥¯¥é¥¹¤È¤·¤Æ¿·¤·¤¤ruby¥¯¥é¥¹¤òÄêµÁ¤·¡¤module¤ÎÄê
+¿ô¤È¤·¤ÆÄêµÁ¤¹¤ë¡¥
VALUE rb_define_module(char *name)
- ¿·¤·¤¤Ruby¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤¹¤ë¡¥
+¿·¤·¤¤ruby¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤¹¤ë¡¥
+
+ VALUE rb_define_module_under(VALUE module, char *name, VALUE super)
+
+¿·¤·¤¤ruby¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤·¡¤module¤ÎÄê¿ô¤È¤·¤ÆÄêµÁ¤¹¤ë¡¥
void rb_include_module(VALUE class, VALUE module)
- ¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¡¥class¤¬¤¹¤Ç¤Ëmodule¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ
- ¤¤¤ë»þ¤Ë¤Ï²¿¤â¤·¤Ê¤¤(¿½Å¥¤¥ó¥¯¥ë¡¼¥É¤Î¶Ø»ß)¡¥
+¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¡¥class¤¬¤¹¤Ç¤Ëmodule¤ò¥¤¥ó¥¯¥ë¡¼
+¥É¤·¤Æ¤¤¤ë»þ¤Ë¤Ï²¿¤â¤·¤Ê¤¤(¿½Å¥¤¥ó¥¯¥ë¡¼¥É¤Î¶Ø»ß)¡¥
void rb_extend_object(VALUE object, VALUE module)
- ¥ª¥Ö¥¸¥§¥¯¥È¤ò¥â¥¸¥å¡¼¥ë(¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥á¥½¥Ã¥É)¤Ç³ÈÄ¥¤¹¤ë¡¥
+¥ª¥Ö¥¸¥§¥¯¥È¤ò¥â¥¸¥å¡¼¥ë(¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥á¥½¥Ã¥É)¤Ç³ÈÄ¥¤¹¤ë¡¥
** Âç°èÊÑ¿ôÄêµÁ
void rb_define_variable(char *name, VALUE *var)
- Ruby¤ÈC¤È¤Ç¶¦Í­¤¹¤ë¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô̾¤¬`$'¤Ç»Ï¤Þ¤é¤Ê
- ¤¤»þ¤Ë¤Ï¼«Æ°Åª¤ËÄɲ䵤ì¤ë¡¥name¤È¤·¤Æruby¤Î¼±Ê̻ҤȤ·¤Æµö¤µ¤ì¤Ê¤¤
- ʸ»ú(Î㤨¤Ð` ')¤ò´Þ¤à¾ì¹ç¤Ë¤Ïruby¥×¥í¥°¥é¥à¤«¤é¤Ï¸«¤¨¤Ê¤¯¤Ê¤ë¡¥
+ruby¤ÈC¤È¤Ç¶¦Í­¤¹¤ë¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô̾¤¬`$'¤Ç»Ï
+¤Þ¤é¤Ê¤¤»þ¤Ë¤Ï¼«Æ°Åª¤ËÄɲ䵤ì¤ë¡¥name¤È¤·¤Æruby¤Î¼±Ê̻ҤȤ·
+¤Æµö¤µ¤ì¤Ê¤¤Ê¸»ú(Î㤨¤Ð` ')¤ò´Þ¤à¾ì¹ç¤Ë¤Ïruby¥×¥í¥°¥é¥à¤«¤é
+¤Ï¸«¤¨¤Ê¤¯¤Ê¤ë¡¥
void rb_define_readonly_variable(char *name, VALUE *var)
- Ruby¤ÈC¤È¤Ç¶¦Í­¤¹¤ëread only¤Î¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥read only¤Ç
- ¤¢¤ë¤³¤È°Ê³°¤Ïrb_define_variable()¤ÈƱ¤¸¡¥
+ruby¤ÈC¤È¤Ç¶¦Í­¤¹¤ëread only¤Î¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥read
+only¤Ç¤¢¤ë¤³¤È°Ê³°¤Ïrb_define_variable()¤ÈƱ¤¸¡¥
void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)())
- ´Ø¿ô¤Ë¤è¤Ã¤Æ¼Â¸½¤µ¤ì¤ëRubyÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ¤Ë¤Ï
- getter¤¬¡¤´Ø¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter¤¬¸Æ¤Ð¤ì¤ë¡¥
+´Ø¿ô¤Ë¤è¤Ã¤Æ¼Â¸½¤µ¤ì¤ërubyÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô¤¬»²¾È¤µ¤ì¤¿»þ
+¤Ë¤Ïgetter¤¬¡¤ÊÑ¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter¤¬¸Æ¤Ð¤ì¤ë¡¥
void rb_define_hooked_variable(char *name, VALUE *var,
VALUE (*getter)(), VALUE (*setter)())
- ´Ø¿ô¤Ë¤è¤Ã¤Æhook¤Î¤Ä¤±¤é¤ì¤¿¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô¤¬»²¾È¤µ
- ¤ì¤¿»þ¤Ë¤Ïgetter¤¬¡¤´Ø¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter¤¬¸Æ¤Ð¤ì¤ë¡¥
- getter¤äsetter¤Ë0¤ò»ØÄꤷ¤¿»þ¤Ë¤Ïhook¤ò»ØÄꤷ¤Ê¤¤¤Î¤ÈƱ¤¸»ö¤Ë¤Ê¤ë¡¥
+´Ø¿ô¤Ë¤è¤Ã¤Æhook¤Î¤Ä¤±¤é¤ì¤¿¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤òÄêµÁ¤¹¤ë¡¥ÊÑ¿ô¤¬
+»²¾È¤µ¤ì¤¿»þ¤Ë¤Ïgetter¤¬¡¤´Ø¿ô¤ËÃͤ¬¥»¥Ã¥È¤µ¤ì¤¿»þ¤Ë¤Ïsetter
+¤¬¸Æ¤Ð¤ì¤ë¡¥getter¤äsetter¤Ë0¤ò»ØÄꤷ¤¿»þ¤Ë¤Ïhook¤ò»ØÄꤷ¤Ê
+¤¤¤Î¤ÈƱ¤¸»ö¤Ë¤Ê¤ë¡¥
void rb_global_variable(VALUE *var)
- GC¤Î¤¿¤á¡¤Ruby¥×¥í¥°¥é¥à¤«¤é¤Ï¥¢¥¯¥»¥¹¤µ¤ì¤Ê¤¤¤¬, Ruby¥ª¥Ö¥¸¥§¥¯¥È
- ¤ò´Þ¤àÂç°èÊÑ¿ô¤ò¥Þ¡¼¥¯¤¹¤ë¡¥
+GC¤Î¤¿¤á¡¤ruby¥×¥í¥°¥é¥à¤«¤é¤Ï¥¢¥¯¥»¥¹¤µ¤ì¤Ê¤¤¤¬, ruby¥ª¥Ö¥¸¥§
+¥¯¥È¤ò´Þ¤àÂç°èÊÑ¿ô¤ò¥Þ¡¼¥¯¤¹¤ë¡¥
** ¥¯¥é¥¹Äê¿ô
void rb_define_const(VALUE class, char *name, VALUE val)
- ¥¯¥é¥¹Äê¿ô¤òÄêµÁ¤¹¤ë¡¥
+¥¯¥é¥¹Äê¿ô¤òÄêµÁ¤¹¤ë¡¥
+
+ void rb_define_global_const(char *name, VALUE val)
+
+Âç°èÄê¿ô¤òÄêµÁ¤¹¤ë¡¥
+
+ rb_define_const(cKernal, name, val)
+
+¤ÈƱ¤¸°ÕÌ£¡¥
** ¥á¥½¥Ã¥ÉÄêµÁ
rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc)
- ¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥argc¤Ïself¤ò½ü¤¯°ú¿ô¤Î¿ô¡¥argc¤¬-1¤Î»þ, ´Ø¿ô¤Ë
- ¤Ï°ú¿ô¤Î¿ô(self¤ò´Þ¤Þ¤Ê¤¤)¤òÂè1°ú¿ô, °ú¿ô¤ÎÇÛÎó¤òÂè2°ú¿ô¤È¤¹¤ë·Á¼°
- ¤ÇÍ¿¤¨¤é¤ì¤ë(Âè3°ú¿ô¤Ïself)¡¥argc¤¬-2¤Î»þ, °ú¿ô¤Ïself, args(args¤Ï
- °ú¿ô¤ò´Þ¤àruby¤ÎÇÛÎó)¤È¤¤¤¦·Á¼°¤ÇÍ¿¤¨¤é¤ì¤ë¡¥
+¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥argc¤Ïself¤ò½ü¤¯°ú¿ô¤Î¿ô¡¥argc¤¬-1¤Î»þ,
+´Ø¿ô¤Ë¤Ï°ú¿ô¤Î¿ô(self¤ò´Þ¤Þ¤Ê¤¤)¤òÂè1°ú¿ô, °ú¿ô¤ÎÇÛÎó¤òÂè2°ú
+¿ô¤È¤¹¤ë·Á¼°¤ÇÍ¿¤¨¤é¤ì¤ë(Âè3°ú¿ô¤Ïself)¡¥argc¤¬-2¤Î»þ, Âè1°ú
+¿ô¤¬self, Âè2°ú¿ô¤¬args(args¤Ï°ú¿ô¤ò´Þ¤àruby¤ÎÇÛÎó)¤È¤¤¤¦·Á
+¼°¤ÇÍ¿¤¨¤é¤ì¤ë¡¥
rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc)
- private¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¡¥
+private¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¡¥
rb_define_singleton_method(VALUE class, char *name, VALUE (*func)(), int argc)
- ÆÃ°Û¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¡¥
+ÆÃ°Û¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥°ú¿ô¤Ïrb_define_method()¤ÈƱ¤¸¡¥
rb_scan_args(int atgc, VALUE *argv, char *fmt, ...)
- argc,argv·Á¼°¤ÇÍ¿¤¨¤é¤ì¤¿°ú¿ô¤òʬ²ò¤¹¤ë¡¥fmt¤Ïɬ¿Ü°ú¿ô¤Î¿ô, Éղðú
- ¿ô¤Î¿ô, »Ä¤ê¤Î°ú¿ô¤¬¤¢¤ë¤«¤ò»ØÄꤹ¤ëʸ»úÎó¤Ç, "¿ô»ú¿ô»ú*"¤È¤¤¤¦·Á¼°
- ¤Ç¤¢¤ë¡¥ 2 ÈÖÌܤοô»ú¤È"*"¤Ï¤½¤ì¤¾¤ì¾Êά²Äǽ¤Ç¤¢¤ë¡¥É¬¿Ü°ú¿ô¤¬°ì¤Ä
- ¤â¤Ê¤¤¾ì¹ç¤Ï0¤ò»ØÄꤹ¤ë¡¥Âè3°ú¿ô°Ê¹ß¤ÏÊÑ¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç, ³ºÅö¤¹¤ë
- Í×ÁǤ¬¤½¤ÎÊÑ¿ô¤Ë³ÊǼ¤µ¤ì¤ë¡¥Éղðú¿ô¤ËÂбþ¤¹¤ë°ú¿ô¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤Ê
- ¤¤¾ì¹ç¤ÏÊÑ¿ô¤ËQnil¤¬ÂåÆþ¤µ¤ì¤ë¡¥
+argc,argv·Á¼°¤ÇÍ¿¤¨¤é¤ì¤¿°ú¿ô¤òʬ²ò¤¹¤ë¡¥fmt¤Ïɬ¿Ü°ú¿ô¤Î¿ô,
+Éղðú¿ô¤Î¿ô, »Ä¤ê¤Î°ú¿ô¤¬¤¢¤ë¤«¤ò»ØÄꤹ¤ëʸ»úÎó¤Ç, "¿ô»ú¿ô
+»ú*"¤È¤¤¤¦·Á¼°¤Ç¤¢¤ë¡¥ 2 ÈÖÌܤοô»ú¤È"*"¤Ï¤½¤ì¤¾¤ì¾Êά²Äǽ¤Ç
+¤¢¤ë¡¥É¬¿Ü°ú¿ô¤¬°ì¤Ä¤â¤Ê¤¤¾ì¹ç¤Ï0¤ò»ØÄꤹ¤ë¡¥Âè3°ú¿ô°Ê¹ß¤ÏÊÑ
+¿ô¤Ø¤Î¥Ý¥¤¥ó¥¿¤Ç, ³ºÅö¤¹¤ëÍ×ÁǤ¬¤½¤ÎÊÑ¿ô¤Ë³ÊǼ¤µ¤ì¤ë¡¥Éղðú
+¿ô¤ËÂбþ¤¹¤ë°ú¿ô¤¬Í¿¤¨¤é¤ì¤Æ¤¤¤Ê¤¤¾ì¹ç¤ÏÊÑ¿ô¤ËQnil¤¬ÂåÆþ¤µ¤ì
+¤ë¡¥
-** Ruby¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·
+** ruby¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·
VALUE rb_funcall(VALUE recv, ID mid, int narg, ...)
- ¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¡¥Ê¸»úÎ󤫤émid¤òÆÀ¤ë¤¿¤á¤Ë¤Ïrb_intern()¤ò»È¤¦¡¥
+¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¡¥Ê¸»úÎ󤫤émid¤òÆÀ¤ë¤¿¤á¤Ë¤Ïrb_intern()¤ò»È¤¦¡¥
VALUE rb_funcall2(VALUE recv, ID mid, int argc, VALUE *argv)
- ¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¡¥°ú¿ô¤òargc,argv·Á¼°¤ÇÅϤ¹¡¥
+¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¡¥°ú¿ô¤òargc,argv·Á¼°¤ÇÅϤ¹¡¥
VALUE rb_eval_string(char *str)
- ʸ»úÎó¤òruby¤È¥¹¥¯¥ê¥×¥È¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¡¦¼Â¹Ô¤¹¤ë¡¥
+ʸ»úÎó¤òruby¤È¥¹¥¯¥ê¥×¥È¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¡¦¼Â¹Ô¤¹¤ë¡¥
ID rb_intern(char *name)
- ʸ»úÎó¤ËÂбþ¤¹¤ëID¤òÊÖ¤¹¡¥
+ʸ»úÎó¤ËÂбþ¤¹¤ëID¤òÊÖ¤¹¡¥
char *rb_id2name(ID id)
- ID¤ËÂбþ¤¹¤ëʸ»úÎó¤òÊÖ¤¹(¥Ç¥Ð¥Ã¥°ÍÑ)¡¥
+ID¤ËÂбþ¤¹¤ëʸ»úÎó¤òÊÖ¤¹(¥Ç¥Ð¥Ã¥°ÍÑ)¡¥
char *rb_class2name(VALUE class)
- class¤Î̾Á°¤òÊÖ¤¹(¥Ç¥Ð¥Ã¥°ÍÑ)¡¥class¤¬Ì¾Á°¤ò»ý¤¿¤Ê¤¤»þ¤Ë¤Ï, °ìÈÖ¶á
- ¤¤Ì¾Á°¤ò»ý¤Ä¥¯¥é¥¹¤Î̾Á°¤òÊÖ¤¹¡¥
+class¤Î̾Á°¤òÊÖ¤¹(¥Ç¥Ð¥Ã¥°ÍÑ)¡¥class¤¬Ì¾Á°¤ò»ý¤¿¤Ê¤¤»þ¤Ë¤Ï,
+ÁÄÀè¤òÁ̤äÆÌ¾Á°¤ò»ý¤Ä¥¯¥é¥¹¤Î̾Á°¤òÊÖ¤¹¡¥
** ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô
VALUE rb_iv_get(VALUE obj, char *name)
- obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ÎÃͤòÆÀ¤ë¡¥`@'¤Ç»Ï¤Þ¤é¤Ê¤¤¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤Ï
- Ruby¥×¥í¥°¥é¥à¤«¤é¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¡Ö±£¤ì¤¿¡×¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤Ë¤Ê¤ë¡¥
+obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ÎÃͤòÆÀ¤ë¡¥`@'¤Ç»Ï¤Þ¤é¤Ê¤¤¥¤¥ó¥¹¥¿¥ó¥¹
+ÊÑ¿ô¤Ï ruby¥×¥í¥°¥é¥à¤«¤é¥¢¥¯¥»¥¹¤Ç¤­¤Ê¤¤¡Ö±£¤ì¤¿¡×¥¤¥ó¥¹¥¿
+¥ó¥¹ÊÑ¿ô¤Ë¤Ê¤ë¡¥
VALUE rb_iv_set(VALUE obj, char *name, VALUE val)
- obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤òval¤Ë¥»¥Ã¥È¤¹¤ë¡¥
+obj¤Î¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤òval¤Ë¥»¥Ã¥È¤¹¤ë¡¥
** À©¸æ¹½Â¤
VALUE rb_iterate(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2)
- func2¤ò¥Ö¥í¥Ã¥¯¤È¤·¤ÆÀßÄꤷ, func1¤ò¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ö¡¥ func1¤Ë
- ¤Ï arg1¤¬°ú¿ô¤È¤·¤ÆÅϤµ¤ì, func2¤Ë¤ÏÂè1°ú¿ô¤Ë¥¤¥Æ¥ì¡¼¥¿¤«¤éÍ¿¤¨¤é¤ì
- ¤¿ÃÍ, Âè2°ú¿ô¤Ëarg2¤¬ÅϤµ¤ì¤ë¡¥
+func2¤ò¥Ö¥í¥Ã¥¯¤È¤·¤ÆÀßÄꤷ, func1¤ò¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ö¡¥
+func1¤Ë¤Ï arg1¤¬°ú¿ô¤È¤·¤ÆÅϤµ¤ì, func2¤Ë¤ÏÂè1°ú¿ô¤Ë¥¤¥Æ¥ì¡¼
+¥¿¤«¤éÍ¿¤¨¤é¤ì¤¿ÃÍ, Âè2°ú¿ô¤Ëarg2¤¬ÅϤµ¤ì¤ë¡¥
VALUE rb_yield(VALUE val)
- val¤òÃͤȤ·¤Æ¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤ò¸Æ¤Ó½Ð¤¹¡¥
+val¤òÃͤȤ·¤Æ¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤ò¸Æ¤Ó½Ð¤¹¡¥
VALUE rb_rescue(VALUE (*func1)(), void *arg1, VALUE (*func2)(), void *arg2)
- ´Ø¿ôfunc1¤òarg1¤ò°ú¿ô¤Ë¸Æ¤Ó½Ð¤¹¡¥func1¤Î¼Â¹ÔÃæ¤ËÎã³°¤¬È¯À¸¤·¤¿»þ¤Ë
- ¤Ï func2¤òarg2¤ò°ú¿ô¤È¤·¤Æ¸Æ¤Ö¡¥Ìá¤êÃͤÏÎã³°¤¬È¯À¸¤·¤Ê¤«¤Ã¤¿»þ¤Ï
- func1¤ÎÌá¤êÃÍ, Îã³°¤¬È¯À¸¤·¤¿»þ¤Ë¤Ïfunc2¤ÎÌá¤êÃͤǤ¢¤ë¡¥
+´Ø¿ôfunc1¤òarg1¤ò°ú¿ô¤Ë¸Æ¤Ó½Ð¤¹¡¥func1¤Î¼Â¹ÔÃæ¤ËÎã³°¤¬È¯À¸¤·
+¤¿»þ¤Ë¤Ï func2¤òarg2¤ò°ú¿ô¤È¤·¤Æ¸Æ¤Ö¡¥Ìá¤êÃͤÏÎã³°¤¬È¯À¸¤·¤Ê
+¤«¤Ã¤¿»þ¤Ïfunc1¤ÎÌá¤êÃÍ, Îã³°¤¬È¯À¸¤·¤¿»þ¤Ë¤Ïfunc2¤ÎÌá¤êÃͤÇ
+¤¢¤ë¡¥
VALUE rb_ensure(VALUE (*func1)(), void *arg1, void (*func2)(), void *arg2)
- ´Ø¿ôfunc1¤òarg1¤ò°ú¿ô¤È¤·¤Æ¼Â¹Ô¤·, ¼Â¹Ô½ªÎ»¸å(¤¿¤È¤¨Îã³°¤¬È¯À¸¤·¤Æ
- ¤â) func2¤òarg2¤ò°ú¿ô¤È¤·¤Æ¼Â¹Ô¤¹¤ë¡¥Ìá¤êÃͤÏfunc1¤ÎÌá¤êÃͤǤ¢¤ë(Îã
- ³°¤¬È¯À¸¤·¤¿»þ¤ÏÌá¤é¤Ê¤¤)¡¥
+´Ø¿ôfunc1¤òarg1¤ò°ú¿ô¤È¤·¤Æ¼Â¹Ô¤·, ¼Â¹Ô½ªÎ»¸å(¤¿¤È¤¨Îã³°¤¬È¯
+À¸¤·¤Æ¤â) func2¤òarg2¤ò°ú¿ô¤È¤·¤Æ¼Â¹Ô¤¹¤ë¡¥Ìá¤êÃͤÏfunc1¤ÎÌá
+¤êÃͤǤ¢¤ë(Îã³°¤¬È¯À¸¤·¤¿»þ¤ÏÌá¤é¤Ê¤¤)¡¥
** Îã³°¡¦¥¨¥é¡¼
void Warning(char *fmt, ...)
- verbose»þ¤Ëɸ½à¥¨¥é¡¼½ÐÎϤ˷ٹð¾ðÊó¤òɽ¼¨¤¹¤ë¡¥°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
+verbose»þ¤Ëɸ½à¥¨¥é¡¼½ÐÎϤ˷ٹð¾ðÊó¤òɽ¼¨¤¹¤ë¡¥°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
void Fail(char *fmt, ...)
- Îã³°¤òȯÀ¸¤µ¤»¤ë¡¥°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
+Îã³°¤òȯÀ¸¤µ¤»¤ë¡¥°ú¿ô¤Ïprintf()¤ÈƱ¤¸¡¥
void Fatal(char *fmt, ...)
- Ã×̿ŪÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥Ä̾ï¤ÎÎã³°½èÍý¤Ï¹Ô¤Ê¤ï¤ì¤º, ¥¤¥ó¥¿¡¼¥×¥ê¥¿
- ¤¬½ªÎ»¤¹¤ë(¤¿¤À¤·ensure¤Ç»ØÄꤵ¤ì¤¿¥³¡¼¥É¤Ï½ªÎ»Á°¤Ë¼Â¹Ô¤µ¤ì¤ë)¡¥
+Ã×̿ŪÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥Ä̾ï¤ÎÎã³°½èÍý¤Ï¹Ô¤Ê¤ï¤ì¤º, ¥¤¥ó¥¿¡¼
+¥×¥ê¥¿¤¬½ªÎ»¤¹¤ë(¤¿¤À¤·ensure¤Ç»ØÄꤵ¤ì¤¿¥³¡¼¥É¤Ï½ªÎ»Á°¤Ë¼Â
+¹Ô¤µ¤ì¤ë)¡¥
void Bug(char *fmt, ...)
- ¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ê¤É¥×¥í¥°¥é¥à¤Î¥Ð¥°¤Ç¤·¤«È¯À¸¤¹¤ë¤Ï¤º¤Î¤Ê¤¤¾õ¶·¤Î»þ
- ¸Æ¤Ö¡¥¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ï¥³¥¢¥À¥ó¥×¤·Ä¾¤Á¤Ë½ªÎ»¤¹¤ë¡¥Îã³°½èÍý¤Ï°ìÀÚ¹Ô
- ¤Ê¤ï¤ì¤Ê¤¤¡¥
+¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ê¤É¥×¥í¥°¥é¥à¤Î¥Ð¥°¤Ç¤·¤«È¯À¸¤¹¤ë¤Ï¤º¤Î¤Ê¤¤¾õ
+¶·¤Î»þ¸Æ¤Ö¡¥¥¤¥ó¥¿¡¼¥×¥ê¥¿¤Ï¥³¥¢¥À¥ó¥×¤·Ä¾¤Á¤Ë½ªÎ»¤¹¤ë¡¥Îã³°
+½èÍý¤Ï°ìÀڹԤʤï¤ì¤Ê¤¤¡¥
** ruby¤Î½é´ü²½¡¦¼Â¹Ô
-Ruby¤ò¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ËËä¤á¹þ¤à¾ì¹ç¤Ë¤Ï°Ê²¼¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤ò»È¤¦¡¥ÄÌ
-¾ï¤Î³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë¤ÏɬÍפʤ¤¡¥
+ruby¤ò¥¢¥×¥ê¥±¡¼¥·¥ç¥ó¤ËËä¤á¹þ¤à¾ì¹ç¤Ë¤Ï°Ê²¼¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹
+¤ò»È¤¦¡¥Ä̾ï¤Î³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë¤ÏɬÍפʤ¤¡¥
void ruby_init(int argc, char **argv, char **envp)
- ruby¥¤¥ó¥¿¥×¥ê¥¿¤Î½é´ü²½¤ò¹Ô¤Ê¤¦¡¥
+ruby¥¤¥ó¥¿¥×¥ê¥¿¤Î½é´ü²½¤ò¹Ô¤Ê¤¦¡¥
void ruby_run()
- ruby¥¤¥ó¥¿¥×¥ê¥¿¤ò¼Â¹Ô¤¹¤ë¡¥
+ruby¥¤¥ó¥¿¥×¥ê¥¿¤ò¼Â¹Ô¤¹¤ë¡¥
void ruby_script(char *name)
- ruby¤Î¥¹¥¯¥ê¥×¥È̾($0)¤òÀßÄꤹ¤ë¡¥
+ruby¤Î¥¹¥¯¥ê¥×¥È̾($0)¤òÀßÄꤹ¤ë¡¥
-* extconf.rb¤Îµ­½Ò
+Appendix B. extconf.rb¤Ç»È¤¨¤ë´Ø¿ô¤¿¤Á
-³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Î¥Ç¥£¥ì¥¯¥È¥ê¤Ë`extconf.rb'¤È¤¤¤¦¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë»þ¤Ë
-¤Ï¡¤¤½¤ì¤¬¼Â¹Ô¤µ¤ì¡¤¥â¥¸¥å¡¼¥ë¤Î¥³¥ó¥Ñ¥¤¥ë¤ËɬÍפʾò·ï¤Î¥Á¥§¥Ã¥¯¤Ê¤É¤ò
-¹Ô¤¦»ö¤¬½ÐÍè¤ë¡¥extconf.rb¤ÎÃæ¤Ç¤Ï°Ê²¼¤Î´Ø¿ô¤ò»È¤¦»ö¤¬¤Ç¤­¤ë¡¥
+extconf.rb¤ÎÃæ¤Ç¤ÏÍøÍѲÄǽ¤Ê¥³¥ó¥Ñ¥¤¥ë¾ò·ï¥Á¥§¥Ã¥¯¤Î´Ø¿ô¤Ï°Ê
+²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
have_library(lib, func)
- ´Ø¿ôfunc¤òÄêµÁ¤·¤Æ¤¤¤ë¥é¥¤¥Ö¥é¥êlib¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥¥é¥¤¥Ö¥é¥ê
- ¤¬Â¸ºß¤¹¤ë»þ¡¤TRUE¤òÊÖ¤¹¡¥
+´Ø¿ôfunc¤òÄêµÁ¤·¤Æ¤¤¤ë¥é¥¤¥Ö¥é¥êlib¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥¥é
+¥¤¥Ö¥é¥ê¤¬Â¸ºß¤¹¤ë»þ¡¤TRUE¤òÊÖ¤¹¡¥
have_func(func)
- ´Ø¿ôfunc¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥func¤¬É¸½à¤Ç¤Ï¥ê¥ó¥¯¤µ¤ì¤Ê¤¤¥é¥¤¥Ö¥é
- ¥êÆâ¤Î¤â¤Î¤Ç¤¢¤ë»þ¤Ë¤ÏÀè¤Ëhave_library¤Ç¤½¤Î¥é¥¤¥Ö¥é¥ê¤ò¥Á¥§¥Ã¥¯¤·
- ¤Æ¤ª¤¯»ö¡¥´Ø¿ô¤¬Â¸ºß¤¹¤ë»þ¡¤TRUE¤òÊÖ¤¹¡¥
+´Ø¿ôfunc¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥func¤¬É¸½à¤Ç¤Ï¥ê¥ó¥¯¤µ¤ì¤Ê¤¤¥é
+¥¤¥Ö¥é¥êÆâ¤Î¤â¤Î¤Ç¤¢¤ë»þ¤Ë¤ÏÀè¤Ëhave_library¤Ç¤½¤Î¥é¥¤¥Ö¥é¥ê
+¤ò¥Á¥§¥Ã¥¯¤·¤Æ¤ª¤¯»ö¡¥´Ø¿ô¤¬Â¸ºß¤¹¤ë»þTRUE¤òÊÖ¤¹¡¥
have_header(header)
- ¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë»þTRUE
- ¤òÊÖ¤¹¡¥
+¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤Î¸ºß¤ò¥Á¥§¥Ã¥¯¤¹¤ë¡¥¥Ø¥Ã¥À¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë
+»þTRUE¤òÊÖ¤¹¡¥
create_makefile(target)
- ³ÈÄ¥¥â¥¸¥å¡¼¥ëÍѤÎMakefile¤òÀ¸À®¤¹¤ë¡¥¤³¤Î´Ø¿ô¤ò¸Æ¤Ð¤Ê¤±¤ì¤Ð¤½¤Î¥â
- ¥¸¥å¡¼¥ë¤Ï¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Ê¤¤¡¥
+³ÈÄ¥¥â¥¸¥å¡¼¥ëÍѤÎMakefile¤òÀ¸À®¤¹¤ë¡¥¤³¤Î´Ø¿ô¤ò¸Æ¤Ð¤Ê¤±¤ì¤Ð
+¤½¤Î¥â¥¸¥å¡¼¥ë¤Ï¥³¥ó¥Ñ¥¤¥ë¤µ¤ì¤Ê¤¤¡¥target¤Ï¥â¥¸¥å¡¼¥ë̾¤òɽ
+¤¹¡¥
/*
* Local variables:
- * fill-column: 70
+ * fill-column: 60
* end:
*/
diff --git a/README.jp b/README.jp
new file mode 100644
index 0000000000..06c0832b10
--- /dev/null
+++ b/README.jp
@@ -0,0 +1,159 @@
+* Ruby¤È¤Ï
+
+Ruby¤Ï¥·¥ó¥×¥ë¤«¤Ä¶¯ÎϤʥª¥Ö¥¸¥§¥¯¥È»Ø¸þ¥¹¥¯¥ê¥×¥È¸À¸ì¤Ç¤¹¡¥
+Ruby¤ÏºÇ½é¤«¤é½ã¿è¤Ê¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¸À¸ì¤È¤·¤ÆÀ߷פµ¤ì¤Æ¤¤¤Þ
+¤¹¤«¤é¡¤¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¥×¥í¥°¥é¥ß¥ó¥°¤ò¼ê·Ú¤Ë¹Ô¤¦»ö¤¬½ÐÍè¤Þ
+¤¹¡¥¤â¤Á¤í¤óÄ̾ï¤Î¼ê³¤­·¿¤Î¥×¥í¥°¥é¥ß¥ó¥°¤â²Äǽ¤Ç¤¹¡¥
+
+Ruby¤Ï¥Æ¥­¥¹¥È½èÍý´Ø·¸¤ÎǽÎϤʤɤËÍ¥¤ì¡¤perl¤ÈƱ¤¸¤¯¤é¤¤¶¯ÎÏ
+¤Ç¤¹¡¥¤µ¤é¤Ë¥·¥ó¥×¥ë¤Êʸˡ¤È¡¤Îã³°½èÍý¤ä¥¤¥Æ¥ì¡¼¥¿¤Ê¤É¤Îµ¡¹½
+¤Ë¤è¤Ã¤Æ¡¤¤è¤êʬ¤«¤ê¤ä¤¹¤¤¥×¥í¥°¥é¥ß¥ó¥°¤¬½ÐÍè¤Þ¤¹¡¥
+
+* Ruby¤ÎÆÃĹ¡¥
+
+ + ¥·¥ó¥×¥ë¤Êʸˡ
+ + ÉáÄ̤Υª¥Ö¥¸¥§¥¯¥È»Ø¸þµ¡Ç½(¥¯¥é¥¹¡¤¥á¥½¥Ã¥É¥³¡¼¥ë¤Ê¤É)
+ + ÆÃ¼ì¤Ê¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þµ¡Ç½(Mixin, ÆÃ°Û¥á¥½¥Ã¥É¤Ê¤É)
+ + ±é»»»Ò¥ª¡¼¥Ð¡¼¥í¡¼¥É
+ + Îã³°½èÍýµ¡Ç½
+ + ¥¤¥Æ¥ì¡¼¥¿¤È¥¯¥í¡¼¥¸¥ã
+ + ¥¬¡¼¥Ù¡¼¥¸¥³¥ì¥¯¥¿
+ + ¥À¥¤¥Ê¥ß¥Ã¥¯¥í¡¼¥Ç¥£¥ó¥° (¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ë¤è¤ë)
+ + °Ü¿¢À­¤¬¹â¤¤¡¥Â¿¤¯¤ÎUNIX¾å¤Çư¤¯
+
+* Æþ¼êË¡
+
+** ftp¤Ç
+
+°Ê²¼¤Î¾ì½ê¤Ë¤ª¤¤¤Æ¤¢¤ê¤Þ¤¹¡¥
+
+ ftp://ftp.caelum.co.jp/pub/lang/ruby/
+
+** ¥á¥¤¥ë¤Ç
+
+°Ê²¼¤Î¥¢¥É¥ì¥¹¤Ë`send'¤È¤¤¤¦Subject¤Î¥á¥¤¥ë¤òÁ÷¤Ã¤Æ²¼¤µ¤¤¡¥
+
+ ruby-archive@caelum.co.jp
+
+ËÜʸ¤Ë¤Ï²¿¤ò½ñ¤¤¤Æ¤â¹½¤¤¤Þ¤»¤ó¡¥ÀÞ¤êÊÖ¤·¡¤ºÇ¿·ÈǤÎruby¤¬Á÷¤Ã
+¤ÆÍè¤Þ¤¹¡¥
+
+* ¥Û¡¼¥à¥Ú¡¼¥¸
+
+ Ruby¤Î¥Û¡¼¥à¥Ú¡¼¥¸¤ÎURL¤Ï
+
+ http://www.caelum.co.jp/~matz/ruby/
+
+ ¤Ç¤¹¡¥
+
+* ¥á¥¤¥ê¥ó¥°¥ê¥¹¥È
+
+ Ruby¤Ë´Ø¤ï¤ëÏÃÂê¤Î¤¿¤á¤Î¥á¥¤¥ê¥ó¥°¥ê¥¹¥È¤ò³«Àߤ·¤Þ¤·¤¿¡¥¥¢
+ ¥É¥ì¥¹¤Ï
+
+ ruby-list@caelum.co.jp
+
+ ¤Ç¤¹¡¥¤³¤Î¥¢¥É¥ì¥¹¤Ë¥á¥¤¥ë¤òÁ÷¤ì¤Ð¡¤¼«Æ°Åª¤ËÅÐÏ¿¤µ¤ì¤Þ¤¹¡¥
+
+* ¥³¥ó¥Ñ¥¤¥ë¡¦¥¤¥ó¥¹¥È¡¼¥ë
+
+°Ê²¼¤Î¼ê½ç¤Ç¹Ô¤Ã¤Æ¤¯¤À¤µ¤¤¡¥
+
+ 1. configure¤ò¼Â¹Ô¤·¤ÆMakefile¤Ê¤É¤òÀ¸À®¤¹¤ë
+
+ 2. (ɬÍפʤé¤Ð)defines.h¤òÊÔ½¸¤¹¤ë
+
+ ¿ʬ¡¤É¬Í×̵¤¤¤È»×¤¤¤Þ¤¹¡¥
+
+ 3. (ɬÍפʤé¤Ð)ext/Setup¤ËÀÅŪ¤Ë¥ê¥ó¥¯¤¹¤ë³ÈÄ¥¥â¥¸¥å¡¼¥ë¤ò
+ »ØÄꤹ¤ë
+
+ ext/Setup¤Ëµ­½Ò¤·¤¿¥â¥¸¥å¡¼¥ë¤ÏÀÅŪ¤Ë¥ê¥ó¥¯¤µ¤ì¤Þ¤¹¡¥
+
+ ¥À¥¤¥Ê¥ß¥Ã¥¯¥í¡¼¥Ç¥£¥ó¥°¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¥¢¡¼¥­¥Æ¥¯
+ ¥Á¥ã¤Ç¤ÏSetup¤Î1¹ÔÌܤΡÖoption nodynamic¡×¤È¤¤¤¦¹Ô¤Î¥³
+ ¥á¥ó¥È¤ò³°¤¹É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥¤Þ¤¿¡¤¤³¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ç
+ ³ÈÄ¥¥â¥¸¥å¡¼¥ë¤òÍøÍѤ¹¤ë¤¿¤á¤Ë¤Ï¡¤¤¢¤é¤«¤¸¤áÀÅŪ¤Ë¥ê¥ó
+ ¥¯¤·¤Æ¤ª¤¯É¬Íפ¬¤¢¤ê¤Þ¤¹¡¥
+
+ 4. make¤ò¼Â¹Ô¤·¤Æ¥³¥ó¥Ñ¥¤¥ë¤¹¤ë
+
+ 5. make test¤Ç¥Æ¥¹¥È¤ò¹Ô¤¦¡¥
+
+ ¡Ötest succeeded¡×¤Èɽ¼¨¤µ¤ì¤ì¤ÐÀ®¸ù¤Ç¤¹¡¥¤¿¤À¤·¥Æ¥¹¥È
+ ¤ËÀ®¸ù¤·¤Æ¤â´°àú¤À¤ÈÊݾڤµ¤ì¤Æ¤¤¤ëÌõ¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó¡¥
+
+ 6. make install
+
+¤â¤·¡¤¥³¥ó¥Ñ¥¤¥ë»þ¤Ë¥¨¥é¡¼¤¬È¯À¸¤·¤¿¾ì¹ç¤Ë¤Ï¥¨¥é¡¼¤Î¥í¥°¤È¥Þ
+¥·¥ó¡¤OS¤Î¼ïÎà¤ò´Þ¤à¤Ç¤­¤ë¤À¤±¾Ü¤·¤¤¥ì¥Ý¡¼¥È¤òºî¼Ô¤ËÁ÷¤Ã¤Æ¤¯
+¤À¤µ¤ë¤È¾¤ÎÊý¤Î¤¿¤á¤Ë¤â¤Ê¤ê¤Þ¤¹¡¥
+
+* °Ü¿¢
+
+UNIX¤Ç¤¢¤ì¤Ðconfigure¤¬¤Û¤È¤ó¤É¤Îº¹°Û¤òµÛ¼ý¤·¤Æ¤¯¤ì¤ë¤Ï¤º¤Ç
+¤¹¤¬¡¤»×¤ï¤Ì¸«Íî¤È¤·¤¬¤¢¤Ã¤¿¾ì¹ç(¤¢¤ë¤Ë°ã¤¤¤Ê¤¤)¡¤ºî¼Ô¤Ë¤½¤Î
+¤³¤È¤ò¥ì¥Ý¡¼¥È¤¹¤ì¤Ð¡¤²ò·è¤Ç¤­¤ë¤«¤âÃΤì¤Þ¤»¤ó¡¥
+
+¥¢¡¼¥¯¥Æ¥¯¥Á¥ã¤Ë¤â¤Ã¤È¤â°Í¸¤¹¤ë¤Î¤ÏGCÉô¤Ç¤¹¡¥ruby¤ÎGC¤ÏÂоÝ
+¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤¬setjmp()¤Ë¤è¤Ã¤ÆÁ´¤Æ¤Î¥ì¥¸¥¹¥¿¤ò jmp_buf¤Ë
+³ÊǼ¤¹¤ë¤³¤È¤È¡¤jmp_buf¤È¥¹¥¿¥Ã¥¯¤¬32bit¥¢¥é¥¤¥ó¥á¥ó¥È¤µ¤ì¤Æ
+¤¤¤ë¤³¤È¤ò²¾Äꤷ¤Æ¤¤¤Þ¤¹¡¥ÆÃ¤ËÁ°¼Ô¤¬À®Î©¤·¤Ê¤¤¾ì¹ç¤ÎÂбþ¤ÏÈó
+¾ï¤Ëº¤Æñ¤Ç¤·¤ç¤¦¡¥¸å¼Ô¤Î²ò·è¤ÏÈæ³ÓŪ´Êñ¤Ç¡¤gc.c¤Ç¥¹¥¿¥Ã¥¯¤ò
+¥Þ¡¼¥¯¤·¤Æ¤¤¤ëÉôʬ¤Ë¥¢¥é¥¤¥ó¥á¥ó¥È¤Î¥Ð¥¤¥È¿ô¤À¤±¤º¤é¤·¤Æ¥Þ¡¼
+¥¯¤¹¤ë¥³¡¼¥É¤òÄɲ乤ë¤À¤±¤ÇºÑ¤ß¤Þ¤¹¡¥¡Ödefined(THINK_C)¡×¤Ç
+³ç¤é¤ì¤Æ¤¤¤ëÉôʬ¤ò»²¹Í¤Ë¤·¤Æ¤¯¤À¤µ¤¤
+
+# ¼ÂºÝ¤Ë¤Ïruby¤ÏThink C¤Ç¤Ï¥³¥ó¥Ñ¥¤¥ë¤Ç¤­¤Þ¤»¤ó¡¥
+
+¥ì¥¸¥¹¥¿¥¦¥£¥ó¥É¥¦¤ò»ý¤ÄCPU¤Ç¤Ï¡¤¥ì¥¸¥¹¥¿¥¦¥£¥ó¥É¥¦¤ò¥¹¥¿¥Ã
+¥¯¤Ë¥Õ¥é¥Ã¥·¥å¤¹¤ë¥¢¥»¥ó¥Ö¥é¥³¡¼¥É¤òÄɲ乤ëɬÍפ¬¤¢¤ë¤«¤âÃÎ
+¤ì¤Þ¤»¤ó¡¥
+
+* ÇÛÉÛ¾ò·ï
+
+ºî¼Ô¤Ï°Ê²¼¤Î¾ò·ï¤Î¤â¤È¤Ëruby¤òÇÛÉÛ¤·¤Þ¤¹¡¥
+
+ + ºÆÇÛÉÛ
+
+ ÇÛÉÛ¤·¤¿¾õÂÖ¤ò°Ý»ý¤¹¤ë¸Â¤ê¼«Í³¤Ç¤¹¡¥Êѹ¹¤ò¹Ô¤Ã¤¿¤â¤Î¤òºÆ
+ ÇÛÉÛ¤¹¤ë¤³¤È¤ò´õ˾¤¹¤ë»þ¤Ë¤Ïºî¼Ô¤ËÏ¢Íí¤·¤Æ¤¯¤À¤µ¤¤¡¥
+
+ Êѹ¹¤ò¹Ô¤Ê¤ï¤Ê¤¤ruby¤ò¥³¥ó¥Ñ¥¤¥ë¤·¤¿¥Ð¥¤¥Ê¥ê¤ÎÇÛÉۤ϶ػß
+ ¤·¤Þ¤»¤ó¤¬¡¤¥Ð¥¤¥Ê¥ê¤ò¼õ¤±¼è¤Ã¤¿¿Í¤¬¥½¡¼¥¹¤òÆþ¼ê¤Ç¤­¤ë¤è
+ ¤¦¤Ë¡¤¥½¡¼¥¹¤ÎÆþ¼êË¡¤òÌÀ¼¨¤·¤Æ¤¯¤À¤µ¤¤¡¥
+
+ + Êѹ¹
+
+ ºÆÇÛÉÛ¤ò¹Ô¤ï¤Ê¤¤¸Â¤ê¡¤¤¤¤«¤Ê¤ëÌÜŪ¤Ç¤¢¤ì¼«Í³¤Ç¤¹¡¥¤¿¤À¤·¡¤
+ µ¡Ç½³ÈÄ¥¤ä¥Ð¥°½¤Àµ¤Ïºî¼Ô¤Ø¤Î¥Õ¥£¡¼¥É¥Ð¥Ã¥¯¤ò´üÂÔ¤·¤Þ¤¹
+ (¤â¤Á¤í¤ó¶¯À©¤Ç¤Ï¤¢¤ê¤Þ¤»¤ó)¡¥
+
+ + ¾¤Î¥×¥í¥°¥é¥à¤Ø¤Î°úÍÑ
+
+ ¤¤¤«¤Ê¤ëÌÜŪ¤Ç¤¢¤ì¼«Í³¤Ç¤¹¡¥¤¿¤À¤·¡¤ruby¤Ë´Þ¤Þ¤ì¤ë¾¤Îºî
+ ¼Ô¤Ë¤è¤ë¥³¡¼¥É¤Ï¡¤¤½¤ì¤¾¤ì¤Îºî¼Ô¤Î°Õ¸þ¤Ë¤è¤ëÀ©¸Â¤¬²Ã¤¨¤é
+ ¤ì¤Þ¤¹¡¥¶ñÂÎŪ¤Ë¤Ïgc.c(°ìÉô)¡¤regex.[ch]¡¤fnmatch.[ch]¡¤
+ glob.c, st.[ch]¤Èmissing¥Ç¥£¥ì¥¯¥È¥ê²¼¤Î¥Õ¥¡¥¤¥ë·²¤¬³ºÅö
+ ¤·¤Þ¤¹¡¥
+
+ + Ruby¥¹¥¯¥ê¥×¥È¤Î¸¢Íø
+
+ Á´¤Æ¤Îruby¥¹¥¯¥ê¥×¥È¤Î¸¢Íø¤Ï¤½¤ì¤¾¤ì¤ÎÃøºî¼Ô¤Ë°¤·¤Þ¤¹¡¥
+ ºî¼Ô¤Ï¤³¤ì¤é¤Ë´Ø¤·¤Æ°ìÀڤθ¢Íø¤ò¼çÄ¥¤·¤Þ¤»¤ó¡¥¤Þ¤¿ruby¤Ë
+ ÁȤ߹þ¤à¤¿¤á¤Î³ÈÄ¥¥â¥¸¥å¡¼¥ë¤Ë´Ø¤·¤Æ¤âƱÍͤǤ¹¡¥
+
+ + ̵ÊݾÚ
+
+ Ruby¤Ï̵ÊݾڤǤ¹¡¥ºî¼Ô¤Ïruby¤ò¥µ¥Ý¡¼¥È¤¹¤ë°Õ»Ö¤Ï¤¢¤ê¤Þ¤¹
+ ¤¬¡¤ruby¼«¿È¤Î¥Ð¥°¤¢¤ë¤¤¤Ïruby¥¹¥¯¥ê¥×¥È¤Î¥Ð¥°¤Ê¤É¤«¤éȯ
+ À¸¤¹¤ë¤¤¤«¤Ê¤ë»³²¤ËÂФ·¤Æ¤âÀÕǤ¤ò»ý¤Á¤Þ¤»¤ó¡¥
+
+* Ãø¼Ô
+
+¥³¥á¥ó¥È¡¤¥Ð¥°¥ì¥Ý¡¼¥È¤½¤Î¾¤Ï matz@ruby.club.or.jp ¤Þ¤Ç¡¥
+-------------------------------------------------------
+created at: Thu Aug 3 11:57:36 JST 1995
+Local variables:
+mode: indented-text
+end:
diff --git a/ToDo b/ToDo
index 5322a83b25..c39e13625d 100644
--- a/ToDo
+++ b/ToDo
@@ -1,9 +1,7 @@
-* threadÂбþ
-* Hand written parser(recursive decent)
-* ¥¯¥é¥¹¥é¥¤¥Ö¥é¥ê¤Î¸«Ä¾¤·(UNIX°Í¸¤ò¸º¤é¤¹)
+* """..."""¤È%Q#...#¤Î¤É¤Á¤é¤ò»Ä¤¹¤«¡¤¤¢¤ë¤¤¤ÏξÊý³è¤«¤¹¤«
+* ¥Ñ¥Ã¥±¡¼¥¸¤Þ¤¿¤ÏÂç°èÊÑ¿ô¤Î¥¢¥¯¥»¥¹À©¸æ
* formatµ¡Ç½
* here document
* perl¤Î¤è¤¦¤Êsetuid check
* write debugger for ruby
-* re-write regex code for speed
-* byte code interpretor
+* re-write regex code for speed and copyright
diff --git a/array.c b/array.c
index 91f7aace9f..040a18403c 100644
--- a/array.c
+++ b/array.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:18 $
created at: Fri Aug 6 09:46:12 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -18,6 +18,16 @@ VALUE rb_to_a();
#define ARY_DEFAULT_SIZE 16
+void
+memclear(mem, size)
+ VALUE *mem;
+ int size;
+{
+ while (size--) {
+ *mem++ = Qnil;
+ }
+}
+
VALUE
ary_new2(len)
int len;
@@ -29,8 +39,10 @@ ary_new2(len)
ary->capa = len;
if (len == 0)
ary->ptr = 0;
- else
+ else {
ary->ptr = ALLOC_N(VALUE, len);
+ memclear(ary->ptr, len);
+ }
return (VALUE)ary;
}
@@ -53,7 +65,7 @@ ary_new3(n, va_alist)
int i;
if (n < 0) {
- Fail("Negative number of items(%d)", n);
+ IndexError("Negative number of items(%d)", n);
}
ary = (struct RArray*)ary_new2(n<ARY_DEFAULT_SIZE?ARY_DEFAULT_SIZE:n);
@@ -96,15 +108,20 @@ assoc_new(car, cdr)
}
static VALUE
-ary_s_new(class)
+ary_s_new(argc, argv, class)
+ int argc;
+ VALUE *argv;
VALUE class;
{
+ VALUE size;
NEWOBJ(ary, struct RArray);
OBJSETUP(ary, class, T_ARRAY);
+ rb_scan_args(argc, argv, "01", &size);
ary->len = 0;
- ary->capa = ARY_DEFAULT_SIZE;
- ary->ptr = ALLOC_N(VALUE, ARY_DEFAULT_SIZE);
+ ary->capa = NIL_P(size)?ARY_DEFAULT_SIZE:NUM2INT(size);
+ ary->ptr = ALLOC_N(VALUE, ary->capa);
+ memclear(ary->ptr, ary->capa);
return (VALUE)ary;
}
@@ -138,7 +155,7 @@ astore(ary, idx, val)
VALUE val;
{
if (idx < 0) {
- Fail("negative index for array");
+ IndexError("negative index for array");
}
if (idx >= ary->capa) {
@@ -146,7 +163,7 @@ astore(ary, idx, val)
REALLOC_N(ary->ptr, VALUE, ary->capa);
}
if (idx > ary->len) {
- MEMZERO(ary->ptr+ary->len, VALUE, idx-ary->len+1);
+ memclear(ary->ptr+ary->len, idx-ary->len+1);
}
if (idx >= ary->len) {
@@ -165,11 +182,14 @@ ary_push(ary, item)
}
static VALUE
-ary_append(ary, item)
+ary_push_method(argc, argv, ary)
+ int argc;
+ VALUE *argv;
struct RArray *ary;
- VALUE item;
{
- astore(ary, ary->len, item);
+ while (argc--) {
+ astore(ary, ary->len, *argv++);
+ }
return (VALUE)ary;
}
@@ -178,6 +198,10 @@ ary_pop(ary)
struct RArray *ary;
{
if (ary->len == 0) return Qnil;
+ if (ary->len * 10 < ary->capa && ary->capa > ARY_DEFAULT_SIZE) {
+ ary->capa = ary->len * 2;
+ REALLOC_N(ary->ptr, VALUE, ary->capa);
+ }
return ary->ptr[--ary->len];
}
@@ -194,6 +218,10 @@ ary_shift(ary)
/* sliding items */
MEMMOVE(ary->ptr, ary->ptr+1, VALUE, ary->len);
+ if (ary->len * 10 < ary->capa && ary->capa > ARY_DEFAULT_SIZE) {
+ ary->capa = ary->len * 2;
+ REALLOC_N(ary->ptr, VALUE, ary->capa);
+ }
return top;
}
@@ -215,6 +243,18 @@ ary_unshift(ary, item)
return ary->ptr[0] = item;
}
+static VALUE
+ary_unshift_method(argc, argv, ary)
+ int argc;
+ VALUE *argv;
+ VALUE ary;
+{
+ while (argc--) {
+ ary_unshift(ary, argv[argc]);
+ }
+ return (VALUE)ary;
+}
+
VALUE
ary_entry(ary, offset)
struct RArray *ary;
@@ -244,10 +284,10 @@ ary_subseq(ary, beg, len)
if (beg < 0) beg = 0;
}
if (len < 0) {
- Fail("negative length for sub-array(size: %d)", ary->len);
+ IndexError("negative length %d", ary->len);
}
if (len == 0) {
- return ary_new();
+ return ary_new2(0);
}
if (beg + len > ary->len) {
len = ary->len - beg;
@@ -270,6 +310,10 @@ beg_len(range, begp, lenp, len)
if (!range_beg_end(range, &beg, &end)) return FALSE;
+ if ((beg > 0 && end > 0 || beg < 0 && end < 0) && beg > end) {
+ IndexError("end smaller than beg [%d..%d]", beg, end);
+ }
+
if (beg < 0) {
beg = len + beg;
if (beg < 0) beg = 0;
@@ -281,10 +325,10 @@ beg_len(range, begp, lenp, len)
else {
if (end < 0) {
end = len + end;
- if (end < 0) end = 0;
+ if (end < 0) end = -1;
}
- if (len < end) end = len;
- if (beg < end) {
+ if (end > len) end = len;
+ if (beg > end) {
*lenp = 0;
}
else {
@@ -301,10 +345,9 @@ ary_aref(argc, argv, ary)
struct RArray *ary;
{
VALUE arg1, arg2;
+ int beg, len;
if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2) {
- int beg, len;
-
beg = NUM2INT(arg1);
len = NUM2INT(arg2);
if (len <= 0) {
@@ -315,17 +358,17 @@ ary_aref(argc, argv, ary)
/* special case - speeding up */
if (FIXNUM_P(arg1)) {
- return ary_entry(ary, NUM2INT(arg1));
+ return ary_entry(ary, FIX2INT(arg1));
}
-
- /* check if idx is Range */
- {
- int beg, len;
-
+ else {
+ /* check if idx is Range */
if (beg_len(arg1, &beg, &len, ary->len)) {
return ary_subseq(ary, beg, len);
}
}
+ if (TYPE(arg1) == T_BIGNUM) {
+ IndexError("index too big");
+ }
return ary_entry(ary, NUM2INT(arg1));
}
@@ -340,7 +383,7 @@ ary_index(ary, val)
if (rb_equal(ary->ptr[i], val))
return INT2FIX(i);
}
- return Qnil; /* should be FALSE? */
+ return Qnil;
}
static VALUE
@@ -351,8 +394,8 @@ ary_indexes(ary, args)
VALUE new_ary;
int i = 0;
- if (!args || args->len == 1) {
- args = (struct RArray*)rb_to_a(args->ptr[0]);
+ if (!args || NIL_P(args)) {
+ return ary_new2(0);
}
new_ary = ary_new2(args->len);
@@ -365,6 +408,53 @@ ary_indexes(ary, args)
return new_ary;
}
+static void
+ary_replace(ary, beg, len, rpl)
+ struct RArray *ary, *rpl;
+ int beg, len;
+{
+ if (TYPE(rpl) != T_ARRAY) {
+ rpl = (struct RArray*)rb_to_a(rpl);
+ }
+ if (beg < 0) {
+ beg = ary->len + beg;
+ if (beg < 0) beg = 0;
+ }
+ if (beg >= ary->len) {
+ len = beg + rpl->len;
+ if (len >= ary->capa) {
+ ary->capa=len;
+ REALLOC_N(ary->ptr, VALUE, ary->capa);
+ }
+ memclear(ary->ptr+ary->len, beg-ary->len);
+ MEMCPY(ary->ptr+beg, rpl->ptr, VALUE, rpl->len);
+ ary->len = len;
+ }
+ else {
+ int alen;
+
+ if (beg + len > ary->len) {
+ len = ary->len - beg;
+ }
+ if (len < 0) {
+ IndexError("negative length %d", ary->len);
+ }
+
+ alen = ary->len + rpl->len - len;
+ if (alen >= ary->capa) {
+ ary->capa=alen;
+ REALLOC_N(ary->ptr, VALUE, ary->capa);
+ }
+
+ if (len != RARRAY(rpl)->len) {
+ MEMMOVE(ary->ptr+beg+rpl->len, ary->ptr+beg+len,
+ VALUE, ary->len-(beg+len));
+ ary->len = alen;
+ }
+ MEMCPY(ary->ptr+beg, rpl->ptr, VALUE, rpl->len);
+ }
+}
+
static VALUE
ary_aset(argc, argv, ary)
int argc;
@@ -374,90 +464,29 @@ ary_aset(argc, argv, ary)
VALUE arg1, arg2;
struct RArray *arg3;
int offset;
+ int beg, len;
if (rb_scan_args(argc, argv, "21", &arg1, &arg2, &arg3) == 3) {
- int beg, len;
-
beg = NUM2INT(arg1);
- if (TYPE(arg3) != T_ARRAY) {
- arg3 = (struct RArray*)rb_to_a(arg3);
- }
- if (beg < 0) {
- beg = ary->len + beg;
- if (beg < 0) {
- Fail("negative index for array(size: %d)", ary->len);
- }
- }
- if (beg >= ary->len) {
- len = beg + arg3->len;
- if (len >= ary->capa) {
- ary->capa=len;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
- }
- MEMZERO(ary->ptr+ary->len, VALUE, beg-ary->len);
- MEMCPY(ary->ptr+beg, arg3->ptr, VALUE, arg3->len);
- ary->len = len;
- }
- else {
- int alen;
-
- len = NUM2INT(arg2);
- if (beg + len > ary->len) {
- len = ary->len - beg;
- }
- if (len < 0) {
- Fail("negative length for sub-array(size: %d)", ary->len);
- }
-
- alen = ary->len + arg3->len - len;
- if (alen >= ary->capa) {
- ary->capa=alen;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
- }
-
- MEMMOVE(ary->ptr+beg+arg3->len, ary->ptr+beg+len,
- VALUE, ary->len-(beg+len));
- MEMCPY(ary->ptr+beg, arg3->ptr, VALUE, arg3->len);
- ary->len = alen;
- }
+ len = NUM2INT(arg2);
+ ary_replace(ary, beg, len, arg3);
return (VALUE)arg3;
}
-
- /* check if idx is Range */
- {
- int beg, len;
-
- if (beg_len(arg1, &beg, &len, ary->len)) {
- Check_Type(arg2, T_ARRAY);
- if (ary->len < beg) {
- len = beg + RARRAY(arg2)->len;
- if (len >= ary->capa) {
- ary->capa=len;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
- }
- MEMZERO(ary->ptr+ary->len, VALUE, beg-ary->len);
- MEMCPY(ary->ptr+beg, RARRAY(arg2)->ptr, VALUE, RARRAY(arg2)->len);
- ary->len = len;
- }
- else {
- int alen;
-
- alen = ary->len + RARRAY(arg2)->len - len;
- if (alen >= ary->capa) {
- ary->capa=alen;
- REALLOC_N(ary->ptr, VALUE, ary->capa);
- }
-
- MEMMOVE(ary->ptr+beg+RARRAY(arg2)->len, ary->ptr+beg+len,
- VALUE, ary->len-(beg+len));
- MEMCPY(ary->ptr+beg, RARRAY(arg2)->ptr, VALUE, RARRAY(arg2)->len);
- ary->len = alen;
- }
- return arg2;
- }
+ else if (FIXNUM_P(arg1)) {
+ offset = FIX2INT(arg1);
+ goto fixnum;
+ }
+ else if (beg_len(arg1, &beg, &len, ary->len)) {
+ /* check if idx is Range */
+ ary_replace(ary, beg, len, arg2);
+ return arg2;
+ }
+ if (TYPE(arg1) == T_BIGNUM) {
+ IndexError("index too big");
}
offset = NUM2INT(arg1);
+ fixnum:
if (offset < 0) {
offset = ary->len + offset;
}
@@ -471,15 +500,10 @@ ary_each(ary)
{
int i;
- if (iterator_p()) {
- for (i=0; i<ary->len; i++) {
- rb_yield(ary->ptr[i]);
- }
- return Qnil;
- }
- else {
- return (VALUE)ary;
+ for (i=0; i<ary->len; i++) {
+ rb_yield(ary->ptr[i]);
}
+ return Qnil;
}
static VALUE
@@ -502,6 +526,15 @@ ary_length(ary)
}
static VALUE
+ary_empty_p(ary)
+ struct RArray *ary;
+{
+ if (ary->len == 0)
+ return TRUE;
+ return FALSE;
+}
+
+static VALUE
ary_clone(ary)
struct RArray *ary;
{
@@ -540,7 +573,7 @@ ary_join(ary, sep)
default:
tmp = obj_as_string(tmp);
}
- if (sep) str_cat(result, sep->ptr, sep->len);
+ if (!NIL_P(sep)) str_cat(result, sep->ptr, sep->len);
str_cat(result, RSTRING(tmp)->ptr, RSTRING(tmp)->len);
}
@@ -556,9 +589,9 @@ ary_join_method(argc, argv, ary)
VALUE sep;
rb_scan_args(argc, argv, "01", &sep);
- if (sep == Qnil) sep = OFS;
+ if (NIL_P(sep)) sep = OFS;
- if (sep != Qnil)
+ if (!NIL_P(sep))
Check_Type(sep, T_STRING);
return ary_join(ary, sep);
@@ -569,7 +602,7 @@ ary_to_s(ary)
VALUE ary;
{
VALUE str = ary_join(ary, OFS);
- if (str == Qnil) return str_new(0, 0);
+ if (NIL_P(str)) return str_new(0, 0);
return str;
}
@@ -581,7 +614,7 @@ ary_print_on(ary, port)
int i;
for (i=0; i<ary->len; i++) {
- if (OFS && i>1) {
+ if (!NIL_P(OFS) && i>0) {
io_write(port, OFS);
}
io_write(port, ary->ptr[i]);
@@ -602,7 +635,7 @@ ary_inspect(ary)
len = 1;
for (i=0; i<ary->len; i++) {
- s = rb_funcall(ary->ptr[i], rb_intern("inspect"), 0, 0);
+ s = rb_inspect(ary->ptr[i]);
if (i > 0) str_cat(str, ", ", 2);
str_cat(str, RSTRING(s)->ptr, RSTRING(s)->len);
len += RSTRING(s)->len + 2;
@@ -635,15 +668,27 @@ VALUE
ary_reverse(ary)
struct RArray *ary;
{
- VALUE ary2 = ary_new2(ary->len);
- int i, j;
+ VALUE *p1, *p2;
+ VALUE tmp;
+
+ p1 = ary->ptr;
+ p2 = p1 + ary->len - 1; /* points last item */
- for (i=ary->len-1, j=0; i >=0; i--, j++) {
- RARRAY(ary2)->ptr[j] = ary->ptr[i];
+ while (p1 < p2) {
+ tmp = *p1;
+ *p1 = *p2;
+ *p2 = tmp;
+ p1++; p2--;
}
- RARRAY(ary2)->len = ary->len;
- return ary2;
+ return (VALUE)ary;
+}
+
+static VALUE
+ary_reverse_method(ary)
+ struct RArray *ary;
+{
+ return ary_reverse(ary_clone(ary));
}
static ID cmp;
@@ -662,19 +707,25 @@ sort_2(a, b)
{
VALUE retval;
- if (!cmp) cmp = rb_intern("<=>");
retval = rb_funcall(*a, cmp, 1, *b);
return NUM2INT(retval);
}
VALUE
-ary_sort(ary)
+ary_sort_bang(ary)
struct RArray *ary;
{
qsort(ary->ptr, ary->len, sizeof(VALUE), iterator_p()?sort_1:sort_2);
return (VALUE)ary;
}
+VALUE
+ary_sort(ary)
+ VALUE ary;
+{
+ return ary_sort_bang(ary_clone(ary));
+}
+
static VALUE
ary_delete(ary, item)
struct RArray *ary;
@@ -689,11 +740,40 @@ ary_delete(ary, item)
}
i2++;
}
- ary->len = i2;
+ if (ary->len == i2) {
+ if (iterator_p()) rb_yield(Qnil);
+ }
+ else {
+ ary->len = i2;
+ }
return (VALUE)ary;
}
+VALUE
+ary_delete_at(ary, at)
+ struct RArray *ary;
+ VALUE at;
+{
+ int i1, i2, pos;
+ VALUE del = Qnil;
+
+ pos = NUM2INT(at);
+ for (i1 = i2 = 0; i1 < ary->len; i1++) {
+ if (i1 == pos) {
+ del = ary->ptr[i1];
+ continue;
+ }
+ if (i1 != i2) {
+ ary->ptr[i2] = ary->ptr[i1];
+ }
+ i2++;
+ }
+ ary->len = i2;
+
+ return del;
+}
+
static VALUE
ary_delete_if(ary)
struct RArray *ary;
@@ -717,6 +797,10 @@ ary_clear(ary)
struct RArray *ary;
{
ary->len = 0;
+ if (ARY_DEFAULT_SIZE*3 < ary->capa) {
+ ary->capa = ARY_DEFAULT_SIZE * 2;
+ REALLOC_N(ary->ptr, VALUE, ary->capa);
+ }
return (VALUE)ary;
}
@@ -731,7 +815,7 @@ ary_fill(argc, argv, ary)
VALUE *p, *pend;
rb_scan_args(argc, argv, "12", &item, &arg1, &arg2);
- if (arg2 == Qnil && beg_len(arg1, &beg, &len, ary->len)) {
+ if (NIL_P(arg2) && beg_len(arg1, &beg, &len, ary->len)) {
/* beg and len set already */
}
else {
@@ -754,7 +838,7 @@ ary_fill(argc, argv, ary)
REALLOC_N(ary->ptr, VALUE, ary->capa);
}
if (beg > ary->len) {
- MEMZERO(ary->ptr+ary->len, VALUE, end-ary->len);
+ memclear(ary->ptr+ary->len, end-ary->len);
}
ary->len = end;
}
@@ -766,28 +850,43 @@ ary_fill(argc, argv, ary)
return (VALUE)ary;
}
-static VALUE
+VALUE
ary_plus(x, y)
struct RArray *x, *y;
{
struct RArray *z;
- switch (TYPE(y)) {
- case T_ARRAY:
- z = (struct RArray*)ary_new2(x->len + y->len);
- MEMCPY(z->ptr, x->ptr, VALUE, x->len);
- MEMCPY(z->ptr+x->len, y->ptr, VALUE, y->len);
- z->len = x->len + RARRAY(y)->len;
- break;
-
- default:
- z = (struct RArray*)ary_clone(x);
- ary_push(z, y);
- break;
+ if (TYPE(y) != T_ARRAY) {
+ return ary_plus(x, rb_to_a(y));
}
+
+ z = (struct RArray*)ary_new2(x->len + y->len);
+ MEMCPY(z->ptr, x->ptr, VALUE, x->len);
+ MEMCPY(z->ptr+x->len, y->ptr, VALUE, y->len);
+ z->len = x->len + RARRAY(y)->len;
return (VALUE)z;
}
+VALUE
+ary_concat(x, y)
+ struct RArray *x, *y;
+{
+ struct RArray *z;
+ VALUE *p, *pend;
+
+ if (TYPE(y) != T_ARRAY) {
+ return ary_concat(x, rb_to_a(y));
+ }
+
+ p = y->ptr;
+ pend = p + y->len;
+ while (p < pend) {
+ astore(x, x->len, *p);
+ p++;
+ }
+ return (VALUE)x;
+}
+
static VALUE
ary_times(ary, times)
struct RArray *ary;
@@ -796,6 +895,10 @@ ary_times(ary, times)
struct RArray *ary2;
int i, len;
+ if (TYPE(times) == T_STRING) {
+ return ary_join(ary, times);
+ }
+
len = NUM2INT(times) * ary->len;
ary2 = (struct RArray*)ary_new2(len);
ary2->len = len;
@@ -820,8 +923,9 @@ ary_assoc(ary, key)
&& RARRAY(*p)->len > 1
&& rb_equal(RARRAY(*p)->ptr[0], key))
return *p;
+ p++;
}
- return Qnil; /* should be FALSE? */
+ return Qnil;
}
VALUE
@@ -834,11 +938,12 @@ ary_rassoc(ary, value)
p = ary->ptr; pend = p + ary->len;
while (p < pend) {
if (TYPE(*p) == T_ARRAY
- && RARRAY(*p)->len > 2
+ && RARRAY(*p)->len > 1
&& rb_equal(RARRAY(*p)->ptr[1], value))
return *p;
+ p++;
}
- return Qnil; /* should be FALSE? */
+ return Qnil;
}
static VALUE
@@ -944,7 +1049,47 @@ ary_or(ary1, ary2)
return ary3;
}
-extern VALUE cKernel;
+static VALUE
+ary_compact_bang(ary)
+ struct RArray *ary;
+{
+ VALUE *p, *t, *end;
+
+ p = t = ary->ptr;
+ end = p + ary->len;
+ while (t < end) {
+ if (NIL_P(*t)) t++;
+ else *p++ = *t++;
+ }
+ ary->len = ary->capa = (p - ary->ptr);
+ REALLOC_N(ary->ptr, VALUE, ary->len);
+
+ return (VALUE)ary;
+}
+
+static VALUE
+ary_compact(ary)
+ struct RArray *ary;
+{
+ return ary_compact_bang(ary_clone(ary));
+}
+
+static VALUE
+ary_nitems(ary)
+ struct RArray *ary;
+{
+ int n = 0;
+ VALUE *p, *pend;
+
+ p = ary->ptr;
+ pend = p + ary->len;
+ while (p < pend) {
+ if (!NIL_P(*p)) n++;
+ p++;
+ }
+ return INT2FIX(n);
+}
+
extern VALUE mEnumerable;
void
@@ -953,7 +1098,7 @@ Init_Array()
cArray = rb_define_class("Array", cObject);
rb_include_module(cArray, mEnumerable);
- rb_define_singleton_method(cArray, "new", ary_s_new, 0);
+ rb_define_singleton_method(cArray, "new", ary_s_new, -1);
rb_define_singleton_method(cArray, "[]", ary_s_create, -1);
rb_define_method(cArray, "to_s", ary_to_s, 0);
rb_define_method(cArray, "inspect", ary_inspect, 0);
@@ -965,26 +1110,32 @@ Init_Array()
rb_define_method(cArray, "hash", ary_hash, 0);
rb_define_method(cArray, "[]", ary_aref, -1);
rb_define_method(cArray, "[]=", ary_aset, -1);
- rb_define_method(cArray, "<<", ary_append, 1);
- rb_define_method(cArray, "push", ary_push, 1);
+ rb_define_method(cArray, "concat", ary_concat, 1);
+ rb_define_method(cArray, "<<", ary_push, 1);
+ rb_define_method(cArray, "push", ary_push_method, -1);
rb_define_method(cArray, "pop", ary_pop, 0);
rb_define_method(cArray, "shift", ary_shift, 0);
- rb_define_method(cArray, "unshift", ary_unshift, 1);
+ rb_define_method(cArray, "unshift", ary_unshift_method, -1);
rb_define_method(cArray, "each", ary_each, 0);
rb_define_method(cArray, "each_index", ary_each_index, 0);
rb_define_method(cArray, "length", ary_length, 0);
rb_define_alias(cArray, "size", "length");
+ rb_define_method(cArray, "empty?", ary_empty_p, 0);
rb_define_method(cArray, "index", ary_index, 1);
rb_define_method(cArray, "indexes", ary_indexes, -2);
rb_define_method(cArray, "clone", ary_clone, 0);
rb_define_method(cArray, "join", ary_join_method, -1);
- rb_define_method(cArray, "reverse", ary_reverse, 0);
+ rb_define_method(cArray, "reverse", ary_reverse_method, 0);
+ rb_define_method(cArray, "reverse!", ary_reverse, 0);
rb_define_method(cArray, "sort", ary_sort, 0);
+ rb_define_method(cArray, "sort!", ary_sort_bang, 0);
rb_define_method(cArray, "delete", ary_delete, 1);
+ rb_define_method(cArray, "delete_at", ary_delete_at, 1);
rb_define_method(cArray, "delete_if", ary_delete_if, 0);
rb_define_method(cArray, "clear", ary_clear, 0);
rb_define_method(cArray, "fill", ary_fill, -1);
- rb_define_method(cArray, "includes", ary_includes, 1);
+ rb_define_method(cArray, "include?", ary_includes, 1);
+ rb_define_method(cArray, "includes?", ary_includes, 1); /* obsolate */
rb_define_method(cArray, "assoc", ary_assoc, 1);
rb_define_method(cArray, "rassoc", ary_rassoc, 1);
@@ -995,4 +1146,10 @@ Init_Array()
rb_define_method(cArray, "-", ary_diff, 1);
rb_define_method(cArray, "&", ary_and, 1);
rb_define_method(cArray, "|", ary_or, 1);
+
+ rb_define_method(cArray, "compact", ary_compact, 0);
+ rb_define_method(cArray, "compact!", ary_compact_bang, 0);
+ rb_define_method(cArray, "nitems", ary_nitems, 0);
+
+ cmp = rb_intern("<=>");
}
diff --git a/bignum.c b/bignum.c
index a9bbe9b272..73316de894 100644
--- a/bignum.c
+++ b/bignum.c
@@ -40,15 +40,6 @@ bignew_1(class, len, sign)
#define bignew(len,sign) bignew_1(cBignum,len,sign)
-static VALUE
-big_s_new(class, y)
- VALUE class;
- struct RBignum *y;
-{
- Check_Type(y, T_BIGNUM);
- return bignew_1(class, y->len, y->sign);
-}
-
VALUE
big_clone(x)
struct RBignum *x;
@@ -136,7 +127,7 @@ int2big(n)
}
big = (struct RBignum*)uint2big(n);
if (neg) {
- big->sign = FALSE;
+ big->sign = 0;
}
return (VALUE)big;
}
@@ -198,11 +189,20 @@ str2inum(str, base)
}
if (len <= (sizeof(VALUE)*CHAR_BIT)) {
- int result = strtoul(str, 0, base);
+ UINT val = strtoul(str, 0, base);
- if (!sign) result = -result;
- if (FIXABLE(result)) return INT2FIX(result);
- return int2big(result);
+ if (POSFIXABLE(val)) {
+ if (sign) return INT2FIX(val);
+ else {
+ int result = -(int)val;
+ return INT2FIX(result);
+ }
+ }
+ else {
+ VALUE big = uint2big(val);
+ RBIGNUM(big)->sign = sign;
+ return big;
+ }
}
len = (len/(sizeof(USHORT)*CHAR_BIT))+1;
@@ -262,7 +262,7 @@ big2str(x, base)
return fix2str(x, base);
}
i = x->len;
- if (x->len == 0) return str_new2("0");
+ if (i == 0) return str_new2("0");
if (base == 10) {
j = (sizeof(USHORT)/sizeof(char)*CHAR_BIT*i*241L)/800+2;
hbase = 10000;
@@ -332,7 +332,7 @@ big2int(x)
USHORT *ds;
if (len > sizeof(long)/sizeof(USHORT))
- Fail("Bignum too big to convert into fixnum");
+ ArgError("Bignum too big to convert into fixnum");
ds = BDIGITS(x);
num = 0;
while (len--) {
@@ -347,12 +347,7 @@ VALUE
big_to_i(x)
VALUE x;
{
- int v = big2int(x);
-
- if (FIXABLE(v)) {
- return INT2FIX(v);
- }
- return x;
+ return bignorm(x);
}
VALUE
@@ -389,7 +384,9 @@ big2dbl(x)
UINT i = x->len;
USHORT *ds = BDIGITS(x);
- while (i--) d = ds[i] + BIGRAD*d;
+ while (i--) {
+ d = ds[i] + BIGRAD*d;
+ }
if (!x->sign) d = -d;
return d;
}
@@ -402,6 +399,38 @@ big_to_f(x)
}
static VALUE
+big_cmp(x, y)
+ struct RBignum *x, *y;
+{
+ int xlen = x->len;
+
+ switch (TYPE(y)) {
+ case T_FIXNUM:
+ y = (struct RBignum*)int2big(FIX2INT(y));
+ break;
+
+ case T_BIGNUM:
+ break;
+
+ default:
+ return num_coerce_bin(x, y);
+ }
+
+ if (x->sign > y->sign) return INT2FIX(1);
+ if (x->sign < y->sign) return INT2FIX(-1);
+ if (xlen < y->len)
+ return (x->sign) ? INT2FIX(-1) : INT2FIX(1);
+ if (xlen > y->len)
+ return (x->sign) ? INT2FIX(1) : INT2FIX(-1);
+
+ while(xlen-- && (BDIGITS(x)[xlen]==BDIGITS(y)[xlen]));
+ if (-1 == xlen) return INT2FIX(0);
+ return (BDIGITS(x)[xlen] > BDIGITS(y)[xlen]) ?
+ (x->sign ? INT2FIX(1) : INT2FIX(-1)) :
+ (x->sign ? INT2FIX(-1) : INT2FIX(1));
+}
+
+static VALUE
big_uminus(x)
struct RBignum *x;
{
@@ -413,6 +442,84 @@ big_uminus(x)
}
static VALUE
+big_neg(x)
+ struct RBignum *x;
+{
+ VALUE z = big_clone(x);
+ UINT i = x->len;
+ USHORT *ds = BDIGITS(z);
+
+ if (!x->sign) big_2comp(z);
+ while (i--) ds[i] = ~ds[i];
+ if (x->sign) big_2comp(z);
+ RBIGNUM(z)->sign = !RBIGNUM(z)->sign;
+
+ return bignorm(z);
+}
+
+static VALUE
+bigsub(x, y)
+ struct RBignum *x, *y;
+{
+ struct RBignum *z = 0;
+ USHORT *zds;
+ long num;
+ UINT i;
+
+ i = x->len;
+ /* if x is larger than y, swap */
+ if (x->len < y->len) {
+ z = x; x = y; y = z; /* swap x y */
+ }
+ else if (x->len == y->len) {
+ while (i > 0) {
+ i--;
+ if (BDIGITS(x)[i] > BDIGITS(y)[i]) {
+ break;
+ }
+ if (BDIGITS(x)[i] < BDIGITS(y)[i]) {
+ z = x; x = y; y = z; /* swap x y */
+ break;
+ }
+ }
+ }
+
+ z = (struct RBignum*)bignew(x->len, (z == 0)?1:0);
+ zds = BDIGITS(z);
+
+ i = x->len;
+ while (i--) zds[i] = BDIGITS(x)[i];
+
+ i = 0; num = 0;
+ do {
+ num += (long)zds[i] - BDIGITS(y)[i];
+ if (num < 0) {
+ zds[i] = num + BIGRAD;
+ num = -1;
+ }
+ else {
+ zds[i] = BIGLO(num);
+ num = 0;
+ }
+ } while (++i < y->len);
+ if (num) {
+ while (num && i < x->len) {
+ num += zds[i];
+ if (num < 0) {
+ zds[i++] = num + BIGRAD;
+ num = -1;
+ }
+ else {
+ zds[i++] = BIGLO(num);
+ num = 0;
+ }
+ }
+ }
+
+ return bignorm(z);
+}
+
+static VALUE
bigadd(x, y, sign)
struct RBignum *x, *y;
char sign;
@@ -422,6 +529,11 @@ bigadd(x, y, sign)
long num;
UINT i, len;
+ if (x->sign == (y->sign ^ sign)) {
+ if (y->sign == sign) return bigsub(y, x);
+ return bigsub(x, y);
+ }
+
if (x->len > y->len) {
len = x->len + 1;
}
@@ -437,53 +549,18 @@ bigadd(x, y, sign)
while (i--) zds[i] = BDIGITS(y)[i];
i = 0; num = 0;
- if (x->sign == z->sign) {
- do {
- num += (long)zds[i] + BDIGITS(x)[i];
- zds[i++] = BIGLO(num);
+ do {
+ num += (long)zds[i] + BDIGITS(x)[i];
+ zds[i++] = BIGLO(num);
num = BIGDN(num);
- } while (i < x->len);
- if (num) {
- while (i < y->len) {
- num += zds[i];
- zds[i++] = BIGLO(num);
- num = BIGDN(num);
- }
- BDIGITS(z)[i] = num;
- }
- }
- else {
- do {
- num += (long)zds[i] - BDIGITS(x)[i];
- if (num < 0) {
- zds[i] = num + BIGRAD;
- num = -1;
- }
- else {
- zds[i] = BIGLO(num);
- num = 0;
- }
- } while (++i < x->len);
- if (num && x->len == y->len) {
- num = 1; i = 0;
- z->sign = 1;
- do {
- num += (BIGRAD-1) - zds[i];
- zds[i++] = BIGLO(num);
- num = BIGDN(num);
- } while (i < y->len);
- }
- else while (i < y->len) {
+ } while (i < x->len);
+ if (num) {
+ while (i < y->len) {
num += zds[i];
- if (num < 0) {
- zds[i++] = num + BIGRAD;
- num = -1;
- }
- else {
- zds[i++] = BIGLO(num);
- num = 0;
- }
+ zds[i++] = BIGLO(num);
+ num = BIGDN(num);
}
+ BDIGITS(z)[i] = num;
}
return bignorm(z);
@@ -495,26 +572,40 @@ big_plus(x, y)
{
VALUE z;
- if (FIXNUM_P(y)) y = int2big(FIX2INT(y));
- else {
- Check_Type(x, T_BIGNUM);
- }
- z = bigadd(x, y, 1);
+ switch (TYPE(y)) {
+ case T_FIXNUM:
+ y = int2big(FIX2INT(y));
+ /* fall through */
+ case T_BIGNUM:
+ return bigadd(x, y, 1);
- return z;
+ case T_FLOAT:
+ return float_new(big2dbl(x) + RFLOAT(y)->value);
+
+ default:
+ return num_coerce_bin(x, y);
+ }
}
VALUE
big_minus(x, y)
VALUE x, y;
{
- if (FIXNUM_P(y)) y = int2big(FIX2INT(y));
- else {
- Check_Type(y, T_BIGNUM);
- }
- x = bigadd(x, y, 0);
+ VALUE cmp;
- return x;
+ switch (TYPE(y)) {
+ case T_FIXNUM:
+ y = int2big(FIX2INT(y));
+ /* fall through */
+ case T_BIGNUM:
+ return bigadd(x, y, 0);
+
+ case T_FLOAT:
+ return float_new(big2dbl(x) - RFLOAT(y)->value);
+
+ default:
+ return num_coerce_bin(x, y);
+ }
}
VALUE
@@ -527,9 +618,19 @@ big_mul(x, y)
USHORT *zds;
if (FIXNUM_P(x)) x = (struct RBignum*)int2big(FIX2INT(x));
- if (FIXNUM_P(y)) y = (struct RBignum*)int2big(FIX2INT(y));
- else {
- Check_Type(y, T_BIGNUM);
+ switch (TYPE(y)) {
+ case T_FIXNUM:
+ y = (struct RBignum*)int2big(FIX2INT(y));
+ break;
+
+ case T_BIGNUM:
+ break;
+
+ case T_FLOAT:
+ return float_new(big2dbl(x) * RFLOAT(y)->value);
+
+ default:
+ return num_coerce_bin(x, y);
}
j = x->len + y->len + 1;
@@ -567,7 +668,7 @@ bigdivmod(x, y, div, mod)
USHORT dd, q;
yds = BDIGITS(y);
- if (ny == 0 && yds[0] == 0) Fail("divided by 0");
+ if (ny == 0 && yds[0] == 0) num_zerodiv();
if (nx < ny) {
if (div) *div = INT2FIX(0);
if (mod) *mod = bignorm(x);
@@ -587,7 +688,7 @@ bigdivmod(x, y, div, mod)
if (div) *div = bignorm(z);
if (mod) {
if (!y->sign) t2 = -t2;
- *mod = FIX2INT(t2);
+ *mod = INT2FIX(t2);
}
return;
}
@@ -683,9 +784,19 @@ big_div(x, y)
{
VALUE z;
- if (FIXNUM_P(y)) y = int2big(FIX2INT(y));
- else {
- Check_Type(y, T_BIGNUM);
+ switch (TYPE(y)) {
+ case T_FIXNUM:
+ y = int2big(FIX2INT(y));
+ break;
+
+ case T_BIGNUM:
+ break;
+
+ case T_FLOAT:
+ return float_new(big2dbl(x) / RFLOAT(y)->value);
+
+ default:
+ return num_coerce_bin(x, y);
}
bigdivmod(x, y, &z, 0);
@@ -698,9 +809,20 @@ big_mod(x, y)
{
VALUE z;
- if (FIXNUM_P(y)) y = int2big(FIX2INT(y));
- else {
- Check_Type(y, T_BIGNUM);
+ switch (TYPE(y)) {
+ case T_FIXNUM:
+ y = int2big(FIX2INT(y));
+ break;
+
+ case T_BIGNUM:
+ break;
+
+ case T_FLOAT:
+ y = dbl2big(RFLOAT(y)->value);
+ break;
+
+ default:
+ return num_coerce_bin(x, y);
}
bigdivmod(x, y, 0, &z);
@@ -713,9 +835,20 @@ big_divmod(x, y)
{
VALUE div, mod;
- if (FIXNUM_P(y)) y = int2big(FIX2INT(y));
- else {
- Check_Type(y, T_BIGNUM);
+ switch (TYPE(y)) {
+ case T_FIXNUM:
+ y = int2big(FIX2INT(y));
+ break;
+
+ case T_FLOAT:
+ y = dbl2big(RFLOAT(y)->value);
+ break;
+
+ case T_BIGNUM:
+ break;
+
+ default:
+ return num_coerce_bin(x, y);
}
bigdivmod(x, y, &div, &mod);
@@ -726,22 +859,37 @@ VALUE
big_pow(x, y)
VALUE x, y;
{
+ double d;
VALUE z;
- int n;
+
+ if (y == INT2FIX(0)) return INT2FIX(1);
+ switch (TYPE(y)) {
+ case T_FLOAT:
+ d = RFLOAT(y)->value;
+ break;
- if (TYPE(y) == T_FLOAT) {
- return float_new(pow(big2dbl(x), RFLOAT(y)->value));
- }
- n = NUM2INT(y);
- if (n == 0) return INT2FIX(1);
- if (n < 0) {
- return float_new(pow(big2dbl(x), (double)n));
+ case T_BIGNUM:
+ if (RBIGNUM(y)->sign) goto pos_big;
+ d = big2dbl(y);
+ break;
+
+ case T_FIXNUM:
+ if (FIX2INT(y) > 0) goto pos_big;
+ d = (double)FIX2INT(y);
+ break;
+
+ default:
+ return num_coerce_bin(x, y);
}
+ return float_new(pow(big2dbl(x), d));
+ pos_big:
z = x;
- while (--n) {
- while (!(n % 2)) {
- n = n /2;
+ for (;;) {
+ y = rb_funcall(y, '-', 1, INT2FIX(1));
+ if (y == INT2FIX(0)) break;
+ while (rb_funcall(y, '%', 1, INT2FIX(2)) == INT2FIX(0)) {
+ y = rb_funcall(y, '/', 1, INT2FIX(2));
x = big_mul(x, x);
}
z = big_mul(z, x);
@@ -906,22 +1054,6 @@ big_xor(x, y)
return bignorm(z);
}
-static VALUE
-big_neg(x)
- struct RBignum *x;
-{
- VALUE z = big_clone(x);
- UINT i = x->len;
- USHORT *ds = BDIGITS(z);
-
- if (!x->sign) big_2comp(z);
- while (i--) ds[i] = ~ds[i];
- if (x->sign) big_2comp(z);
- RBIGNUM(z)->sign = !RBIGNUM(z)->sign;
-
- return bignorm(z);
-}
-
static VALUE big_rshift();
VALUE
@@ -1014,32 +1146,6 @@ big_aref(x, y)
}
static VALUE
-big_cmp(x, y)
- struct RBignum *x, *y;
-{
- int xlen = x->len;
-
- if (FIXNUM_P(y)) {
- y = (struct RBignum*)int2big(FIX2INT(y));
- }
- else {
- Check_Type(y, T_BIGNUM);
- }
- if (x->sign > y->sign) return INT2FIX(1);
- if (x->sign < y->sign) return INT2FIX(-1);
- if (xlen < y->len)
- return (x->sign) ? INT2FIX(-1) : INT2FIX(1);
- if (xlen > y->len)
- return (x->sign) ? INT2FIX(1) : INT2FIX(-1);
-
- while(xlen-- && (BDIGITS(x)[xlen]==BDIGITS(y)[xlen]));
- if (-1 == xlen) return INT2FIX(0);
- return (BDIGITS(x)[xlen] < BDIGITS(y)[xlen]) ?
- (x->sign ? INT2FIX(1) : INT2FIX(-1)) :
- (x->sign ? INT2FIX(-1) : INT2FIX(1));
-}
-
-static VALUE
big_hash(x)
struct RBignum *x;
{
@@ -1059,13 +1165,12 @@ big_coerce(x, y)
VALUE y;
{
if (FIXNUM_P(y)) {
- return int2big(FIX2INT(y));
+ return assoc_new(int2big(FIX2INT(y)), x);
}
else {
- Fail("can't coerce %s to Bignum", rb_class2name(CLASS_OF(y)));
+ TypeError("can't coerce %s to Bignum", rb_class2name(CLASS_OF(y)));
}
/* not reached */
- return Qnil;
}
static VALUE
@@ -1079,11 +1184,43 @@ big_abs(x)
return (VALUE)x;
}
+/* !!!warnig!!!!
+ this is not really a random number!!
+*/
+
+VALUE
+big_rand(max)
+ struct RBignum *max;
+{
+ struct RBignum *v;
+ int len;
+
+ len = max->len;
+ v = RBIGNUM(bignew(len,1));
+ while (len--) {
+#ifdef HAVE_RANDOM
+ BDIGITS(v)[len] = random();
+#else
+ BDIGITS(v)[len] = rand();
+#endif
+ }
+
+ return big_mod(v, max);
+}
+
+static VALUE
+big_size(big)
+ struct RBignum *big;
+{
+ return INT2FIX(big->len*2);
+}
+
void
Init_Bignum()
{
cBignum = rb_define_class("Bignum", cInteger);
- rb_define_singleton_method(cBignum, "new", big_s_new, 1);
+
+ rb_undef_method(CLASS_OF(cBignum), "new");
rb_define_method(cBignum, "to_s", big_to_s, 0);
rb_define_method(cBignum, "coerce", big_coerce, 1);
@@ -1107,5 +1244,6 @@ Init_Bignum()
rb_define_method(cBignum, "hash", big_hash, 0);
rb_define_method(cBignum, "to_i", big_to_i, 0);
rb_define_method(cBignum, "to_f", big_to_f, 0);
- rb_define_method(cBignum, "abs_f", big_abs, 0);
+ rb_define_method(cBignum, "abs", big_abs, 0);
+ rb_define_method(cBignum, "size", big_size, 0);
}
diff --git a/class.c b/class.c
index 204c476fa7..3e8ce517a6 100644
--- a/class.c
+++ b/class.c
@@ -39,7 +39,7 @@ singleton_class_new(super)
{
struct RClass *cls = (struct RClass*)class_new(super);
- FL_SET(cls, FL_SINGLE);
+ FL_SET(cls, FL_SINGLETON);
return (VALUE)cls;
}
@@ -58,7 +58,7 @@ VALUE
singleton_class_clone(class)
struct RClass *class;
{
- if (!FL_TEST(class, FL_SINGLE))
+ if (!FL_TEST(class, FL_SINGLETON))
return (VALUE)class;
else {
/* copy singleton(unnamed) class */
@@ -68,7 +68,7 @@ singleton_class_clone(class)
clone->super = class->super;
clone->m_tbl = new_idhash();
st_foreach(class->m_tbl, clone_method, clone->m_tbl);
- FL_SET(clone, FL_SINGLE);
+ FL_SET(clone, FL_SINGLETON);
return (VALUE)clone;
}
}
@@ -78,7 +78,7 @@ rb_define_class_id(id, super)
ID id;
struct RBasic *super;
{
- struct RClass *cls = (struct RClass*)class_new(super);
+ struct RClass *cls;
if (!super) super = (struct RBasic*)cClass;
cls = (struct RClass*)class_new(super);
@@ -100,7 +100,6 @@ rb_define_class(name, super)
id = rb_intern(name);
class = rb_define_class_id(id, super);
st_add_direct(rb_class_tbl, id, class);
- rb_set_class_path(class, 0, name);
return class;
}
@@ -128,7 +127,7 @@ module_new()
NEWOBJ(mdl, struct RClass);
OBJSETUP(mdl, cModule, T_MODULE);
- mdl->super = Qnil;
+ mdl->super = 0;
mdl->m_tbl = new_idhash();
return (VALUE)mdl;
@@ -171,6 +170,7 @@ rb_define_module_under(under, name)
id = rb_intern(name);
module = rb_define_module_id(id);
rb_const_set(under, id, module);
+ rb_set_class_path(module, under, name);
return module;
}
@@ -201,7 +201,7 @@ rb_include_module(class, module)
{
struct RClass *p;
- if (!module) return;
+ if (NIL_P(module)) return;
switch (TYPE(module)) {
case T_MODULE:
@@ -212,10 +212,8 @@ rb_include_module(class, module)
}
if (class == module) return;
- if (BUILTIN_TYPE(class) == T_CLASS) {
- rb_clear_cache(class);
- }
-
+ rb_clear_cache();
+
while (module) {
/* ignore if the module included already in superclasses */
for (p = class->super; p; p = p->super) {
@@ -258,7 +256,7 @@ rb_undef_method(class, name)
struct RClass *class;
char *name;
{
- rb_add_method(class, rb_intern(name), Qnil, NOEX_PUBLIC);
+ rb_add_method(class, rb_intern(name), 0, NOEX_PUBLIC);
}
void
@@ -275,18 +273,7 @@ VALUE
rb_singleton_class(obj)
struct RBasic *obj;
{
- switch (TYPE(obj)) {
- case T_OBJECT:
- case T_CLASS:
- case T_MODULE:
- case T_STRUCT:
- break;
- default:
- Fail("can't define singleton method for built-in class");
- break;
- }
-
- if (FL_TEST(obj->class, FL_SINGLE)) {
+ if (FL_TEST(obj->class, FL_SINGLETON)) {
return (VALUE)obj->class;
}
return obj->class = singleton_class_new(obj->class);
@@ -338,10 +325,10 @@ rb_define_attr(class, id, pub)
attreq = rb_intern(buf);
sprintf(buf, "@%s", name);
attriv = rb_intern(buf);
- if (rb_method_boundp(class, attr) == FALSE) {
+ if (!rb_method_boundp(class, attr)) {
rb_add_method(class, attr, NEW_IVAR(attriv), 0);
}
- if (pub && rb_method_boundp(class, attreq) == FALSE) {
+ if (pub && !rb_method_boundp(class, attreq)) {
rb_add_method(class, attreq, NEW_ATTRSET(attriv), 0);
}
}
@@ -372,7 +359,7 @@ rb_scan_args(argc, argv, fmt, va_alist)
if (isdigit(*p)) {
n = *p - '0';
if (n > argc)
- Fail("Wrong number of arguments (%d for %d)", argc, n);
+ ArgError("Wrong # of arguments (%d for %d)", argc, n);
for (i=0; i<n; i++) {
var = va_arg(vargs, VALUE*);
*var = argv[i];
@@ -408,7 +395,7 @@ rb_scan_args(argc, argv, fmt, va_alist)
}
else if (*p == '\0') {
if (argc > i) {
- Fail("Wrong # of arguments(%d for %d)", argc, i);
+ ArgError("Wrong # of arguments(%d for %d)", argc, i);
}
}
else {
@@ -419,6 +406,6 @@ rb_scan_args(argc, argv, fmt, va_alist)
return argc;
error:
- Fail("bad scan arg format: %s", fmt);
+ Fatal("bad scan arg format: %s", fmt);
return 0;
}
diff --git a/compar.c b/compar.c
index e7d1e62d79..e406a0f0fe 100644
--- a/compar.c
+++ b/compar.c
@@ -6,7 +6,7 @@
$Date: 1994/10/14 06:19:05 $
created at: Thu Aug 26 14:39:48 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -34,7 +34,7 @@ cmp_gt(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
- if (t > 0) return y;
+ if (t > 0) return TRUE;
return FALSE;
}
@@ -45,7 +45,7 @@ cmp_ge(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
- if (t >= 0) return y;
+ if (t >= 0) return TRUE;
return FALSE;
}
@@ -56,7 +56,7 @@ cmp_lt(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
- if (t < 0) return y;
+ if (t < 0) return TRUE;
return FALSE;
}
@@ -67,7 +67,7 @@ cmp_le(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
- if (t <= 0) return y;
+ if (t <= 0) return TRUE;
return FALSE;
}
diff --git a/config.dj b/config.dj
new file mode 100644
index 0000000000..13f4e6ddb6
--- /dev/null
+++ b/config.dj
@@ -0,0 +1,35 @@
+#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-msdos"
diff --git a/config.guess b/config.guess
index a3d6a9f1bf..ce6e12a8fd 100755
--- a/config.guess
+++ b/config.guess
@@ -1,6 +1,6 @@
#! /bin/sh
# Attempt to guess a canonical system name.
-# Copyright (C) 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc.
#
# This file is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
@@ -14,7 +14,7 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -51,14 +51,19 @@ trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
# Note: order is significant - the case branches are not exclusive.
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
- alpha:OSF1:V*:*)
- # After 1.2, OSF1 uses "V1.3" for uname -r.
- echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^V//'`
- exit 0 ;;
alpha:OSF1:*:*)
+ # A Vn.n version is a released version.
+ # A Tn.n version is a released field test version.
+ # A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
- echo alpha-dec-osf${UNAME_RELEASE}
- exit 0 ;;
+ echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'`
+ exit 0 ;;
+ 21064:Windows_NT:50:3)
+ echo alpha-dec-winnt3.5
+ exit 0 ;;
+ Amiga*:UNIX_System_V:4.0:*)
+ echo m68k-cbm-sysv4
+ exit 0;;
amiga:NetBSD:*:*)
echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;;
@@ -75,6 +80,9 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun4*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
+ i86pc:SunOS:5.*:*)
+ echo i386-pc-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
sun4*:SunOS:6*:*)
# According to config.sub, this is the proper way to canonicalize
# SunOS6. Hard to guess exactly what SunOS6 will be like, but
@@ -93,15 +101,30 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;;
+ atari*:NetBSD:*:*)
+ echo m68k-atari-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ sun3*:NetBSD:*:*)
+ echo m68k-sun-netbsd${UNAME_RELEASE}
+ exit 0 ;;
+ mac68k:NetBSD:*:*)
+ echo m68k-apple-netbsd${UNAME_RELEASE}
+ exit 0 ;;
RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
+ mips:*:4*:UMIPS)
+ echo mips-mips-riscos4sysv
+ exit 0 ;;
mips:*:5*:RISCos)
echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;;
+ Night_Hawk:Power_UNIX:*:*)
+ echo powerpc-harris-powerunix
+ exit 0 ;;
m88k:CX/UX:7*:*)
echo m88k-harris-cxux7
exit 0 ;;
@@ -112,12 +135,17 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
echo m88k-motorola-sysv3
exit 0 ;;
AViiON:dgux:*:*)
+ # DG/UX returns AViiON for all architectures
+ UNAME_PROCESSOR=`/usr/bin/uname -p`
+ if [ $UNAME_PROCESSOR = mc88100 -o $UNAME_PROCESSOR = mc88110 ] ; then
if [ ${TARGET_BINARY_INTERFACE}x = m88kdguxelfx \
-o ${TARGET_BINARY_INTERFACE}x = x ] ; then
echo m88k-dg-dgux${UNAME_RELEASE}
else
echo m88k-dg-dguxbcs${UNAME_RELEASE}
fi
+ else echo i586-dg-dgux${UNAME_RELEASE}
+ fi
exit 0 ;;
M88*:DolphinOS:*:*) # DolphinOS (SVR3)
echo m88k-dolphin-sysv3
@@ -169,10 +197,8 @@ EOF
else
IBM_ARCH=powerpc
fi
- if grep bos410 /usr/include/stdio.h >/dev/null 2>&1; then
- IBM_REV=4.1
- elif grep bos411 /usr/include/stdio.h >/dev/null 2>&1; then
- IBM_REV=4.1.1
+ if [ -x /usr/bin/oslevel ] ; then
+ IBM_REV=`/usr/bin/oslevel`
else
IBM_REV=4.${UNAME_RELEASE}
fi
@@ -185,7 +211,7 @@ EOF
echo romp-ibm-bsd4.4
exit 0 ;;
ibmrt:*BSD:*|romp-ibm:BSD:*) # covers RT/PC NetBSD and
- echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
+ echo romp-ibm-bsd${UNAME_RELEASE} # 4.3 with uname added to
exit 0 ;; # report: romp-ibm BSD 4.3
*:BOSX:*:*)
echo rs6000-bull-bosx
@@ -203,7 +229,7 @@ EOF
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
- 9000/7?? | 9000/8?7 ) HP_ARCH=hppa1.1 ;;
+ 9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;;
9000/8?? ) HP_ARCH=hppa1.0 ;;
esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
@@ -239,18 +265,21 @@ EOF
rm -f dummy.c dummy
echo unknown-hitachi-hiuxwe2
exit 0 ;;
- 9000/7??:4.3bsd:*:* | 9000/8?7:4.3bsd:*:* )
+ 9000/7??:4.3bsd:*:* | 9000/8?[79]:4.3bsd:*:* )
echo hppa1.1-hp-bsd
exit 0 ;;
9000/8??:4.3bsd:*:*)
echo hppa1.0-hp-bsd
exit 0 ;;
- hp7??:OSF1:*:* | hp8?7:OSF1:*:* )
+ hp7??:OSF1:*:* | hp8?[79]:OSF1:*:* )
echo hppa1.1-hp-osf
exit 0 ;;
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
exit 0 ;;
+ parisc*:Lites*:*:*)
+ echo hppa1.1-hp-lites
+ exit 0 ;;
C1*:ConvexOS:*:* | convex:ConvexOS:C1*:*)
echo c1-convex-bsd
exit 0 ;;
@@ -269,20 +298,23 @@ EOF
C4*:ConvexOS:*:* | convex:ConvexOS:C4*:*)
echo c4-convex-bsd
exit 0 ;;
- CRAY*X-MP:UNICOS:*:*)
+ CRAY*X-MP:*:*:*)
echo xmp-cray-unicos
exit 0 ;;
- CRAY*Y-MP:UNICOS:*:*)
- echo ymp-cray-unicos
- exit 0 ;;
- CRAY-2:UNICOS:*:*)
+ CRAY*Y-MP:*:*:*)
+ echo ymp-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY*C90:*:*:*)
+ echo c90-cray-unicos${UNAME_RELEASE}
+ exit 0 ;;
+ CRAY-2:*:*:*)
echo cray2-cray-unicos
exit 0 ;;
hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;;
i[34]86:BSD/386:*:* | *:BSD/OS:*:*)
- echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
+ echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
@@ -290,11 +322,20 @@ EOF
*:NetBSD:*:*)
echo ${UNAME_MACHINE}-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
+ i*:CYGWIN*:*)
+ echo i386-pc-cygwin32
+ exit 0 ;;
+ p*:CYGWIN*:*)
+ echo powerpcle-unknown-cygwin32
+ exit 0 ;;
+ prep*:SunOS:5.*:*)
+ echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
+ exit 0 ;;
*:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
- echo ${UNAME_MACHINE}-unknown-linux
+ echo ${UNAME_MACHINE}-pc-linux
exit 0 ;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions
# are messed up and put the nodename in both sysname and nodename.
@@ -305,23 +346,25 @@ EOF
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
else
- echo ${UNAME_MACHINE}-unknown-sysv${UNAME_RELEASE}
+ echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi
exit 0 ;;
i[34]86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
- echo ${UNAME_MACHINE}-unknown-isc$UNAME_REL
+ echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
elif /bin/uname -X 2>/dev/null >/dev/null ; then
UNAME_REL=`(/bin/uname -X|egrep Release|sed -e 's/.*= //')`
(/bin/uname -X|egrep i80486 >/dev/null) && UNAME_MACHINE=i486
- echo ${UNAME_MACHINE}-unknown-sco$UNAME_REL
+ (/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
+ && UNAME_MACHINE=i586
+ echo ${UNAME_MACHINE}-pc-sco$UNAME_REL
else
- echo ${UNAME_MACHINE}-unknown-sysv32
+ echo ${UNAME_MACHINE}-pc-sysv32
fi
exit 0 ;;
Intel:Mach:3*:*)
- echo i386-unknown-mach3
+ echo i386-pc-mach3
exit 0 ;;
paragon:*:*:*)
echo i860-intel-osf1
@@ -345,19 +388,19 @@ EOF
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4 && exit 0 ;;
- m680[234]0:LynxOS:2.2*:*)
+ m680[234]0:LynxOS:2.[23]*:*)
echo m68k-lynx-lynxos${UNAME_RELEASE}
exit 0 ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
- i[34]86:LynxOS:2.2*:*)
+ i[34]86:LynxOS:2.[23]*:*)
echo i386-lynx-lynxos${UNAME_RELEASE}
exit 0 ;;
- TSUNAMI:LynxOS:2.2*:*)
+ TSUNAMI:LynxOS:2.[23]*:*)
echo sparc-lynx-lynxos${UNAME_RELEASE}
exit 0 ;;
- rs6000:LynxOS:2.2*:*)
+ rs6000:LynxOS:2.[23]*:*)
echo rs6000-lynx-lynxos${UNAME_RELEASE}
exit 0 ;;
RM*:SINIX-*:*:*)
@@ -371,12 +414,29 @@ EOF
echo ns32k-sni-sysv
fi
exit 0 ;;
+ mc68*:A/UX:*:*)
+ echo m68k-apple-aux${UNAME_RELEASE}
+ exit 0 ;;
+ R3000:*System_V*:*:*)
+ if [ -d /usr/nec ]; then
+ echo mips-nec-sysv${UNAME_RELEASE}
+ else
+ echo mips-unknown-sysv${UNAME_RELEASE}
+ fi
+ exit 0 ;;
+ powerpc:JCC_BSD+:*:*)
+ echo powerpc-jcc-bsd4.4
+ exit 0 ;;
esac
#echo '(No uname command or uname output not recognized.)' 1>&2
#echo "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" 1>&2
cat >dummy.c <<EOF
+#ifdef _SEQUENT_
+# include <sys/types.h>
+# include <sys/utsname.h>
+#endif
main ()
{
#if defined (sony)
@@ -427,7 +487,7 @@ main ()
#endif
#if defined (__386BSD__)
- printf ("i386-unknown-bsd\n"); exit (0);
+ printf ("i386-pc-bsd\n"); exit (0);
#endif
#if defined (sequent)
@@ -440,7 +500,18 @@ main ()
#endif
#if defined (_SEQUENT_)
- printf ("i386-sequent-ptx\n"); exit (0);
+ struct utsname un;
+
+ uname(&un);
+
+ if (strncmp(un.version, "V2", 2) == 0) {
+ printf ("i386-sequent-ptx2\n"); exit (0);
+ }
+ if (strncmp(un.version, "V1", 2) == 0) { /* XXX is V1 correct? */
+ printf ("i386-sequent-ptx1\n"); exit (0);
+ }
+ printf ("i386-sequent-ptx\n"); exit (0);
+
#endif
#if defined (vax)
diff --git a/config.sub b/config.sub
index 5641cc1ce6..27819cc8dc 100755
--- a/config.sub
+++ b/config.sub
@@ -1,9 +1,9 @@
#! /bin/sh
# Configuration validation subroutine script, version 1.1.
-# Copyright (C) 1991, 1992, 1993, 1994, 1995 Free Software Foundation, Inc.
+# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc.
# This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME GNU software
-# can handle that machine. It does not imply ALL GNU software can.
+# can handle that machine. It does not imply ALL GNU software can.
#
# This file is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
@@ -17,7 +17,8 @@
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
-# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+# Foundation, Inc., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
# As a special exception to the GNU General Public License, if you
# distribute this file as part of a program that contains a
@@ -40,6 +41,8 @@
# The goal of this file is to map all the various variations of a given
# machine specification into a single specification in the form:
# CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or in some cases, the newer four-part form:
+# CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
# It is wrong to echo any other type of specification.
if [ x$1 = x ]
@@ -61,11 +64,21 @@ case $1 in
;;
esac
-# Separate what the user gave into CPU-COMPANY and OS (if any).
-basic_machine=`echo $1 | sed 's/-[^-]*$//'`
-if [ $basic_machine != $1 ]
-then os=`echo $1 | sed 's/.*-/-/'`
-else os=; fi
+# Separate what the user gave into CPU-COMPANY and OS or KERNEL-OS (if any).
+# Here we must recognize all the valid KERNEL-OS combinations.
+maybe_os=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\2/'`
+case $maybe_os in
+ linux-gnu*)
+ os=-$maybe_os
+ basic_machine=`echo $1 | sed 's/^\(.*\)-\([^-]*-[^-]*\)$/\1/'`
+ ;;
+ *)
+ basic_machine=`echo $1 | sed 's/-[^-]*$//'`
+ if [ $basic_machine != $1 ]
+ then os=`echo $1 | sed 's/.*-/-/'`
+ else os=; fi
+ ;;
+esac
### Let's recognize common machines as not being operating systems so
### that things like config.sub decstation-3100 work. We also
@@ -80,38 +93,43 @@ case $os in
-unicom* | -ibm* | -next | -hp | -isi* | -apollo | -altos* | \
-convergent* | -ncr* | -news | -32* | -3600* | -3100* | -hitachi* |\
-c[123]* | -convex* | -sun | -crds | -omron* | -dg | -ultra | -tti* | \
- -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp )
+ -harris | -dolphin | -highlevel | -gould | -cbm | -ns | -masscomp | \
+ -apple)
os=
basic_machine=$1
;;
-hiux*)
os=-hiuxwe2
;;
+ -sco5)
+ os=sco3.2v5
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
+ ;;
-sco4)
os=-sco3.2v4
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2.[4-9]*)
os=`echo $os | sed -e 's/sco3.2./sco3.2v/'`
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco3.2v[4-9]*)
# Don't forget version if it is 3.2v4 or newer.
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-sco*)
os=-sco3.2v2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-isc)
os=-isc2.2
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-clix*)
basic_machine=clipper-intergraph
;;
-isc*)
- basic_machine=`echo $1 | sed -e 's/86-.*/86-unknown/'`
+ basic_machine=`echo $1 | sed -e 's/86-.*/86-pc/'`
;;
-lynx*)
os=-lynxos
@@ -122,33 +140,43 @@ case $os in
-windowsnt*)
os=`echo $os | sed -e 's/windowsnt/winnt/'`
;;
+ -psos*)
+ os=-psos
+ ;;
esac
# Decode aliases for certain CPU-COMPANY combinations.
case $basic_machine in
# Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below.
- tahoe | i[345]86 | i860 | m68k | m68000 | m88k | ns32k | arm | pyramid \
+ tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \
+ | arme[lb] | pyramid \
| tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \
- | alpha | we32k | ns16k | clipper | sparclite | i370 | sh \
- | powerpc | sparc64 | 1750a | dsp16xx | mips64 | mipsel \
+ | alpha | we32k | ns16k | clipper | i370 | sh \
+ | powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \
| pdp11 | mips64el | mips64orion | mips64orionel \
- | sparc)
- basic_machine=$basic_machine-unknown
- ;;
+ | sparc | sparclet | sparclite | sparc64)
+ basic_machine=$basic_machine-unknown
+ ;;
+ # We use `pc' rather than `unknown'
+ # because (1) that's what they normally are, and
+ # (2) the word "unknown" tends to confuse beginning users.
+ i[3456]86)
+ basic_machine=$basic_machine-pc
+ ;;
# Object if more than one company name word.
*-*-*)
- echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
- exit 1
+ echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
+ exit 1
;;
# Recognize the basic CPU types with company name.
- vax-* | tahoe-* | i[345]86-* | i860-* | m68k-* | m68000-* | m88k-* \
+ vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \
| sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \
- | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
+ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \
| none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \
| hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \
| pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \
- | pdp11-* | sh-* | powerpc-* | sparc64-* | mips64-* | mipsel-* \
+ | pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-*)
;;
# Recognize the various machine names and aliases which stand
@@ -188,6 +216,10 @@ case $basic_machine in
basic_machine=m68k-apollo
os=-sysv
;;
+ aux)
+ basic_machine=m68k-apple
+ os=-aux
+ ;;
balance)
basic_machine=ns32k-sequent
os=-dynix
@@ -220,6 +252,10 @@ case $basic_machine in
basic_machine=cray2-cray
os=-unicos
;;
+ [ctj]90-cray)
+ basic_machine=c90-cray
+ os=-unicos
+ ;;
crds | unos)
basic_machine=m68k-crds
;;
@@ -256,6 +292,10 @@ case $basic_machine in
encore | umax | mmax)
basic_machine=ns32k-encore
;;
+ ews4800)
+ basic_machine=mips-nec
+ os=-sysv4
+ ;;
fx2800)
basic_machine=i860-alliant
;;
@@ -306,20 +346,20 @@ case $basic_machine in
os=-mvs
;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2?
- i[345]86v32)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[3456]86v32)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32
;;
- i[345]86v4*)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[3456]86v4*)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4
;;
- i[345]86v)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[3456]86v)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv
;;
- i[345]86sol2)
- basic_machine=`echo $1 | sed -e 's/86.*/86-unknown/'`
+ i[3456]86sol2)
+ basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2
;;
iris | iris4d)
@@ -417,14 +457,41 @@ case $basic_machine in
pc532 | pc532-*)
basic_machine=ns32k-pc532
;;
- pentium-*)
- # We will change tis to say i586 once there has been
- # time for various packages to start to recognize that.
- basic_machine=i486-`echo $basic_machine | sed 's/^[^-]*-//'`
+ pentium | p5)
+ basic_machine=i586-intel
+ ;;
+ pentiumpro | p6)
+ basic_machine=i686-intel
+ ;;
+ pentium-* | p5-*)
+ basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ pentiumpro-* | p6-*)
+ basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ k5)
+ # We don't have specific support for AMD's K5 yet, so just call it a Pentium
+ basic_machine=i586-amd
+ ;;
+ nexen)
+ # We don't have specific support for Nexgen yet, so just call it a Pentium
+ basic_machine=i586-nexgen
;;
pn)
basic_machine=pn-gould
;;
+ power) basic_machine=rs6000-ibm
+ ;;
+ ppc) basic_machine=powerpc-unknown
+ ;;
+ ppc-*) basic_machine=powerpc-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
+ ppcle | powerpclittle | ppc-le | powerpc-little)
+ basic_machine=powerpcle-unknown
+ ;;
+ ppcle-* | powerpclittle-*)
+ basic_machine=powerpcle-`echo $basic_machine | sed 's/^[^-]*-//'`
+ ;;
ps2)
basic_machine=i386-ibm
;;
@@ -519,6 +586,10 @@ case $basic_machine in
basic_machine=m68k-wrs
os=-vxworks
;;
+ vxworks29k)
+ basic_machine=a29k-wrs
+ os=-vxworks
+ ;;
xmp)
basic_machine=xmp-cray
os=-unicos
@@ -586,6 +657,8 @@ esac
if [ x"$os" != x"" ]
then
case $os in
+ # First match some system type aliases
+ # that might get confused with valid system types.
# -solaris* is a basic system type, with this one exception.
-solaris1 | -solaris1.*)
os=`echo $os | sed -e 's|solaris1|sunos4|'`
@@ -597,21 +670,25 @@ case $os in
os=-sysv4
;;
-gnu/linux*)
- os=`echo $os | sed -e 's|gnu/linux|linux|'`
+ os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;;
# First accept the basic system types.
# The portable systems comes first.
- # Each alternative must end in a *, to match a version number.
+ # Each alternative MUST END IN A *, to match a version number.
# -sysv* is not here because it comes later, after sysvr4.
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
- | -vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[345]* \
+ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
- | -amigados* | -msdos* | -newsos* | -unicos* | -aos* \
+ | -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \
| -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \
- | -riscos* | -linux* | -uniplus* | -iris* | -rtu* | -xenix* \
+ | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
- | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta | -udi | -eabi)
+ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
+ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
+ | -cygwin32* | -pe* | -psos* | -moss* | -proelf* \
+ | -linux*)
+ # Remember, each alternative MUST END IN *, to match a version number.
;;
-sunos5*)
os=`echo $os | sed -e 's|sunos5|solaris2|'`
@@ -637,6 +714,9 @@ case $os in
-ctix* | -uts*)
os=-sysv
;;
+ -ns2 )
+ os=-nextstep2
+ ;;
# Preserve the version number of sinix5.
-sinix5.*)
os=`echo $os | sed -e 's|sinix|sysv|'`
@@ -690,6 +770,9 @@ case $basic_machine in
*-acorn)
os=-riscix1.2
;;
+ arm*-semi)
+ os=-aout
+ ;;
pdp11-*)
os=-none
;;
@@ -741,6 +824,9 @@ case $basic_machine in
m88k-omron*)
os=-luna
;;
+ *-next )
+ os=-nextstep
+ ;;
*-sequent)
os=-ptx
;;
@@ -825,6 +911,9 @@ case $basic_machine in
-vxworks*)
vendor=wrs
;;
+ -aux*)
+ vendor=apple
+ ;;
esac
basic_machine=`echo $basic_machine | sed "s/unknown/$vendor/"`
;;
diff --git a/configure.bat b/configure.bat
new file mode 100644
index 0000000000..84e5191bbe
--- /dev/null
+++ b/configure.bat
@@ -0,0 +1,5 @@
+@echo off
+sed -f top.sed Makefile.in >Makefile
+sed -f top.sed ext/extmk.rb.in > ext\extmk.rb
+copy ext\Setup.dj ext\Setup
+copy config.dj config.h
diff --git a/configure.in b/configure.in
index fc87754cb8..7f89f5e69c 100644
--- a/configure.in
+++ b/configure.in
@@ -21,6 +21,17 @@ then
(it is also a good idea to do 'make clean' before compiling))
fi
+dnl checks for thread
+rb_thread=yes
+AC_ARG_ENABLE(thread, [--disable-thread never use user-level thread], [
+ rb_thread=$enableval
+])
+if test $rb_thread = yes; then
+ AC_DEFINE(THREAD)
+fi
+
+AC_CANONICAL_HOST
+
dnl Checks for programs.
AC_PROG_CC
AC_PROG_GCC_TRADITIONAL
@@ -29,19 +40,18 @@ AC_PROG_INSTALL
AC_PROG_MAKE_SET
# checks for UNIX variants that set C preprocessor variables
-AC_AIX
AC_MINIX
dnl Checks for libraries.
AC_CHECK_LIB(crypt, crypt)
-AC_CHECK_LIB(dl, dlopen, [:]) # Dynamic linking for SunOS/Solaris and SYSV
+AC_CHECK_LIB(dl, dlopen) # Dynamic linking for SunOS/Solaris and SYSV
AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX
dnl Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
-AC_CHECK_HEADERS(limits.h sys/file.h sys/ioctl.h pwd.h\
- sys/time.h sys/times.h sys/param.h unistd.h\
+AC_CHECK_HEADERS(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)
dnl Checks for typedefs, structures, and compiler characteristics.
@@ -57,40 +67,75 @@ AC_TYPE_SIGNAL
AC_FUNC_ALLOCA
AC_FUNC_VFORK
AC_REPLACE_FUNCS(dup2 setenv memmove mkdir strerror strftime\
- strstr strtoul strdup crypt)
+ strstr strtoul strdup strcasecmp crypt flock)
AC_CHECK_FUNCS(fmod killpg random wait4 waitpid syscall getcwd\
- truncate chsize times utimes fcntl\
+ truncate chsize times utimes fcntl lockf setitimer\
setruid seteuid setreuid setrgid setegid setregid\
- getgroups getpriority sigprocmask dlopen)
-if test "$ac_cv_func strftime" = no; then
+ getgroups getpgid getpriority dlopen sigprocmask sigaction)
+if test "$ac_cv_func_strftime" = no; then
AC_STRUCT_TIMEZONE
AC_TRY_LINK([],
[extern int daylight; int i = daylight;], AC_DEFINE(HAVE_DAYLIGHT))
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_TRY_RUN([
+#include <stdio.h>
+#include <signal.h>
+
+void sig_handler(dummy)
+ int dummy;
+{
+}
+
+int main(argc, argv)
+ int argc;
+ char ** argv;
+{
+ signal(SIGINT, sig_handler);
+ kill(getpid(), SIGINT);
+ kill(getpid(), SIGINT);
+ return 0;
+}
+],
+ rb_cv_bsd_signal=yes,
+ 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
+
AC_C_BIGENDIAN
+AC_CHAR_UNSIGNED
AC_MSG_CHECKING([count field in FILE structures])
AC_CACHE_VAL(rb_cv_fcnt,
[AC_TRY_COMPILE([#include <stdio.h>],
[FILE *f = stdin; f->_cnt = 0;], rb_cv_fcnt="_cnt", )
-if test "$rb_cv_fcnt=" = ""; then
+if test "$rb_cv_fcnt" = ""; then
AC_TRY_COMPILE([#include <stdio.h>],
[FILE *f = stdin; f->__cnt = 0;], rb_cv_fcnt="__cnt", )
fi
-if test "$rb_cv_fcnt=" = ""; then
+if test "$rb_cv_fcnt" = ""; then
AC_TRY_COMPILE([#include <stdio.h>],
[FILE *f = stdin; f->_r = 0;], rb_cv_fcnt="_r", )
fi
-if test "$rb_cv_fcnt=" = ""; then
+if test "$rb_cv_fcnt" = ""; then
AC_TRY_COMPILE([#include <stdio.h>],
- [FILE *f = stdin; f->readCount = 0;], rb_cv_fcnt="readCount", )
+ [FILE *f = stdin; f->readCount = 0;],
+ rb_cv_fcnt="readCount", rb_cv_fcnt="not found")
fi])
-if test "$rb_cv_fcnt"; then
+if test "$rb_cv_fcnt" = "not found"; then
+ AC_MSG_RESULT([not found(OK if using GNU libc)])
+else
AC_MSG_RESULT($rb_cv_fcnt)
AC_DEFINE_UNQUOTED(FILE_COUNT, $rb_cv_fcnt)
-else
- AC_MSG_RESULT([not found(OK if using GNU libc)])
fi
if test "$ac_cv_func_getpwent" = yes; then
@@ -105,31 +150,45 @@ if test "$ac_cv_func_getpwent" = yes; then
fi
dnl wheather use dln_a_out ot not
-AC_ARG_WITH(dln-a-out, [--with-dln-a-out use dln_a_out if possible], [
+AC_ARG_WITH(dln-a-out, [--with-dln-a-out use dln_a_out if possible], [
case $withval in
yes) with_dln_a_out=yes;;
*) with_dln_a_out=no;;
esac], [with_dln_a_out=no])
-if test "$with_dln_a_out" = yes && test "$ac_cv_header_a_out_h" = yes; then
-
- AC_MSG_CHECKING(whether matz's dln works)
- cat confdefs.h > config.h
- AC_CACHE_VAL(rb_cv_dln_a_out,
- [AC_TRY_COMPILE([
-#define USE_DLN_A_OUT
-#include "dln.c"
+case "$host_os" in
+ linux*)
+ AC_MSG_CHECKING(whether ELF binaries are produced)
+ AC_CACHE_VAL(rb_cv_linux_elf,
+ [AC_TRY_RUN([
+/* Test for whether ELF binaries are produced */
+#include <fcntl.h>
+#include <stdlib.h>
+main() {
+ char buffer[4];
+ int i=open("conftest",O_RDONLY);
+ if(i==-1)
+ exit(1); /* fail */
+ if(read(i,&buffer[0],4)<4)
+ exit(1); /* fail */
+ if(buffer[0] != 127 || buffer[1] != 'E' ||
+ buffer[2] != 'L' || buffer[3] != 'F')
+ exit(1); /* fail */
+ exit(0); /* succeed (yes, it's ELF) */
+}
],
- [],
- 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
- AC_DEFINE(USE_DLN_A_OUT)
- fi
-else
- rb_cv_dln_a_out=no
-fi
+ 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
+ with_dln_a_out=yes
+ else
+ LDFLAGS="-rdynamic"
+ fi;;
+esac
+
+AC_SUBST(DLDFLAGS)dnl
AC_SUBST(STATIC)dnl
AC_SUBST(CCDLFLAGS)dnl
@@ -138,7 +197,63 @@ AC_SUBST(DLEXT)dnl
STATIC=
-if test "$rb_cv_dln_a_out" = yes; then
+if test "$with_dln_a_out" != yes; then
+ rb_cv_dlopen=unknown
+ AC_MSG_CHECKING(whether OS depend dynamic link works)
+ if test "$GCC" = yes; then
+ CCDLFLAGS=-fpic
+ else
+ case "$host_os" in
+ hpux*) CCDLFLAGS='+z';;
+ solaris*|irix*) CCDLFLAGS='-K pic' ;;
+ sunos*) CCDLFLAGS='-pic' ;;
+ svr4*|esix*) CCDLFLAGS='-Kpic' ;;
+ *) CCDLFLAGS='' ;;
+ esac
+ fi
+
+ case "$host_os" in
+ hpux*) DLDFLAGS="-E"
+ LDSHARED='ld -b'
+ LDFLAGS="-Wl,-E"
+ rb_cv_dlopen=yes;;
+ solaris*) LDSHARED='ld -G'
+ rb_cv_dlopen=yes;;
+ sunos*) LDSHARED='ld -assert nodefinitions'
+ rb_cv_dlopen=yes;;
+ svr4*|esix*) LDSHARED="ld -G"
+ rb_cv_dlopen=yes ;;
+ linux*) LDSHARED="gcc -shared"
+ rb_cv_dlopen=yes ;;
+ freebsd*) LDSHARED="ld -Bshareable"
+ rb_cv_dlopen=yes ;;
+ *) LDSHARED='ld' ;;
+ esac
+ AC_MSG_RESULT($rb_cv_dlopen)
+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_TRY_COMPILE([
+#define USE_DLN_A_OUT
+#include "dln.c"
+],
+ [],
+ 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)
+ fi
+ fi
+fi
+
+if test "$dln_a_out_works" = yes; then
if test "$GCC" = yes; then
STATIC=-static
else
@@ -147,45 +262,48 @@ if test "$rb_cv_dln_a_out" = yes; then
DLEXT=o
AC_DEFINE(DLEXT, ".o")
CCDLFLAGS=
- LDCMD=
-
else
-
- AC_CANONICAL_HOST
case "$host_os" in
hpux*) DLEXT=sl
AC_DEFINE(DLEXT, ".sl");;
+ nextstep*) DLEXT=o
+ AC_DEFINE(DLEXT, ".o");;
*) DLEXT=so
AC_DEFINE(DLEXT, ".so");;
esac
+fi
- if test "$GCC" = yes; then
- CCDLFLAGS=-fpic
- else
- case "$host_os" in
- hpux*) CCDLFLAGS='+z';;
- solaris*|irix*) CCDLFLAGS='-K pic' ;;
- sunos*) CCDLFLAGS='-pic' ;;
- svr4*|esix*) CCDLFLAGS='-Kpic' ;;
- *) CCDLFLAGS='' ;;
- esac
- fi
-
- case "$host_os" in
- hpux*) LDSHARED='ld -b' ;;
- solaris*) LDSHARED='ld -G' ;;
- sunos*) LDSHARED='ld -assert nodefinitions' ;;
- svr4*|esix*) LDSHARED="ld -G" ;;
- linux*) LDSHARED="gcc-elf -shared" ;;
- *) LDSHARED='ld' ;;
- esac
+AC_SUBST(STRIP)dnl
+if test "$with_dln_a_out" = yes; then
+ STRIP=true
+else
+ STRIP=strip
fi
+case "$host_os" in
+ linux*)
+ STRIP='strip -S -x';;
+ nextstep*)
+ STRIP='strip -A -n';;
+esac
+
+EXTSTATIC=
+AC_SUBST(EXTSTATIC)dnl
+AC_ARG_WITH(static-linked-ext,
+ [--with-static-linked-ext link external modules statically],
+ [case $withval in
+ yes) STATIC=
+ EXTSTATIC=static;;
+ *) ;;
+ esac])
+
if test "$prefix" = NONE; then
- AC_DEFINE_UNQUOTED(RUBY_LIB, ".:${ac_default_prefix}/lib/ruby")
-else
- AC_DEFINE_UNQUOTED(RUBY_LIB, ".:${prefix}/lib/ruby")
+ prefix=$ac_default_prefix
fi
+AC_DEFINE_UNQUOTED(RUBY_LIB, "${prefix}/lib/ruby:.")
+AC_SUBST(archlib)dnl
+archlib="${prefix}/lib/ruby/${host_cpu}-${host_os}"
+AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "$archlib")
echo "creating config.h"
cat confdefs.h > config.h
diff --git a/defines.h b/defines.h
index 2eb509f214..bef61b00fa 100644
--- a/defines.h
+++ b/defines.h
@@ -16,10 +16,21 @@
#define EUC
#undef SJIS
-#define SAFE_SIGHANDLE
+#ifdef NeXT
+#define S_IXUSR _S_IXUSR /* execute/search permission, owner */
+#define S_IXGRP 0000010 /* execute/search permission, group */
+#define S_IXOTH 0000001 /* execute/search permission, other */
+#define S_ISREG(mode) (((mode) & (_S_IFMT)) == (_S_IFREG))
+#endif /* NeXT */
#ifdef NT
#include "missing/nt.h"
#endif
+#ifdef sparc
+#define FLUSH_REGISTER_WINDOWS asm("ta 3")
+#else
+#define FLUSH_REGISTER_WINDOWS /* empty */
+#endif
+
#endif
diff --git a/dir.c b/dir.c
index f291b94da2..a1a6114406 100644
--- a/dir.c
+++ b/dir.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:28 $
created at: Wed Jan 5 09:51:01 JST 1994
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -43,10 +43,11 @@
# endif
#endif
+#include <errno.h>
+
char *getenv();
static VALUE cDir;
-static ID id_dir;
static void
free_dir(dir)
@@ -66,11 +67,17 @@ dir_s_open(dir_class, dirname)
Check_Type(dirname, T_STRING);
dirp = opendir(dirname->ptr);
- if (dirp == NULL) Fail("Can't open directory %s", dirname->ptr);
+ if (dirp == NULL) {
+ if (errno == EMFILE || errno == ENFILE) {
+ gc();
+ dirp = opendir(dirname->ptr);
+ }
+ if (dirp == NULL) {
+ rb_sys_fail(dirname->ptr);
+ }
+ }
- obj = obj_alloc(dir_class);
- if (!id_dir) id_dir = rb_intern("dir");
- Make_Data_Struct(obj, id_dir, DIR*, 0, free_dir, d);
+ obj = Make_Data_Struct(dir_class, DIR*, 0, free_dir, d);
*d = dirp;
return obj;
@@ -84,8 +91,7 @@ closeddir()
#define GetDIR(obj, dirp) {\
DIR **_dp;\
- if (!id_dir) id_dir = rb_intern("dir");\
- Get_Data_Struct(obj, id_dir, DIR*, _dp);\
+ Get_Data_Struct(obj, DIR*, _dp);\
dirp = *_dp;\
if (dirp == NULL) closeddir();\
}
@@ -94,14 +100,14 @@ static VALUE
dir_each(dir)
VALUE dir;
{
- extern VALUE rb_lastline;
DIR *dirp;
struct dirent *dp;
+ VALUE file;
GetDIR(dir, dirp);
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
- rb_lastline = str_new(dp->d_name, NAMLEN(dp));
- rb_yield(rb_lastline);
+ file = str_new(dp->d_name, NAMLEN(dp));
+ rb_yield(file);
}
return dir;
}
@@ -113,9 +119,13 @@ dir_tell(dir)
DIR *dirp;
int pos;
+#if !defined(__CYGWIN32__)
GetDIR(dir, dirp);
pos = telldir(dirp);
return int2inum(pos);
+#else
+ rb_notimplement();
+#endif
}
static VALUE
@@ -124,9 +134,13 @@ dir_seek(dir, pos)
{
DIR *dirp;
+#if !defined(__CYGWIN32__)
GetDIR(dir, dirp);
seekdir(dirp, NUM2INT(pos));
return dir;
+#else
+ rb_notimplement();
+#endif
}
static VALUE
@@ -146,8 +160,8 @@ dir_close(dir)
{
DIR **dirpp;
- Get_Data_Struct(dir, id_dir, DIR*, dirpp);
- if (*dirpp == NULL) Fail("already closed directory");
+ Get_Data_Struct(dir, DIR*, dirpp);
+ if (*dirpp == NULL) closeddir();
closedir(*dirpp);
*dirpp = NULL;
@@ -176,7 +190,7 @@ dir_s_chdir(argc, argv, obj)
}
if (chdir(dist) < 0)
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
return INT2FIX(0);
}
@@ -189,9 +203,9 @@ dir_s_getwd(dir)
char path[MAXPATHLEN];
#ifdef HAVE_GETCWD
- if (getcwd(path, sizeof(path)) == 0) Fail(path);
+ if (getcwd(path, sizeof(path)) == 0) rb_sys_fail(path);
#else
- if (getwd(path) == 0) Fail(path);
+ if (getwd(path) == 0) rb_sys_fail(path);
#endif
return str_new2(path);
@@ -201,12 +215,16 @@ static VALUE
dir_s_chroot(dir, path)
VALUE dir, path;
{
+#if !defined(DJGPP) && !defined(__CYGWIN32__)
Check_Type(path, T_STRING);
if (chroot(RSTRING(path)->ptr) == -1)
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
return INT2FIX(0);
+#else
+ rb_notimplement();
+#endif
}
static VALUE
@@ -346,6 +364,17 @@ dir_s_glob(dir, str)
return ary;
}
+static VALUE
+dir_foreach(io, dirname)
+ VALUE io;
+ struct RString *dirname;
+{
+ VALUE dir;
+
+ dir = dir_s_open(cDir, dirname);
+ return rb_ensure(dir_each, dir, dir_close, dir);
+}
+
void
Init_Dir()
{
@@ -356,6 +385,7 @@ Init_Dir()
rb_include_module(cDir, mEnumerable);
rb_define_singleton_method(cDir, "open", dir_s_open, 1);
+ rb_define_singleton_method(cDir, "foreach", dir_foreach, 1);
rb_define_method(cDir,"each", dir_each, 0);
rb_define_method(cDir,"rewind", dir_rewind, 0);
diff --git a/dln.c b/dln.c
index 84ffef3aac..b4005e973c 100644
--- a/dln.c
+++ b/dln.c
@@ -6,10 +6,14 @@
$Date: 1994/12/09 01:28:23 $
created at: Tue Jan 18 17:05:06 JST 1994
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
+#ifdef _AIX
+#pragma alloca
+#endif
+
#include "config.h"
#include "defines.h"
#include "dln.h"
@@ -57,7 +61,7 @@ int eaccess();
#endif
#ifndef FUNCNAME_PATTERN
-# if defined(hpux) || defined(__NetBSD__) || defined(__BORLANDC__)
+# if defined(__hp9000s300) || defined(__NetBSD__) || defined(__BORLANDC__) || defined(__FreeBSD__)
# define FUNCNAME_PATTERN "_Init_%.200s"
# else
# define FUNCNAME_PATTERN "Init_%.200s"
@@ -276,7 +280,7 @@ sym_hash(hdrp, syms)
struct nlist *sym = syms;
struct nlist *end = syms + (hdrp->a_syms / sizeof(struct nlist));
- tbl = st_init_table(strcmp, st_strhash);
+ tbl = st_init_strtable();
if (tbl == NULL) {
dln_errno = errno;
return NULL;
@@ -345,12 +349,11 @@ dln_init(prog)
p++;
}
*p = '\0';
- printf("%s\n", buf);
return dln_init(buf);
}
dln_init_p = 1;
- undef_tbl = st_init_table(strcmp, st_strhash);
+ undef_tbl = st_init_strtable();
close(fd);
return 0;
@@ -462,7 +465,7 @@ link_undef(name, base, reloc)
break;
}
if (reloc_tbl == NULL) {
- reloc_tbl = st_init_table(ST_NUMCMP, ST_NUMHASH);
+ reloc_tbl = st_init_numtable();
}
st_insert(reloc_tbl, u_no++, obj);
}
@@ -548,6 +551,25 @@ unlink_undef(name, value)
st_foreach(reloc_tbl, reloc_undef, &arg);
}
+#ifdef N_INDR
+struct indr_data {
+ char *name0, *name1;
+};
+
+static int
+reloc_repl(no, undef, data)
+ int no;
+ struct undef *undef;
+ struct indr_data *data;
+{
+ if (strcmp(data->name0, undef->name) == 0) {
+ free(undef->name);
+ undef->name = strdup(data->name1);
+ }
+ return ST_CONTINUE;
+}
+#endif
+
static int
load_1(fd, disp, need_init)
int fd;
@@ -581,6 +603,32 @@ load_1(fd, disp, need_init)
struct nlist *old_sym;
int value = sym->n_value;
+#ifdef N_INDR
+ if (sym->n_type == (N_INDR | N_EXT)) {
+ char *key = sym->n_un.n_name;
+
+ if (st_lookup(sym_tbl, sym[1].n_un.n_name, &old_sym)) {
+ if (st_delete(undef_tbl, &key, NULL)) {
+ unlink_undef(key, old_sym->n_value);
+ free(key);
+ }
+ }
+ else {
+ struct indr_data data;
+
+ data.name0 = sym->n_un.n_name;
+ data.name1 = sym[1].n_un.n_name;
+ st_foreach(reloc_tbl, reloc_repl, &data);
+
+ st_insert(undef_tbl, strdup(sym[1].n_un.n_name), NULL);
+ if (st_delete(undef_tbl, &key, NULL)) {
+ free(key);
+ }
+ }
+ sym += 2;
+ continue;
+ }
+#endif
if (sym->n_type == (N_UNDF | N_EXT)) {
if (st_lookup(sym_tbl, sym->n_un.n_name, &old_sym) == 0) {
old_sym = NULL;
@@ -624,7 +672,7 @@ load_1(fd, disp, need_init)
sym = syms;
while (sym < end) {
struct nlist *new_sym;
- char *key;
+ char *key, *name;
switch (sym->n_type) {
case N_COMM:
@@ -764,7 +812,7 @@ load_1(fd, disp, need_init)
if (strcmp(name+1, "libs_to_be_linked") == 0) {
libs_to_be_linked = (char**)sym->n_value;
}
- if (strcmp(name+1, buf) == 0) {
+ else if (strcmp(name+1, buf) == 0) {
init_p = 1;
((int (*)())sym->n_value)();
}
@@ -808,6 +856,7 @@ search_undef(key, value, lib_tbl)
int value;
st_table *lib_tbl;
{
+#if 0
static char *last = "";
int offset;
@@ -817,6 +866,13 @@ search_undef(key, value, lib_tbl)
target_offset = offset;
}
return ST_STOP;
+#else
+ int offset;
+
+ if (st_lookup(lib_tbl, key, &offset) == 0) return ST_CONTINUE;
+ target_offset = offset;
+ return ST_STOP;
+#endif
}
struct symdef {
@@ -879,7 +935,7 @@ load_lib(lib)
if (strncmp(ahdr.ar_name, "__.SYMDEF", 9) == 0) {
/* make hash table from __.SYMDEF */
- lib_tbl = st_init_table(strcmp, st_strhash);
+ lib_tbl = st_init_strtable();
data = (int*)xmalloc(size);
if (data == NULL) goto syserr;
size = read(fd, data, size);
@@ -1020,6 +1076,11 @@ dln_sym(name)
#include <ctype.h> /* for isdigit() */
#include <errno.h> /* for global errno */
#include <string.h> /* for strerror() */
+#include <sys/ldr.h>
+#endif
+
+#ifdef NeXT
+/*#include <mach-o/rld.h>*/
#endif
static char *
@@ -1095,8 +1156,8 @@ aix_loaderror(char *pathname)
ERRBUF_APPEND("\n");
}
errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
- Fail(errbuf);
-return;
+ LoadError(errbuf);
+ return;
}
#endif
@@ -1125,9 +1186,12 @@ dln_load(file)
# ifndef RTLD_LAZY
# define RTLD_LAZY 1
# endif
+# ifndef RTLD_GLOBAL
+# define RTLD_GLOBAL 0
+# endif
/* Load file */
- if ((handle = dlopen(file, RTLD_LAZY)) == NULL) {
+ if ((handle = dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {
goto failed;
}
@@ -1150,13 +1214,14 @@ dln_load(file)
flags = BIND_DEFERRED;
lib = shl_load(file, flags, 0);
if (lib == NULL) {
- char buf[256];
- Fail("Failed to load %.200s", file);
+ rb_sys_fail(file);
}
shl_findsym(&lib, buf, TYPE_PROCEDURE, (void*)&init_fct);
if (init_fct == NULL) {
- shl_findsym(&lib, buf, TYPE_DATA, (void*)&init_fct);
+ shl_findsym(&lib, buf, TYPE_UNDEFINED, (void*)&init_fct);
if (init_fct == NULL) {
+ extern int errno;
+ errno = ENOSYM;
rb_sys_fail(file);
}
}
@@ -1179,14 +1244,54 @@ dln_load(file)
}
#endif /* _AIX */
+#ifdef NeXT
+#define DLN_DEFINED
+/*----------------------------------------------------
+ By SHIROYAMA Takayuki Psi@fortune.nest.or.jp
+
+ Special Thanks...
+ Yu tomoak-i@is.aist-nara.ac.jp,
+ Mi hisho@tasihara.nest.or.jp,
+ and... Miss ARAI Akino(^^;)
+ ----------------------------------------------------*/
+ {
+ unsigned long init_address;
+ char *object_files[2] = {NULL, NULL};
+
+ void (*init_fct)();
+ int len = strlen(file);
+ char *point;
+ char init_name[len +7];
+
+ object_files[0] = file;
+
+ /* Load object file, if return value ==0 , load failed*/
+ if(rld_load(NULL, NULL, object_files, NULL) == 0) {
+ LoadError("Failed to load %.200s", file);
+ }
+
+ /* lookup the initial function */
+ if(rld_lookup(NULL, buf, &init_address) == 0) {
+ LoadError("Failed to lookup Init function %.200s",file);
+ }
+
+ /* Cannot call *init_address directory, so copy this value to
+ funtion pointer */
+
+ init_fct = (void(*)())init_address;
+ (*init_fct)();
+ return ;
+ }
+#endif
+
#ifndef DLN_DEFINED
- Fail("dynamic link not supported");
+ rb_notimplement("dynamic link not supported");
#endif
#endif /* USE_DLN_A_OUT */
-#ifndef _AIX
+#if !defined(_AIX) && !defined(NeXT)
failed:
- Fail("%s - %s", dln_strerror(), file);
+ LoadError("%s - %s", dln_strerror(), file);
#endif
}
@@ -1228,8 +1333,7 @@ dln_find_1(fname, path, exe_flag)
if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0)
return fname;
- for (dp = path;; dp = ++ep)
- {
+ for (dp = path;; dp = ++ep) {
register int l;
int i;
int fspace;
@@ -1243,8 +1347,7 @@ dln_find_1(fname, path, exe_flag)
l = ep - dp;
bp = fbuf;
fspace = sizeof fbuf - 2;
- if (l > 0)
- {
+ if (l > 0) {
/*
** If the length of the component is zero length,
** start from the current directory. If the
@@ -1253,13 +1356,11 @@ dln_find_1(fname, path, exe_flag)
** take the path literally.
*/
- if (*dp == '~' && (l == 1 || dp[1] == '/'))
- {
+ if (*dp == '~' && (l == 1 || dp[1] == '/')) {
char *home;
home = getenv("HOME");
- if (home != NULL)
- {
+ if (home != NULL) {
i = strlen(home);
if ((fspace -= i) < 0)
goto toolong;
@@ -1269,8 +1370,7 @@ dln_find_1(fname, path, exe_flag)
dp++;
l--;
}
- if (l > 0)
- {
+ if (l > 0) {
if ((fspace -= l) < 0)
goto toolong;
memcpy(bp, dp, l);
@@ -1284,9 +1384,8 @@ dln_find_1(fname, path, exe_flag)
/* now append the file name */
i = strlen(fname);
- if ((fspace -= i) < 0)
- {
- toolong:
+ if ((fspace -= i) < 0) {
+ toolong:
fprintf(stderr, "openpath: pathname too long (ignored)\n");
*bp = '\0';
fprintf(stderr, "\tDirectory \"%s\"\n", fbuf);
diff --git a/enum.c b/enum.c
index df277a504a..39c09dbec8 100644
--- a/enum.c
+++ b/enum.c
@@ -6,20 +6,19 @@
$Date: 1995/01/10 10:42:29 $
created at: Fri Oct 1 15:15:19 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
#include "ruby.h"
VALUE mEnumerable;
-static ID id_each, id_match, id_cmp;
+static ID id_each, id_eqq, id_cmp;
void
rb_each(obj)
VALUE obj;
{
- if (!id_each) id_each = rb_intern("each");
rb_funcall(obj, id_each, 0, 0);
}
@@ -27,8 +26,7 @@ static void
grep_i(i, arg)
VALUE i, *arg;
{
- if (!id_match) id_match = rb_intern("=~");
- if (rb_funcall(arg[0], id_match, 1, i)) {
+ if (RTEST(rb_funcall(arg[0], id_eqq, 1, i))) {
ary_push(arg[1], i);
}
}
@@ -37,8 +35,7 @@ static void
grep_iter_i(i, pat)
VALUE i, pat;
{
- if (!id_match) id_match = rb_intern("=~");
- if (rb_funcall(pat, id_match, 1, i)) {
+ if (RTEST(rb_funcall(pat, id_eqq, 1, i))) {
rb_yield(i);
}
}
@@ -61,33 +58,47 @@ enum_grep(obj, pat)
}
}
+struct find_arg {
+ int found;
+ VALUE val;
+};
+
static void
-find_i(i, foundp)
+find_i(i, arg)
VALUE i;
- int *foundp;
+ struct find_arg *arg;
{
- if (rb_yield(i)) {
- *foundp = TRUE;
+ if (RTEST(rb_yield(i))) {
+ arg->found = TRUE;
+ arg->val = i;
rb_break();
}
}
static VALUE
-enum_find(obj)
+enum_find(argc, argv, obj)
+ int argc;
+ VALUE argv;
VALUE obj;
{
- int enum_found;
-
- enum_found = FALSE;
- rb_iterate(rb_each, obj, find_i, &enum_found);
- return enum_found;
+ struct find_arg arg;
+ VALUE if_none;
+
+ rb_scan_args(argc, argv, "01", &if_none);
+ arg.found = FALSE;
+ rb_iterate(rb_each, obj, find_i, &arg);
+ if (arg.found) {
+ return arg.val;
+ }
+ if (NIL_P(if_none)) return Qnil;
+ return rb_eval_cmd(if_none, Qnil);
}
static void
find_all_i(i, tmp)
VALUE i, tmp;
{
- if (rb_yield(i)) {
+ if (RTEST(rb_yield(i))) {
ary_push(tmp, i);
}
}
@@ -99,7 +110,7 @@ enum_find_all(obj)
VALUE tmp;
tmp = ary_new();
- rb_iterate(rb_each, obj, find_all_i, 0);
+ rb_iterate(rb_each, obj, find_all_i, tmp);
return tmp;
}
@@ -111,7 +122,7 @@ collect_i(i, tmp)
VALUE retval;
retval = rb_yield(i);
- if (retval) {
+ if (RTEST(retval)) {
ary_push(tmp, retval);
}
}
@@ -179,23 +190,37 @@ min_i(i, min)
{
VALUE cmp;
- if (*min == Qnil)
+ if (NIL_P(*min))
*min = i;
else {
- if (!id_cmp) id_cmp = rb_intern("<=>");
cmp = rb_funcall(i, id_cmp, 1, *min);
if (FIX2INT(cmp) < 0)
*min = i;
}
}
+static void
+min_ii(i, min)
+ VALUE i, *min;
+{
+ VALUE cmp;
+
+ if (NIL_P(*min))
+ *min = i;
+ else {
+ cmp = rb_yield(assoc_new(i, *min));
+ if (FIX2INT(cmp) < 0)
+ *min = i;
+ }
+}
+
static VALUE
enum_min(obj)
VALUE obj;
{
VALUE min = Qnil;
- rb_iterate(rb_each, obj, min_i, &min);
+ rb_iterate(rb_each, obj, iterator_p()?min_ii:min_i, &min);
return min;
}
@@ -205,23 +230,37 @@ max_i(i, max)
{
VALUE cmp;
- if (*max == Qnil)
+ if (NIL_P(*max))
*max = i;
else {
- if (!id_cmp) id_cmp = rb_intern("<=>");
cmp = rb_funcall(i, id_cmp, 1, *max);
if (FIX2INT(cmp) > 0)
*max = i;
}
}
+static void
+max_ii(i, max)
+ VALUE i, *max;
+{
+ VALUE cmp;
+
+ if (NIL_P(*max))
+ *max = i;
+ else {
+ cmp = rb_yield(assoc_new(i, *max));
+ if (FIX2INT(cmp) > 0)
+ *max = i;
+ }
+}
+
static VALUE
enum_max(obj)
VALUE obj;
{
VALUE max = Qnil;
- rb_iterate(rb_each, obj, max_i, &max);
+ rb_iterate(rb_each, obj, iterator_p()?max_ii:max_i, &max);
return max;
}
@@ -291,7 +330,7 @@ length_i(i, length)
(*length)++;
}
-static VALUE
+VALUE
enum_length(obj)
VALUE obj;
{
@@ -310,7 +349,7 @@ Init_Enumerable()
rb_define_method(mEnumerable,"sort", enum_sort, 0);
rb_define_method(mEnumerable,"grep", enum_grep, 1);
- rb_define_method(mEnumerable,"find", enum_find, 0);
+ rb_define_method(mEnumerable,"find", enum_find, -1);
rb_define_method(mEnumerable,"find_all", enum_find_all, 0);
rb_define_method(mEnumerable,"collect", enum_collect, 0);
rb_define_method(mEnumerable,"reverse", enum_reverse, 0);
@@ -319,4 +358,9 @@ Init_Enumerable()
rb_define_method(mEnumerable,"index", enum_index, 1);
rb_define_method(mEnumerable,"member?", enum_member, 1);
rb_define_method(mEnumerable,"length", enum_length, 0);
+ rb_define_method(mEnumerable,"size", enum_length, 0);
+
+ id_eqq = rb_intern("===");
+ id_each = rb_intern("each");
+ id_cmp = rb_intern("<=>");
}
diff --git a/env.h b/env.h
index 5f31e5cebc..ff53def099 100644
--- a/env.h
+++ b/env.h
@@ -16,9 +16,11 @@ extern struct FRAME {
VALUE *argv;
ID last_func;
struct RClass *last_class;
+ VALUE cbase;
struct FRAME *prev;
char *file;
int line;
+ int iter;
} *the_frame;
extern struct SCOPE {
@@ -28,8 +30,9 @@ extern struct SCOPE {
int flag;
} *the_scope;
-#define SCOPE_ALLOCA 0
-#define SCOPE_MALLOC 1
+#define SCOPE_ALLOCA 0
+#define SCOPE_MALLOC 1
+#define SCOPE_NOSTACK 2
extern int rb_in_eval;
diff --git a/error.c b/error.c
index 6634663eb1..61d5468c0d 100644
--- a/error.c
+++ b/error.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:31 $
created at: Mon Aug 9 16:11:34 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -32,32 +32,41 @@ err_sprintf(buf, fmt, args)
sprintf(buf, "%s:%d: ", sourcefile, sourceline);
vsprintf((char*)buf+strlen(buf), fmt, args);
}
- if (buf[strlen(buf)-1] != '\n')
- strcat(buf, "\n");
}
static void
-err_print(fmt, args)
- char *fmt;
- va_list args;
+err_append(s)
+ char *s;
{
- extern errstr;
- char buf[BUFSIZ];
+ extern VALUE errinfo;
- err_sprintf(buf, fmt, args);
if (rb_in_eval) {
- if (errstr == Qnil) {
- errstr = str_new2(buf);
+ if (NIL_P(errinfo)) {
+ errinfo = str_new2(s);
}
else {
- str_cat(errstr, buf, strlen(buf));
+ str_cat(errinfo, "\n", 1);
+ str_cat(errinfo, s, strlen(s));
}
}
else {
- fputs(buf, stderr);
+ fputs(s, stderr);
+ fputs("\n", stderr);
+ fflush(stderr);
}
}
+static void
+err_print(fmt, args)
+ char *fmt;
+ va_list args;
+{
+ char buf[BUFSIZ];
+
+ err_sprintf(buf, fmt, args);
+ err_append(buf);
+}
+
void
Error(fmt, va_alist)
char *fmt;
@@ -71,18 +80,18 @@ Error(fmt, va_alist)
nerrs++;
}
-int
-yyerror(msg)
- char *msg;
+void
+Error_Append(fmt, va_alist)
+ char *fmt;
+ va_dcl
{
- static char *f;
- static int line;
+ va_list args;
+ char buf[BUFSIZ];
- if (line == sourceline && strcmp(f, sourcefile) == 0)
- return;
- f = sourcefile; line = sourceline;
- Error("%s", msg);
- return 0;
+ va_start(args);
+ vsprintf(buf, fmt, args);
+ va_end(args);
+ err_append(buf);
}
void
@@ -103,32 +112,226 @@ Warning(fmt, va_alist)
}
void
-Fatal(fmt, va_alist)
+Bug(fmt, va_alist)
char *fmt;
va_dcl
{
+ char buf[BUFSIZ];
va_list args;
+ sprintf(buf, "[BUG] %s", fmt);
+ rb_in_eval = 0;
+
va_start(args);
- err_print(fmt, args);
+ err_print(buf, args);
va_end(args);
- rb_exit(1);
+ abort();
}
+static struct types {
+ int type;
+ char *name;
+} builtin_types[] = {
+ T_NIL, "nil",
+ T_OBJECT, "Object",
+ T_CLASS, "Class",
+ T_ICLASS, "iClass", /* internal use: mixed-in module holder */
+ T_MODULE, "Module",
+ T_FLOAT, "Float",
+ T_STRING, "String",
+ T_REGEXP, "Regexp",
+ T_ARRAY, "Array",
+ T_FIXNUM, "Fixnum",
+ T_HASH, "Hash",
+ T_STRUCT, "Struct",
+ T_BIGNUM, "Bignum",
+ T_FILE, "File",
+ T_TRUE, "TRUE",
+ T_FALSE, "FALSE",
+ T_DATA, "Data", /* internal use: wrapped C pointers */
+ T_MATCH, "Match", /* data of $~ */
+ T_VARMAP, "Varmap", /* internal use: dynamic variables */
+ T_SCOPE, "Scope", /* internal use: variable scope */
+ T_NODE, "Node", /* internal use: syntax tree node */
+ -1, 0,
+};
+
+extern void TypeError();
+
void
-Bug(fmt, va_alist)
+Check_Type(x, t)
+ VALUE x;
+ int t;
+{
+ struct types *type = builtin_types;
+
+ if (TYPE(x)!=(t)) {
+ while (type->type >= 0) {
+ if (type->type == t) {
+ TypeError("wrong argument type %s (expected %s)",
+ rb_class2name(CLASS_OF(x)), type->name);
+ }
+ type++;
+ }
+ Bug("unknown type 0x%x", t);
+ }
+}
+
+/* exception classes */
+#include "errno.h"
+
+extern VALUE cString;
+VALUE eGlobalExit, eException;
+VALUE eSystemExit, eInterrupt, eFatal;
+VALUE eRuntimeError;
+VALUE eSyntaxError;
+VALUE eTypeError;
+VALUE eArgError;
+VALUE eNameError;
+VALUE eIndexError;
+VALUE eNotImpError;
+VALUE eLoadError;
+
+VALUE eSystemCallError;
+VALUE mErrno;
+
+VALUE
+exc_new0(etype, ptr, len)
+ VALUE etype;
+ char *ptr;
+ UINT len;
+{
+ NEWOBJ(exc, struct RString);
+ OBJSETUP(exc, etype, T_STRING);
+
+ exc->len = len;
+ exc->orig = 0;
+ exc->ptr = ALLOC_N(char,len+1);
+ if (ptr) {
+ memcpy(exc->ptr, ptr, len);
+ }
+ exc->ptr[len] = '\0';
+ return (VALUE)exc;
+}
+
+VALUE
+exc_new(etype, s)
+ VALUE etype;
+ char *s;
+{
+ return exc_new0(etype, s, strlen(s));
+}
+
+VALUE
+exc_new2(etype, str)
+ VALUE etype;
+ struct RString *str;
+{
+ Check_Type(str, T_STRING);
+ return exc_new(etype, str->ptr, str->len);
+}
+
+static VALUE
+exc_s_new(argc, argv, etype)
+ int argc;
+ VALUE *argv;
+ VALUE etype;
+{
+ VALUE arg;
+
+ if (rb_scan_args(argc, argv, "01", &arg) == 0) {
+ return exc_new0(etype, 0, 0);
+ }
+ Check_Type(arg, T_STRING);
+ return exc_new2(etype, arg);
+}
+
+static VALUE *syserr_list;
+
+static void
+set_syserr(i, name)
+ int i;
+ char *name;
+{
+ syserr_list[i] = rb_define_class_under(mErrno, name, eSystemCallError);
+ rb_global_variable(&syserr_list[i]);
+}
+
+static void init_syserr();
+
+void
+Init_Exception()
+{
+ eGlobalExit = rb_define_class("GlobalExit", cString);
+ rb_define_method(eGlobalExit, "new", exc_s_new, -1);
+
+ eSystemExit = rb_define_class("SystemExit", eGlobalExit);
+ eFatal = rb_define_class("fatal", eGlobalExit);
+ eInterrupt = rb_define_class("Interrupt", eGlobalExit);
+
+ eException = rb_define_class("Exception", eGlobalExit);
+ eSyntaxError = rb_define_class("SyntaxError", eException);
+ eTypeError = rb_define_class("TypeError", eException);
+ eArgError = rb_define_class("ArgumentError", eException);
+ eNameError = rb_define_class("NameError", eException);
+ eIndexError = rb_define_class("IndexError", eException);
+ eNotImpError = rb_define_class("NotImplementError", eException);
+ eLoadError = rb_define_class("LoadError", eException);
+
+ eRuntimeError = rb_define_class("RuntimeError", eException);
+
+ init_syserr();
+}
+
+#define RAISE_ERROR(class) {\
+ va_list args;\
+ char buf[BUFSIZ];\
+\
+ va_start(args);\
+ vsprintf(buf, fmt, args);\
+ va_end(args);\
+\
+ rb_raise(exc_new(class, buf));\
+}
+
+void
+Raise(exc, fmt, va_alist)
char *fmt;
va_dcl
{
- char buf[BUFSIZ];
- va_list args;
+ RAISE_ERROR(exc);
+}
- sprintf(buf, "[BUG] %s", fmt);
+void
+TypeError(fmt, va_alist)
+ char *fmt;
+ va_dcl
+{
+ RAISE_ERROR(eTypeError);
+}
- va_start(args);
- err_print(buf, args);
- va_end(args);
- abort();
+void
+ArgError(fmt, va_alist)
+ char *fmt;
+ va_dcl
+{
+ RAISE_ERROR(eArgError);
+}
+
+void
+NameError(fmt, va_alist)
+ char *fmt;
+ va_dcl
+{
+ RAISE_ERROR(eNameError);
+}
+
+void
+IndexError(fmt, va_alist)
+ char *fmt;
+ va_dcl
+{
+ RAISE_ERROR(eIndexError);
}
void
@@ -136,6 +339,30 @@ Fail(fmt, va_alist)
char *fmt;
va_dcl
{
+ RAISE_ERROR(eRuntimeError);
+}
+
+void
+rb_notimplement()
+{
+ Raise(eNotImpError,
+ "The %s() function is unimplemented on this machine",
+ rb_id2name(the_frame->last_func));
+}
+
+void
+LoadError(fmt, va_alist)
+ char *fmt;
+ va_dcl
+{
+ RAISE_ERROR(eLoadError);
+}
+
+void
+Fatal(fmt, va_alist)
+ char *fmt;
+ va_dcl
+{
va_list args;
char buf[BUFSIZ];
@@ -143,7 +370,8 @@ Fail(fmt, va_alist)
vsprintf(buf, fmt, args);
va_end(args);
- rb_fail(str_new2(buf));
+ rb_in_eval = 0;
+ rb_fatal(exc_new(eFatal, buf));
}
void
@@ -153,39 +381,397 @@ rb_sys_fail(mesg)
char *strerror();
char buf[BUFSIZ];
extern int errno;
+ int n = errno;
- if (mesg == Qnil)
- sprintf(buf, "%s", strerror(errno));
- else
+ if (RTEST(mesg))
sprintf(buf, "%s - %s", strerror(errno), mesg);
+ else
+ sprintf(buf, "%s", strerror(errno));
errno = 0;
- rb_fail(str_new2(buf));
-}
-
-static char *builtin_types[] = {
- "Nil",
- "Object",
- "Class",
- "iClass",
- "Module",
- "Float",
- "String",
- "Regexp",
- "Array",
- "Fixnum",
- "Hash",
- "Struct",
- "Bignum",
- "Data",
- "Match",
-};
+ if (!syserr_list[n]) {
+ char name[6];
-void
-WrongType(x, t)
- VALUE x;
- int t;
+ sprintf(name, "E%03d", n);
+ set_syserr(n, name);
+ }
+ rb_raise(exc_new(syserr_list[n], buf));
+}
+
+extern int sys_nerr;
+
+static void
+init_syserr()
{
- Fail("wrong argument type %s (expected %s)",
- rb_class2name(CLASS_OF(x)), builtin_types[t]);
+ eSystemCallError = rb_define_class("SystemCallError", eException);
+ mErrno = rb_define_module("Errno");
+ syserr_list = ALLOC_N(VALUE, sys_nerr+1);
+ MEMZERO(syserr_list, VALUE, sys_nerr+1);
+
+#ifdef EPERM
+ set_syserr(EPERM, "EPERM");
+#endif
+#ifdef ENOENT
+ set_syserr(ENOENT, "ENOENT");
+#endif
+#ifdef ESRCH
+ set_syserr(ESRCH, "ESRCH");
+#endif
+#ifdef EINTR
+ set_syserr(EINTR, "EINTR");
+#endif
+#ifdef EIO
+ set_syserr(EIO, "EIO");
+#endif
+#ifdef ENXIO
+ set_syserr(ENXIO, "ENXIO");
+#endif
+#ifdef E2BIG
+ set_syserr(E2BIG, "E2BIG");
+#endif
+#ifdef ENOEXEC
+ set_syserr(ENOEXEC, "ENOEXEC");
+#endif
+#ifdef EBADF
+ set_syserr(EBADF, "EBADF");
+#endif
+#ifdef ECHILD
+ set_syserr(ECHILD, "ECHILD");
+#endif
+#ifdef EAGAIN
+ set_syserr(EAGAIN, "EAGAIN");
+#endif
+#ifdef ENOMEM
+ set_syserr(ENOMEM, "ENOMEM");
+#endif
+#ifdef EACCES
+ set_syserr(EACCES, "EACCES");
+#endif
+#ifdef EFAULT
+ set_syserr(EFAULT, "EFAULT");
+#endif
+#ifdef ENOTBLK
+ set_syserr(ENOTBLK, "ENOTBLK");
+#endif
+#ifdef EBUSY
+ set_syserr(EBUSY, "EBUSY");
+#endif
+#ifdef EEXIST
+ set_syserr(EEXIST, "EEXIST");
+#endif
+#ifdef EXDEV
+ set_syserr(EXDEV, "EXDEV");
+#endif
+#ifdef ENODEV
+ set_syserr(ENODEV, "ENODEV");
+#endif
+#ifdef ENOTDIR
+ set_syserr(ENOTDIR, "ENOTDIR");
+#endif
+#ifdef EISDIR
+ set_syserr(EISDIR, "EISDIR");
+#endif
+#ifdef EINVAL
+ set_syserr(EINVAL, "EINVAL");
+#endif
+#ifdef ENFILE
+ set_syserr(ENFILE, "ENFILE");
+#endif
+#ifdef EMFILE
+ set_syserr(EMFILE, "EMFILE");
+#endif
+#ifdef ENOTTY
+ set_syserr(ENOTTY, "ENOTTY");
+#endif
+#ifdef ETXTBSY
+ set_syserr(ETXTBSY, "ETXTBSY");
+#endif
+#ifdef EFBIG
+ set_syserr(EFBIG, "EFBIG");
+#endif
+#ifdef ENOSPC
+ set_syserr(ENOSPC, "ENOSPC");
+#endif
+#ifdef ESPIPE
+ set_syserr(ESPIPE, "ESPIPE");
+#endif
+#ifdef EROFS
+ set_syserr(EROFS, "EROFS");
+#endif
+#ifdef EMLINK
+ set_syserr(EMLINK, "EMLINK");
+#endif
+#ifdef EPIPE
+ set_syserr(EPIPE, "EPIPE");
+#endif
+#ifdef EDOM
+ set_syserr(EDOM, "EDOM");
+#endif
+#ifdef ERANGE
+ set_syserr(ERANGE, "ERANGE");
+#endif
+#ifdef EDEADLK
+ set_syserr(EDEADLK, "EDEADLK");
+#endif
+#ifdef ENAMETOOLONG
+ set_syserr(ENAMETOOLONG, "ENAMETOOLONG");
+#endif
+#ifdef ENOLCK
+ set_syserr(ENOLCK, "ENOLCK");
+#endif
+#ifdef ENOSYS
+ set_syserr(ENOSYS, "ENOSYS");
+#endif
+#ifdef ENOTEMPTY
+ set_syserr(ENOTEMPTY, "ENOTEMPTY");
+#endif
+#ifdef ELOOP
+ set_syserr(ELOOP, "ELOOP");
+#endif
+#ifdef EWOULDBLOCK
+ set_syserr(EWOULDBLOCK, "EWOULDBLOCK");
+#endif
+#ifdef ENOMSG
+ set_syserr(ENOMSG, "ENOMSG");
+#endif
+#ifdef EIDRM
+ set_syserr(EIDRM, "EIDRM");
+#endif
+#ifdef ECHRNG
+ set_syserr(ECHRNG, "ECHRNG");
+#endif
+#ifdef EL2NSYNC
+ set_syserr(EL2NSYNC, "EL2NSYNC");
+#endif
+#ifdef EL3HLT
+ set_syserr(EL3HLT, "EL3HLT");
+#endif
+#ifdef EL3RST
+ set_syserr(EL3RST, "EL3RST");
+#endif
+#ifdef ELNRNG
+ set_syserr(ELNRNG, "ELNRNG");
+#endif
+#ifdef EUNATCH
+ set_syserr(EUNATCH, "EUNATCH");
+#endif
+#ifdef ENOCSI
+ set_syserr(ENOCSI, "ENOCSI");
+#endif
+#ifdef EL2HLT
+ set_syserr(EL2HLT, "EL2HLT");
+#endif
+#ifdef EBADE
+ set_syserr(EBADE, "EBADE");
+#endif
+#ifdef EBADR
+ set_syserr(EBADR, "EBADR");
+#endif
+#ifdef EXFULL
+ set_syserr(EXFULL, "EXFULL");
+#endif
+#ifdef ENOANO
+ set_syserr(ENOANO, "ENOANO");
+#endif
+#ifdef EBADRQC
+ set_syserr(EBADRQC, "EBADRQC");
+#endif
+#ifdef EBADSLT
+ set_syserr(EBADSLT, "EBADSLT");
+#endif
+#ifdef EDEADLOCK
+ set_syserr(EDEADLOCK, "EDEADLOCK");
+#endif
+#ifdef EBFONT
+ set_syserr(EBFONT, "EBFONT");
+#endif
+#ifdef ENOSTR
+ set_syserr(ENOSTR, "ENOSTR");
+#endif
+#ifdef ENODATA
+ set_syserr(ENODATA, "ENODATA");
+#endif
+#ifdef ETIME
+ set_syserr(ETIME, "ETIME");
+#endif
+#ifdef ENOSR
+ set_syserr(ENOSR, "ENOSR");
+#endif
+#ifdef ENONET
+ set_syserr(ENONET, "ENONET");
+#endif
+#ifdef ENOPKG
+ set_syserr(ENOPKG, "ENOPKG");
+#endif
+#ifdef EREMOTE
+ set_syserr(EREMOTE, "EREMOTE");
+#endif
+#ifdef ENOLINK
+ set_syserr(ENOLINK, "ENOLINK");
+#endif
+#ifdef EADV
+ set_syserr(EADV, "EADV");
+#endif
+#ifdef ESRMNT
+ set_syserr(ESRMNT, "ESRMNT");
+#endif
+#ifdef ECOMM
+ set_syserr(ECOMM, "ECOMM");
+#endif
+#ifdef EPROTO
+ set_syserr(EPROTO, "EPROTO");
+#endif
+#ifdef EMULTIHOP
+ set_syserr(EMULTIHOP, "EMULTIHOP");
+#endif
+#ifdef EDOTDOT
+ set_syserr(EDOTDOT, "EDOTDOT");
+#endif
+#ifdef EBADMSG
+ set_syserr(EBADMSG, "EBADMSG");
+#endif
+#ifdef EOVERFLOW
+ set_syserr(EOVERFLOW, "EOVERFLOW");
+#endif
+#ifdef ENOTUNIQ
+ set_syserr(ENOTUNIQ, "ENOTUNIQ");
+#endif
+#ifdef EBADFD
+ set_syserr(EBADFD, "EBADFD");
+#endif
+#ifdef EREMCHG
+ set_syserr(EREMCHG, "EREMCHG");
+#endif
+#ifdef ELIBACC
+ set_syserr(ELIBACC, "ELIBACC");
+#endif
+#ifdef ELIBBAD
+ set_syserr(ELIBBAD, "ELIBBAD");
+#endif
+#ifdef ELIBSCN
+ set_syserr(ELIBSCN, "ELIBSCN");
+#endif
+#ifdef ELIBMAX
+ set_syserr(ELIBMAX, "ELIBMAX");
+#endif
+#ifdef ELIBEXEC
+ set_syserr(ELIBEXEC, "ELIBEXEC");
+#endif
+#ifdef EILSEQ
+ set_syserr(EILSEQ, "EILSEQ");
+#endif
+#ifdef ERESTART
+ set_syserr(ERESTART, "ERESTART");
+#endif
+#ifdef ESTRPIPE
+ set_syserr(ESTRPIPE, "ESTRPIPE");
+#endif
+#ifdef EUSERS
+ set_syserr(EUSERS, "EUSERS");
+#endif
+#ifdef ENOTSOCK
+ set_syserr(ENOTSOCK, "ENOTSOCK");
+#endif
+#ifdef EDESTADDRREQ
+ set_syserr(EDESTADDRREQ, "EDESTADDRREQ");
+#endif
+#ifdef EMSGSIZE
+ set_syserr(EMSGSIZE, "EMSGSIZE");
+#endif
+#ifdef EPROTOTYPE
+ set_syserr(EPROTOTYPE, "EPROTOTYPE");
+#endif
+#ifdef ENOPROTOOPT
+ set_syserr(ENOPROTOOPT, "ENOPROTOOPT");
+#endif
+#ifdef EPROTONOSUPPORT
+ set_syserr(EPROTONOSUPPORT, "EPROTONOSUPPORT");
+#endif
+#ifdef ESOCKTNOSUPPORT
+ set_syserr(ESOCKTNOSUPPORT, "ESOCKTNOSUPPORT");
+#endif
+#ifdef EOPNOTSUPP
+ set_syserr(EOPNOTSUPP, "EOPNOTSUPP");
+#endif
+#ifdef EPFNOSUPPORT
+ set_syserr(EPFNOSUPPORT, "EPFNOSUPPORT");
+#endif
+#ifdef EAFNOSUPPORT
+ set_syserr(EAFNOSUPPORT, "EAFNOSUPPORT");
+#endif
+#ifdef EADDRINUSE
+ set_syserr(EADDRINUSE, "EADDRINUSE");
+#endif
+#ifdef EADDRNOTAVAIL
+ set_syserr(EADDRNOTAVAIL, "EADDRNOTAVAIL");
+#endif
+#ifdef ENETDOWN
+ set_syserr(ENETDOWN, "ENETDOWN");
+#endif
+#ifdef ENETUNREACH
+ set_syserr(ENETUNREACH, "ENETUNREACH");
+#endif
+#ifdef ENETRESET
+ set_syserr(ENETRESET, "ENETRESET");
+#endif
+#ifdef ECONNABORTED
+ set_syserr(ECONNABORTED, "ECONNABORTED");
+#endif
+#ifdef ECONNRESET
+ set_syserr(ECONNRESET, "ECONNRESET");
+#endif
+#ifdef ENOBUFS
+ set_syserr(ENOBUFS, "ENOBUFS");
+#endif
+#ifdef EISCONN
+ set_syserr(EISCONN, "EISCONN");
+#endif
+#ifdef ENOTCONN
+ set_syserr(ENOTCONN, "ENOTCONN");
+#endif
+#ifdef ESHUTDOWN
+ set_syserr(ESHUTDOWN, "ESHUTDOWN");
+#endif
+#ifdef ETOOMANYREFS
+ set_syserr(ETOOMANYREFS, "ETOOMANYREFS");
+#endif
+#ifdef ETIMEDOUT
+ set_syserr(ETIMEDOUT, "ETIMEDOUT");
+#endif
+#ifdef ECONNREFUSED
+ set_syserr(ECONNREFUSED, "ECONNREFUSED");
+#endif
+#ifdef EHOSTDOWN
+ set_syserr(EHOSTDOWN, "EHOSTDOWN");
+#endif
+#ifdef EHOSTUNREACH
+ set_syserr(EHOSTUNREACH, "EHOSTUNREACH");
+#endif
+#ifdef EALREADY
+ set_syserr(EALREADY, "EALREADY");
+#endif
+#ifdef EINPROGRESS
+ set_syserr(EINPROGRESS, "EINPROGRESS");
+#endif
+#ifdef ESTALE
+ set_syserr(ESTALE, "ESTALE");
+#endif
+#ifdef EUCLEAN
+ set_syserr(EUCLEAN, "EUCLEAN");
+#endif
+#ifdef ENOTNAM
+ set_syserr(ENOTNAM, "ENOTNAM");
+#endif
+#ifdef ENAVAIL
+ set_syserr(ENAVAIL, "ENAVAIL");
+#endif
+#ifdef EISNAM
+ set_syserr(EISNAM, "EISNAM");
+#endif
+#ifdef EREMOTEIO
+ set_syserr(EREMOTEIO, "EREMOTEIO");
+#endif
+#ifdef EDQUOT
+ set_syserr(EDQUOT, "EDQUOT");
+#endif
}
diff --git a/eval.c b/eval.c
index c1363a6840..43a4bf07f6 100644
--- a/eval.c
+++ b/eval.c
@@ -11,8 +11,8 @@
************************************************/
#include "ruby.h"
-#include "env.h"
#include "node.h"
+#include "env.h"
#include "sig.h"
#include <stdio.h>
@@ -23,30 +23,21 @@
#ifdef HAVE_STRING_H
# include <string.h>
#else
-char *strchr();
char *strrchr();
#endif
-VALUE cProc;
+static VALUE cProc;
static VALUE proc_call();
-static void rb_clear_cache_body();
-static void rb_clear_cache_entry();
-
-/* #define TEST /* prints cache miss */
-#ifdef TEST
-#include <stdio.h>
-#endif
-
#define CACHE_SIZE 0x200
#define CACHE_MASK 0x1ff
#define EXPR1(c,m) ((((int)(c)>>3)^(m))&CACHE_MASK)
struct cache_entry { /* method hash table. */
ID mid; /* method's id */
+ ID mid0; /* method's original id */
struct RClass *class; /* receiver's class */
struct RClass *origin; /* where method defined */
- int nargs; /* # of args */
NODE *method;
int noex;
};
@@ -62,14 +53,7 @@ rb_add_method(class, mid, node, noex)
{
NODE *body;
- if (class == Qnil) class = (struct RClass*)cObject;
- if (st_lookup(class->m_tbl, mid, &body)) {
- Warning("redefine %s", rb_id2name(mid));
- rb_clear_cache_body(body);
- }
- else {
- rb_clear_cache_entry(class, mid);
- }
+ if (NIL_P(class)) class = (struct RClass*)cObject;
body = NEW_METHOD(node, noex);
st_insert(class->m_tbl, mid, body);
}
@@ -83,7 +67,7 @@ search_method(class, id, origin)
while (!st_lookup(class->m_tbl, id, &body)) {
class = class->super;
- if (class == Qnil) return Qnil;
+ if (!class) return 0;
}
if (origin) *origin = class;
@@ -102,29 +86,25 @@ rb_get_method_body(classp, idp, noexp)
struct RClass *origin;
struct cache_entry *ent;
- if ((body = search_method(class, id, &origin)) == FALSE) {
- return Qnil;
+ if ((body = search_method(class, id, &origin)) == 0) {
+ return 0;
}
- if (body->nd_body == Qnil) return Qnil;
+ if (!body->nd_body) return 0;
- ent = cache + EXPR1(class, id);
-#ifdef TEST
- if (ent->mid != 0) {
- fprintf(stderr, "0x%x 0x%x %x\n", class, id, EXPR1(class, id));
- }
-#endif
/* store in cache */
+ ent = cache + EXPR1(class, id);
ent->class = class;
ent->noex = body->nd_noex;
body = body->nd_body;
if (nd_type(body) == NODE_FBODY) {
+ ent->mid = id;
*classp = ent->origin = (struct RClass*)body->nd_orig;
- *idp = ent->mid = body->nd_mid;
+ *idp = ent->mid0 = body->nd_mid;
body = ent->method = body->nd_head;
}
else {
*classp = ent->origin = origin;
- ent->mid = id;
+ ent->mid = ent->mid0 = id;
ent->method = body;
}
@@ -142,17 +122,9 @@ rb_alias(class, name, def)
if (name == def) return;
body = search_method(class, def, &origin);
- if (body == Qnil || body->nd_body == Qnil) {
- Fail("undefined method `%s' for class `%s'",
- rb_id2name(def), rb_class2name(class));
- }
-
- if (st_lookup(class->m_tbl, name, &old)) {
- Warning("redefine %s", rb_id2name(name));
- rb_clear_cache_body(body);
- }
- else {
- rb_clear_cache_entry(class, name);
+ if (!body || !body->nd_body) {
+ NameError("undefined method `%s' for class `%s'",
+ rb_id2name(def), rb_class2name(class));
}
st_insert(class->m_tbl, name,
@@ -170,9 +142,9 @@ rb_export_method(class, name, noex)
struct RClass *origin;
body = search_method(class, name, &origin);
- if (body == Qnil) {
- Fail("undefined method `%s' for class `%s'",
- rb_id2name(name), rb_class2name(class));
+ if (!body) {
+ NameError("undefined method `%s' for class `%s'",
+ rb_id2name(name), rb_class2name(class));
}
if (body->nd_noex != noex) {
if (class == origin) {
@@ -200,85 +172,56 @@ method_boundp(class, id, ex)
return FALSE;
}
-VALUE
+int
rb_method_boundp(class, id)
struct RClass *class;
ID id;
{
- return method_boundp(class, id, 0);
-}
-
-static void
-rb_clear_cache_body(body)
- NODE *body;
-{
- struct cache_entry *ent, *end;
-
- ent = cache; end = ent + CACHE_SIZE;
- while (ent < end) {
- if (ent->method == body) {
- ent->class = Qnil;
- ent->mid = Qnil;
- }
- ent++;
- }
-}
-
-static void
-rb_clear_cache_entry(class, mid)
- struct RClass *class;
- ID mid;
-{
- struct cache_entry *ent;
-
- /* is it in the method cache? */
- ent = cache + EXPR1(class, mid);
- if (ent->mid == mid && ent->class == class) {
- ent->class = Qnil;
- ent->mid = Qnil;
- }
+ if (method_boundp(class, id, NOEX_PRIVATE))
+ return TRUE;
+ return FALSE;
}
void
-rb_clear_cache(class)
- struct RClass *class;
+rb_clear_cache()
{
struct cache_entry *ent, *end;
ent = cache; end = ent + CACHE_SIZE;
while (ent < end) {
- if (ent->origin == class) {
- ent->class = Qnil;
- ent->mid = Qnil;
- }
+ ent->mid = 0;
ent++;
}
}
-static ID match, each, aref, aset;
-VALUE errstr, errat;
+static ID init, eqq, each, aref, aset;
+VALUE errinfo = Qnil, errat = Qnil;
extern NODE *eval_tree;
extern int nerrs;
-extern VALUE TopSelf;
-VALUE Qself;
-
-#define PUSH_SELF(s) { \
- VALUE __saved_self__ = Qself; \
- Qself = s; \
+extern VALUE cKernel;
+extern VALUE eGlobalExit;
+extern VALUE eInterrupt;
+extern VALUE eSystemExit;
+extern VALUE eException;
+extern VALUE eRuntimeError;
+extern VALUE eSyntaxError;
+static VALUE eLocalJumpError;
-#define POP_SELF() Qself = __saved_self__; }
+extern VALUE TopSelf;
struct FRAME *the_frame;
struct SCOPE *the_scope;
static struct FRAME *top_frame;
-static struct SCOPE *top_scope;
+static struct SCOPE *top_scope;
#define PUSH_FRAME() { \
struct FRAME _frame; \
_frame.prev = the_frame; \
_frame.file = sourcefile; \
_frame.line = sourceline; \
+ _frame.iter = the_iter->iter; \
+ _frame.cbase = the_frame->cbase; \
the_frame = &_frame; \
#define POP_FRAME() the_frame = _frame.prev; }
@@ -289,6 +232,7 @@ struct BLOCK {
VALUE self;
struct FRAME frame;
struct SCOPE *scope;
+ struct RClass *class;
int level;
int iter;
struct RVarmap *d_vars;
@@ -297,24 +241,29 @@ struct BLOCK {
#define PUSH_BLOCK(v,b) { \
struct BLOCK _block; \
- _block.level = tag_level; \
+ _block.level = (int)&prot_tag; \
_block.var = v; \
_block.body = b; \
- _block.self = Qself; \
+ _block.self = self; \
_block.frame = *the_frame; \
+ _block.class = the_class; \
_block.frame.file = sourcefile; \
_block.frame.line = sourceline; \
_block.scope = the_scope; \
_block.d_vars = the_dyna_vars; \
_block.prev = the_block; \
- _block.iter = iter->iter; \
+ _block.iter = the_iter->iter; \
the_block = &_block; \
#define PUSH_BLOCK2(b) { \
- b->prev = the_block; \
- the_block = b; \
-
-#define POP_BLOCK() the_block = the_block->prev; }
+ struct BLOCK _block; \
+ _block = *b; \
+ _block.prev = the_block; \
+ the_block = &_block;
+
+#define POP_BLOCK() \
+ the_block = the_block->prev; \
+}
struct RVarmap *the_dyna_vars;
#define PUSH_VARS() { \
@@ -324,13 +273,28 @@ struct RVarmap *the_dyna_vars;
#define POP_VARS() the_dyna_vars = _old; }
VALUE
+dyna_var_defined(id)
+ ID id;
+{
+ struct RVarmap *vars = the_dyna_vars;
+
+ while (vars && vars->id) {
+ if (vars->id == id) return TRUE;
+ vars = vars->next;
+ }
+ return FALSE;
+}
+
+VALUE
dyna_var_ref(id)
ID id;
{
struct RVarmap *vars = the_dyna_vars;
- while (vars) {
- if (vars->id == id) return vars->val;
+ while (vars && vars->id) {
+ if (vars->id == id) {
+ return vars->val;
+ }
vars = vars->next;
}
return Qnil;
@@ -343,16 +307,16 @@ dyna_var_asgn(id, value)
{
struct RVarmap *vars = the_dyna_vars;
- while (vars) {
+ while (vars && vars->id) {
if (vars->id == id) {
vars->val = value;
- return;
+ return value;
}
vars = vars->next;
}
{
NEWOBJ(_vars, struct RVarmap);
- OBJSETUP(_vars, Qnil, T_VARMAP);
+ OBJSETUP(_vars, 0, T_VARMAP);
_vars->id = id;
_vars->val = value;
_vars->next = the_dyna_vars;
@@ -360,11 +324,22 @@ dyna_var_asgn(id, value)
}
return value;
}
-
+
+static VALUE
+dyna_var_mark()
+{
+ NEWOBJ(_vars, struct RVarmap);
+ OBJSETUP(_vars, 0, T_VARMAP);
+ _vars->id = 0;
+ _vars->val = Qnil;
+ _vars->next = the_dyna_vars;
+ the_dyna_vars = _vars;
+}
+
static struct iter {
int iter;
struct iter *prev;
-} *iter;
+} *the_iter;
#define ITER_NOT 0
#define ITER_PRE 1
@@ -372,20 +347,16 @@ static struct iter {
#define PUSH_ITER(i) { \
struct iter _iter; \
- _iter.prev = iter; \
+ _iter.prev = the_iter; \
_iter.iter = (i); \
- iter = &_iter; \
+ the_iter = &_iter; \
#define POP_ITER() \
- iter = _iter.prev; \
+ the_iter = _iter.prev; \
}
-static int tag_level, target_level;
static struct tag {
- int level;
jmp_buf buf;
- struct gc_list *gclist;
- VALUE self;
struct FRAME *frame;
struct iter *iter;
struct tag *prev;
@@ -393,57 +364,50 @@ static struct tag {
#define PUSH_TAG() { \
struct tag _tag; \
- _tag.level= ++tag_level; \
- _tag.self = Qself; \
_tag.frame = the_frame; \
- _tag.iter = iter; \
+ _tag.iter = the_iter; \
_tag.prev = prot_tag; \
- prot_tag = &_tag; \
+ prot_tag = &_tag;
-#define EXEC_TAG() (setjmp(prot_tag->buf))
+#define EXEC_TAG() ((NODE*)setjmp(prot_tag->buf))
-#define JUMP_TAG(val) { \
- Qself = prot_tag->self; \
+#define JUMP_TAG(st) { \
the_frame = prot_tag->frame; \
- iter = prot_tag->iter; \
- longjmp(prot_tag->buf,(val)); \
+ the_iter = prot_tag->iter; \
+ longjmp(prot_tag->buf,(int)(st)); \
}
+#define JUMP_TAG3(val,data1,data2) \
+ JUMP_TAG(newnode(NODE_TAG,(val),(data1),(data2)))
+
+#define JUMP_TAG2(val,data) JUMP_TAG3((val),(data),0)
+
#define POP_TAG() \
- tag_level--; \
prot_tag = _tag.prev; \
}
-#define TAG_RETURN 1
-#define TAG_BREAK 2
-#define TAG_CONTINUE 3
-#define TAG_RETRY 4
-#define TAG_REDO 5
-#define TAG_FAIL 6
-#define TAG_EXIT 7
+#define TAG_RETURN 0x1
+#define TAG_BREAK 0x2
+#define TAG_NEXT 0x3
+#define TAG_RETRY 0x4
+#define TAG_REDO 0x5
+#define TAG_RAISE 0x6
+#define TAG_THROW 0x7
+#define TAG_FATAL 0x8
-#define IN_BLOCK 0x08
+#define IN_BLOCK 0x10
struct RClass *the_class;
-struct class_link {
- struct RClass *class;
- struct class_link *prev;
-} *class_link;
#define PUSH_CLASS() { \
- struct class_link _link; \
- _link.class = the_class; \
- _link.prev = class_link; \
- class_link = &_link \
+ struct RClass *_class = the_class; \
-#define POP_CLASS() \
- the_class = class_link->class; \
- class_link = _link.prev; }
+#define POP_CLASS() the_class = _class; }
#define PUSH_SCOPE() { \
struct SCOPE *_old; \
NEWOBJ(_scope, struct SCOPE); \
- OBJSETUP(_scope, Qnil, T_SCOPE); \
+ OBJSETUP(_scope, 0, T_SCOPE); \
_old = the_scope; \
the_scope = _scope; \
@@ -452,54 +416,96 @@ struct class_link {
the_scope->local_vars = 0;\
the_scope->local_tbl = 0;\
}\
+ the_scope->flag |= SCOPE_NOSTACK;\
the_scope = _old;\
}
static VALUE rb_eval();
-static VALUE f_eval();
+static VALUE eval();
+static NODE *compile();
static VALUE rb_call();
VALUE rb_apply();
-VALUE rb_xstring();
-void rb_fail();
-
-VALUE rb_rescue();
static void module_setup();
static VALUE masign();
static void asign();
-static VALUE last_val;
-
extern VALUE rb_stderr;
extern int sourceline;
extern char *sourcefile;
-static ID last_func;
static void
-error_print(last_func)
- ID last_func;
+error_pos()
{
- if (errat) {
- fwrite(RSTRING(errat)->ptr, 1, RSTRING(errat)->len, stderr);
- if (last_func) {
- fprintf(stderr, ":in `%s': ", rb_id2name(last_func));
+ if (sourcefile) {
+ if (the_frame->last_func) {
+ fprintf(stderr, "%s:%d:in `%s': ", sourcefile, sourceline,
+ rb_id2name(the_frame->last_func));
}
else {
- fprintf(stderr, ": ");
+ fprintf(stderr, "%s:%d: ", sourcefile, sourceline);
}
}
+}
- if (errstr) {
- fwrite(RSTRING(errstr)->ptr, 1, RSTRING(errstr)->len, stderr);
- if (RSTRING(errstr)->ptr[RSTRING(errstr)->len - 1] != '\n') {
- putc('\n', stderr);
+static void
+error_print(state)
+ NODE *state;
+{
+ struct FRAME *frame = the_frame;
+ VALUE etype;
+
+ if (!NIL_P(errat)) {
+ VALUE mesg;
+
+ switch (TYPE(errat)) {
+ case T_STRING:
+ mesg = errat;
+ errat = Qnil;
+ break;
+ case T_ARRAY:
+ mesg = RARRAY(errat)->ptr[0];
+ break;
}
+ fwrite(RSTRING(mesg)->ptr, 1, RSTRING(mesg)->len, stderr);
+ fprintf(stderr, ": ");
+ }
+
+ etype = rb_class_path(CLASS_OF(errinfo));
+
+ if (verbose) {
+ fwrite(RSTRING(etype)->ptr, 1, RSTRING(etype)->len, stderr);
+ putc('|', stderr);
+ }
+ if (RSTRING(errinfo)->len == 0) {
+ fprintf(stderr, "unhandled exception.\n");
}
else {
- fprintf(stderr, "unhandled failure.\n");
+ fwrite(RSTRING(errinfo)->ptr, 1, RSTRING(errinfo)->len, stderr);
+ if (RSTRING(errinfo)->ptr[RSTRING(errinfo)->len - 1] != '\n') {
+ putc('\n', stderr);
+ }
+ }
+
+ if (!NIL_P(errat)) {
+ int i;
+ struct RArray *ep = RARRAY(errat);
+
+#define TRACE_MAX (TRACE_HEAD+TRACE_TAIL+5)
+#define TRACE_HEAD 8
+#define TRACE_TAIL 5
+
+ for (i=1; i<ep->len; i++) {
+ fprintf(stderr, "\tfrom %s\n", RSTRING(ep->ptr[i])->ptr);
+ if (i == TRACE_HEAD && ep->len > TRACE_MAX) {
+ fprintf(stderr, "\t ... %d levels...\n",
+ ep->len - TRACE_HEAD - TRACE_TAIL);
+ i = ep->len - TRACE_TAIL;
+ }
+ }
}
}
@@ -511,9 +517,12 @@ ruby_init(argc, argv, envp)
int argc;
char **argv, **envp;
{
- int state;
static struct FRAME frame;
+ static struct iter iter;
+ NODE *state;
+
the_frame = top_frame = &frame;
+ the_iter = &iter;
origenviron = environ;
#ifdef NT
@@ -526,144 +535,171 @@ ruby_init(argc, argv, envp)
the_scope->local_tbl = 0;
top_scope = the_scope;
- PUSH_TAG();
- PUSH_ITER(ITER_NOT);
+ PUSH_TAG()
if ((state = EXEC_TAG()) == 0) {
rb_call_inits();
the_class = (struct RClass*)cObject;
+ the_frame->cbase = (VALUE)newnode(NODE_CREF,cObject,0,0);
ruby_options(argc, argv, envp);
}
- POP_ITER();
POP_TAG();
+ if (state) error_print(state);
POP_SCOPE();
the_scope = top_scope;
-
- if (state == TAG_EXIT) {
- rb_trap_exit();
- exit(FIX2UINT(last_val));
- }
- if (state) {
- error_print(last_func);
- }
}
static VALUE
-Eval()
+eval_node(self)
+ VALUE self;
{
VALUE result = Qnil;
NODE *tree;
- int state;
- if (!eval_tree) return Qnil;
+ if (!eval_tree) return FALSE;
tree = eval_tree;
eval_tree = 0;
- result = rb_eval(tree);
+ result = rb_eval(self, tree);
return result;
}
+int rb_in_eval;
+
+#ifdef THREAD
+static void thread_cleanup();
+static void thread_wait_other_threads();
+#endif
+
+static int exit_status;
+
void
ruby_run()
{
- int state;
+ NODE *state;
+ static NODE *ex;
if (nerrs > 0) exit(nerrs);
init_stack();
- rb_define_variable("$!", &errstr);
errat = Qnil; /* clear for execution */
PUSH_TAG();
PUSH_ITER(ITER_NOT);
if ((state = EXEC_TAG()) == 0) {
- Eval();
+ eval_node(TopSelf);
+ }
+ POP_ITER();
+ POP_TAG();
+
+ if (state && !ex) ex = state;
+ PUSH_TAG();
+ PUSH_ITER(ITER_NOT);
+ if ((state = EXEC_TAG()) == 0) {
rb_trap_exit();
+#ifdef THREAD
+ thread_cleanup();
+ thread_wait_other_threads();
+#endif
+ }
+ else {
+ ex = state;
}
POP_ITER();
POP_TAG();
- switch (state) {
- case 0:
- break;
+ if (!ex) {
+ exit(0);
+ }
+
+ switch (ex->nd_tag) {
case TAG_RETURN:
- Fatal("unexpected return");
+ error_pos();
+ fprintf(stderr, "unexpected return\n");
+ exit(1);
break;
- case TAG_CONTINUE:
- Fatal("unexpected continue");
+ case TAG_NEXT:
+ error_pos();
+ fprintf(stderr, "unexpected next\n");
+ exit(1);
break;
case TAG_BREAK:
- Fatal("unexpected break");
+ error_pos();
+ fprintf(stderr, "unexpected break\n");
+ exit(1);
break;
case TAG_REDO:
- Fatal("unexpected redo");
+ error_pos();
+ fprintf(stderr, "unexpected redo\n");
+ exit(1);
break;
case TAG_RETRY:
- Fatal("retry outside of protect clause");
+ error_pos();
+ fprintf(stderr, "retry outside of protect clause\n");
+ exit(1);
break;
- case TAG_FAIL:
- error_print(last_func);
+ case TAG_RAISE:
+ case TAG_FATAL:
+ if (obj_is_kind_of(errinfo, eSystemExit)) {
+ exit(exit_status);
+ }
+ error_print(ex);
exit(1);
break;
- case TAG_EXIT:
- exit(FIX2UINT(last_val));
+ case TAG_THROW:
+ error_pos();
+ fprintf(stderr, "uncaught throw `%s'\n", rb_id2name(ex->nd_tlev));
+ exit(1);
break;
default:
- Bug("Unknown longjmp status %d", state);
+ Bug("Unknown longjmp status %d", ex->nd_tag);
break;
}
- exit(0);
}
static void
-syntax_error()
+compile_error(at)
+ char *at;
{
VALUE mesg;
- mesg = errstr;
+ mesg = errinfo;
nerrs = 0;
- errstr = str_new2("syntax error in eval():\n");
- str_cat(errstr, RSTRING(mesg)->ptr, RSTRING(mesg)->len);
- rb_fail(errstr);
+ errinfo = exc_new(eSyntaxError, "compile error in ");
+ str_cat(errinfo, at, strlen(at));
+ str_cat(errinfo, ":\n", 2);
+ str_cat(errinfo, RSTRING(mesg)->ptr, RSTRING(mesg)->len);
+ rb_raise(errinfo);
}
VALUE
rb_eval_string(str)
char *str;
{
+ VALUE v;
char *oldsrc = sourcefile;
- lex_setsrc("(eval)", str, strlen(str));
- eval_tree = 0;
- PUSH_VARS();
- yyparse();
- POP_VARS();
+ sourcefile = "(eval)";
+ v = eval(TopSelf, str_new2(str), Qnil);
sourcefile = oldsrc;
- if (nerrs == 0) {
- return Eval();
- }
- else {
- syntax_error();
- }
- return Qnil; /* not reached */
+
+ return v;
}
void
rb_eval_cmd(cmd, arg)
VALUE cmd, arg;
{
- int state;
+ NODE *state;
struct SCOPE *saved_scope;
if (TYPE(cmd) != T_STRING) {
- if (TYPE(cmd) == T_OBJECT
- && obj_is_kind_of(cmd, cProc)) {
+ if (obj_is_kind_of(cmd, cProc)) {
proc_call(cmd, arg);
return;
}
}
- PUSH_SELF(TopSelf);
PUSH_CLASS();
PUSH_TAG();
saved_scope = the_scope;
@@ -672,31 +708,29 @@ rb_eval_cmd(cmd, arg)
the_class = (struct RClass*)cObject;
if ((state = EXEC_TAG()) == 0) {
- f_eval(Qself, cmd);
+ eval(TopSelf, cmd, Qnil);
}
the_scope = saved_scope;
POP_TAG();
POP_CLASS();
- POP_SELF();
- switch (state) {
- case 0:
- break;
+ if (state == 0) return;
+ switch (state->nd_tag) {
case TAG_RETURN:
- Fatal("unexpected return");
+ Raise(eLocalJumpError, "unexpected return");
break;
- case TAG_CONTINUE:
- Fatal("unexpected continue");
+ case TAG_NEXT:
+ Raise(eLocalJumpError, "unexpected next");
break;
case TAG_BREAK:
- Fatal("unexpected break");
+ Raise(eLocalJumpError, "unexpected break");
break;
case TAG_REDO:
- Fatal("unexpected redo");
+ Raise(eLocalJumpError, "unexpected redo");
break;
case TAG_RETRY:
- Fatal("retry outside of protect clause");
+ Raise(eLocalJumpError, "retry outside of protect clause");
break;
default:
JUMP_TAG(state);
@@ -709,8 +743,7 @@ rb_trap_eval(cmd, sig)
VALUE cmd;
int sig;
{
-#ifdef SAFE_SIGHANDLE
- int state;
+ NODE *state;
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
@@ -721,9 +754,74 @@ rb_trap_eval(cmd, sig)
trap_immediate = 0;
JUMP_TAG(state);
}
-#else
- rb_eval_cmd(cmd, ary_new3(1, INT2FIX(sig)));
-#endif
+}
+
+static VALUE
+superclass(self, node)
+ VALUE self;
+ NODE *node;
+{
+ VALUE val;
+ NODE *state;
+
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ val = rb_eval(self, node);
+ }
+ POP_TAG();
+ if ((state && state->nd_tag == TAG_RAISE) || !val || TYPE(val) != T_CLASS){
+ switch (nd_type(node)) {
+ case NODE_COLON2:
+ TypeError("undefined superclass `%s'", rb_id2name(node->nd_mid));
+ case NODE_CVAR:
+ case NODE_CONST:
+ TypeError("undefined superclass `%s'", rb_id2name(node->nd_vid));
+ }
+ if (state) JUMP_TAG(state);
+ TypeError("superclass undefined");
+ }
+ if (state) JUMP_TAG(state);
+
+ return val;
+}
+
+static VALUE
+ev_const_defined(cref, id)
+ NODE *cref;
+ ID id;
+{
+ NODE *cbase = cref;
+
+ while (cbase && cbase->nd_clss != cObject) {
+ struct RClass *class = RCLASS(cbase->nd_clss);
+
+ if (class->iv_tbl &&
+ st_lookup(class->iv_tbl, id, 0)) {
+ return TRUE;
+ }
+ cbase = cbase->nd_next;
+ }
+ return rb_const_defined(cref->nd_clss, id);
+}
+
+static VALUE
+ev_const_get(cref, id)
+ NODE *cref;
+ ID id;
+{
+ NODE *cbase = cref;
+ VALUE result;
+
+ while (cbase && cbase->nd_clss != cObject) {
+ struct RClass *class = RCLASS(cbase->nd_clss);
+
+ if (class->iv_tbl &&
+ st_lookup(class->iv_tbl, id, &result)) {
+ return result;
+ }
+ cbase = cbase->nd_next;
+ }
+ return rb_const_get(cref->nd_clss, id);
}
#define SETUP_ARGS {\
@@ -739,9 +837,11 @@ rb_trap_eval(cmd, sig)
n = node->nd_args;\
argv = ALLOCA_N(VALUE,argc);\
for (i=0;i<argc;i++) {\
- argv[i] = rb_eval(n->nd_head);\
+ argv[i] = rb_eval(self,n->nd_head);\
n=n->nd_next;\
}\
+ sourceline = nd_line(node);\
+ sourcefile = node->file;\
}\
else {\
argc = 0;\
@@ -749,73 +849,111 @@ rb_trap_eval(cmd, sig)
}\
}\
else {\
- VALUE args = rb_eval(n);\
+ VALUE args = rb_eval(self,n);\
if (TYPE(args) != T_ARRAY)\
args = rb_to_a(args);\
argc = RARRAY(args)->len;\
argv = ALLOCA_N(VALUE, argc);\
MEMCPY(argv, RARRAY(args)->ptr, VALUE, argc);\
+ sourceline = nd_line(node);\
+ sourcefile = node->file;\
}\
}
-#define RETURN(v) do { result = (v); goto finish; } while (0)
+int
+rb_test_false_or_nil(v)
+ VALUE v;
+{
+ return (v != Qnil) && (v != FALSE);
+}
+
+static int handle_rescue();
+VALUE rb_yield_0();
static VALUE
-rb_eval(node)
+rb_eval(self, node)
+ VALUE self;
register NODE *node;
{
- int state;
+ NODE *state;
VALUE result = Qnil;
+#define RETURN(v) { result = (v); goto finish; }
+
again:
- if (node == Qnil) RETURN(Qnil);
+ if (!node) RETURN(Qnil);
- sourceline = node->line;
+ sourceline = nd_line(node);
sourcefile = node->file;
switch (nd_type(node)) {
case NODE_BLOCK:
while (node) {
- result = rb_eval(node->nd_head);
+ result = rb_eval(self, node->nd_head);
node = node->nd_next;
}
break;
+ /* begin .. end without clauses */
+ case NODE_BEGIN:
+ node = node->nd_body;
+ goto again;
+
+ /* nodes for speed-up(default match) */
+ case NODE_MATCH:
+ result = reg_match2(node->nd_head->nd_lit);
+ break;
+
+ /* nodes for speed-up(top-level loop for -n/-p) */
+ case NODE_OPT_N:
+ while (!NIL_P(f_gets())) {
+ rb_eval(self, node->nd_body);
+ }
+ RETURN(Qnil);
+
case NODE_SELF:
- RETURN(Qself);
+ RETURN(self);
case NODE_NIL:
RETURN(Qnil);
case NODE_IF:
- if (rb_eval(node->nd_cond)) {
+ if (RTEST(rb_eval(self, node->nd_cond))) {
node = node->nd_body;
}
else {
node = node->nd_else;
}
- if (node) goto again;
- RETURN(Qnil);
+ goto again;
+
+ case NODE_UNLESS:
+ if (!RTEST(rb_eval(self, node->nd_cond))) {
+ node = node->nd_body;
+ }
+ else {
+ node = node->nd_else;
+ }
+ goto again;
case NODE_CASE:
{
VALUE val;
- val = rb_eval(node->nd_head);
+ val = rb_eval(self, node->nd_head);
node = node->nd_body;
while (node) {
- if (nd_type(node) == NODE_WHEN) {
- NODE *tag = node->nd_head;
+ NODE *tag;
- while (tag) {
- if (rb_funcall(rb_eval(tag->nd_head), match, 1, val)){
- RETURN(rb_eval(node->nd_body));
- }
- tag = tag->nd_next;
- }
+ if (nd_type(node) != NODE_WHEN) {
+
+ RETURN(rb_eval(self, node));
}
- else {
- RETURN(rb_eval(node));
+ tag = node->nd_head;
+ while (tag) {
+ if (RTEST(rb_funcall2(rb_eval(self, tag->nd_head),eqq,1,&val))){
+ RETURN(rb_eval(self, node->nd_body));
+ }
+ tag = tag->nd_next;
}
node = node->nd_next;
}
@@ -824,60 +962,62 @@ rb_eval(node)
case NODE_WHILE:
PUSH_TAG();
- switch (state = EXEC_TAG()) {
- case 0:
- while_cont:
- while (rb_eval(node->nd_cond)) {
+ if ((state = EXEC_TAG()) == 0) {
+ while_next:
+ for (;;) {
+ if (node->nd_state && !RTEST(rb_eval(self, node->nd_cond)))
+ break;
while_redo:
- rb_eval(node->nd_body);
+ rb_eval(self, node->nd_body);
+ if (!node->nd_state && !RTEST(rb_eval(self, node->nd_cond)))
+ break;
+ }
+ }
+ else {
+ switch (state->nd_tag) {
+ case TAG_REDO:
+ state = 0;
+ goto while_redo;
+ case TAG_NEXT:
+ state = 0;
+ goto while_next;
+ default:
+ break;
}
- break;
- case TAG_REDO:
- state = 0;
- goto while_redo;
- case TAG_CONTINUE:
- state = 0;
- goto while_cont;
- default:
- break;
}
POP_TAG();
- switch (state) {
- case 0:
- case TAG_BREAK:
- break;
- default:
+ if (state && state->nd_tag != TAG_BREAK) {
JUMP_TAG(state);
- break;
}
RETURN(Qnil);
- case NODE_WHILE2:
+ case NODE_UNTIL:
PUSH_TAG();
- switch (state = EXEC_TAG()) {
- case 0:
- while2_cont:
- do {
- while2_redo:
- rb_eval(node->nd_body);
- } while (rb_eval(node->nd_cond));
- break;
- case TAG_REDO:
- state = 0;
- goto while2_redo;
- case TAG_CONTINUE:
- state = 0;
- goto while2_cont;
- default:
- case TAG_BREAK:
- break;
+ if ((state = EXEC_TAG()) == 0) {
+ until_next:
+ for (;;) {
+ if (node->nd_state && RTEST(rb_eval(self, node->nd_cond)))
+ break;
+ until_redo:
+ rb_eval(self, node->nd_body);
+ if (!node->nd_state && RTEST(rb_eval(self, node->nd_cond)))
+ break;
+ }
+ }
+ else {
+ switch (state->nd_tag) {
+ case TAG_REDO:
+ state = 0;
+ goto while_redo;
+ case TAG_NEXT:
+ state = 0;
+ goto while_next;
+ default:
+ break;
+ }
}
POP_TAG();
- switch (state) {
- case 0:
- case TAG_BREAK:
- break;
- default:
+ if (state && state->nd_tag != TAG_BREAK) {
JUMP_TAG(state);
}
RETURN(Qnil);
@@ -885,6 +1025,8 @@ rb_eval(node)
case NODE_ITER:
case NODE_FOR:
{
+ int tag_level;
+
iter_retry:
PUSH_BLOCK(node->nd_var, node->nd_body);
PUSH_TAG();
@@ -893,36 +1035,37 @@ rb_eval(node)
if (state == 0) {
if (nd_type(node) == NODE_ITER) {
PUSH_ITER(ITER_PRE);
- result = rb_eval(node->nd_iter);
+ result = rb_eval(self, node->nd_iter);
POP_ITER();
}
else {
VALUE recv;
- recv = rb_eval(node->nd_iter);
+ recv = rb_eval(self, node->nd_iter);
PUSH_ITER(ITER_PRE);
+ sourceline = nd_line(node);
+ sourcefile = node->file;
result = rb_call(CLASS_OF(recv),recv,each,0,0,0);
POP_ITER();
}
}
POP_TAG();
+ tag_level = the_block->level;
POP_BLOCK();
- switch (state) {
- case 0:
- break;
-
+ if (state == 0) break;
+ switch (state->nd_tag) {
case TAG_RETRY:
goto iter_retry;
case IN_BLOCK|TAG_BREAK:
- if (target_level != tag_level) {
+ if (state->nd_tlev != tag_level) {
JUMP_TAG(state);
}
result = Qnil;
break;
case IN_BLOCK|TAG_RETURN:
- if (target_level == tag_level) {
- state &= ~IN_BLOCK;
+ if (state->nd_tlev == tag_level) {
+ state->nd_tag &= ~IN_BLOCK;
}
/* fall through */
default:
@@ -931,79 +1074,91 @@ rb_eval(node)
}
break;
- case NODE_FAIL:
- {
- VALUE mesg = rb_eval(node->nd_stts);
- if (mesg) Check_Type(mesg, T_STRING);
- rb_fail(mesg);
- }
- break;
-
case NODE_YIELD:
- result = rb_yield(rb_eval(node->nd_stts));
+ result = rb_yield_0(rb_eval(self, node->nd_stts), 0);
break;
- case NODE_BEGIN:
- if (node->nd_resq == Qnil && node->nd_ensr == Qnil) {
- node = node->nd_head;
- goto again;
+ case NODE_RESCUE:
+ retry_entry:
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ result = rb_eval(self, node->nd_head);
}
- else {
- VALUE (*r_proc)();
-
- if (node->nd_resq == (NODE*)1) {
- r_proc = 0;
- }
- else {
- r_proc = rb_eval;
- }
- if (node->nd_ensr) {
- PUSH_TAG();
- if ((state = EXEC_TAG()) == 0) {
- result = rb_rescue(rb_eval, node->nd_head, r_proc, node->nd_resq);
- }
- POP_TAG();
- /* ensure clause */
- rb_eval(node->nd_ensr);
- if (state) {
- JUMP_TAG(state);
+ POP_TAG();
+ if (state) {
+ if (state->nd_tag == TAG_RAISE) {
+ NODE *resq = node->nd_resq;
+ while (resq) {
+ if (handle_rescue(self, resq)) {
+ state = 0;
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ result = rb_eval(self, resq->nd_body);
+ }
+ POP_TAG();
+ if (state == 0) {
+ errat = Qnil;
+ }
+ else if (state->nd_tag == TAG_RETRY) {
+ state = 0;
+ goto retry_entry;
+ }
+ break;
+ }
+ resq = resq->nd_head; /* next rescue */
}
}
- else {
- result = rb_rescue(rb_eval, node->nd_head, r_proc, node->nd_resq);
+ if (state) {
+ JUMP_TAG(state);
}
}
break;
+ case NODE_ENSURE:
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ result = rb_eval(self, node->nd_head);
+ }
+ POP_TAG();
+ rb_eval(self, node->nd_ensr);
+ if (state) {
+ JUMP_TAG(state);
+ }
+ break;
+
case NODE_AND:
- if ((result = rb_eval(node->nd_1st)) == FALSE) RETURN(result);
+ result = rb_eval(self, node->nd_1st);
+ if (!RTEST(result)) break;
node = node->nd_2nd;
goto again;
case NODE_OR:
- if ((result = rb_eval(node->nd_1st)) != FALSE) RETURN(result);
+ result = rb_eval(self, node->nd_1st);
+ if (RTEST(result)) break;
node = node->nd_2nd;
goto again;
case NODE_NOT:
- if (rb_eval(node->nd_body)) result = FALSE;
+ if (RTEST(rb_eval(self, node->nd_body))) result = FALSE;
else result = TRUE;
break;
case NODE_DOT2:
case NODE_DOT3:
- RETURN(range_new(rb_eval(node->nd_beg), rb_eval(node->nd_end)));
+ RETURN(range_new(rb_eval(self, node->nd_beg), rb_eval(self, node->nd_end)));
case NODE_FLIP2: /* like AWK */
if (node->nd_state == 0) {
- if (rb_eval(node->nd_beg)) {
- node->nd_state = rb_eval(node->nd_end)?0:1;
+ if (RTEST(rb_eval(self, node->nd_beg))) {
+ node->nd_state = rb_eval(self, node->nd_end)?0:1;
result = TRUE;
}
- result = FALSE;
+ else {
+ result = FALSE;
+ }
}
else {
- if (rb_eval(node->nd_end)) {
+ if (RTEST(rb_eval(self, node->nd_end))) {
node->nd_state = 0;
}
result = TRUE;
@@ -1012,39 +1167,22 @@ rb_eval(node)
case NODE_FLIP3: /* like SED */
if (node->nd_state == 0) {
- if (rb_eval(node->nd_beg)) {
+ if (RTEST(rb_eval(self, node->nd_beg))) {
node->nd_state = 1;
result = TRUE;
}
result = FALSE;
}
else {
- if (rb_eval(node->nd_end)) {
+ if (RTEST(rb_eval(self, node->nd_end))) {
node->nd_state = 0;
}
result = TRUE;
}
break;
- case NODE_BREAK:
- JUMP_TAG(TAG_BREAK);
- break;
-
- case NODE_CONTINUE:
- JUMP_TAG(TAG_CONTINUE);
- break;
-
- case NODE_REDO:
- JUMP_TAG(TAG_REDO);
- break;
-
- case NODE_RETRY:
- JUMP_TAG(TAG_RETRY);
- break;
-
case NODE_RETURN:
- if (node->nd_stts) last_val = rb_eval(node->nd_stts);
- JUMP_TAG(TAG_RETURN);
+ JUMP_TAG2(TAG_RETURN,(node->nd_stts)?rb_eval(self, node->nd_stts):Qnil);
break;
case NODE_CALL:
@@ -1053,7 +1191,7 @@ rb_eval(node)
int argc; VALUE *argv; /* used in SETUP_ARGS */
PUSH_ITER(ITER_NOT);
- recv = rb_eval(node->nd_recv);
+ recv = rb_eval(self, node->nd_recv);
SETUP_ARGS;
POP_ITER();
result = rb_call(CLASS_OF(recv),recv,node->nd_mid,argc,argv,0);
@@ -1067,7 +1205,7 @@ rb_eval(node)
PUSH_ITER(ITER_NOT);
SETUP_ARGS;
POP_ITER();
- result = rb_call(CLASS_OF(Qself),Qself,node->nd_mid,argc,argv,1);
+ result = rb_call(CLASS_OF(self),self,node->nd_mid,argc,argv,1);
}
break;
@@ -1086,8 +1224,8 @@ rb_eval(node)
POP_ITER();
}
- PUSH_ITER(iter->iter?ITER_PRE:ITER_NOT);
- result = rb_call(the_frame->last_class->super, Qself,
+ PUSH_ITER(the_iter->iter?ITER_PRE:ITER_NOT);
+ result = rb_call(the_frame->last_class->super, self,
the_frame->last_func, argc, argv, 1);
POP_ITER();
}
@@ -1095,11 +1233,14 @@ rb_eval(node)
case NODE_SCOPE:
{
+ VALUE save = the_frame->cbase;
+
PUSH_SCOPE();
PUSH_TAG();
- if (node->nd_cnt > 0) {
- the_scope->local_vars = ALLOCA_N(VALUE, node->nd_cnt);
- MEMZERO(the_scope->local_vars, VALUE, node->nd_cnt);
+ if (node->nd_rval) the_frame->cbase = (VALUE)node->nd_rval;
+ if (node->nd_tbl) {
+ the_scope->local_vars = ALLOCA_N(VALUE, node->nd_tbl[0]);
+ memclear(the_scope->local_vars, node->nd_tbl[0]);
the_scope->local_tbl = node->nd_tbl;
}
else {
@@ -1107,11 +1248,12 @@ rb_eval(node)
the_scope->local_tbl = 0;
}
if ((state = EXEC_TAG()) == 0) {
- result = rb_eval(node->nd_body);
+ result = rb_eval(self, node->nd_body);
}
POP_TAG();
POP_SCOPE();
- if (state != 0) JUMP_TAG(state);
+ the_frame->cbase = save;
+ if (state) JUMP_TAG(state);
}
break;
@@ -1120,12 +1262,12 @@ rb_eval(node)
VALUE recv, args, val;
NODE *rval;
- recv = rb_eval(node->nd_recv);
+ recv = rb_eval(self, node->nd_recv);
rval = node->nd_args->nd_head;
- args = rb_eval(node->nd_args->nd_next);
+ args = rb_eval(self, node->nd_args->nd_next);
val = rb_apply(recv, aref, args);
- val = rb_funcall(val, node->nd_mid, 1, rb_eval(rval));
+ val = rb_funcall(val, node->nd_mid, 1, rb_eval(self, rval));
ary_push(args, val);
rb_apply(recv, aset, args);
result = val;
@@ -1134,38 +1276,40 @@ rb_eval(node)
case NODE_OP_ASGN2:
{
- ID id = node->nd_aid;
+ ID id = node->nd_next->nd_vid;
VALUE recv, val;
- recv = rb_funcall(rb_eval(node->nd_recv), id, 0);
+ recv = rb_eval(self, node->nd_recv);
+ val = rb_funcall(recv, id, 0);
- id = id_attrset(id);
+ val = rb_funcall(recv, node->nd_next->nd_mid, 2, val,
+ rb_eval(self, node->nd_value));
- val = rb_eval(node->nd_value);
- rb_funcall(recv, id, 1, val);
+ rb_funcall2(recv, id_attrset(id), 1, &val);
result = val;
}
break;
case NODE_MASGN:
- result = masign(node, rb_eval(node->nd_value));
+ result = masign(self, node, rb_eval(self, node->nd_value));
break;
case NODE_LASGN:
if (the_scope->local_vars == 0)
Bug("unexpected local variable asignment");
- result = the_scope->local_vars[node->nd_cnt] = rb_eval(node->nd_value);
+ the_scope->local_vars[node->nd_cnt] = rb_eval(self, node->nd_value);
+ result = the_scope->local_vars[node->nd_cnt];
break;
case NODE_DASGN:
- result = dyna_var_asgn(node->nd_vid, rb_eval(node->nd_value));
+ result = dyna_var_asgn(node->nd_vid, rb_eval(self, node->nd_value));
break;
case NODE_GASGN:
{
VALUE val;
- val = rb_eval(node->nd_value);
+ val = rb_eval(self, node->nd_value);
rb_gvar_set(node->nd_entry, val);
result = val;
}
@@ -1175,8 +1319,8 @@ rb_eval(node)
{
VALUE val;
- val = rb_eval(node->nd_value);
- rb_ivar_set(Qself, node->nd_vid, val);
+ val = rb_eval(self, node->nd_value);
+ rb_ivar_set(self, node->nd_vid, val);
result = val;
}
break;
@@ -1185,15 +1329,21 @@ rb_eval(node)
{
VALUE val;
- val = rb_eval(node->nd_value);
+ val = rb_eval(self, node->nd_value);
+ /* check for static scope constants */
+ if (verbose && ev_const_defined(the_frame->cbase, node->nd_vid)) {
+ Warning("already initialized constnant %s",
+ rb_id2name(node->nd_vid));
+ }
rb_const_set(the_class, node->nd_vid, val);
result = val;
}
break;
case NODE_LVAR:
- if (the_scope->local_vars == 0)
+ if (the_scope->local_vars == 0) {
Bug("unexpected local variable");
+ }
result = the_scope->local_vars[node->nd_cnt];
break;
@@ -1206,18 +1356,13 @@ rb_eval(node)
break;
case NODE_IVAR:
- result = rb_ivar_get(Qself, node->nd_vid);
+ result = rb_ivar_get(self, node->nd_vid);
break;
case NODE_CVAR:
- {
- VALUE val;
-
- val = rb_const_get(node->nd_rval->nd_clss, node->nd_vid);
- nd_set_type(node, NODE_CONST);
- node->nd_cval = val;
- result = val;
- }
+ result = ev_const_get(the_frame->cbase, node->nd_vid);
+ nd_set_type(node, NODE_CONST);
+ node->nd_cval = result;
break;
case NODE_CONST:
@@ -1228,7 +1373,7 @@ rb_eval(node)
{
VALUE cls;
- cls = rb_eval(node->nd_head);
+ cls = rb_eval(self, node->nd_head);
switch (TYPE(cls)) {
case T_CLASS:
case T_MODULE:
@@ -1237,7 +1382,7 @@ rb_eval(node)
Check_Type(cls, T_CLASS);
break;
}
- result = rb_const_get(cls, node->nd_mid);
+ result = rb_const_get_at(cls, node->nd_mid);
}
break;
@@ -1273,11 +1418,11 @@ rb_eval(node)
list = node->nd_head;
while (list) {
- key = rb_eval(list->nd_head);
+ key = rb_eval(self, list->nd_head);
list = list->nd_next;
if (list == 0)
Bug("odd number list for Hash");
- val = rb_eval(list->nd_head);
+ val = rb_eval(self, list->nd_head);
list = list->nd_next;
hash_aset(hash, key, val);
}
@@ -1297,7 +1442,7 @@ rb_eval(node)
i = node->nd_alen;
ary = ary_new2(i);
for (i=0;node;node=node->nd_next) {
- RARRAY(ary)->ptr[i++] = rb_eval(node->nd_head);
+ RARRAY(ary)->ptr[i++] = rb_eval(self, node->nd_head);
RARRAY(ary)->len = i;
}
@@ -1309,9 +1454,10 @@ rb_eval(node)
result = str_new3(node->nd_lit);
break;
- case NODE_STR2:
- case NODE_XSTR2:
+ case NODE_DSTR:
+ case NODE_DXSTR:
case NODE_DREGX:
+ case NODE_DREGX_ONCE:
{
VALUE str, str2;
NODE *list = node->nd_next;
@@ -1322,7 +1468,15 @@ rb_eval(node)
str2 = list->nd_head->nd_lit;
}
else {
- str2 = rb_eval(list->nd_head);
+ if (nd_type(list->nd_head) == NODE_EVSTR) {
+ rb_in_eval++;
+ list->nd_head = compile(list->nd_head->nd_lit);
+ rb_in_eval--;
+ if (!node) {
+ compile_error("string expand");
+ }
+ }
+ str2 = rb_eval(self, list->nd_head);
}
if (str2) {
str2 = obj_as_string(str2);
@@ -1330,22 +1484,29 @@ rb_eval(node)
}
list = list->nd_next;
}
- if (nd_type(node) == NODE_DREGX) {
- VALUE re = reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
- node->nd_cflag);
- result = re;
- }
- else if (nd_type(node) == NODE_XSTR2) {
- result = rb_xstring(str);
- }
- else {
+ switch (nd_type(node)) {
+ case NODE_DREGX:
+ result = reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
+ node->nd_cflag);
+ break;
+ case NODE_DREGX_ONCE: /* regexp expand once */
+ result = reg_new(RSTRING(str)->ptr, RSTRING(str)->len,
+ node->nd_cflag);
+ nd_set_type(node, NODE_LIT);
+ node->nd_lit = result;
+ break;
+ case NODE_DXSTR:
+ result = rb_funcall(self, '`', 1, str);
+ break;
+ default:
result = str;
+ break;
}
}
break;
case NODE_XSTR:
- result = rb_xstring(node->nd_lit);
+ result = rb_funcall(self, '`', 1, node->nd_lit);
break;
case NODE_LIT:
@@ -1354,8 +1515,8 @@ rb_eval(node)
case NODE_ATTRSET:
if (the_frame->argc != 1)
- Fail("Wrong # of arguments(%d for 1)", the_frame->argc);
- result = rb_ivar_set(Qself, node->nd_vid, the_frame->argv[0]);
+ ArgError("Wrong # of arguments(%d for 1)", the_frame->argc);
+ result = rb_ivar_set(self, node->nd_vid, the_frame->argv[0]);
break;
case NODE_DEFN:
@@ -1365,9 +1526,17 @@ rb_eval(node)
int noex;
body = search_method(the_class, node->nd_mid, &origin);
- if (body && verbose && origin != (VALUE)the_class
- && body->nd_noex != node->nd_noex) {
- Warning("change method %s's scope", rb_id2name(node->nd_mid));
+ if (body) {
+ if (origin == (VALUE)the_class) {
+ Warning("redefine %s", rb_id2name(node->nd_mid));
+ }
+ else {
+ if (body->nd_noex != node->nd_noex) {
+ Warning("change method %s's scope",
+ rb_id2name(node->nd_mid));
+ }
+ }
+ rb_clear_cache();
}
if (body) noex = body->nd_noex;
@@ -1380,23 +1549,38 @@ rb_eval(node)
case NODE_DEFS:
if (node->nd_defn) {
- VALUE recv = rb_eval(node->nd_recv);
+ VALUE recv = rb_eval(self, node->nd_recv);
+ VALUE class;
+ NODE *body;
+
+ if (NIL_P(recv)) {
+ TypeError("Can't define method \"%s\" for nil",
+ rb_id2name(node->nd_mid));
+ }
- if (recv == Qnil) {
- Fail("Can't define method \"%s\" for nil",
- rb_id2name(node->nd_mid));
+ class = rb_singleton_class(recv);
+ if (st_lookup(RCLASS(class)->m_tbl, node->nd_mid, &body)) {
+ Warning("redefine %s", rb_id2name(node->nd_mid));
}
+ rb_clear_cache();
rb_funcall(recv, rb_intern("singleton_method_added"),
1, INT2FIX(node->nd_mid));
- rb_add_method(rb_singleton_class(recv),node->nd_mid,node->nd_defn,
- NOEX_PUBLIC);
+ rb_add_method(class, node->nd_mid, node->nd_defn, NOEX_PUBLIC);
result = Qnil;
}
break;
case NODE_UNDEF:
- rb_add_method(the_class, node->nd_mid, Qnil, NOEX_PUBLIC);
- result = Qnil;
+ {
+ NODE *body;
+
+ if (st_lookup(the_class->m_tbl, node->nd_mid, &body)) {
+ Warning("redefine %s", rb_id2name(node->nd_mid));
+ }
+ rb_clear_cache();
+ rb_add_method(the_class, node->nd_mid, 0, NOEX_PUBLIC);
+ result = Qnil;
+ }
break;
case NODE_ALIAS:
@@ -1410,35 +1594,33 @@ rb_eval(node)
struct RClass *tmp;
if (node->nd_super) {
- super = rb_eval(node->nd_super);
- if (super == Qnil || TYPE(super) != T_CLASS) {
- Fail("superclass undefined");
- }
+ super = superclass(self, node->nd_super);
}
else {
- super = Qnil;
+ super = 0;
}
- if (rb_const_defined(the_class, node->nd_cname)) {
+ if (!rb_autoload_defined(node->nd_cname) &&
+ ev_const_defined(the_frame->cbase, node->nd_cname)) {
class = rb_const_get(the_class, node->nd_cname);
+ if (TYPE(class) != T_CLASS)
+ TypeError("%s is not a class", rb_id2name(node->nd_cname));
if (super) {
- if (TYPE(class) != T_CLASS)
- Fail("%s is not a class", rb_id2name(node->nd_cname));
tmp = RCLASS(class)->super;
- while (FL_TEST(tmp, FL_SINGLE)) {
+ while (FL_TEST(tmp, FL_SINGLETON)) {
tmp = RCLASS(tmp)->super;
}
while (TYPE(tmp) == T_ICLASS) {
tmp = RCLASS(tmp)->super;
}
if (tmp != RCLASS(super))
- Fail("superclass mismatch for %s",
- rb_id2name(node->nd_cname));
+ TypeError("superclass mismatch for %s",
+ rb_id2name(node->nd_cname));
}
Warning("extending class %s", rb_id2name(node->nd_cname));
}
else {
- if (super == Qnil) super = cObject;
+ if (!super) super = cObject;
class = rb_define_class_id(node->nd_cname, super);
rb_const_set(the_class, node->nd_cname, class);
rb_set_class_path(class,the_class,rb_id2name(node->nd_cname));
@@ -1453,10 +1635,11 @@ rb_eval(node)
{
VALUE module;
- if (rb_const_defined(the_class, node->nd_cname)) {
+ if (!rb_autoload_defined(node->nd_cname) &&
+ ev_const_defined(the_frame->cbase, node->nd_cname)) {
module = rb_const_get(the_class, node->nd_cname);
if (TYPE(module) != T_MODULE)
- Fail("%s is not a module", rb_id2name(node->nd_cname));
+ TypeError("%s is not a module", rb_id2name(node->nd_cname));
Warning("extending module %s", rb_id2name(node->nd_cname));
}
else {
@@ -1473,8 +1656,11 @@ rb_eval(node)
case NODE_DEFINED:
{
VALUE obj;
+ char buf[20];
+ char *desc = 0;
node = node->nd_head;
+
switch (nd_type(node)) {
case NODE_SUPER:
case NODE_ZSUPER:
@@ -1486,17 +1672,16 @@ rb_eval(node)
break;
case NODE_FCALL:
- obj = CLASS_OF(Qself);
+ obj = CLASS_OF(self);
goto check_bound;
case NODE_CALL:
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
- obj = rb_eval(node->nd_recv);
+ obj = rb_eval(self, node->nd_recv);
}
POP_TAG();
- if (state == TAG_FAIL) {
- result = FALSE;
+ if (state) {
break;
}
else {
@@ -1505,27 +1690,23 @@ rb_eval(node)
check_bound:
if (method_boundp(obj, node->nd_mid,
nd_type(node)== NODE_CALL)) {
- result = TRUE;
+ desc = "method";
}
- else result = FALSE;
}
break;
case NODE_YIELD:
- result = iterator_p();
+ if (iterator_p()) {
+ desc = "iterator";
+ }
break;
- case NODE_BREAK:
- case NODE_CONTINUE:
- case NODE_REDO:
- case NODE_RETRY:
-
case NODE_SELF:
+ desc = "self"; break;
case NODE_NIL:
- case NODE_FAIL:
- case NODE_ATTRSET:
- case NODE_DEFINED:
+ desc = "nil"; break;
+ case NODE_ATTRSET:
case NODE_OP_ASGN1:
case NODE_OP_ASGN2:
case NODE_MASGN:
@@ -1534,60 +1715,80 @@ rb_eval(node)
case NODE_GASGN:
case NODE_IASGN:
case NODE_CASGN:
+ desc = "asignment"; break;
+
case NODE_LVAR:
+ desc = "local-variable"; break;
case NODE_DVAR:
- result = TRUE;
- break;
+ desc = "dynamic-local-variable"; break;
case NODE_GVAR:
- result = rb_gvar_defined(node->nd_entry);
+ if (rb_gvar_defined(node->nd_entry)) {
+ desc = "global-variable";
+ }
break;
case NODE_IVAR:
- result = rb_ivar_defined(node->nd_vid);
+ if (rb_ivar_defined(self, node->nd_vid)) {
+ desc = "instance-variable";
+ }
break;
case NODE_CVAR:
- result = rb_const_defined(node->nd_rval->nd_clss, node->nd_vid);
- break;
-
- case NODE_CONST:
- result = TRUE;
+ if (ev_const_defined(the_frame->cbase, node->nd_vid)) {
+ case NODE_CONST: /* jump in */
+ desc = "class-constant";
+ }
break;
case NODE_COLON2:
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
- obj = rb_eval(node->nd_head);
+ obj = rb_eval(self, node->nd_head);
}
POP_TAG();
- if (state == TAG_FAIL) result = FALSE;
+ if (state) {
+ break;
+ }
else {
if (state) JUMP_TAG(state);
- result = rb_const_defined(obj, node->nd_mid);
+ switch (TYPE(obj)) {
+ case T_CLASS:
+ case T_MODULE:
+ if (rb_const_defined_at(obj, node->nd_mid))
+ desc = "class-constant";
+ break;
+ }
}
break;
case NODE_NTH_REF:
- result = reg_nth_defined(node->nd_nth, MATCH_DATA);
+ if (reg_nth_defined(node->nd_nth, MATCH_DATA)) {
+ sprintf(buf, "$%d", node->nd_nth);
+ desc = buf;
+ }
break;
case NODE_BACK_REF:
- result = reg_nth_defined(0, MATCH_DATA);
+ if (reg_nth_defined(0, MATCH_DATA)) {
+ sprintf(buf, "$%c", node->nd_nth);
+ desc = buf;
+ }
break;
default:
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
- rb_eval(node);
+ rb_eval(self, node);
}
POP_TAG();
- if (state == TAG_FAIL) result = FALSE;
+ if (state) break;
else {
- if (state) JUMP_TAG(state);
- result = TRUE;
+ desc = "expression";
}
}
+ if (desc) result = str_new2(desc);
+ else result = FALSE;
}
break;
@@ -1595,12 +1796,8 @@ rb_eval(node)
Bug("unknown node type %d", nd_type(node));
}
finish:
-#ifdef SAFE_SIGHANDLE
- if (trap_pending) {
- rb_trap_exec();
- }
-#endif
- return result; /* not reached */
+ CHECK_INTS;
+ return result;
}
static void
@@ -1608,7 +1805,8 @@ module_setup(module, node)
VALUE module;
NODE *node;
{
- int state;
+ NODE *state;
+ VALUE save = the_frame->cbase;
/* fill c-ref */
node->nd_clss = module;
@@ -1616,12 +1814,12 @@ module_setup(module, node)
PUSH_CLASS();
the_class = (struct RClass*)module;
- PUSH_SELF((VALUE)the_class);
PUSH_SCOPE();
- if (node->nd_cnt > 0) {
- the_scope->local_vars = ALLOCA_N(VALUE, node->nd_cnt);
- MEMZERO(the_scope->local_vars, VALUE, node->nd_cnt);
+ if (node->nd_rval) the_frame->cbase = node->nd_rval;
+ if (node->nd_tbl) {
+ the_scope->local_vars = ALLOCA_N(VALUE, node->nd_tbl[0]);
+ memclear(the_scope->local_vars, node->nd_tbl[0]);
the_scope->local_tbl = node->nd_tbl;
}
else {
@@ -1631,21 +1829,48 @@ module_setup(module, node)
PUSH_TAG();
if ((state = EXEC_TAG()) == 0) {
- rb_eval(node->nd_body);
+ rb_eval((VALUE)the_class, node->nd_body);
}
POP_TAG();
POP_SCOPE();
- POP_SELF();
POP_CLASS();
+ the_frame->cbase = save;
if (state) JUMP_TAG(state);
}
-VALUE
-rb_responds_to(obj, id)
+int
+rb_respond_to(obj, id)
VALUE obj;
ID id;
{
- if (rb_method_boundp(CLASS_OF(obj), id)) {
+ if (rb_method_boundp(CLASS_OF(obj), id, 0)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static VALUE
+krn_respond_to(argc, argv, obj)
+ int argc;
+ VALUE *argv;
+ VALUE obj;
+{
+ VALUE mid, priv;
+ ID id;
+
+ rb_scan_args(argc, argv, "11", &mid, &priv);
+ id = rb_to_id(mid);
+ if (rb_method_boundp(CLASS_OF(obj), id, !RTEST(priv))) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+static VALUE
+mod_method_defined(mod, mid)
+ VALUE mod, mid;
+{
+ if (rb_method_boundp(mod, rb_to_id(mid), TRUE)) {
return TRUE;
}
return FALSE;
@@ -1655,11 +1880,11 @@ void
rb_exit(status)
int status;
{
- last_val = INT2FIX(status);
- if (prot_tag)
- JUMP_TAG(TAG_EXIT);
- rb_trap_exit();
- exit(FIX2UINT(last_val));
+ if (prot_tag) {
+ exit_status = status;
+ rb_raise(exc_new(eSystemExit, ""));
+ }
+ exit(status);
}
static VALUE
@@ -1671,71 +1896,141 @@ f_exit(argc, argv, obj)
VALUE status;
if (rb_scan_args(argc, argv, "01", &status) == 1) {
- Need_Fixnum(status);
+ status = NUM2INT(status);
}
else {
- status = INT2FIX(0);
+ status = 0;
}
- last_val = status;
- JUMP_TAG(TAG_EXIT);
-
- return Qnil; /* not reached */
+ rb_exit(status);
+ /* not reached */
}
void
rb_break()
{
- JUMP_TAG(TAG_BREAK);
+ JUMP_TAG2(TAG_BREAK, 0);
}
-void
-rb_redo()
+static VALUE
+f_break()
+{
+ JUMP_TAG2(TAG_BREAK, 0);
+}
+
+static VALUE
+f_next()
+{
+ JUMP_TAG2(TAG_NEXT, 0);
+}
+
+static VALUE
+f_redo()
+{
+ JUMP_TAG2(TAG_REDO, 0);
+}
+
+static VALUE
+f_retry()
+{
+ JUMP_TAG2(TAG_RETRY, 0);
+}
+
+#ifdef __GNUC__
+static volatile voidfn rb_longjmp;
+#endif
+
+static VALUE make_backtrace();
+
+static void
+rb_longjmp(tag, mesg)
+ int tag;
+ VALUE mesg;
{
- JUMP_TAG(TAG_REDO);
+ if (NIL_P(errat) && NIL_P(mesg)) {
+ errinfo = exc_new(eRuntimeError, "");
+ }
+
+ if (sourcefile && (NIL_P(errat) || !NIL_P(mesg))) {
+ errat = make_backtrace();
+ }
+
+ if (!NIL_P(mesg)) {
+ if (obj_is_kind_of(mesg, eGlobalExit)) {
+ errinfo = mesg;
+ }
+ else {
+ errinfo = exc_new2(eRuntimeError, mesg);
+ }
+ str_freeze(errinfo);
+ }
+
+ JUMP_TAG2(tag, 0);
}
void
-rb_retry()
+rb_raise(mesg)
+ VALUE mesg;
{
- JUMP_TAG(TAG_RETRY);
+ rb_longjmp(TAG_RAISE, mesg);
}
void
-rb_fail(mesg)
+rb_fatal(mesg)
VALUE mesg;
{
- char buf[BUFSIZ];
+ rb_longjmp(TAG_FATAL, mesg);
+}
- if (errat == Qnil && mesg == Qnil) {
- errstr = Qnil;
+void
+rb_interrupt()
+{
+ rb_raise(exc_new(eInterrupt, "Interrupt"));
+}
+
+static VALUE
+f_raise(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE arg1, arg2;
+ VALUE etype, mesg;
+
+ etype = eRuntimeError;
+ mesg = Qnil;
+ switch (rb_scan_args(argc, argv, "02", &arg1, &arg2)) {
+ case 1:
+ mesg = arg1;
+ break;
+ case 2:
+ etype = arg1;
+ mesg = arg2;
+ break;
}
- if (errat == Qnil && sourcefile) {
- if (the_frame->last_func) {
- last_func = the_frame->last_func;
+ if (!NIL_P(mesg)) {
+ Check_Type(mesg, T_STRING);
+ if (!obj_is_kind_of(mesg, eException)) {
+ mesg = exc_new2(etype, mesg);
}
- sprintf(buf, "%s:%d", sourcefile, sourceline);
- errat = str_new2(buf);
}
- if (mesg) {
- errstr = mesg;
- }
- if (prot_tag->level == 0) error_print(last_func);
- JUMP_TAG(TAG_FAIL);
+ PUSH_FRAME(); /* fake frame */
+ *the_frame = *_frame.prev->prev;
+ rb_raise(mesg);
+ POP_FRAME();
}
-VALUE
+int
iterator_p()
{
- if (iter->iter) return TRUE;
+ if (the_frame->iter) return TRUE;
return FALSE;
}
static VALUE
f_iterator_p()
{
- if (iter->prev && iter->prev->iter) return TRUE;
+ if (the_frame->prev && the_frame->prev->iter) return TRUE;
return FALSE;
}
@@ -1743,18 +2038,19 @@ VALUE
rb_yield_0(val, self)
VALUE val, self;
{
- struct BLOCK *block;
NODE *node;
- int state;
+ NODE *state;
VALUE result = Qnil;
+ struct BLOCK *block;
struct SCOPE *old_scope;
struct FRAME frame;
if (!iterator_p()) {
- Fail("yield called out of iterator");
+ Raise(eLocalJumpError, "yield called out of iterator");
}
PUSH_VARS();
+ PUSH_CLASS();
block = the_block;
frame = block->frame;
frame.prev = the_frame;
@@ -1763,52 +2059,53 @@ rb_yield_0(val, self)
the_scope = block->scope;
the_block = block->prev;
the_dyna_vars = block->d_vars;
+ the_class = block->class;
+ if (!self) self = block->self;
+ node = block->body;
if (block->var) {
if (nd_type(block->var) == NODE_MASGN)
- masign(block->var, val);
+ masign(self, block->var, val);
else
- asign(block->var, val);
+ asign(self, block->var, val);
}
- node = block->body;
-
PUSH_ITER(block->iter);
- PUSH_SELF(self?self:block->self);
PUSH_TAG();
- switch (state = EXEC_TAG()) {
+ if ((state = EXEC_TAG()) == 0) {
redo:
- case 0:
if (!node) {
result = Qnil;
}
else if (nd_type(node) == NODE_CFUNC) {
- result = (*node->nd_cfnc)(val,node->nd_argc);
+ result = (*node->nd_cfnc)(val,node->nd_argc,self);
}
else {
- result = rb_eval(node);
+ result = rb_eval(self, node);
+ }
+ }
+ else {
+ switch (state->nd_tag) {
+ case TAG_REDO:
+ goto redo;
+ case TAG_NEXT:
+ state = 0;
+ break;
+ case TAG_BREAK:
+ case TAG_RETURN:
+ state->nd_tlev = block->level;
+ state->nd_tag = IN_BLOCK|state->nd_tag;
+ break;
+ default:
+ break;
}
- break;
- case TAG_REDO:
- goto redo;
- case TAG_CONTINUE:
- state = 0;
- break;
- case TAG_BREAK:
- case TAG_RETURN:
- target_level = block->level;
- state = IN_BLOCK|state;
- break;
- default:
- break;
}
POP_TAG();
- POP_SELF();
POP_ITER();
+ POP_CLASS();
POP_VARS();
the_block = block;
the_frame = the_frame->prev;
the_scope = old_scope;
if (state) JUMP_TAG(state);
-
return result;
}
@@ -1823,11 +2120,10 @@ static VALUE
f_loop()
{
for (;;) { rb_yield(Qnil); }
- return Qnil;
}
static VALUE
-masign(node, val)
+masign(self, node, val)
NODE *node;
VALUE val;
{
@@ -1842,30 +2138,31 @@ masign(node, val)
}
len = RARRAY(val)->len;
for (i=0; list && i<len; i++) {
- asign(list->nd_head, RARRAY(val)->ptr[i]);
+ asign(self, list->nd_head, RARRAY(val)->ptr[i]);
list = list->nd_next;
}
if (node->nd_args) {
if (!list && i<len) {
- asign(node->nd_args, ary_new4(len-i, RARRAY(val)->ptr+i));
+ asign(self, node->nd_args, ary_new4(len-i, RARRAY(val)->ptr+i));
}
else {
- asign(node->nd_args, Qnil);
+ asign(self, node->nd_args, ary_new2(0));
}
}
}
else if (node->nd_args) {
- asign(node->nd_args, Qnil);
+ asign(self, node->nd_args, Qnil);
}
while (list) {
- asign(list->nd_head, Qnil);
+ asign(self, list->nd_head, Qnil);
list = list->nd_next;
}
return val;
}
static void
-asign(lhs, val)
+asign(self, lhs, val)
+ VALUE self;
NODE *lhs;
VALUE val;
{
@@ -1875,7 +2172,7 @@ asign(lhs, val)
break;
case NODE_IASGN:
- rb_ivar_set(Qself, lhs->nd_vid, val);
+ rb_ivar_set(self, lhs->nd_vid, val);
break;
case NODE_LASGN:
@@ -1895,16 +2192,16 @@ asign(lhs, val)
case NODE_CALL:
{
VALUE recv;
- recv = rb_eval(lhs->nd_recv);
- if (lhs->nd_args->nd_head == Qnil) {
+ recv = rb_eval(self, lhs->nd_recv);
+ if (!lhs->nd_args->nd_head) {
/* attr set */
- rb_funcall(recv, lhs->nd_mid, 1, val);
+ rb_funcall2(recv, lhs->nd_mid, 1, &val);
}
else {
/* array set */
VALUE args;
- args = rb_eval(lhs->nd_args);
+ args = rb_eval(self, lhs->nd_args);
RARRAY(args)->ptr[RARRAY(args)->len-1] = val;
rb_apply(recv, lhs->nd_mid, args);
}
@@ -1922,13 +2219,15 @@ rb_iterate(it_proc, data1, bl_proc, data2)
VALUE (*it_proc)(), (*bl_proc)();
void *data1, *data2;
{
- int state;
+ NODE *state;
VALUE retval = Qnil;
NODE *node = NEW_CFUNC(bl_proc, data2);
+ VALUE self = TopSelf;
+ int tag_level;
iter_retry:
PUSH_ITER(ITER_PRE);
- PUSH_BLOCK(Qnil, node);
+ PUSH_BLOCK(0, node);
PUSH_TAG();
state = EXEC_TAG();
@@ -1937,33 +2236,53 @@ rb_iterate(it_proc, data1, bl_proc, data2)
}
POP_TAG();
+ tag_level = the_block->level;
POP_BLOCK();
POP_ITER();
- switch (state) {
- case 0:
- break;
+ if (state) {
+ switch (state->nd_tag) {
+ case TAG_RETRY:
+ goto iter_retry;
- case TAG_RETRY:
- goto iter_retry;
+ case IN_BLOCK|TAG_BREAK:
+ if (state->nd_tlev != tag_level) {
+ JUMP_TAG(state);
+ }
+ retval = Qnil;
+ break;
- case IN_BLOCK|TAG_BREAK:
- if (target_level != tag_level) {
+ case IN_BLOCK|TAG_RETURN:
+ if (state->nd_tlev == tag_level) {
+ state->nd_tag &= ~IN_BLOCK;
+ }
+ /* fall through */
+ default:
JUMP_TAG(state);
}
- retval = Qnil;
- break;
+ }
+ return retval;
+}
- case IN_BLOCK|TAG_RETURN:
- if (target_level == tag_level) {
- state &= ~IN_BLOCK;
- }
- /* fall through */
- default:
- JUMP_TAG(state);
+static int
+handle_rescue(self, node)
+ VALUE self;
+ NODE *node;
+{
+ int argc; VALUE *argv; /* used in SETUP_ARGS */
+
+ if (!node->nd_args) {
+ return obj_is_kind_of(errinfo, eException);
}
- return retval;
+ PUSH_ITER(ITER_NOT);
+ SETUP_ARGS;
+ POP_ITER();
+ while (argc--) {
+ if (obj_is_kind_of(errinfo, argv[0])) return 1;
+ argv++;
+ }
+ return 0;
}
VALUE
@@ -1971,43 +2290,36 @@ rb_rescue(b_proc, data1, r_proc, data2)
VALUE (*b_proc)(), (*r_proc)();
void *data1, *data2;
{
- int state;
- VALUE result = Qnil;
- volatile SIGHANDLE handle;
+ NODE *state;
+ VALUE result;
PUSH_TAG();
- switch (state = EXEC_TAG()) {
- case 0:
- handle = sig_beg();
+ if ((state = EXEC_TAG()) == 0) {
retry_entry:
result = (*b_proc)(data1);
- break;
-
- case TAG_FAIL:
- sig_end(handle);
- if (r_proc) {
- PUSH_TAG();
- state = EXEC_TAG();
- if (state == 0) {
- result = (*r_proc)(data2);
+ }
+ else {
+ if (state->nd_tag == TAG_RAISE) {
+ if (r_proc) {
+ PUSH_TAG();
+ state = EXEC_TAG();
+ if (state == 0) {
+ result = (*r_proc)(data2, errinfo);
+ }
+ POP_TAG();
+ if (state && state->nd_tag == TAG_RETRY) {
+ state = 0;
+ goto retry_entry;
+ }
}
- POP_TAG();
- if (state == TAG_RETRY) {
- goto retry_entry;
+ else {
+ result = Qnil;
+ state = 0;
+ }
+ if (state == 0) {
+ errat = Qnil;
}
}
- else {
- state = 0;
- }
- if (state == 0) {
- errat = Qnil;
- last_func = 0;
- }
- break;
-
- default:
- sig_end(handle);
- break;
}
POP_TAG();
if (state) JUMP_TAG(state);
@@ -2020,7 +2332,7 @@ rb_ensure(b_proc, data1, e_proc, data2)
VALUE (*b_proc)(), (*e_proc)();
void *data1, *data2;
{
- int state;
+ NODE *state;
VALUE result = Qnil;
PUSH_TAG();
@@ -2030,7 +2342,7 @@ rb_ensure(b_proc, data1, e_proc, data2)
POP_TAG();
(*e_proc)(data2);
- if (state != 0) {
+ if (state) {
JUMP_TAG(state);
}
return result;
@@ -2044,7 +2356,7 @@ f_missing(argc, argv, obj)
VALUE *argv;
VALUE obj;
{
- VALUE desc;
+ VALUE desc = 0;
ID id;
char *format;
struct FRAME *frame;
@@ -2052,27 +2364,44 @@ f_missing(argc, argv, obj)
id = FIX2INT(argv[0]);
argc--; argv++;
- if (TYPE(obj) == T_STRING) {
- desc = krn_inspect(obj);
- }
- else {
+ switch (TYPE(obj)) {
+ case T_NIL:
+ format = "undefined method `%s' for nil";
+ break;
+ case T_TRUE:
+ format = "undefined method `%s' for TRUE";
+ break;
+ case T_FALSE:
+ format = "undefined method `%s' for FALSE";
+ break;
+ case T_OBJECT:
desc = obj_as_string(obj);
+ break;
+ default:
+ desc = rb_inspect(obj);
+ break;
+ }
+ if (desc) {
+ if (last_noex)
+ format = "private method `%s' called for %s(%s)";
+ else if (argc == 0) {
+ format = "undefined local variable or method `%s' for %s(%s)";
+ }
+ else {
+ format = "undefined method `%s' for %s(%s)";
+ }
+ if (RSTRING(desc)->len > 65) {
+ desc = krn_to_s(obj);
+ }
}
- if (last_noex)
- format = "method `%s' not available for %s(%s)";
- else
- format = "undefined method `%s' for %s(%s)";
- /* fake frame */
- PUSH_FRAME();
- frame = the_frame->prev;
- *the_frame = *frame->prev;
- the_frame->prev = frame;
-
- Fail(format,
- rb_id2name(id),
- RSTRING(desc)->ptr,
- rb_class2name(CLASS_OF(obj)));
+ PUSH_FRAME(); /* fake frame */
+ *the_frame = *_frame.prev->prev;
+
+ NameError(format,
+ rb_id2name(id),
+ desc?RSTRING(desc)->ptr:"",
+ desc?rb_class2name(CLASS_OF(obj)):"");
POP_FRAME();
}
@@ -2095,8 +2424,20 @@ rb_undefined(obj, id, argc, argv, noex)
return rb_funcall2(obj, rb_intern("method_missing"), argc+1, nargv);
}
-#define STACK_LEVEL_MAX 10000
-static int stack_level;
+#define STACK_LEVEL_MAX 655350
+extern VALUE *gc_stack_start;
+static int
+stack_length()
+{
+ VALUE pos;
+
+#ifdef sparc
+ return gc_stack_start - &pos + 0x80;
+#else
+ return (&pos < gc_stack_start) ? gc_stack_start - &pos
+ : &pos - gc_stack_start;
+#endif
+}
static VALUE
rb_call(class, recv, mid, argc, argv, scope)
@@ -2109,38 +2450,30 @@ rb_call(class, recv, mid, argc, argv, scope)
{
NODE *body;
int noex;
- VALUE result = Qnil;
+ ID id = mid;
struct cache_entry *ent;
+ VALUE result = Qnil;
int itr;
enum node_type type;
+ static int tick;
/* is it in the method cache? */
ent = cache + EXPR1(class, mid);
if (ent->mid == mid && ent->class == class) {
class = ent->origin;
- mid = ent->mid;
- body = ent->method;
+ id = ent->mid0;
noex = ent->noex;
+ body = ent->method;
}
- else {
- ID id = mid;
-
- if ((body = rb_get_method_body(&class, &id, &noex)) == FALSE) {
- return rb_undefined(recv, mid, argc, argv, 0);
- }
- mid = id;
+ else if ((body = rb_get_method_body(&class, &id, &noex)) == 0) {
+ return rb_undefined(recv, mid, argc, argv, 0);
}
- switch (noex) {
- case NOEX_PUBLIC:
- break;
- case NOEX_PRIVATE:
- if (scope == 0) /* receiver specified */
- return rb_undefined(recv, mid, argc, argv, 1);
- break;
- }
+ /* receiver specified form for private method */
+ if (noex == NOEX_PRIVATE && scope == 0)
+ return rb_undefined(recv, mid, argc, argv, 1);
- switch (iter->iter) {
+ switch (the_iter->iter) {
case ITER_PRE:
itr = ITER_CUR;
break;
@@ -2153,16 +2486,15 @@ rb_call(class, recv, mid, argc, argv, scope)
type = nd_type(body);
if (type == NODE_ZSUPER) {
/* for re-scoped method */
- return rb_call(class->super, recv, mid, argc, argv, scope?scope:1);
+ return rb_call(class->super, recv, id, argc, argv, scope?scope:1);
}
- if (stack_level++ > STACK_LEVEL_MAX)
- Fail("stack level too deep");
+ if (++tick % 1000 == 0 && stack_length() > STACK_LEVEL_MAX)
+ Fatal("stack level too deep");
PUSH_ITER(itr);
- PUSH_SELF(recv);
PUSH_FRAME();
- the_frame->last_func = mid;
+ the_frame->last_func = id;
the_frame->last_class = class;
the_frame->argc = argc;
the_frame->argv = argv;
@@ -2173,7 +2505,7 @@ rb_call(class, recv, mid, argc, argv, scope)
int len = body->nd_argc;
if (len >= 0 && argc != len) {
- Fail("Wrong # of arguments(%d for %d)", argc, len);
+ ArgError("Wrong # of arguments(%d for %d)", argc, len);
}
switch (len) {
@@ -2273,7 +2605,7 @@ rb_call(class, recv, mid, argc, argv, scope)
len, rb_class2name(class), rb_id2name(mid));
}
else {
- Fail("too many arguments(%d)", len);
+ ArgError("too many arguments(%d)", len);
}
break;
}
@@ -2283,19 +2615,20 @@ rb_call(class, recv, mid, argc, argv, scope)
/* for attr get/set */
case NODE_ATTRSET:
case NODE_IVAR:
- result = rb_eval(body);
+ result = rb_eval(recv, body);
break;
default:
{
- int state;
+ NODE *state;
VALUE *local_vars;
PUSH_SCOPE();
- if (body->nd_cnt > 0) {
- local_vars = ALLOCA_N(VALUE, body->nd_cnt);
- MEMZERO(local_vars, VALUE, body->nd_cnt);
+ if (body->nd_rval) the_frame->cbase = body->nd_rval;
+ if (body->nd_tbl) {
+ local_vars = ALLOCA_N(VALUE, body->nd_tbl[0]);
+ memclear(local_vars, body->nd_tbl[0]);
the_scope->local_tbl = body->nd_tbl;
the_scope->local_vars = local_vars;
}
@@ -2306,6 +2639,8 @@ rb_call(class, recv, mid, argc, argv, scope)
body = body->nd_body;
PUSH_TAG();
+ PUSH_VARS();
+ dyna_var_mark();
state = EXEC_TAG();
if (state == 0) {
if (nd_type(body) == NODE_BLOCK) {
@@ -2321,7 +2656,7 @@ rb_call(class, recv, mid, argc, argv, scope)
if (i > argc
|| (node->nd_rest == -1
&& i+(node->nd_opt?node->nd_opt->nd_alen:0)<argc)){
- Fail("Wrong # of arguments(%d for %d)", argc, i);
+ ArgError("Wrong # of arguments(%d for %d)", argc, i);
}
if (local_vars) {
@@ -2333,56 +2668,54 @@ rb_call(class, recv, mid, argc, argv, scope)
NODE *opt = node->nd_opt;
while (opt && argc) {
- asign(opt->nd_head, *argv);
+ asign(recv, opt->nd_head, *argv);
argv++; argc--;
opt = opt->nd_next;
}
- rb_eval(opt);
+ rb_eval(recv, opt);
}
if (node->nd_rest >= 0) {
if (argc > 0)
local_vars[node->nd_rest]=ary_new4(argc,argv);
else
- local_vars[node->nd_rest] = ary_new2(0);
+ local_vars[node->nd_rest]=ary_new2(0);
}
}
}
else if (nd_type(body) == NODE_ARGS) {
body = 0;
}
- result = rb_eval(body);
+ result = rb_eval(recv, body);
}
+ POP_VARS();
POP_TAG();
POP_SCOPE();
- switch (state) {
- case 0:
- break;
- case TAG_CONTINUE:
- Fatal("unexpected continue");
- break;
- case TAG_BREAK:
- Fatal("unexpected break");
- break;
- case TAG_REDO:
- Fatal("unexpected redo");
- break;
- case TAG_RETURN:
- result = last_val;
- break;
- case TAG_RETRY:
- if (!iterator_p()) {
- Fatal("retry outside of rescue clause");
+ if (state) {
+ switch (state->nd_tag) {
+ case TAG_NEXT:
+ Raise(eLocalJumpError, "unexpected next");
+ break;
+ case TAG_BREAK:
+ Raise(eLocalJumpError, "unexpected break");
+ break;
+ case TAG_REDO:
+ Raise(eLocalJumpError, "unexpected redo");
+ break;
+ case TAG_RETURN:
+ result = state->nd_tval;
+ break;
+ case TAG_RETRY:
+ if (!iterator_p()) {
+ Raise(eLocalJumpError, "retry outside of rescue clause");
+ }
+ default:
+ JUMP_TAG(state);
}
- default:
- stack_level--;
- JUMP_TAG(state);
}
}
}
POP_FRAME();
- POP_SELF();
POP_ITER();
- stack_level--;
return result;
}
@@ -2410,7 +2743,7 @@ f_send(argc, argv, recv)
VALUE vid;
ID mid;
- if (argc == 0) Fail("no method name given");
+ if (argc == 0) ArgError("no method name given");
vid = argv[0]; argc--; argv++;
if (TYPE(vid) == T_STRING) {
@@ -2463,26 +2796,31 @@ rb_funcall2(recv, mid, argc, argv)
}
static VALUE
-f_caller(argc, argv)
- int argc;
- VALUE *argv;
+backtrace(lev)
+ int lev;
{
- VALUE level;
struct FRAME *frame = the_frame;
- int lev, n;
char buf[BUFSIZ];
+ VALUE ary;
- rb_scan_args(argc, argv, "01", &level);
- if (level == Qnil) lev = 1;
- else lev = NUM2INT(level);
- n = lev;
- if (n < 0) Fail("negative level(%d)", n);
+ ary = ary_new();
+ if (lev < 0) {
+ if (frame->last_func) {
+ sprintf(buf, "%s:%d:in `%s'", sourcefile, sourceline,
+ rb_id2name(frame->last_func));
+ }
+ else {
+ sprintf(buf, "%s:%d", sourcefile, sourceline);
+ }
+ ary_push(ary, str_new2(buf));
+ }
else {
- while (n-- > 0) {
+ while (lev-- > 0) {
frame = frame->prev;
if (!frame) return Qnil;
}
- if (!frame->file) return Qnil;
+ }
+ while (frame && frame->file) {
if (frame->prev && frame->prev->last_func) {
sprintf(buf, "%s:%d:in `%s'",
frame->file, frame->line,
@@ -2491,73 +2829,169 @@ f_caller(argc, argv)
else {
sprintf(buf, "%s:%d", frame->file, frame->line);
}
+ ary_push(ary, str_new2(buf));
+ frame = frame->prev;
}
- return str_new2(buf);
+ return ary;
+}
+
+static VALUE
+f_caller(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE level;
+ struct FRAME *frame = the_frame;
+ int lev;
+
+ rb_scan_args(argc, argv, "01", &level);
+
+ if (NIL_P(level)) lev = 1;
+ else lev = NUM2INT(level);
+ if (lev < 0) ArgError("negative level(%d)", lev);
+
+ return backtrace(lev);
}
void
rb_backtrace()
{
- VALUE c, lev;
- int n = 0;
+ int i, lev;
+ VALUE ary, c;
- lev = INT2FIX(n);
- while (c = f_caller(1, &lev)) {
- printf("%s\n", RSTRING(c)->ptr);
- n++;
- lev = INT2FIX(n);
+ lev = INT2FIX(0);
+ ary = backtrace(-1);
+ for (i=0; i<RARRAY(ary)->len; i++) {
+ printf("\tfrom %s\n", RSTRING(RARRAY(ary)->ptr)->ptr);
}
}
+static VALUE
+make_backtrace()
+{
+ VALUE lev;
+
+ lev = INT2FIX(0);
+ return backtrace(-1);
+}
+
ID
rb_frame_last_func()
{
return the_frame->last_func;
}
-int rb_in_eval = 0;
+static NODE*
+compile(src)
+ struct RString *src;
+{
+ NODE *node;
+
+ Check_Type(src, T_STRING);
+
+ errinfo = Qnil;
+ node = compile_string(sourcefile, src->ptr, src->len);
+
+ if (nerrs == 0) return node;
+ return 0;
+}
+
+static void blk_free();
static VALUE
-f_eval(obj, src)
- VALUE obj;
+eval(self, src, scope)
+ VALUE self;
struct RString *src;
+ struct RData *scope;
{
+ struct BLOCK *data;
VALUE result = Qnil;
- int state;
NODE *node;
+ NODE *state;
+ struct BLOCK *old_block;
+ struct SCOPE *old_scope;
+ struct FRAME frame;
+ char *file = sourcefile;
+ int line = sourceline;
- Check_Type(src, T_STRING);
PUSH_TAG();
- rb_in_eval = 1;
- node = eval_tree;
-
PUSH_CLASS();
+ if (!NIL_P(scope)) {
+ if (TYPE(scope) != T_DATA || scope->dfree != blk_free) {
+ TypeError("wrong argument type %s (expected Proc/Binding)",
+ rb_class2name(CLASS_OF(scope)));
+ }
+
+ Get_Data_Struct(scope, struct BLOCK, data);
+
+ /* PUSH BLOCK from data */
+ frame = data->frame;
+ frame.prev = the_frame;
+ the_frame = &(frame);
+ old_scope = the_scope;
+ the_scope = data->scope;
+ old_block = the_block;
+ the_block = data->prev;
+ the_dyna_vars = data->d_vars;
+ the_class = data->class;
+ self = data->self;
+ }
+
+ rb_in_eval++;
if (TYPE(the_class) == T_ICLASS) {
the_class = (struct RClass*)RBASIC(the_class)->class;
}
-
if ((state = EXEC_TAG()) == 0) {
- lex_setsrc("(eval)", src->ptr, src->len);
- eval_tree = 0;
- PUSH_VARS();
- yyparse();
- POP_VARS();
- if (nerrs == 0) {
- result = Eval();
+ if (!compile(src)) {
+ rb_in_eval--;
+ compile_error("eval()");
}
+ result = eval_node(self);
+ }
+ if (!NIL_P(scope)) {
+ the_frame = the_frame->prev;
+ the_scope = old_scope;
+ the_block = old_block;
}
- eval_tree = node;
POP_CLASS();
POP_TAG();
- if (state) JUMP_TAG(state);
-
- if (nerrs > 0) {
- syntax_error();
+ rb_in_eval--;
+ if (state) {
+ VALUE err ;
+
+ switch (state->nd_tag) {
+ case TAG_RAISE:
+ sourcefile = file;
+ sourceline = line;
+ if (strcmp(sourcefile, "(eval)") == 0) {
+ err = errat;
+ if (sourceline != 1) {
+ str_cat(err, ": ", 2);
+ str_cat(err, RSTRING(errinfo)->ptr, RSTRING(errinfo)->len);
+ }
+ errat = Qnil;
+ rb_raise(exc_new2(CLASS_OF(errinfo), err));
+ }
+ rb_raise(Qnil);
+ }
+ JUMP_TAG(state);
}
return result;
}
+static VALUE
+f_eval(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
+{
+ VALUE src, scope;
+
+ rb_scan_args(argc, argv, "11", &src, &scope);
+ return eval(self, src, scope);
+}
+
VALUE rb_load_path;
char *dln_find_file();
@@ -2567,20 +3001,18 @@ find_file(file)
char *file;
{
extern VALUE rb_load_path;
- VALUE sep, vpath;
+ VALUE vpath;
char *path;
if (file[0] == '/') return file;
if (rb_load_path) {
Check_Type(rb_load_path, T_ARRAY);
- sep = str_new2(":");
- vpath = ary_join(rb_load_path, sep);
+ vpath = ary_join(rb_load_path, str_new2(":"));
path = RSTRING(vpath)->ptr;
- sep = Qnil;
}
else {
- path = Qnil;
+ path = 0;
}
return dln_find_file(file, path);
@@ -2591,36 +3023,39 @@ f_load(obj, fname)
VALUE obj;
struct RString *fname;
{
- int state, in_eval = rb_in_eval;
+ NODE *state;
char *file, *src;
+ volatile ID last_func;
Check_Type(fname, T_STRING);
file = find_file(fname->ptr);
- if (!file) Fail("No such file to load -- %s", fname->ptr);
+ if (!file) LoadError("No such file to load -- %s", fname->ptr);
- PUSH_SELF(TopSelf);
PUSH_TAG();
PUSH_CLASS();
the_class = (struct RClass*)cObject;
PUSH_SCOPE();
the_scope->local_vars = top_scope->local_vars;
the_scope->local_tbl = top_scope->local_tbl;
- rb_in_eval = 1;
+
state = EXEC_TAG();
+ last_func = the_frame->last_func;
+ the_frame->last_func = 0;
if (state == 0) {
+ rb_in_eval++;
rb_load_file(file);
+ rb_in_eval--;
if (nerrs == 0) {
- Eval();
+ eval_node(TopSelf);
}
}
+ the_frame->last_func = last_func;
top_scope->flag = the_scope->flag;
POP_SCOPE();
POP_CLASS();
POP_TAG();
- POP_SELF();
- rb_in_eval = in_eval;
if (nerrs > 0) {
- rb_fail(errstr);
+ rb_raise(errinfo);
}
if (state) JUMP_TAG(state);
@@ -2629,16 +3064,17 @@ f_load(obj, fname)
static VALUE rb_features;
-static VALUE
+static int
rb_provided(feature)
char *feature;
{
+ struct RArray *features = RARRAY(rb_features);
VALUE *p, *pend;
char *f;
int len;
- p = RARRAY(rb_features)->ptr;
- pend = p + RARRAY(rb_features)->len;
+ p = features->ptr;
+ pend = p + features->len;
while (p < pend) {
Check_Type(*p, T_STRING);
f = RSTRING(*p)->ptr;
@@ -2653,6 +3089,11 @@ rb_provided(feature)
return FALSE;
}
+#ifdef THREAD
+static int thread_loading();
+static void thread_loading_done();
+#endif
+
void
rb_provide(feature)
char *feature;
@@ -2670,7 +3111,8 @@ f_require(obj, fname)
VALUE load;
Check_Type(fname, T_STRING);
- if (rb_provided(fname->ptr)) return FALSE;
+ if (rb_provided(fname->ptr))
+ return FALSE;
ext = strrchr(fname->ptr, '.');
if (ext) {
@@ -2680,9 +3122,9 @@ f_require(obj, fname)
if (file) goto rb_load;
}
else if (strcmp(".o", ext) == 0) {
- feature = fname->ptr;
+ file = feature = fname->ptr;
if (strcmp(".o", DLEXT) != 0) {
- buf = ALLOCA_N(char, strlen(fname->ptr) + 3);
+ buf = ALLOCA_N(char, strlen(fname->ptr)+sizeof(DLEXT)+1);
strcpy(buf, feature);
ext = strrchr(buf, '.');
strcpy(ext, DLEXT);
@@ -2696,7 +3138,7 @@ f_require(obj, fname)
if (file) goto dyna_load;
}
}
- buf = ALLOCA_N(char, strlen(fname->ptr) + 4);
+ buf = ALLOCA_N(char, strlen(fname->ptr) + 5);
sprintf(buf, "%s.rb", fname->ptr);
file = find_file(buf);
if (file) {
@@ -2710,58 +3152,80 @@ f_require(obj, fname)
feature = buf;
goto dyna_load;
}
- Fail("No such file to load -- %s", fname->ptr);
+ LoadError("No such file to load -- %s", fname->ptr);
dyna_load:
- load = str_new2(file);
- file = RSTRING(load)->ptr;
- dln_load(file);
- rb_provide(feature);
+#ifdef THREAD
+ if (thread_loading(feature)) return FALSE;
+ else {
+ NODE *state;
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+#endif
+ load = str_new2(file);
+ file = RSTRING(load)->ptr;
+ dln_load(file);
+ rb_provide(feature);
+#ifdef THREAD
+ }
+ POP_TAG();
+ thread_loading_done();
+ if (state) JUMP_TAG(state);
+ }
+#endif
return TRUE;
rb_load:
- f_load(obj, fname);
- rb_provide(feature);
+#ifdef THREAD
+ if (thread_loading(feature)) return FALSE;
+ else {
+ NODE *state;
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+#endif
+ f_load(obj, fname);
+ rb_provide(feature);
+#ifdef THREAD
+ }
+ POP_TAG();
+ thread_loading_done();
+ if (state) JUMP_TAG(state);
+ }
+#endif
return TRUE;
}
static void
-set_method_visibility(argc, argv, ex)
+set_method_visibility(self, argc, argv, ex)
+ VALUE self;
int argc;
VALUE *argv;
int ex;
{
- VALUE self = Qself;
int i;
- ID id;
for (i=0; i<argc; i++) {
- if (FIXNUM_P(argv[i])) {
- id = FIX2INT(argv[i]);
- }
- else {
- Check_Type(argv[i], T_STRING);
- id = rb_intern(RSTRING(argv[i])->ptr);
- }
- rb_export_method(self, id, ex);
+ rb_export_method(self, rb_to_id(argv[i]), ex);
}
}
static VALUE
-mod_public(argc, argv)
+mod_public(argc, argv, module)
int argc;
VALUE *argv;
+ VALUE module;
{
- set_method_visibility(argc, argv, NOEX_PUBLIC);
+ set_method_visibility(module, argc, argv, NOEX_PUBLIC);
return Qnil;
}
static VALUE
-mod_private(argc, argv)
+mod_private(argc, argv, module)
int argc;
VALUE *argv;
+ VALUE module;
{
- set_method_visibility(argc, argv, NOEX_PRIVATE);
+ set_method_visibility(module, argc, argv, NOEX_PRIVATE);
return Qnil;
}
@@ -2775,19 +3239,13 @@ mod_modfunc(argc, argv, module)
ID id;
NODE *body, *old;
- set_method_visibility(argc, argv, NOEX_PRIVATE);
+ set_method_visibility(module, argc, argv, NOEX_PRIVATE);
for (i=0; i<argc; i++) {
- if (FIXNUM_P(argv[i])) {
- id = FIX2INT(argv[i]);
- }
- else {
- Check_Type(argv[i], T_STRING);
- id = rb_intern(RSTRING(argv[i])->ptr);
- }
+ id = rb_to_id(argv[i]);
body = search_method(module, id, 0);
if (body == 0 || body->nd_body == 0) {
- Fail("undefined method `%s' for module `%s'",
- rb_id2name(id), rb_class2name(module));
+ NameError("undefined method `%s' for module `%s'",
+ rb_id2name(id), rb_class2name(module));
}
rb_add_method(rb_singleton_class(module), id, body->nd_body, NOEX_PUBLIC);
}
@@ -2806,7 +3264,21 @@ mod_include(argc, argv, module)
Check_Type(argv[i], T_MODULE);
rb_include_module(module, argv[i]);
}
- return (VALUE)module;
+ return Qnil;
+}
+
+VALUE /* moved from object.c for push_iter */
+class_s_new(argc, argv, class)
+ int argc;
+ VALUE *argv;
+ VALUE class;
+{
+ VALUE obj = obj_alloc(class);
+
+ PUSH_ITER(iterator_p()?ITER_PRE:ITER_NOT);
+ rb_funcall2(obj, init, argc, argv);
+ POP_ITER();
+ return obj;
}
static VALUE
@@ -2823,7 +3295,13 @@ obj_extend(argc, argv, obj)
VALUE *argv;
VALUE obj;
{
- return mod_include(argc, argv, rb_singleton_class(obj));
+ int i;
+
+ mod_include(argc, argv, rb_singleton_class(obj));
+ for (i=0; i<argc; i++) {
+ rb_funcall(argv[i], rb_intern("object_extended"), 1, obj);
+ }
+ return Qnil;
}
void
@@ -2833,16 +3311,66 @@ rb_extend_object(obj, module)
rb_include_module(rb_singleton_class(obj), module);
}
-extern VALUE cKernel;
extern VALUE cModule;
VALUE f_trace_var();
VALUE f_untrace_var();
+extern VALUE rb_str_setter();
+
+static VALUE
+errat_setter(val, id, var)
+ VALUE val;
+ ID id;
+ VALUE *var;
+{
+ if (!NIL_P(val) && TYPE(val) != T_ARRAY) {
+ TypeError("value of $@ must be Array of String");
+ }
+ return *var = val;
+}
+
+static VALUE
+f_catch(dmy, tag)
+{
+ NODE *state;
+ ID t;
+ VALUE val;
+
+ t = rb_to_id(tag);
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ val = rb_yield(tag);
+ }
+ POP_TAG();
+ if (state) {
+ if (state->nd_tag == TAG_THROW && state->nd_tlev == t) {
+ return state->nd_tval;
+ }
+ JUMP_TAG(state);
+ }
+ return val;
+}
+
+static VALUE
+f_throw(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE tag, value;
+ ID t;
+
+ rb_scan_args(argc, argv, "11", &tag, &value);
+ t = rb_to_id(tag);
+ JUMP_TAG3(TAG_THROW, value, t);
+ /* not reached */
+}
+
void
Init_eval()
{
- match = rb_intern("=~");
+ init = rb_intern("initialize");
+ eqq = rb_intern("===");
each = rb_intern("each");
aref = rb_intern("[]");
@@ -2851,25 +3379,49 @@ Init_eval()
rb_global_variable(&top_scope);
rb_global_variable(&eval_tree);
rb_global_variable(&the_dyna_vars);
- rb_define_private_method(cKernel, "exit", f_exit, -1);
- rb_define_private_method(cKernel, "eval", f_eval, 1);
+
+ rb_define_hooked_variable("$@", &errat, 0, errat_setter);
+ rb_define_hooked_variable("$!", &errinfo, 0, rb_str_setter);
+
+ rb_define_private_method(cKernel, "eval", f_eval, -1);
rb_define_private_method(cKernel, "iterator?", f_iterator_p, 0);
rb_define_private_method(cKernel, "method_missing", f_missing, -1);
rb_define_private_method(cKernel, "loop", f_loop, 0);
+
+ rb_define_method(cKernel, "respond_to?", krn_respond_to, -1);
+
+ rb_define_private_method(cKernel, "break", f_break, 0);
+ rb_define_alias(cKernel, "break!", "break");
+ rb_define_private_method(cKernel, "next", f_next, 0);
+ rb_define_alias(cKernel, "next!", "next");
+ rb_define_alias(cKernel, "continue", "next");
+ rb_define_private_method(cKernel, "redo", f_redo, 0);
+ rb_define_alias(cKernel, "redo!", "redo");
+ rb_define_private_method(cKernel, "retry", f_retry, 0);
+ rb_define_alias(cKernel, "retry!", "retry");
+ rb_define_private_method(cKernel, "raise", f_raise, -1);
+ rb_define_alias(cKernel, "fail", "raise");
+
rb_define_private_method(cKernel, "caller", f_caller, -1);
+ rb_define_private_method(cKernel, "exit", f_exit, -1);
+
+ rb_define_private_method(cKernel, "catch", f_catch, 1);
+ rb_define_private_method(cKernel, "throw", f_throw, -1);
+
rb_define_method(cKernel, "send", f_send, -1);
rb_define_method(cModule, "include", mod_include, -1);
rb_define_method(cModule, "public", mod_public, -1);
rb_define_method(cModule, "private", mod_private, -1);
rb_define_method(cModule, "module_function", mod_modfunc, -1);
+ rb_define_method(cModule, "method_defined?", mod_method_defined, 1);
rb_define_method(CLASS_OF(TopSelf), "include", top_include, -1);
rb_define_method(cObject, "extend", obj_extend, -1);
rb_define_private_method(cKernel, "trace_var", f_trace_var, -1);
- rb_define_private_method(cKernel, "untrace_var", f_untrace_var, 1);
+ rb_define_private_method(cKernel, "untrace_var", f_untrace_var, -1);
}
VALUE f_autoload();
@@ -2909,8 +3461,6 @@ scope_dup(scope)
}
}
-static ID blkdata;
-
static void
blk_mark(data)
struct BLOCK *data;
@@ -2931,6 +3481,29 @@ blk_free(data)
}
static VALUE
+f_binding(self)
+ VALUE self;
+{
+ extern VALUE cData;
+ struct BLOCK *data;
+ VALUE bind;
+
+ PUSH_BLOCK(0,0);
+ bind = Make_Data_Struct(cData, struct BLOCK, blk_mark, blk_free, data);
+ MEMCPY(data, the_block, struct BLOCK, 1);
+
+ data->iter = ITER_NOT;
+ data->frame.last_func = 0;
+ data->frame.argv = ALLOC_N(VALUE, data->frame.argc);
+ MEMCPY(data->frame.argv, the_block->frame.argv, VALUE, data->frame.argc);
+
+ scope_dup(data->scope);
+ POP_BLOCK();
+
+ return bind;
+}
+
+static VALUE
proc_s_new(class)
VALUE class;
{
@@ -2938,15 +3511,13 @@ proc_s_new(class)
struct BLOCK *data;
if (!iterator_p() && !f_iterator_p()) {
- Fail("tryed to create Procedure-Object out of iterator");
+ ArgError("tryed to create Procedure-Object out of iterator");
}
- proc = obj_alloc(class);
-
- if (!blkdata) blkdata = rb_intern("blk");
- Make_Data_Struct(proc, blkdata, struct BLOCK, blk_mark, blk_free, data);
- MEMCPY(data, the_block, struct BLOCK, 1);
+ proc = Make_Data_Struct(class, struct BLOCK, blk_mark, blk_free, data);
+ *data = *the_block;
+ data->iter = ITER_NOT;
data->frame.argv = ALLOC_N(VALUE, data->frame.argc);
MEMCPY(data->frame.argv, the_block->frame.argv, VALUE, data->frame.argc);
@@ -2967,7 +3538,8 @@ proc_call(proc, args)
{
struct BLOCK *data;
VALUE result = Qnil;
- int state;
+ NODE *state;
+ int tag_level;
if (TYPE(args) == T_ARRAY) {
switch (RARRAY(args)->len) {
@@ -2980,11 +3552,12 @@ proc_call(proc, args)
}
}
- Get_Data_Struct(proc, blkdata, struct BLOCK, data);
+ Get_Data_Struct(proc, struct BLOCK, data);
/* PUSH BLOCK from data */
PUSH_BLOCK2(data);
PUSH_ITER(ITER_CUR);
+ the_frame->iter = ITER_CUR;
PUSH_TAG();
state = EXEC_TAG();
@@ -2994,34 +3567,1047 @@ proc_call(proc, args)
POP_TAG();
POP_ITER();
+ tag_level = the_block->level;
POP_BLOCK();
- switch (state) {
- case 0:
- break;
- case TAG_BREAK:
- case IN_BLOCK|TAG_BREAK:
- Fail("break from block-closure");
- break;
- case TAG_RETURN:
- case IN_BLOCK|TAG_RETURN:
- Fail("return from block-closure");
- break;
- default:
+ if (state) {
+ if (data->scope && (data->scope->flag & SCOPE_NOSTACK)) {
+ /* orphan procedure */
+ switch (state->nd_tag) {
+ case TAG_BREAK: /* never happen */
+ break;
+ case IN_BLOCK|TAG_BREAK:
+ if (state->nd_tlev != tag_level)
+ Raise(eLocalJumpError, "break from proc-closure");
+ break;
+ case TAG_RETRY:
+ Raise(eLocalJumpError, "retry from proc-closure");
+ break;
+ case TAG_RETURN: /* never happen */
+ case IN_BLOCK|TAG_RETURN:
+ Raise(eLocalJumpError, "return from proc-closure");
+ break;
+ }
+ }
+ else {
+ state->nd_tag &= ~IN_BLOCK;
+ }
JUMP_TAG(state);
}
-
return result;
}
void
Init_Proc()
{
- cProc = rb_define_class("Proc", cObject);
+ eLocalJumpError = rb_define_class("LocalJumpError", eException);
+ cProc = rb_define_class("Proc", cObject);
rb_define_singleton_method(cProc, "new", proc_s_new, 0);
rb_define_method(cProc, "call", proc_call, -2);
- rb_define_private_method(cKernel, "lambda", f_lambda, 0);
rb_define_private_method(cKernel, "proc", f_lambda, 0);
+ rb_define_private_method(cKernel, "lambda", f_lambda, 0);
+ rb_define_private_method(cKernel, "binding", f_binding, 0);
}
+
+#ifdef THREAD
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
+
+int thread_pending = 0;
+
+static VALUE cThread;
+
+#include <sys/types.h>
+#include <sys/time.h>
+#include <signal.h>
+#include <errno.h>
+
+extern VALUE last_status;
+
+enum thread_status {
+ THREAD_RUNNABLE,
+ THREAD_STOPPED,
+ THREAD_TO_KILL,
+ THREAD_KILLED,
+};
+
+#define WAIT_FD (1<<0)
+#define WAIT_TIME (1<<1)
+#define WAIT_JOIN (1<<2)
+
+/* +infty, for this purpose */
+#define DELAY_INFTY 1E30
+
+typedef struct thread * thread_t;
+
+struct thread {
+ struct thread *next, *prev;
+ jmp_buf context;
+ VALUE (*func)();
+ void *arg;
+
+ VALUE result;
+
+ int stk_len;
+ int stk_max;
+ VALUE*stk_ptr;
+ VALUE*stk_pos;
+
+ struct FRAME *frame;
+ struct SCOPE *scope;
+ struct RClass *class;
+ struct RVarmap *dyna_vars;
+ struct BLOCK *block;
+ struct iter *iter;
+ struct tag *tag;
+
+ char *file;
+ int line;
+
+ VALUE errat, errinfo;
+ VALUE last_status;
+ VALUE last_line;
+ VALUE last_match;
+
+ enum thread_status status;
+ int wait_for;
+ int fd;
+ double delay;
+ thread_t join;
+ VALUE thread;
+};
+
+static thread_t curr_thread;
+static int num_waiting_on_fd;
+static int num_waiting_on_timer;
+static int num_waiting_on_join;
+
+thread_curr() {return (int)curr_thread;}
+
+#define FOREACH_THREAD(x) x = curr_thread; do { x = x->next;
+#define END_FOREACH(x) } while (x != curr_thread)
+
+/* Return the current time as a floating-point number */
+static double
+timeofday()
+{
+ struct timeval tv;
+ gettimeofday(&tv, NULL);
+ return (double)tv.tv_sec + (double)tv.tv_usec * 1e-6;
+}
+
+static thread_t main_thread;
+
+#define ADJ(addr) (void*)(((VALUE*)(addr)-th->stk_pos)+th->stk_ptr)
+#define STACK(addr) (th->stk_pos<(addr) && (addr)<th->stk_pos+th->stk_len)
+
+static void
+thread_mark(th)
+ thread_t th;
+{
+ struct FRAME *frame;
+ struct BLOCK *block;
+
+ gc_mark(th->result);
+ gc_mark_locations(th->stk_ptr, th->stk_ptr+th->stk_len);
+#ifdef THINK_C
+ gc_mark_locations(th->stk_ptr+2, th->stk_ptr+th->stk_len+2);
+#endif
+ gc_mark(th->thread);
+ if (th->join) gc_mark(th->join->thread);
+
+ gc_mark(th->scope);
+ gc_mark(th->dyna_vars);
+ gc_mark(th->errat);
+ gc_mark(th->errinfo);
+ gc_mark(th->last_line);
+ gc_mark(th->last_match);
+
+ /* mark data in copied stack */
+ frame = th->frame;
+ while (frame && frame != top_frame) {
+ frame = ADJ(frame);
+ if (frame->argv && !STACK(frame->argv)) {
+ gc_mark_frame(frame);
+ }
+ frame = frame->prev;
+ }
+ block = th->block;
+ while (block) {
+ block = ADJ(block);
+ if (block->frame.argv && !STACK(block->frame.argv)) {
+ gc_mark_frame(&block->frame);
+ }
+ block = block->prev;
+ }
+}
+
+void
+gc_mark_threads()
+{
+ thread_t th;
+
+ FOREACH_THREAD(th) {
+ thread_mark(th);
+ } END_FOREACH(th);
+}
+
+static void
+thread_free(th)
+ thread_t th;
+{
+ if (th->stk_ptr) free(th->stk_ptr);
+ th->stk_ptr = 0;
+}
+
+static thread_t
+thread_check(data)
+ struct RData *data;
+{
+ if (TYPE(data) != T_DATA || data->dfree != thread_free) {
+ TypeError("wrong argument type %s (expected Thread)",
+ rb_class2name(CLASS_OF(data)));
+ }
+ return (thread_t)data->data;
+}
+
+VALUE lastline_get();
+void lastline_set();
+VALUE backref_get();
+void backref_set();
+
+static int
+thread_save_context(th)
+ thread_t th;
+{
+ VALUE v;
+
+ th->stk_len = stack_length();
+ th->stk_pos = (gc_stack_start<(VALUE*)&v)?gc_stack_start
+ :gc_stack_start - th->stk_len;
+ if (th->stk_len > th->stk_max) {
+ th->stk_max = th->stk_len;
+ REALLOC_N(th->stk_ptr, VALUE, th->stk_max);
+ }
+ FLUSH_REGISTER_WINDOWS;
+ MEMCPY(th->stk_ptr, th->stk_pos, VALUE, th->stk_len);
+
+ th->frame = the_frame;
+ th->scope = the_scope;
+ th->class = the_class;
+ th->dyna_vars = the_dyna_vars;
+ th->block = the_block;
+ th->iter = the_iter;
+ th->tag = prot_tag;
+ th->errat = errat;
+ th->errinfo = errinfo;
+ th->last_status = last_status;
+ th->last_line = lastline_get();
+ th->last_match = backref_get();
+
+ th->file = sourcefile;
+ th->line = sourceline;
+}
+
+static void thread_restore_context();
+
+static void
+stack_extend(th, exit)
+ thread_t th;
+ int exit;
+{
+ VALUE space[1024];
+
+ memset(space, 0, 1); /* prevent array from optimization */
+ thread_restore_context(th, exit);
+}
+
+static void
+thread_restore_context(th, exit)
+ thread_t th;
+ int exit;
+{
+ VALUE v;
+ static thread_t tmp;
+ static int ex;
+
+ if (!th->stk_ptr) Bug("unsaved context");
+
+ if (&v < gc_stack_start) {
+ /* Stack grows downward */
+ if (&v > th->stk_pos) stack_extend(th, exit);
+ }
+ else {
+ /* Stack grows upward */
+ if (&v < th->stk_pos + th->stk_len) stack_extend(th, exit);
+ }
+
+ the_frame = th->frame;
+ the_scope = th->scope;
+ the_class = th->class;
+ the_dyna_vars = th->dyna_vars;
+ the_block = th->block;
+ the_iter = th->iter;
+ prot_tag = th->tag;
+ the_class = th->class;
+ errat = th->errat;
+ errinfo = th->errinfo;
+ last_status = th->last_status;
+
+ lastline_set(th->last_line);
+ backref_set(th->last_match);
+
+ sourcefile = th->file;
+ sourceline = th->line;
+
+ tmp = th;
+ ex = exit;
+ FLUSH_REGISTER_WINDOWS;
+ MEMCPY(tmp->stk_pos, tmp->stk_ptr, VALUE, tmp->stk_len);
+
+ switch (ex) {
+ case 1:
+ JUMP_TAG2(TAG_FATAL, INT2FIX(0));
+ break;
+
+ case 2:
+ rb_interrupt();
+ break;
+
+ default:
+ longjmp(tmp->context, 1);
+ }
+}
+
+static void
+thread_ready(th)
+ thread_t th;
+{
+ /* The thread is no longer waiting on anything */
+ if (th->wait_for & WAIT_FD) {
+ num_waiting_on_fd--;
+ }
+ if (th->wait_for & WAIT_TIME) {
+ num_waiting_on_timer--;
+ }
+ if (th->wait_for & WAIT_JOIN) {
+ num_waiting_on_join--;
+ }
+ th->wait_for = 0;
+ th->status = THREAD_RUNNABLE;
+}
+
+static void
+thread_remove()
+{
+ thread_ready(curr_thread);
+ curr_thread->status = THREAD_KILLED;
+ curr_thread->prev->next = curr_thread->next;
+ curr_thread->next->prev = curr_thread->prev;
+ thread_schedule();
+}
+
+static int
+thread_dead(th)
+ thread_t th;
+{
+ return th->status == THREAD_KILLED;
+}
+
+void
+thread_schedule()
+{
+ thread_t next;
+ thread_t th;
+ thread_t curr;
+
+ thread_pending = 0;
+ if (curr_thread == curr_thread->next) return;
+
+ next = 0;
+ curr = curr_thread; /* real current thread */
+
+ if (curr_thread->status == THREAD_KILLED) {
+ curr_thread = curr_thread->prev;
+ }
+
+ again:
+ FOREACH_THREAD(th) {
+ if (th->status != THREAD_STOPPED && th->status != THREAD_KILLED) {
+ next = th;
+ break;
+ }
+ }
+ END_FOREACH(th);
+
+ if (num_waiting_on_join) {
+ FOREACH_THREAD(th) {
+ if ((th->wait_for & WAIT_JOIN) && thread_dead(th->join)) {
+ th->join = 0;
+ th->wait_for &= ~WAIT_JOIN;
+ th->status = THREAD_RUNNABLE;
+ num_waiting_on_join--;
+ if (!next) next = th;
+ }
+ }
+ END_FOREACH(th);
+ }
+
+ if (num_waiting_on_fd > 0 || num_waiting_on_timer > 0) {
+ fd_set readfds;
+ struct timeval delay_tv, *delay_ptr;
+ double delay, now;
+
+ int n, max;
+
+ do {
+ select_err:
+ max = 0;
+ FD_ZERO(&readfds);
+ if (num_waiting_on_fd > 0) {
+ FOREACH_THREAD(th) {
+ if (th->wait_for & WAIT_FD) {
+ FD_SET(th->fd, &readfds);
+ if (th->fd > max) max = th->fd;
+ }
+ }
+ END_FOREACH(th);
+ }
+
+ delay = DELAY_INFTY;
+ if (num_waiting_on_timer > 0) {
+ now = timeofday();
+ FOREACH_THREAD(th) {
+ if (th->wait_for & WAIT_TIME) {
+ if (th->delay <= now) {
+ th->delay = 0.0;
+ th->wait_for &= ~WAIT_TIME;
+ th->status = THREAD_RUNNABLE;
+ num_waiting_on_timer--;
+ next = th;
+ } else if (th->delay < delay) {
+ delay = th->delay;
+ }
+ }
+ }
+ END_FOREACH(th);
+ }
+ /* Do the select if needed */
+ if (num_waiting_on_fd > 0 || !next) {
+ /* Convert delay to a timeval */
+ /* If a thread is runnable, just poll */
+ if (next) {
+ delay_tv.tv_sec = 0;
+ delay_tv.tv_usec = 0;
+ delay_ptr = &delay_tv;
+ }
+ else if (delay == DELAY_INFTY) {
+ delay_ptr = 0;
+ }
+ else {
+ delay -= now;
+ delay_tv.tv_sec = (unsigned int)delay;
+ delay_tv.tv_usec = (delay - (double)delay_tv.tv_sec) * 1e6;
+ delay_ptr = &delay_tv;
+ }
+ n = select(max+1, &readfds, 0, 0, delay_ptr);
+ if (n > 0) {
+ /* Some descriptors are ready.
+ Make the corresponding threads runnable. */
+ FOREACH_THREAD(th)
+ if ((th->wait_for&WAIT_FD)
+ && FD_ISSET(th->fd, &readfds)) {
+ /* Wake up only one thread per fd. */
+ FD_CLR(th->fd, &readfds);
+ th->status = THREAD_RUNNABLE;
+ th->fd = 0;
+ th->wait_for &= ~WAIT_FD;
+ num_waiting_on_fd--;
+ if (!next) next = th; /* Found one. */
+ }
+ END_FOREACH(th);
+ }
+ if (n < 0 && !next) goto select_err;
+ }
+ /* The delays for some of the threads should have expired.
+ Go through the loop once more, to check the delays. */
+ } while (!next && delay != DELAY_INFTY);
+ }
+
+ if (!next) {
+ FOREACH_THREAD(th) {
+ 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)":"");
+ }
+ END_FOREACH(th);
+ Fatal("Thread: deadlock");
+ }
+ if (next == curr) {
+ return;
+ }
+
+ /* context switch */
+ if (curr == curr_thread) {
+ thread_save_context(curr);
+ if (setjmp(curr->context)) {
+ return;
+ }
+ }
+
+ curr_thread = next;
+ if (next->status == THREAD_TO_KILL) {
+ /* execute ensure-clause if any */
+ thread_restore_context(next, 1);
+ }
+ thread_restore_context(next, 0);
+}
+
+void
+thread_wait_fd(fd)
+ int fd;
+{
+ if (curr_thread == curr_thread->next) return;
+
+ curr_thread->status = THREAD_STOPPED;
+ curr_thread->fd = fd;
+ num_waiting_on_fd++;
+ curr_thread->wait_for |= WAIT_FD;
+ thread_schedule();
+}
+
+void
+thread_fd_writable(fd)
+ int fd;
+{
+ struct timeval zero;
+ fd_set fds;
+
+ zero.tv_sec = zero.tv_usec = 0;
+ if (curr_thread == curr_thread->next) return;
+
+ for (;;) {
+ FD_ZERO(&fds);
+ FD_SET(fd, &fds);
+ if (select(fd+1, 0, &fds, 0, &zero) == 1) break;
+ thread_schedule();
+ }
+}
+
+void
+thread_wait_for(time)
+ struct timeval time;
+{
+ double date;
+
+ if (curr_thread == curr_thread->next) {
+ int n;
+#ifndef linux
+ double d, limit;
+ limit = timeofday()+(double)time.tv_sec+(double)time.tv_usec*1e-6;
+#endif
+ for (;;) {
+ TRAP_BEG;
+ n = select(0, 0, 0, 0, &time);
+ TRAP_END;
+ if (n == 0) return;
+
+#ifndef linux
+ d = limit - timeofday();
+
+ time.tv_sec = (int)d;
+ time.tv_usec = (int)((d - (int)d)*1e6);
+ if (time.tv_usec < 0) {
+ time.tv_usec += 1e6;
+ time.tv_sec -= 1;
+ }
+ if (time.tv_sec < 0) return;
+#endif
+ }
+ }
+
+ date = timeofday() + (double)time.tv_sec + (double)time.tv_usec*1e-6;
+ curr_thread->status = THREAD_STOPPED;
+ curr_thread->delay = date;
+ num_waiting_on_timer++;
+ curr_thread->wait_for |= WAIT_TIME;
+ thread_schedule();
+}
+
+void thread_sleep();
+
+int
+thread_select(max, read, write, except, timeout)
+ int max;
+ fd_set *read, *write, *except;
+ struct timeval *timeout;
+{
+ double limit;
+ struct timeval zero;
+ fd_set r, *rp, w, *wp, x, *xp;
+ int n;
+
+ if (!read && !write && !except) {
+ if (!timeout) {
+ thread_sleep();
+ return;
+ }
+ thread_wait_for(*timeout);
+ return 0;
+ }
+
+ if (timeout) {
+ limit = timeofday()+
+ (double)timeout->tv_sec+(double)timeout->tv_usec*1e-6;
+ }
+
+ if (curr_thread == curr_thread->next) { /* no other thread */
+#ifndef linux
+ struct timeval tv, *tvp = timeout;
+
+ if (timeout) {
+ tv = *timeout;
+ tvp = &tv;
+ }
+ for (;;) {
+ TRAP_BEG;
+ n = select(max, read, write, except, tvp);
+ TRAP_END;
+ if (n < 0 && errno == EINTR) {
+ if (timeout) {
+ double d = timeofday() - limit;
+
+ tv.tv_sec = (unsigned int)d;
+ tv.tv_usec = (d - (double)tv.tv_sec) * 1e6;
+ }
+ continue;
+ }
+ return n;
+ }
+#else
+ for (;;) {
+ TRAP_BEG;
+ n = select(max, read, write, except, timeout);
+ TRAP_END;
+ if (n < 0 && errno == EINTR) {
+ continue;
+ }
+ return n;
+ }
+#endif
+
+ }
+
+ for (;;) {
+ zero.tv_sec = zero.tv_usec = 0;
+ if (read) {rp = &r; r = *read;} else {rp = 0;}
+ if (write) {wp = &w; w = *write;} else {wp = 0;}
+ if (except) {xp = &x; x = *except;} else {xp = 0;}
+ n = select(max, rp, wp, xp, &zero);
+ if (n > 0) {
+ /* write back fds */
+ if (read) {*read = r;}
+ if (write) {*write = w;}
+ if (except) {*except = x;}
+ return n;
+ }
+ if (n < 0 && errno != EINTR) {
+ return n;
+ }
+ if (timeout) {
+ if (timeout->tv_sec == 0 && timeout->tv_usec == 0) return 0;
+ if (limit <= timeofday()) return 0;
+ }
+
+ thread_schedule();
+ CHECK_INTS;
+ }
+}
+
+static VALUE
+thread_join(dmy, data)
+ VALUE dmy;
+ struct RData *data;
+{
+ thread_t th = thread_check(data);
+
+ if (thread_dead(th)) return Qnil;
+ if ((th->wait_for & WAIT_JOIN) && th->join == curr_thread)
+ Fatal("Thread.join: deadlock");
+ curr_thread->status = THREAD_STOPPED;
+ curr_thread->join = th;
+ num_waiting_on_join++;
+ curr_thread->wait_for |= WAIT_JOIN;
+ thread_schedule();
+
+ return Qnil;
+}
+
+static VALUE
+thread_current()
+{
+ return curr_thread->thread;
+}
+
+int
+th_cur()
+{
+ return (int)curr_thread;
+}
+
+static VALUE
+thread_run(data)
+ struct RData *data;
+{
+ thread_t th = thread_check(data);
+
+ if (th->status == THREAD_KILLED) Fail("killed thread");
+ thread_ready(th);
+ thread_schedule();
+
+ return (VALUE)data;
+}
+
+static VALUE
+thread_kill(data)
+ struct RData *data;
+{
+ thread_t th = thread_check(data);
+
+ if (th->status == THREAD_TO_KILL) return Qnil;
+ if (th->status == THREAD_KILLED) return Qnil;
+ if (th == th->next || th == main_thread) rb_exit(0);
+
+ thread_ready(th);
+ th->status = THREAD_TO_KILL;
+ thread_schedule();
+ /* not reached */
+}
+
+static VALUE
+thread_s_kill(obj, th)
+ VALUE obj, th;
+{
+ return thread_kill(th);
+}
+
+static VALUE
+thread_exit()
+{
+ return thread_kill(curr_thread->thread);
+}
+
+static VALUE
+thread_stop_method(data)
+ struct RData *data;
+{
+ thread_t th = thread_check(data);
+
+ th->status = THREAD_STOPPED;
+ thread_schedule();
+
+ return Qnil;
+}
+
+static void
+thread_stop()
+{
+ thread_stop_method(curr_thread->thread);
+}
+
+void
+thread_sleep()
+{
+ if (curr_thread == curr_thread->next) {
+ TRAP_BEG;
+ sleep((32767<<16)+32767);
+ TRAP_END;
+ return;
+ }
+ thread_stop_method(curr_thread->thread);
+}
+
+static thread_t
+thread_alloc()
+{
+ thread_t th;
+
+ th = ALLOC(struct thread);
+ th->status = THREAD_RUNNABLE;
+ th->func = 0;
+ th->arg = 0;
+
+ th->status = 0;
+ th->result = 0;
+ th->errinfo = Qnil;
+ th->errat = 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->class = 0;
+ th->dyna_vars = 0;
+ th->block = 0;
+ th->iter = 0;
+ th->tag = 0;
+
+ th->thread = data_object_alloc(cThread, th, 0, thread_free);
+
+ if (curr_thread) {
+ th->prev = curr_thread;
+ curr_thread->next->prev = th;
+ th->next = curr_thread->next;
+ curr_thread->next = th;
+ }
+ else {
+ curr_thread = th->prev = th->next = th;
+ th->status = THREAD_RUNNABLE;
+ }
+
+ return th;
+}
+
+VALUE
+thread_create(fn, arg)
+ VALUE (*fn)();
+ void *arg;
+{
+ thread_t th = thread_alloc();
+ NODE *state;
+
+ thread_save_context(curr_thread);
+ if (setjmp(curr_thread->context)) {
+ return th->thread;
+ }
+
+ th->func = fn;
+ th->arg = arg;
+
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ thread_save_context(th);
+ if (setjmp(th->context) == 0) {
+ curr_thread = th;
+ th->result = (*th->func)(th->arg, th);
+ }
+ }
+ POP_TAG();
+ if (state && th->status != THREAD_TO_KILL) {
+ /* global exit within this thread */
+ main_thread->errat = errat;
+ main_thread->errinfo = errinfo;
+ thread_cleanup();
+ }
+ thread_remove();
+}
+
+static void
+thread_yield(arg, th)
+ thread_t th;
+{
+ scope_dup(the_block->scope);
+ rb_yield(th->thread);
+}
+
+static VALUE
+thread_start()
+{
+ if (!iterator_p()) {
+ Raise(eLocalJumpError, "must be called as iterator");
+ }
+ return thread_create(thread_yield, 0);
+}
+
+static VALUE
+thread_value(data)
+ struct RData *data;
+{
+ thread_t th = thread_check(data);
+
+ thread_join(0, data);
+ return th->result;
+}
+
+static VALUE
+thread_status(data)
+ struct RData *data;
+{
+ thread_t th = thread_check(data);
+
+ return thread_dead(th)?FALSE:TRUE;
+}
+
+static VALUE
+thread_stopped(data)
+ struct RData *data;
+{
+ thread_t th = thread_check(data);
+
+ if (thread_dead(th)) return TRUE;
+ if (th->status == THREAD_STOPPED) return TRUE;
+ return FALSE;
+}
+
+static void
+thread_wait_other_threads()
+{
+ /* wait other threads to terminate */
+ while (curr_thread != curr_thread->next) {
+ thread_schedule();
+ }
+}
+
+static void
+thread_cleanup()
+{
+ thread_t th;
+
+ FOREACH_THREAD(th) {
+ if (th != curr_thread && th->status != THREAD_KILLED) {
+ th->status = THREAD_TO_KILL;
+ th->wait_for = 0;
+ }
+ }
+ END_FOREACH(th);
+}
+
+int thread_critical;
+
+static VALUE
+thread_exclusive()
+{
+ NODE *state;
+
+ thread_critical++;
+
+ PUSH_TAG();
+ if ((state = EXEC_TAG()) == 0) {
+ rb_yield(Qnil);
+ }
+ POP_TAG();
+ thread_critical--;
+
+ if (state) JUMP_TAG(state);
+ thread_schedule();
+ return Qnil;
+}
+
+void
+thread_interrupt()
+{
+ thread_t th = main_thread;
+
+ thread_ready(main_thread);
+ if (th == curr_thread) {
+ rb_interrupt();
+ }
+ curr_thread = main_thread;
+ thread_restore_context(curr_thread, 2);
+}
+
+static thread_t loading_thread;
+static int loading_nest;
+
+static int
+thread_loading(feature)
+ char *feature;
+{
+ if (curr_thread != curr_thread->next && loading_thread) {
+ while (loading_thread != curr_thread) {
+ thread_schedule();
+ CHECK_INTS;
+ }
+ if (rb_provided(feature)) return TRUE; /* no need to load */
+ }
+
+ loading_thread = curr_thread;
+ loading_nest++;
+
+ return FALSE;
+}
+
+static void
+thread_loading_done()
+{
+ if (--loading_nest == 0) {
+ loading_thread = 0;
+ }
+}
+
+#if defined(HAVE_SETITIMER) && !defined(__BOW__)
+static void
+catch_timer(sig)
+ int sig;
+{
+#if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL)
+ signal(sig, catch_timer);
+#endif
+ if (!thread_critical) {
+ if (trap_immediate) {
+ trap_immediate = 0;
+ thread_schedule();
+ }
+ else thread_pending = 1;
+ }
+}
+#else
+int thread_tick = THREAD_TICK;
+#endif
+
+void
+Init_Thread()
+{
+ cThread = rb_define_class("Thread", cObject);
+
+ rb_define_singleton_method(cThread, "new", thread_start, 0);
+ rb_define_singleton_method(cThread, "start", thread_start, 0);
+ rb_define_singleton_method(cThread, "fork", thread_start, 0);
+
+ rb_define_singleton_method(cThread, "stop", thread_stop, 0);
+ rb_define_singleton_method(cThread, "kill", thread_s_kill, 1);
+ rb_define_singleton_method(cThread, "exit", thread_exit, 0);
+ rb_define_singleton_method(cThread, "pass", thread_schedule, 0);
+ rb_define_singleton_method(cThread, "join", thread_join, 1);
+ rb_define_singleton_method(cThread, "current", thread_current, 0);
+ rb_define_singleton_method(cThread, "exclusive", thread_exclusive, 0);
+
+ rb_define_method(cThread, "run", thread_run, 0);
+ rb_define_method(cThread, "stop", thread_stop_method, 0);
+ rb_define_method(cThread, "exit", thread_kill, 0);
+ rb_define_method(cThread, "value", thread_value, 0);
+ rb_define_method(cThread, "status", thread_status, 0);
+ rb_define_method(cThread, "stop?", thread_stopped, 0);
+ rb_define_method(cThread, "stopped?", thread_stopped, 0);
+
+ /* allocate main thread */
+ main_thread = thread_alloc();
+
+#if defined(HAVE_SETITIMER) && !defined(__BOW__)
+ {
+ struct itimerval tval;
+
+#ifdef POSIX_SIGNAL
+ posix_signal(SIGVTALRM, catch_timer);
+#else
+ signal(SIGVTALRM, catch_timer);
+#endif
+
+ tval.it_interval.tv_sec = 0;
+ tval.it_interval.tv_usec = 50000;
+ tval.it_value = tval.it_interval;
+ setitimer(ITIMER_VIRTUAL, &tval, NULL);
+ }
+#endif
+}
+#endif
diff --git a/ext/Setup b/ext/Setup
index 93586ea0e6..4ea6aea10a 100644
--- a/ext/Setup
+++ b/ext/Setup
@@ -2,6 +2,8 @@
#dbm
#etc
+#kconv
#marshal
+#md5
#socket
-tkutil
+#tkutil
diff --git a/ext/Setup.dj b/ext/Setup.dj
new file mode 100644
index 0000000000..eb60525de0
--- /dev/null
+++ b/ext/Setup.dj
@@ -0,0 +1,8 @@
+option nodynamic
+
+dbm
+#etc
+marshal
+md5
+#socket
+#tkutil
diff --git a/ext/dbm/MANIFEST b/ext/dbm/MANIFEST
index 141b8dd601..8beec6783d 100644
--- a/ext/dbm/MANIFEST
+++ b/ext/dbm/MANIFEST
@@ -1,5 +1,4 @@
MANIFEST
dbm.c
-dbm.doc
depend
extconf.rb
diff --git a/ext/dbm/dbm.c b/ext/dbm/dbm.c
index dbdd99c0ca..5d8a12e3f9 100644
--- a/ext/dbm/dbm.c
+++ b/ext/dbm/dbm.c
@@ -17,10 +17,14 @@
#include <errno.h>
VALUE cDBM;
-static ID id_dbm;
extern VALUE mEnumerable;
+struct dbmdata {
+ int di_size;
+ DBM *di_dbm;
+};
+
static void
closeddbm()
{
@@ -28,24 +32,15 @@ closeddbm()
}
#define GetDBM(obj, dbmp) {\
- DBM **_dbm;\
- Get_Data_Struct(obj, id_dbm, DBM*, _dbm);\
- dbmp = *_dbm;\
- if (dbmp == Qnil) closeddbm();\
+ Get_Data_Struct(obj, struct dbmdata, dbmp);\
+ if (dbmp->di_dbm == 0) closeddbm();\
}
static void
free_dbm(dbmp)
- DBM **dbmp;
+ struct dbmdata *dbmp;
{
- if (*dbmp) dbm_close(*dbmp);
-}
-
-#define MakeDBM(obj, dp) {\
- DBM **_dbm;\
- if (!id_dbm) id_dbm = rb_intern("dbm");\
- Make_Data_Struct(obj,id_dbm,DBM*,Qnil,free_dbm,_dbm);\
- *_dbm=dp;\
+ if (dbmp->di_dbm) dbm_close(dbmp->di_dbm);
}
static VALUE
@@ -55,7 +50,8 @@ fdbm_s_open(argc, argv, class)
VALUE class;
{
VALUE file, vmode;
- DBM *dbm, **dbm2;
+ DBM *dbm;
+ struct dbmdata *dbmp;
int mode;
VALUE obj;
@@ -70,7 +66,7 @@ fdbm_s_open(argc, argv, class)
}
Check_Type(file, T_STRING);
- dbm = Qnil;
+ dbm = 0;
if (mode >= 0)
dbm = dbm_open(RSTRING(file)->ptr, O_RDWR|O_CREAT, mode);
if (!dbm)
@@ -83,8 +79,9 @@ fdbm_s_open(argc, argv, class)
rb_sys_fail(RSTRING(file)->ptr);
}
- obj = obj_alloc(class);
- MakeDBM(obj, dbm);
+ obj = Make_Data_Struct(class,struct dbmdata,0,free_dbm,dbmp);
+ dbmp->di_dbm = dbm;
+ dbmp->di_size = -1;
return obj;
}
@@ -93,12 +90,12 @@ static VALUE
fdbm_close(obj)
VALUE obj;
{
- DBM **dbmp;
+ struct dbmdata *dbmp;
- Get_Data_Struct(obj, id_dbm, DBM*, dbmp);
- if (*dbmp == Qnil) Fail("already closed DBM file");
- dbm_close(*dbmp);
- *dbmp = Qnil;
+ Get_Data_Struct(obj, struct dbmdata, dbmp);
+ if (dbmp->di_dbm == 0) closeddbm();
+ dbm_close(dbmp->di_dbm);
+ dbmp->di_dbm = 0;
return Qnil;
}
@@ -108,15 +105,17 @@ fdbm_fetch(obj, keystr)
VALUE obj, keystr;
{
datum key, value;
+ struct dbmdata *dbmp;
DBM *dbm;
Check_Type(keystr, T_STRING);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
value = dbm_fetch(dbm, key);
- if (value.dptr == Qnil) {
+ if (value.dptr == 0) {
return Qnil;
}
return str_new(value.dptr, value.dsize);
@@ -128,38 +127,47 @@ fdbm_indexes(obj, args)
struct RArray *args;
{
VALUE *p, *pend;
- struct RArray *new;
+ VALUE new;
int i = 0;
- if (!args || args->len == 1 && TYPE(args->ptr) != T_ARRAY) {
- args = (struct RArray*)rb_to_a(args->ptr[0]);
- }
-
- new = (struct RArray*)ary_new2(args->len);
+ args = (struct RArray*)rb_to_a(args);
+ new = ary_new2(args->len);
p = args->ptr; pend = p + args->len;
while (p < pend) {
- new->ptr[i++] = fdbm_fetch(obj, *p++);
- new->len = i;
+ ary_push(new, fdbm_fetch(obj, *p++));
}
- return (VALUE)new;
+ return new;
}
static VALUE
fdbm_delete(obj, keystr)
VALUE obj, keystr;
{
- datum key;
+ datum key, value;
+ struct dbmdata *dbmp;
DBM *dbm;
Check_Type(keystr, T_STRING);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
+
+ value = dbm_fetch(dbm, key);
+ if (value.dptr == 0) {
+ if (iterator_p()) rb_yield(Qnil);
+ return Qnil;
+ }
+
if (dbm_delete(dbm, key)) {
+ dbmp->di_size = -1;
Fail("dbm_delete failed");
}
+ else if (dbmp->di_size >= 0) {
+ dbmp->di_size--;
+ }
return obj;
}
@@ -168,10 +176,12 @@ fdbm_shift(obj)
VALUE obj;
{
datum key, val;
+ struct dbmdata *dbmp;
DBM *dbm;
VALUE keystr, valstr;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
key = dbm_firstkey(dbm);
if (!key.dptr) return Qnil;
@@ -188,17 +198,19 @@ fdbm_delete_if(obj)
VALUE obj;
{
datum key, val;
+ struct dbmdata *dbmp;
DBM *dbm;
VALUE keystr, valstr;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
keystr = str_new(key.dptr, key.dsize);
valstr = str_new(val.dptr, val.dsize);
- if (rb_yield(assoc_new(keystr, valstr))
- && dbm_delete(dbm, key)) {
- Fail("dbm_delete failed");
+ if (RTEST(rb_yield(assoc_new(keystr, valstr)))) {
+ if (dbm_delete(dbm, key)) {
+ Fail("dbm_delete failed");
+ }
}
}
return obj;
@@ -209,9 +221,12 @@ fdbm_clear(obj)
VALUE obj;
{
datum key;
+ struct dbmdata *dbmp;
DBM *dbm;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
+ dbmp->di_size = -1;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
if (dbm_delete(dbm, key)) {
Fail("dbm_delete failed");
@@ -225,6 +240,7 @@ fdbm_store(obj, keystr, valstr)
VALUE obj, keystr, valstr;
{
datum key, val;
+ struct dbmdata *dbmp;
DBM *dbm;
if (valstr == Qnil) {
@@ -232,19 +248,26 @@ fdbm_store(obj, keystr, valstr)
return Qnil;
}
- Check_Type(keystr, T_STRING);
+ keystr = obj_as_string(keystr);
+
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
- Check_Type(valstr, T_STRING);
+
+ if (NIL_P(valstr)) return fdbm_delete(obj, keystr);
+
+ valstr = obj_as_string(valstr);
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
- GetDBM(obj, dbm);
+ Get_Data_Struct(obj, struct dbmdata, dbmp);
+ dbmp->di_size = -1;
+ dbm = dbmp->di_dbm;
if (dbm_store(dbm, key, val, DBM_REPLACE)) {
dbm_clearerr(dbm);
if (errno == EPERM) rb_sys_fail(Qnil);
Fail("dbm_store failed");
}
+
return valstr;
}
@@ -253,24 +276,56 @@ fdbm_length(obj)
VALUE obj;
{
datum key;
+ struct dbmdata *dbmp;
DBM *dbm;
int i = 0;
- GetDBM(obj, dbm);
+ Get_Data_Struct(obj, struct dbmdata, dbmp);
+ if (dbmp->di_size > 0) return INT2FIX(dbmp->di_size);
+ dbm = dbmp->di_dbm;
+
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
i++;
}
+ dbmp->di_size = i;
+
return INT2FIX(i);
}
static VALUE
+fdbm_empty(obj)
+ VALUE obj;
+{
+ datum key;
+ struct dbmdata *dbmp;
+ DBM *dbm;
+ int i = 0;
+
+ Get_Data_Struct(obj, struct dbmdata, dbmp);
+ if (dbmp->di_size < 0) {
+ dbm = dbmp->di_dbm;
+
+ for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
+ i++;
+ }
+ }
+ else {
+ i = dbmp->di_size;
+ }
+ if (i == 0) return TRUE;
+ return FALSE;
+}
+
+static VALUE
fdbm_each_value(obj)
VALUE obj;
{
datum key, val;
+ struct dbmdata *dbmp;
DBM *dbm;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
rb_yield(str_new(val.dptr, val.dsize));
@@ -283,9 +338,11 @@ fdbm_each_key(obj)
VALUE obj;
{
datum key;
+ struct dbmdata *dbmp;
DBM *dbm;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
rb_yield(str_new(key.dptr, key.dsize));
}
@@ -298,9 +355,11 @@ fdbm_each_pair(obj)
{
datum key, val;
DBM *dbm;
+ struct dbmdata *dbmp;
VALUE keystr, valstr;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
@@ -317,11 +376,14 @@ fdbm_keys(obj)
VALUE obj;
{
datum key;
+ struct dbmdata *dbmp;
DBM *dbm;
VALUE ary;
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
+
ary = ary_new();
- GetDBM(obj, dbm);
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
ary_push(ary, str_new(key.dptr, key.dsize));
}
@@ -334,11 +396,14 @@ fdbm_values(obj)
VALUE obj;
{
datum key, val;
+ struct dbmdata *dbmp;
DBM *dbm;
VALUE ary;
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
+
ary = ary_new();
- GetDBM(obj, dbm);
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
ary_push(ary, str_new(val.dptr, val.dsize));
@@ -352,13 +417,15 @@ fdbm_has_key(obj, keystr)
VALUE obj, keystr;
{
datum key, val;
+ struct dbmdata *dbmp;
DBM *dbm;
Check_Type(keystr, T_STRING);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
val = dbm_fetch(dbm, key);
if (val.dptr) return TRUE;
return FALSE;
@@ -369,13 +436,15 @@ fdbm_has_value(obj, valstr)
VALUE obj, valstr;
{
datum key, val;
+ struct dbmdata *dbmp;
DBM *dbm;
Check_Type(valstr, T_STRING);
val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
if (val.dsize == RSTRING(valstr)->len &&
@@ -390,10 +459,12 @@ fdbm_to_a(obj)
VALUE obj;
{
datum key, val;
+ struct dbmdata *dbmp;
DBM *dbm;
VALUE ary;
- GetDBM(obj, dbm);
+ GetDBM(obj, dbmp);
+ dbm = dbmp->di_dbm;
ary = ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
@@ -417,6 +488,7 @@ Init_dbm()
rb_define_method(cDBM, "indexes", fdbm_indexes, -2);
rb_define_method(cDBM, "length", fdbm_length, 0);
rb_define_alias(cDBM, "size", "length");
+ rb_define_method(cDBM, "empty?", fdbm_empty, 0);
rb_define_method(cDBM, "each", fdbm_each_pair, 0);
rb_define_method(cDBM, "each_value", fdbm_each_value, 0);
rb_define_method(cDBM, "each_key", fdbm_each_key, 0);
@@ -427,9 +499,11 @@ Init_dbm()
rb_define_method(cDBM, "delete", fdbm_delete, 1);
rb_define_method(cDBM, "delete_if", fdbm_delete_if, 0);
rb_define_method(cDBM, "clear", fdbm_clear, 0);
- rb_define_method(cDBM, "includes", fdbm_has_key, 1);
- rb_define_method(cDBM, "has_key", fdbm_has_key, 1);
- rb_define_method(cDBM, "has_value", fdbm_has_value, 1);
+ rb_define_method(cDBM, "include?", fdbm_has_key, 1);
+ rb_define_method(cDBM, "has_key?", fdbm_has_key, 1);
+ rb_define_method(cDBM, "has_value?", fdbm_has_value, 1);
+ rb_define_method(cDBM, "key?", fdbm_has_key, 1);
+ rb_define_method(cDBM, "value?", fdbm_has_value, 1);
rb_define_method(cDBM, "to_a", fdbm_to_a, 0);
}
diff --git a/ext/dbm/dbm.doc b/ext/dbm/dbm.doc
deleted file mode 100644
index 45f174b7aa..0000000000
--- a/ext/dbm/dbm.doc
+++ /dev/null
@@ -1,107 +0,0 @@
-.\" dbm.doc - -*- Indented-Text -*- created at: Thu Mar 23 20:28:31 JST 1995
-
-** DBM(¥¯¥é¥¹)
-
-NDBM¥Õ¥¡¥¤¥ë¤ò¥¢¥¯¥»¥¹¤¹¤ë¥¯¥é¥¹¡¥¥­¡¼¡¤¥Ç¡¼¥¿¤È¤â¤Ëʸ»úÎó¤Ç¤Ê¤±¤ì¤Ð¤Ê
-¤é¤Ê¤¤¤È¤¤¤¦À©¸Â¤È¡¤¥Ç¡¼¥¿¤¬¥Õ¥¡¥¤¥ë¤ËÊݸ¤µ¤ì¤ë¤È¤¤¤¦ÅÀ¤ò½ü¤¤¤Æ¤Ï
-Dict¥¯¥é¥¹¤ÈÁ´¤¯Æ±Íͤ˰·¤¦¤³¤È¤¬¤Ç¤­¤ë¡¥NDBM¤òÈ÷¤¨¤Æ¤¤¤Ê¤¤¥·¥¹¥Æ¥à¤Ç¤Ï
-¤³¤Î¥¯¥é¥¹¤ÏÄêµÁ¤µ¤ì¤Ê¤¤¡¥
-
-SuperClass: Object
-
-Included Modules: Enumerable
-
-Methods:
-
- self [key]
-
- key¤ò¥­¡¼¤È¤¹¤ëÃͤòÊÖ¤¹¡¥
-
- self [key]= value
-
- key¤ò¥­¡¼¤È¤·¤Æ¡¤value¤ò³ÊǼ¤¹¤ë¡¥value¤È¤·¤Ænil¤ò»ØÄꤹ¤ë¤È¡¤
- key¤ËÂФ¹¤ë¹àÌܤκï½ü¤È¤Ê¤ë¡¥
-
- clear
-
- DBM¥Õ¥¡¥¤¥ë¤ÎÃæ¿È¤ò¶õ¤Ë¤¹¤ë¡¥
-
- close
-
- DBM¥Õ¥¡¥¤¥ë¤ò¥¯¥í¡¼¥º¤¹¤ë¡¥°Ê¸å¤ÎÁàºî¤ÏÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥
-
- delete(key)
-
- key¤ò¥­¡¼¤È¤¹¤ëÁȤòºï½ü¤¹¤ë¡¥
-
- delete_if
-
- Í×ÁǤòºï½ü¤¹¤ë¥¤¥Æ¥ì¡¼¥¿¡¥key::value¤È¤¤¤¦¥Ú¥¢¤òÍ¿¤¨¤Æ¡¤¥Ö¥í¥Ã
- ¥¯¤òɾ²Á¤·¤¿Ãͤ¬¿¿¤Î»þ¡¤³ºÅö¤¹¤ë¹àÌܤòºï½ü¤¹¤ë¡¥
-
- each
- each_pair
-
- key::value¤Ê¤ë¥Ú¥¢¤òÍ¿¤¨¤ë¥¤¥Æ¥ì¡¼¥¿¡¥
-
- each_key
-
- Á´¤Æ¤Îkey¤ËÂФ·¤Æ·«¤êÊÖ¤¹¥¤¥Æ¥ì¡¼¥¿¡¥
-
- each_value
-
- Á´¤Æ¤Îvalue¤ËÂФ·¤Æ·«¤êÊÖ¤¹¥¤¥Æ¥ì¡¼¥¿¡¥
-
- has_key(key)
- includes(key)
-
- key¤¬¥Ç¡¼¥¿¥Ù¡¼¥¹Ãæ¤Ë¸ºß¤¹¤ë»þ¡¤¿¿¤òÊÖ¤¹
-
- has_value(value)
-
- value¤òÃͤȤ¹¤ëÁȤ¬¥Ç¡¼¥¿¥Ù¡¼¥¹Ãæ¤Ë¸ºß¤¹¤ë»þ¡¤¿¿¤ò
- ÊÖ¤¹
-
- indexes(ary)
- indexes(key-1, ..., key-n)
-
- 1ÈÖÌܤηÁ¼°¤Ç¤Ïʸ»úÎó¤ÎÇÛÎó¤ò°ú¿ô¤È¤·¤Æ¼õ¤±¤Æ¡¤¤½¤ÎÍ×ÁǤò¥­¡¼
- ¤È¤¹¤ëÍ×ÁǤò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥2ÈÖÌܤηÁ¼°¤Ç¤Ï³Æ°ú¿ô¤ÎÃͤò¥­¡¼¤È
- ¤¹¤ëÍ×ÁǤò´Þ¤àÇÛÎó¤òÊÖ¤¹.
-
- keys
-
- ¥Ç¡¼¥¿¥Ù¡¼¥¹Ãæ¤Ë¸ºß¤¹¤ë¥­¡¼Á´¤Æ¤ò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥
-
- length
- size
-
- ¥Ç¡¼¥¿¥Ù¡¼¥¹Ãæ¤ÎÍ×ÁǤοô¤òÊÖ¤¹¡¥(Ãí°Õ:¸½ºß¤Î¼Â¸½¤Ç¤ÏÍ×ÁÇ¿ô¤ò¿ô
- ¤¨¤ë¤¿¤á¤Ë¥Ç¡¼¥¿¥Ù¡¼¥¹¤òÁ´Éô¸¡º÷¤¹¤ë¤Î¤Ç¡¤·ë¹½¥³¥¹¥È¤¬¹â¤¤¡¥µ¤
- ¤ò¤Ä¤±¤Æ»È¤¦¤³¤È.)
-
- shift
-
- ¥Ç¡¼¥¿¥Ù¡¼¥¹Ãæ¤ÎÍ×ÁǤò°ì¤Ä¼è¤ê½Ð¤·(¥Ç¡¼¥¿¥Ù¡¼¥¹¤«¤éºï½ü¤¹¤ë)¡¤
- key::value¤È¤¤¤¦¥Ú¥¢¤òÊÖ¤¹¡¥
-
- to_a
-
- ¥Ç¡¼¥¿¥Ù¡¼¥¹Ãæ¤Îkey-value¥Ú¥¢¤òÍ×ÁǤȤ¹¤ëÇÛÎó¤òÊÖ¤¹¡¥
-
- values
-
- ¥Ç¡¼¥¿¥Ù¡¼¥¹Ãæ¤Ë¸ºß¤¹¤ëÃÍÁ´¤Æ¤ò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥
-
-Single Methods:
-
- open(dbname[, mode])
-
- dbname¤Ç»ØÄꤷ¤¿¥Ç¡¼¥¿¥Ù¡¼¥¹¤ò¥â¡¼¥É¤òmode¤ËÀßÄꤷ¤Æ¥ª¡¼¥×¥ó¤¹
- ¤ë¡¥mode¤Î¾ÊάÃͤÏ0666¤Ç¤¢¤ë¡¥mode¤È¤·¤Ænil¤ò»ØÄꤹ¤ë¤È¥Ç¡¼¥¿
- ¥Ù¡¼¥¹¤¬´û¤Ë¸ºß¤·¤Ê¤¤»þ¤Ë¤Ï¿·¤¿¤Ë¥ª¡¼¥×¥ó¤»¤º¡¤nil¤òÊÖ¤¹¡¥
-
--------------------------------------------------------
-Local variables:
-fill-column: 70
-end:
diff --git a/ext/dbm/extconf.rb b/ext/dbm/extconf.rb
index 5105cd662f..2302ee2d5d 100644
--- a/ext/dbm/extconf.rb
+++ b/ext/dbm/extconf.rb
@@ -1,4 +1,4 @@
-have_library("dbm", "dbm_open")
+have_library("gdbm", "dbm_open") or have_library("dbm", "dbm_open")
if have_func("dbm_open")
create_makefile("dbm")
end
diff --git a/ext/etc/etc.c b/ext/etc/etc.c
index e4e4098f8a..524800bd03 100644
--- a/ext/etc/etc.c
+++ b/ext/etc/etc.c
@@ -24,12 +24,16 @@ static VALUE
etc_getlogin(obj)
VALUE obj;
{
+ char *getenv();
+ char *login;
+
#ifdef HAVE_GETLOGIN
char *getlogin();
- char *login = getlogin();
+
+ login = getlogin();
+ if (!login) login = getenv("USER");
#else
- char *getenv();
- char *login = getenv("USER");
+ login = getenv("USER");
#endif
if (login)
@@ -42,7 +46,7 @@ static VALUE
setup_passwd(pwd)
struct passwd *pwd;
{
- if (pwd == Qnil) rb_sys_fail("/etc/passwd");
+ if (pwd == 0) rb_sys_fail("/etc/passwd");
return struct_new(sPasswd,
str_new2(pwd->pw_name),
str_new2(pwd->pw_passwd),
@@ -69,7 +73,8 @@ setup_passwd(pwd)
#ifdef PW_EXPIRE
INT2FIX(pwd->pw_expire),
#endif
- Qnil);
+ 0 /*dummy*/
+ );
}
#endif
@@ -91,7 +96,7 @@ etc_getpwuid(argc, argv, obj)
uid = getuid();
}
pwd = getpwuid(uid);
- if (pwd == Qnil) Fail("can't find user for %d", uid);
+ if (pwd == 0) Fail("can't find user for %d", uid);
return setup_passwd(pwd);
#else
return Qnil;
@@ -107,7 +112,7 @@ etc_getpwnam(obj, nam)
Check_Type(nam, T_STRING);
pwd = getpwnam(RSTRING(nam)->ptr);
- if (pwd == Qnil) Fail("can't find user for %s", RSTRING(nam)->ptr);
+ if (pwd == 0) Fail("can't find user for %s", RSTRING(nam)->ptr);
return setup_passwd(pwd);
#else
return Qnil;
@@ -130,7 +135,7 @@ etc_passwd(obj)
return obj;
}
pw = getpwent();
- if (pw == Qnil) Fail("can't fetch next -- /etc/passwd");
+ if (pw == 0) Fail("can't fetch next -- /etc/passwd");
return setup_passwd(pw);
#else
return Qnil;
@@ -155,8 +160,7 @@ setup_group(grp)
str_new2(grp->gr_name),
str_new2(grp->gr_passwd),
INT2FIX(grp->gr_gid),
- mem,
- Qnil);
+ mem);
}
#endif
@@ -170,7 +174,7 @@ etc_getgrgid(obj, id)
gid = NUM2INT(id);
grp = getgrgid(gid);
- if (grp == Qnil) Fail("can't find group for %d", gid);
+ if (grp == 0) Fail("can't find group for %d", gid);
return setup_group(grp);
#else
return Qnil;
@@ -186,7 +190,7 @@ etc_getgrnam(obj, nam)
Check_Type(nam, T_STRING);
grp = getgrnam(RSTRING(nam)->ptr);
- if (grp == Qnil) Fail("can't find group for %s", RSTRING(nam)->ptr);
+ if (grp == 0) Fail("can't find group for %s", RSTRING(nam)->ptr);
return setup_group(grp);
#else
return Qnil;
@@ -214,7 +218,7 @@ etc_group(obj)
#endif
}
-VALUE mEtc;
+static VALUE mEtc;
void
Init_etc()
@@ -252,9 +256,11 @@ Init_etc()
#ifdef PW_EXPIRE
"expire",
#endif
- Qnil);
+ 0);
+ rb_global_variable(&sPasswd);
#ifdef HAVE_GETGRENT
- sGroup = struct_define("Group", "name", "passwd", "gid", "mem", Qnil);
+ sGroup = struct_define("Group", "name", "passwd", "gid", "mem", 0);
+ rb_global_variable(&sGroup);
#endif
}
diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in
index b61ccd222f..bd4eed306b 100644
--- a/ext/extmk.rb.in
+++ b/ext/extmk.rb.in
@@ -1,21 +1,24 @@
#! /usr/local/bin/ruby
-if $ARGV[0] == 'install'
+if ARGV[0] == 'static'
+ $force_static = TRUE
+ ARGV.shift
+elsif ARGV[0] == 'install'
$install = TRUE
- $ARGV.shift
-end
-
-if $ARGV[0] == 'clean'
+ ARGV.shift
+elsif ARGV[0] == 'clean'
$clean = TRUE
- $ARGV.shift
+ ARGV.shift
end
+$extlist = []
+
$cache_mod = FALSE;
$lib_cache = {}
$func_cache = {}
$hdr_cache = {}
-if File.exists?("config.cache") then
+if File.exist?("config.cache") then
f = open("config.cache", "r")
while f.gets
case $_
@@ -31,10 +34,10 @@ if File.exists?("config.cache") then
end
def older(file1, file2)
- if !File.exists?(file1) then
+ if !File.exist?(file1) then
return TRUE
end
- if !File.exists?(file2) then
+ if !File.exist?(file2) then
return FALSE
end
if File.mtime(file1) < File.mtime(file2)
@@ -61,7 +64,7 @@ def have_library(lib, func)
end
cfile = open("conftest.c", "w")
- printf cfile, "\
+ cfile.printf "\
int main() { return 0; }
int t() { %s(); return 0; }
", func
@@ -99,7 +102,7 @@ def have_func(func)
end
cfile = open("conftest.c", "w")
- printf cfile, "\
+ cfile.printf "\
char %s();
int main() { return 0; }
int t() { %s(); return 0; }
@@ -136,7 +139,7 @@ def have_header(header)
end
cfile = open("conftest.c", "w")
- printf cfile, "\
+ cfile.printf "\
#include <%s>
", header
cfile.close
@@ -162,7 +165,7 @@ def create_header()
hfile = open("extconf.h", "w")
for line in $defs
line =~ /^-D(.*)/
- printf hfile, "#define %s 1\n", $1
+ hfile.printf "#define %s 1\n", $1
end
hfile.close
end
@@ -180,7 +183,7 @@ def create_makefile(target)
$libs = "" if not $libs
mfile = open("Makefile", "w")
- printf mfile, "\
+ mfile.printf "\
SHELL = /bin/sh
#### Start of system configuration section. ####
@@ -191,36 +194,37 @@ VPATH = @srcdir@
CC = @CC@
CFLAGS = %s #$CFLAGS %s
+LDFLAGS = @LDFLAGS@
+DLDFLAGS = @DLDFLAGS@
LDSHARED = @LDSHARED@
", if $static then "" else "@CCDLFLAGS@" end, $defs.join(" ")
- printf mfile, "\
+ mfile.printf "\
prefix = @prefix@
-binprefix =
exec_prefix = @exec_prefix@
bindir = $(exec_prefix)/bin
-libdir = @prefix@/lib/ruby
+libdir = @archlib@
@SET_MAKE@
#### End of system configuration section. ####
"
- printf mfile, "LIBS = %s\n", $libs
- printf mfile, "OBJS = "
+ mfile.printf "LIBS = %s\n", $libs
+ mfile.printf "OBJS = "
if !$objs then
$objs = Dir["*.c"]
for f in $objs
f.sub!(/\.c$/, ".o")
end
end
- printf mfile, $objs.join(" ")
- printf mfile, "\n"
+ mfile.printf $objs.join(" ")
+ mfile.printf "\n"
- printf mfile, "\
+ dots = if "@INSTALL@" =~ /^\// then "" else "../" end
+ mfile.printf "\
TARGET = %s.%s
-INSTALL = @INSTALL@
-INSTALL_DATA = @INSTALL_DATA@
+INSTALL = %s@INSTALL@
all: $(TARGET)
@@ -229,56 +233,53 @@ clean:; @rm -f *.o *.so *.sl
@rm -f core ruby *~
realclean: clean
-", target, if $static then "o" else "@DLEXT@" end
+", target,
+ if $static then "o" else "@DLEXT@" end, dots
if !$static
- printf mfile, "\
+ mfile.printf "\
install: $(libdir)/$(TARGET)
$(libdir)/$(TARGET): $(TARGET)
@test -d $(libdir) || mkdir $(libdir)
- $(INSTALL_DATA) $(TARGET) $(libdir)/$(TARGET)
+ $(INSTALL) $(TARGET) $(libdir)/$(TARGET)
"
else
- printf mfile, "\
+ mfile.printf "\
install:;
"
end
if !$static && "@DLEXT@" != "o"
- printf mfile, "\
+ mfile.printf "\
$(TARGET): $(OBJS)
- $(LDSHARED) -o $(TARGET) $(OBJS) $(LIBS)
+ $(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LIBS)
"
- elsif !File.exists?(target + ".c")
- printf mfile, "\
+ elsif !File.exist?(target + ".c")
+ mfile.printf "\
$(TARGET): $(OBJS)
- ld $(LDDLFLAGS) -r $(TARGET) $(OBJS)
+ ld $(LDFLAGS) -r -o $(TARGET) $(OBJS)
"
end
- if File.exists?("depend")
+ if File.exist?("depend")
dfile = open("depend", "r")
- printf mfile, "###\n"
+ mfile.printf "###\n"
while line = dfile.gets()
- printf mfile, "%s", line
+ mfile.printf "%s", line
end
dfile.close
end
mfile.close
if $static
- $extinit += format("\
-\tInit_%s();\n\
-\trb_provide(\"%s.o\");\n\
-", target, target)
- $extobjs += format("ext/%s/%s.o ", $static, target)
+ $extlist.push [$static,target]
end
end
def extmake(target)
- if $static_ext[target]
+ if $force_static or $static_ext[target]
$static = target
else
$static = FALSE
@@ -294,19 +295,19 @@ def extmake(target)
begin
Dir.chdir target
if $static_ext.size > 0 ||
- !File.exists?("./Makefile") ||
+ !File.exist?("./Makefile") ||
older("./Makefile", "../Setup") ||
older("./Makefile", "../extmk.rb") ||
older("./Makefile", "./extconf.rb")
then
$defs = []
- if File.exists?("extconf.rb")
+ if File.exist?("extconf.rb")
load "extconf.rb"
else
create_makefile(target);
end
end
- if File.exists?("./Makefile")
+ if File.exist?("./Makefile")
if $install
system "make install"
elsif $clean
@@ -328,10 +329,10 @@ if File.file? "./Setup"
while f.gets()
$_.chop!
sub!(/#.*$/, '')
- continue if /^\s*$/
+ next if /^\s*$/
if /^option +nodynamic/
$nodynamic = TRUE
- continue
+ next
end
$static_ext[$_.split[0]] = TRUE
end
@@ -339,36 +340,56 @@ if File.file? "./Setup"
end
for d in Dir["*"]
- File.directory?(d) || continue
- File.file?(d + "/MANIFEST") || continue
+ File.directory?(d) || next
+ File.file?(d + "/MANIFEST") || next
d = $1 if d =~ /\/([\/]*)$/
- print "compiling ", d, "\n"
-
+ if $install
+ print "installing ", d, "\n"
+ elsif $clean
+ print "cleaning ", d, "\n"
+ else
+ print "compiling ", d, "\n"
+ end
extmake(d)
end
if $cache_mod
f = open("config.cache", "w")
for k,v in $lib_cache
- printf f, "lib: %s %s\n", k, v
+ f.printf "lib: %s %s\n", k, v
end
for k,v in $func_cache
- printf f, "func: %s %s\n", k, v
+ f.printf "func: %s %s\n", k, v
end
for k,v in $hdr_cache
- printf f, "hdr: %s %s\n", k, v
+ f.printf "hdr: %s %s\n", k, v
end
f.close
end
-exit if $install
-if $extobjs
+exit if $install or $clean
+if $extlist.size > 0
+ for s,t in $extlist
+ f = format("%s/%s.o", s, t)
+ if File.exist?(f)
+ $extinit += format("\
+\tInit_%s();\n\
+\trb_provide(\"%s.o\");\n\
+", t, t)
+ $extobjs += "ext/"
+ $extobjs += f
+ $extobjs += " "
+ else
+ FALSE
+ end
+ end
+
if older("extinit.c", "Setup")
f = open("extinit.c", "w")
- printf f, "void Init_ext() {\n"
- printf f, $extinit
- printf f, "}\n"
+ f.printf "void Init_ext() {\n"
+ f.printf $extinit
+ f.printf "}\n"
f.close
end
if older("extinit.o", "extinit.c")
@@ -378,16 +399,19 @@ if $extobjs
end
Dir.chdir ".."
- $extobjs = "ext/extinit.o " + $extobjs
if older("ruby", "ext/Setup") or older("ruby", "miniruby")
`rm -f ruby`
end
+
+ $extobjs = "ext/extinit.o " + $extobjs
system format('make ruby PROGRAM=ruby EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs)
else
Dir.chdir ".."
- `rm -f ruby`
- `cp miniruby ruby`
+ if older("ruby", "miniruby")
+ `rm -f ruby`
+ `cp miniruby ruby`
+ end
end
#Local variables:
diff --git a/ext/kconv/MANIFEST b/ext/kconv/MANIFEST
new file mode 100644
index 0000000000..8f37a9e166
--- /dev/null
+++ b/ext/kconv/MANIFEST
@@ -0,0 +1,2 @@
+MANIFEST
+kconv.c
diff --git a/ext/kconv/kconv.c b/ext/kconv/kconv.c
new file mode 100644
index 0000000000..fd6c3bed0a
--- /dev/null
+++ b/ext/kconv/kconv.c
@@ -0,0 +1,1934 @@
+/** Network Kanji Filter. (PDS Version)
+************************************************************************
+** Copyright (C) 1987, Fujitsu LTD. (Itaru ICHIKAWA)
+** Ï¢ÍíÀè¡§ ¡Ê³ô¡ËÉÙ»ÎÄ̸¦µæ½ê¡¡¥½¥Õ¥È£³¸¦¡¡»ÔÀî¡¡»ê
+** ¡ÊE-Mail Address: ichikawa@flab.fujitsu.co.jp¡Ë
+** Copyright (C) 1996
+** Ï¢ÍíÀè¡§ ΰµåÂç³Ø¾ðÊó¹©³Ø²Ê ²ÏÌî ¿¿¼£ mine/X0208 support
+** ¡ÊE-Mail Address: kono@ie.u-ryukyu.ac.jp¡Ë
+** Ï¢ÍíÀè¡§ COW for DOS & Win16 & Win32 & OS/2
+** ¡ÊE-Mail Address: GHG00637@niftyserve.or.jp¡Ë
+** ±ÄÍø¤òÌÜŪ¤È¤·¤Ê¤¤¸Â¤ê¡¢¤³¤Î¥½¡¼¥¹¤Î¤¤¤«¤Ê¤ë
+** Ê£¼Ì¡¤²þÊÑ¡¤½¤Àµ¤âµöÂú¤·¤Þ¤¹¡£¤½¤ÎºÝ¤Ë¤Ï¡¢¤³¤ÎÉôʬ¤ò»Ä¤¹¤³¤È¡£
+** ¤³¤Î¥×¥í¥°¥é¥à¤Ë¤Ä¤¤¤Æ¤ÏÆÃ¤Ë²¿¤ÎÊݾڤ⤷¤Ê¤¤¡¢°­¤·¤«¤é¤º¡£
+** Everyone is permitted to do anything on this program
+** including copying, modifying, improving
+** as long as you don't try to make money off it,
+** or pretend that you wrote it.
+** i.e., the above copyright notice has to appear in all copies.
+** THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE.
+***********************************************************************/
+
+/***********************************************************************
+** 1996/03/10 modified for Kconv - by Ikuo Nakagawa
+***********************************************************************/
+/***********************************************************************
+** 1996/12/18 modified for kconv(ruby) - by matz@ruby.club.or.jp
+***********************************************************************/
+
+static char *CopyRight =
+ "Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa),1996 S. Kono, COW";
+static char *Version =
+ "1.62";
+static char *Patchlevel =
+ "5/9612/Shinji Kono, COW matz";
+
+/*
+**
+**
+**
+** 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
+**/
+/******************************/
+/* ¥Ç¥Õ¥©¥ë¥È¤Î½ÐÎÏ¥³¡¼¥ÉÁªÂò */
+/* Select DEFAULT_CODE */
+#define DEFAULT_CODE_JIS
+/* #define DEFAULT_CODE_SJIS */
+/* #define DEFAULT_CODE_EUC */
+/******************************/
+/* ¥×¥í¥È¥¿¥¤¥×¤ÎÁªÂò */
+#define ANSI_C_PROTOTYPE
+/******************************/
+
+/* for Kconv: _AUTO, _EUC, _SJIS, _JIS */
+#define _AUTO 0
+#define _JIS 1
+#define _EUC 2
+#define _SJIS 3
+
+#ifdef __STDC__
+#define ANSI_C_PROTOTYPE
+#endif
+
+#if (defined(__TURBOC__) || defined(LSI_C)) && !defined(MSDOS)
+#define MSDOS
+#endif
+
+#include <stdio.h>
+
+#if defined(MSDOS) || defined(__OS2__)
+#include <stdlib.h>
+#include <fcntl.h>
+#include <io.h>
+#endif
+
+#ifdef MSDOS
+#ifdef LSI_C
+#define setbinmode(fp) fsetbin(fp)
+#else /* Microsoft C, Turbo C */
+#define setbinmode(fp) setmode(fileno(fp), O_BINARY)
+#endif
+#else /* UNIX,OS/2 */
+#define setbinmode(fp)
+#endif
+
+#ifdef _IOFBF /* SysV and MSDOS */
+#define setvbuffer(fp, buf, size) setvbuf(fp, buf, _IOFBF, size)
+#else /* BSD */
+#define setvbuffer(fp, buf, size) setbuffer(fp, buf, size)
+#endif
+
+/*Borland C++ 4.5 EasyWin*/
+#if defined(__TURBOC__) && defined(_Windows) && !defined(__WIN32__) /*Easy Win */
+#define EASYWIN
+#include <windows.h>
+#endif
+
+#define FALSE 0
+#define TRUE 1
+
+/* state of output_mode and input_mode */
+
+#define ASCII 0
+#define X0208 1
+#define X0201 2
+#define NO_X0201 3
+#define JIS_INPUT 4
+#define SJIS_INPUT 5
+#define LATIN1_INPUT 6
+#define FIXED_MIME 7
+#define DOUBLE_SPACE -2
+
+#define NL 0x0a
+#define ESC 0x1b
+#define SP 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 */
+
+#define _GETC() (*inptr ? (int)(*inptr++) : EOF)
+#define _UNGETC(c) (*--inptr = (c))
+#define PUTCHAR(c) (outlen + 1 < outsiz ? \
+ ((outptr[outlen++] = (c)), (outptr[outlen] = '\0')) : EOF)
+#define GETC() ((!mime_mode)?_GETC():mime_getc())
+#define UNGETC(c) ((!mime_mode)?_UNGETC(c):mime_ungetc(c))
+
+#ifdef EASYWIN /*Easy Win */
+extern POINT _BufferSize;
+#endif
+
+/* buffers */
+
+static unsigned char hold_buf[HOLD_SIZE*2];
+static int hold_count;
+static unsigned char *inptr;
+static char *outptr;
+static int outsiz;
+static int outlen;
+
+/* 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 */
+static unsigned int mime_input = 0; /* undecoded */
+
+/* flags */
+static int unbuf_f = FALSE;
+static int estab_f = FALSE;
+#ifdef notdef
+static int nop_f = FALSE;
+static int binmode_f = TRUE; /* binary mode */
+#endif
+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 = FALSE; /* 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 */
+
+static int fold();
+#define FOLD_MARGIN 10
+#define DEFAULT_FOLD 60
+
+/* 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 */
+
+/* X0208 -> ASCII translation table */
+
+static unsigned char cv[],dv[],ev[],fv[];
+
+#ifdef notdef
+static int file_out = FALSE;
+static int end_check;
+#endif
+static int add_cr = FALSE;
+static int del_cr = FALSE;
+
+/* function prototype */
+#ifdef ANSI_C_PROTOTYPE
+static void (*iconv) (register int c2,register int c1); /* s_iconv or oconv */
+static void (*oconv) (register int c2,register int c1); /* [ejs]_oconv */
+static int do_kconv(char *i, char *o, int siz, int out_code, int in_code);
+static void h_conv(register int c2,register int c1);
+static int push_hold_buf(int c2,int c1);
+static void s_iconv(register int c2,register int c1);
+static void e_oconv(register int c2,register int c1);
+static void s_oconv(register int c2,register int c1);
+static void j_oconv(register int c2,register int c1);
+static int fold(register int c2,register int c1);
+static int pre_convert(register int c1,register int c2);
+static int mime_begin();
+static int mime_getc();
+static int mime_ungetc(unsigned int c);
+static int mime_integrity(unsigned char *p);
+static int base64decode(int c);
+#else
+static void (*iconv) (); /* s_iconv or oconv */
+static void (*oconv) (); /* [ejs]_oconv */
+static int s_iconv ();
+static int e_oconv ();
+static int j_oconv ();
+static int s_oconv ();
+static int noconvert ();
+static int do_kconv();
+static void h_conv ();
+static int push_hold_buf ();
+#endif
+
+#ifdef notdef
+main (argc, argv)
+ int argc;
+ char **argv;
+{
+ register FILE *fin;
+ register char *cp;
+
+#ifdef EASYWIN /*Easy Win */
+ _BufferSize.y = 400;/*Set Scroll Buffer Size*/
+#endif
+#ifdef DEFAULT_CODE_JIS
+ oconv = j_oconv; /* DEFAULT Code is JIS */
+#endif
+#ifdef DEFAULT_CODE_SJIS
+ oconv = s_oconv; /* DEFAULT Code is S-JIS */
+#endif
+#ifdef DEFAULT_CODE_EUC
+ oconv = e_oconv; /* DEFAULT Code is EUC */
+#endif
+
+ for (argc--,argv++; (argc > 0) && **argv == '-'; argc--, argv++) {
+ cp = *argv;
+ 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
+ case 'v':
+ usage();
+ exit(1);
+ break;
+ /* Input code assumption */
+ case 'J': /* JIS input */
+ case 'E': /* AT&T EUC input */
+ input_f = JIS_INPUT;
+ continue;
+ case 'S': /* MS Kanji input */
+ input_f = SJIS_INPUT;
+ if(x0201_f==NO_X0201) x0201_f=TRUE;
+ continue;
+ case 'Z': /* Convert X0208 alphabet to asii */
+ /* bit:0 Convert X0208
+ bit:1 Convert Kankaku to one space
+ bit:2 Convert Kankaku to two spaces
+ */
+ if('9'>= *cp && *cp>='0')
+ alpha_f |= 1<<(*cp++ -'0');
+ else
+ alpha_f |= TRUE;
+ continue;
+ case 'x': /* Convert X0201 kana to X0208 or X0201 Conversion */
+ x0201_f = FALSE; /* No X0201->X0208 conversion */
+ /* accept X0201
+ ESC-(-I in JIS, EUC, MS Kanji
+ SI/SO in JIS, EUC, MS Kanji
+ SSO in EUC, JIS, not in MS Kanji
+ MS Kanji (0xa0-0xdf)
+ output X0201
+ ESC-(-I in JIS (0x20-0x5f)
+ SSO in EUC (0xa0-0xdf)
+ 0xa0-0xd in MS Kanji (0xa0-0xdf)
+ */
+ continue;
+ case 'X': /* Assume X0201 kana */
+ /* Default value is NO_X0201 for EUC/MS-Kanji mix */
+ x0201_f = TRUE;
+ continue;
+ case 'f': /* folding -f60 or -f */
+ fold_f = TRUE;
+ fold_len = atoi(cp);
+ if(!(0<fold_len && fold_len<BUFSIZ))
+ fold_len = DEFAULT_FOLD;
+ while('0'<= *cp && *cp <='9') cp++;
+ continue;
+ case 'm': /* MIME support */
+ mime_f = TRUE;
+ if(*cp=='B'||*cp=='Q') {
+ mime_mode = *cp++;
+ mimebuf_f = FIXED_MIME;
+ }
+ continue;
+ case 'B': /* Broken JIS support */
+ /* bit:0 no ESC JIS
+ bit:1 allow any x on ESC-(-x or ESC-$-x
+ bit:2 reset to ascii on NL
+ */
+ if('9'>= *cp && *cp>='0')
+ broken_f |= 1<<(*cp++ -'0');
+ else
+ broken_f |= TRUE;
+ continue;
+ case 'O':/* for Output file */
+ file_out = TRUE;
+ continue;
+ case 'c':/* add cr code */
+ add_cr = TRUE;
+ continue;
+ case 'd':/* delete cr code */
+ del_cr = TRUE;
+ continue;
+ default:
+ /* bogus option but ignored */
+ continue;
+ }
+ }
+ }
+
+ 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
+ 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
+ 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);
+}
+
+int
+noconvert (f)
+ register FILE *f;
+{
+ register int c;
+
+ while ((c = getc (f)) != EOF)
+ putchar (c);
+ return 1;
+}
+
+#endif /* notdef */
+
+static int
+do_kconv(i, o, siz, out_code, in_code)
+ char *i;
+ char *o;
+ int siz, out_code, in_code;
+{
+ register int c1,
+ c2;
+
+ c2 = 0;
+
+ if (siz <= 0) {
+ return 0;
+ }
+ *o = '\0';
+
+ inptr = (unsigned char *)i; /* input buffer */
+ outptr = o; /* output buffer */
+ outsiz = siz; /* output buffer size */
+ outlen = 0; /* current length of output string */
+ x0201_f = FALSE; /* don't assume JISX0201 kana */
+ rot_f = FALSE; /* rot14/43 mode */
+ input_f = FALSE; /* non fixed input code */
+ alpha_f = FALSE; /* convert JISX0208 alphbet to ASCII */
+ mime_f = TRUE; /* convert MIME base64 */
+ broken_f = FALSE; /* convert ESC-less broken JIS */
+
+ switch (out_code) {
+ case _SJIS:
+ oconv = s_oconv;
+ break;
+ case _EUC:
+ oconv = e_oconv;
+ break;
+ default:
+ oconv = j_oconv;
+ break;
+ }
+
+ switch (in_code) {
+ case _SJIS:
+ input_f = SJIS_INPUT;
+ x0201_f = TRUE;
+ break;
+ case _EUC:
+ case _JIS:
+ input_f = JIS_INPUT;
+ break;
+ default:
+ input_f = FALSE;
+ break;
+ }
+
+ 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;
+ mime_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()) != EOF) {
+ if(!c2 && !input_mode && c1<DEL && !mime_mode && !output_mode
+ && !shift_mode && !fold_f && !rot_f) {
+ /* plain ASCII tight loop, no conversion and no fold */
+ while(c1!='=' && c1!=SO && c1!=EOF &&
+ c1!=ESC && c1!='$' && c1<DEL && c1!='\r' && c1!='\n') {
+ PUTCHAR(c1);
+ c1 = _GETC();
+ }
+ if(c1==EOF) LAST;
+ }
+ 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 (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 <= SP)) {
+ /* 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()) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ LAST;
+ } else if(c2==(0xde)) { /* ÂùÅÀ */
+ (*oconv)(dv[(c1-SSP)*2],dv[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else if(c2==(0xdf)&&ev[(c1-SSP)*2]) {
+ /* ȾÂùÅÀ */
+ (*oconv)(ev[(c1-SSP)*2],ev[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ }
+ UNGETC(c2); 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(); /* skip SSO */
+ euc_1byte_check:
+ if(x0201_f && SSP<=c1 && c1<0xe0) {
+ if(dv[(c1-SSP)*2]||ev[(c1-SSP)*2]) {
+ if((c2 = GETC()) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ LAST;
+ }
+ /* forward lookup ÂùÅÀ/ȾÂùÅÀ */
+ if(c2 != SSO) {
+ UNGETC(c2); c2 = 0;
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ NEXT;
+ } else if((c2 = GETC()) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ (*oconv)(0,SSO);
+ LAST;
+ } else if(c2==(0xde)) { /* ÂùÅÀ */
+ (*oconv)(dv[(c1-SSP)*2],dv[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else if(c2==(0xdf)&&ev[(c1-SSP)*2]) {
+ /* ȾÂùÅÀ */
+ (*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 > SP) && (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()) == EOF) {
+ (*oconv)(cv[(c1-SSP)*2],cv[(c1-SSP)*2+1]);
+ LAST;
+ } else if(c2==(0xde&0x7f)) { /* ÂùÅÀ */
+ (*oconv)(dv[(c1-SSP)*2],dv[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ } else if(c2==(0xdf&0x7f)&&ev[(c1-SSP)*2]) {
+ /* ȾÂùÅÀ */
+ (*oconv)(ev[(c1-SSP)*2],ev[(c1-SSP)*2+1]);
+ c2=0;
+ NEXT;
+ }
+ UNGETC(c2); 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()) == 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()) == EOF) {
+ (*oconv) (0, '=');
+ LAST;
+ } else if(c1 == '?') {
+ /* =? is mime conversion start sequence */
+ if(mime_begin() == EOF) /* check in detail */
+ LAST;
+ else
+ NEXT;
+ } else {
+ (*oconv) (0, '=');
+ _UNGETC(c1);
+ NEXT;
+ }
+ } else if(c1 == '$' && broken_f && !mime_mode) {
+ /* try to recover missing escape */
+ if((c1 = GETC()) == 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()) == EOF) {
+ (*oconv) (0, ESC);
+ LAST;
+ } else if(c1 == '$') {
+ if((c1 = GETC()) == 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(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()) == 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);
+ return outlen;
+}
+
+
+static void
+h_conv (c2, c1)
+ register int c1,
+ c2;
+{
+ register 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()) != EOF) {
+ if(c2) {
+ /* second byte */
+ if(!estab_f) {
+ /* not established */
+ if(c1 > SSP) {
+ /* it is still ambiguious yet */
+ SEND;
+ } else if(c1 < AT) {
+ /* ignore bogus first byte */
+ c2 = 0;
+ SEND;
+ } else {
+ /* now established */
+ /* it seems to be MS Kanji */
+ estab_f = TRUE;
+ iconv = s_iconv;
+ SEND;
+ }
+ } else
+ SEND;
+ } else {
+ /* First byte */
+ if(c1 > DEL) {
+ /* 8th bit is on */
+ if(c1 < SSP) {
+ /* it seems to be MS Kanji */
+ estab_f = TRUE;
+ iconv = s_iconv;
+ } else if(c1 < 0xe0) {
+ /* it seems to be EUC */
+ estab_f = TRUE;
+ iconv = oconv;
+ } else {
+ /* still ambiguious */
+ }
+ c2 = c1;
+ NEXT;
+ } else
+ /* 7 bit code , then send without any process */
+ SEND;
+ }
+ /* send: */
+ if((push_hold_buf (c2, c1) == EOF) || estab_f)
+ break;
+ c2 = 0;
+ continue;
+ }
+
+ /** now,
+ ** 1) EOF is detected, or
+ ** 2) Code is established, or
+ ** 3) Buffer is FULL (but last word is pushed)
+ **
+ ** in 1) and 3) cases, we continue to use
+ ** Kanji codes by oconv and leave estab_f unchanged.
+ **/
+
+ for (wc = 0; wc < hold_count; wc += 2) {
+ c2 = hold_buf[wc];
+ c1 = hold_buf[wc+1];
+ (*iconv) (c2, c1);
+ }
+ return;
+}
+
+
+
+int
+push_hold_buf (c2, c1)
+ int c2,
+ c1;
+{
+ if(hold_count >= HOLD_SIZE*2)
+ return (EOF);
+ hold_buf[hold_count++] = c2;
+ hold_buf[hold_count++] = c1;
+ return ((hold_count >= HOLD_SIZE*2) ? EOF : hold_count);
+}
+
+
+static void
+s_iconv (c2, c1)
+ register int c2,
+ c1;
+{
+ if((c2 == EOF) || (c2 == 0)) {
+ /* NOP */
+ } else {
+ c2 = c2 + c2 - ((c2 <= 0x9f) ? SJ0162 : SJ6394);
+ if(c1 < 0x9f)
+ c1 = c1 - ((c1 > DEL) ? SP : 0x1f);
+ else {
+ c1 = c1 - 0x7e;
+ c2++;
+ }
+ }
+ (*oconv) (c2, c1);
+}
+
+
+static void
+e_oconv (c2, c1)
+ register int c2,
+ c1;
+{
+ c2 = pre_convert(c1,c2); c1 = c1_return;
+ if(fold_f) {
+ switch(fold(c2,c1)) {
+ case '\n':
+ if(add_cr == TRUE) {
+ PUTCHAR('\r');
+ c1 = '\n';
+ }
+ PUTCHAR('\n');
+ break;
+ case 0: return;
+ case '\r':
+ c1 = '\n'; c2 = 0;
+ break;
+ case '\t':
+ case ' ':
+ c1 = ' '; c2 = 0;
+ break;
+ }
+ }
+ if(c2==DOUBLE_SPACE) {
+ PUTCHAR(' '); PUTCHAR(' ');
+ return;
+ }
+ if(c2 == EOF)
+ return;
+ else if(c2 == 0 && (c1&0x80)) {
+ PUTCHAR(SSO); PUTCHAR(c1);
+ } else if(c2 == 0) {
+ if(c1 == '\n' && add_cr == TRUE)
+ PUTCHAR('\r');
+ if(c1 != '\r')
+ PUTCHAR(c1);
+ else if(del_cr == FALSE)
+ PUTCHAR(c1);
+ } else {
+ if((c1<0x20 || 0x7e<c1) ||
+ (c2<0x20 || 0x7e<c2)) {
+ estab_f = FALSE;
+ return; /* too late to rescue this char */
+ }
+ PUTCHAR(c2 | 0x080);
+ PUTCHAR(c1 | 0x080);
+ }
+}
+
+
+static void
+s_oconv (c2, c1)
+ register int c2,
+ c1;
+{
+ c2 = pre_convert(c1,c2); c1 = c1_return;
+ if(fold_f) {
+ switch(fold(c2,c1)) {
+ case '\n':
+ if(add_cr == TRUE) {
+ PUTCHAR('\r');
+ c1 = '\n';
+ }
+ PUTCHAR('\n');
+ break;
+ case '\r':
+ c1 = '\n'; c2 = 0;
+ break;
+ case 0: return;
+ case '\t':
+ case ' ':
+ c1 = ' '; c2 = 0;
+ break;
+ }
+ }
+ if(c2==DOUBLE_SPACE) {
+ PUTCHAR(' '); PUTCHAR(' ');
+ return;
+ }
+ if(c2 == EOF)
+ return;
+ else if(c2 == 0) {
+ if(c1 == '\n' && add_cr == TRUE)
+ PUTCHAR('\r');
+ if(c1 != '\r')
+ PUTCHAR(c1);
+ else if(del_cr == FALSE)
+ PUTCHAR(c1);
+ } else {
+ if((c1<0x20 || 0x7e<c1) ||
+ (c2<0x20 || 0x7e<c2)) {
+ estab_f = FALSE;
+ return; /* too late to rescue this char */
+ }
+ PUTCHAR((((c2 - 1) >> 1) + ((c2 <= 0x5e) ? 0x71 : 0xb1)));
+ PUTCHAR((c1 + ((c2 & 1) ? ((c1 < 0x60) ? 0x1f : 0x20) : 0x7e)));
+ }
+}
+
+static void
+j_oconv (c2, c1)
+ register int c2,
+ c1;
+{
+ c2 = pre_convert(c1,c2); c1 = c1_return;
+ if(fold_f) {
+ switch(fold(c2,c1)) {
+ case '\n':
+ if(output_mode) {
+ PUTCHAR(ESC);
+ PUTCHAR('(');
+ PUTCHAR(ascii_intro);
+ }
+ if(add_cr == TRUE) {
+ PUTCHAR('\r');
+ c1 = '\n';
+ }
+ PUTCHAR('\n');
+ output_mode = ASCII;
+ break;
+ case '\r':
+ c1 = '\n'; c2 = 0;
+ break;
+ case '\t':
+ case ' ':
+ c1 = ' '; c2 = 0;
+ break;
+ case 0: return;
+ }
+ }
+ if(c2 == EOF) {
+ if(output_mode) {
+ PUTCHAR(ESC);
+ PUTCHAR('(');
+ PUTCHAR(ascii_intro);
+ }
+ } else if(c2 == 0 && (c1 & 0x80)) {
+ if(input_mode==X0201 || !iso8859_f) {
+ if(output_mode!=X0201) {
+ PUTCHAR(ESC);
+ PUTCHAR('(');
+ PUTCHAR('I');
+ output_mode = X0201;
+ }
+ c1 &= 0x7f;
+ } else {
+ /* iso8859 introduction, or 8th bit on */
+ /* Can we convert in 7bit form using ESC-'-'-A ?
+ Is this popular? */
+ }
+ PUTCHAR(c1);
+ } else if(c2 == 0) {
+ if(output_mode) {
+ PUTCHAR(ESC);
+ PUTCHAR('(');
+ PUTCHAR(ascii_intro);
+ output_mode = ASCII;
+ }
+ if(c1 == '\n' && add_cr == TRUE)
+ PUTCHAR('\r');
+ if(c1 != '\r')
+ PUTCHAR(c1);
+ else if(del_cr == FALSE)
+ PUTCHAR(c1);
+ } else if(c2 == DOUBLE_SPACE) {
+ if(output_mode) {
+ PUTCHAR(ESC);
+ PUTCHAR('(');
+ PUTCHAR(ascii_intro);
+ output_mode = ASCII;
+ }
+ PUTCHAR(' ');
+ if(c1 == '\n' && add_cr == TRUE)
+ PUTCHAR('\r');
+ if(c1 != '\r')
+ PUTCHAR(c1);
+ else if(del_cr == FALSE)
+ PUTCHAR(c1);
+ } else {
+ if(output_mode != X0208) {
+ PUTCHAR(ESC);
+ PUTCHAR('$');
+ PUTCHAR(kanji_intro);
+ output_mode = X0208;
+ }
+ if(c1<0x20 || 0x7e<c1)
+ return;
+ if(c2<0x20 || 0x7e<c2)
+ return;
+ PUTCHAR(c2);
+ if(c1 == '\n' && add_cr == TRUE)
+ PUTCHAR('\r');
+ if(c1 != '\r')
+ PUTCHAR(c1);
+ else if(del_cr == FALSE)
+ PUTCHAR(c1);
+ }
+}
+
+
+#define rot13(c) ( \
+ ( c < 'A' ) ? c: \
+ (c <= 'M') ? (c + 13): \
+ (c <= 'Z') ? (c - 13): \
+ (c < 'a') ? (c): \
+ (c <= 'm') ? (c + 13): \
+ (c <= 'z') ? (c - 13): \
+ (c) \
+)
+
+#define rot47(c) ( \
+ ( c < '!' ) ? c: \
+ ( c <= 'O' ) ? (c + 47) : \
+ ( c <= '~' ) ? (c - 47) : \
+ c \
+)
+
+/*
+ Return value of fold()
+
+ \n add newline and output char
+ \r add newline and output nothing
+ ' ' space
+ 0 skip
+ 1 (or else) normal output
+
+ fold state in prev (previous character)
+
+ >0x80 Japanese (X0208/X0201)
+ <0x80 ASCII
+ \n new line
+ ' ' space
+
+ This fold algorthm does not preserve heading space in a line.
+ This is the main difference from fmt.
+*/
+
+int
+fold(c2,c1)
+register 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; /* ¡«*/
+ if(c1==0xdf) return 1; /* ¡¬*/
+ if(c1==0xa4) return 1; /* ¡£*/
+ if(c1==0xa3) return 1; /* ¡¤*/
+ if(c1==0xa1) return 1; /* ¡×*/
+ 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; /* ¡¢ */
+ if(c1=='#') return 1; /* ¡£ */
+ if(c1=='$') return 1; /* ¡¤ */
+ if(c1=='%') return 1; /* ¡¥ */
+ if(c1=='\'') return 1; /* ¡Ü */
+ if(c1=='(') return 1; /* ¡¨ */
+ if(c1==')') return 1; /* ¡© */
+ if(c1=='*') return 1; /* ¡ª */
+ if(c1=='+') return 1; /* ¡« */
+ if(c1==',') return 1; /* ¡¬ */
+ }
+ line = 2;
+ return '\n'; /* add one new line before this character */
+ }
+}
+
+int
+pre_convert(c1,c2)
+register int c1,c2;
+{
+ if(c2) c1 &= 0x7f;
+ c1_return = c1;
+ if(c2==EOF) return c2;
+ c2 &= 0x7f;
+ if(rot_f) {
+ if(c2) {
+ c1 = rot47(c1);
+ c2 = rot47(c2);
+ } else {
+ if(!(c1 & 0x80))
+ c1 = rot13(c1);
+ }
+ c1_return = c1;
+ }
+ /* JISX0208 Alphabet */
+ if(alpha_f && c2 == 0x23 ) return 0;
+ /* JISX0208 Kigou */
+ if(alpha_f && c2 == 0x21 ) {
+ if(0x21==c1) {
+ if(alpha_f&0x2) {
+ c1_return = ' ';
+ return 0;
+ } else if(alpha_f&0x4) {
+ c1_return = ' ';
+ return DOUBLE_SPACE;
+ } else {
+ return c2;
+ }
+ } else if(0x20<c1 && c1<0x7f && fv[c1-0x20]) {
+ c1_return = fv[c1-0x20];
+ return 0;
+ }
+ }
+ return c2;
+}
+
+
+/* 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
+} ;
+
+
+/* This converts =?ISO-2022-JP?B?HOGE HOGE?= */
+
+unsigned char *mime_pattern[] = {
+ (unsigned char *)"\075?ISO-8859-1?Q?",
+ (unsigned char *)"\075?ISO-2022-JP?B?",
+ (unsigned char *)"\075?ISO-2022-JP?Q?",
+ NULL
+};
+
+int mime_encode[] = {
+ 'Q', 'B', 'Q',
+ 0
+};
+
+int iso8859_f_save;
+
+#define nkf_toupper(c) (('a'<=c && c<='z')?(c-('a'-'A')):c)
+/* I don't trust portablity of toupper */
+
+int
+mime_begin()
+{
+ int c1;
+ int i,j,k;
+ unsigned char *p,*q;
+ int r[20]; /* recovery buffer, max mime pattern lenght */
+
+ mime_mode = FALSE;
+ /* =? has been checked */
+ j = 0;
+ p = mime_pattern[j];
+ r[0]='='; r[1]='?';
+
+ for(i=2;p[i]>' ';i++) { /* start at =? */
+ if( ((r[i] = c1 = _GETC())==EOF) || nkf_toupper(c1) != p[i] ) {
+ /* pattern fails, try next one */
+ q = p;
+ while (p = mime_pattern[++j]) {
+ for(k=2;k<i;k++) /* assume length(p) > i */
+ if(p[k]!=q[k]) break;
+ if(k==i && nkf_toupper(c1)==p[k]) break;
+ }
+ if(p) continue; /* found next one, continue */
+ /* all fails, output from recovery buffer */
+ _UNGETC(c1);
+ for(j=0;j<i;j++) {
+ (*oconv)(0,r[j]);
+ }
+ return c1;
+ }
+ }
+ iso8859_f_save = iso8859_f;
+ if(j==0) {
+ iso8859_f = TRUE;
+ }
+ mime_mode = mime_encode[j];
+ if(mime_mode=='B') {
+ mimebuf_f = unbuf_f;
+ if(!unbuf_f) {
+ /* do MIME integrity check */
+ return mime_integrity(mime_pattern[j]);
+ }
+ }
+ mimebuf_f = TRUE;
+ return c1;
+}
+
+#define mime_getc0() (mimebuf_f?_GETC():Fifo(mime_input++))
+#define mime_ungetc0(c) (mimebuf_f?_UNGETC(c):mime_input--)
+
+int
+mime_getc()
+{
+ int c1, c2, c3, c4, cc;
+ int t1, t2, t3, t4, mode, exit_mode;
+
+ if(mime_top != mime_last) { /* Something is in FIFO */
+ return Fifo(mime_top++);
+ }
+
+ if(mimebuf_f == FIXED_MIME)
+ exit_mode = mime_mode;
+ else
+ exit_mode = FALSE;
+ if(mime_mode == 'Q') {
+ if((c1 = mime_getc0()) == EOF) return (EOF);
+ if(c1=='_') return ' ';
+ if(c1!='=' && c1!='?')
+ return c1;
+ mime_mode = exit_mode; /* prepare for quit */
+ if(c1<=' ') return c1;
+ if((c2 = mime_getc0()) == EOF) return (EOF);
+ if(c2<=' ') return c2;
+ if(c1=='?'&&c2=='=') {
+ /* end Q encoding */
+ input_mode = exit_mode;
+ iso8859_f = iso8859_f_save;
+ return _GETC();
+ }
+ if(c1=='?') {
+ mime_mode = 'Q'; /* still in MIME */
+ mime_ungetc0(c2);
+ return c1;
+ }
+ if((c3 = mime_getc0()) == EOF) return (EOF);
+ if(c2<=' ') return c2;
+ mime_mode = 'Q'; /* still in MIME */
+#define hex(c) (('0'<=c&&c<='9')?(c-'0'):\
+ ('A'<=c&&c<='F')?(c-'A'+10):('a'<=c&&c<='f')?(c-'a'+10):0)
+ return ((hex(c2)<<4) + hex(c3));
+ }
+
+ if(mime_mode != 'B') {
+ mime_mode = FALSE;
+ return _GETC();
+ }
+
+
+ /* Base64 encoding */
+ /*
+ MIME allows line break in the middle of
+ Base64, but we are very pessimistic in decoding
+ in unbuf mode because MIME encoded code may broken by
+ less or editor's control sequence (such as ESC-[-K in unbuffered
+ mode. ignore incomplete MIME.
+ */
+ mode = mime_mode;
+ mime_mode = exit_mode; /* prepare for quit */
+
+ while ((c1 = mime_getc0())<=' ') {
+ if(c1==EOF)
+ return (EOF);
+ }
+ if((c2 = mime_getc0())<=' ') {
+ if(c2==EOF)
+ return (EOF);
+ if(mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c2;
+ }
+ if((c1 == '?') && (c2 == '=')) {
+ input_mode = ASCII;
+ while((c1 = _GETC())==' ' /* || c1=='\n' || c1=='\r' */);
+ return c1;
+ }
+ if((c3 = mime_getc0())<=' ') {
+ if(c3==EOF)
+ return (EOF);
+ if(mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c3;
+ }
+ if((c4 = mime_getc0())<=' ') {
+ if(c4==EOF)
+ return (EOF);
+ if(mimebuf_f!=FIXED_MIME) input_mode = ASCII;
+ return c4;
+ }
+
+ mime_mode = mode; /* still in MIME sigh... */
+
+ /* BASE 64 decoding */
+
+ t1 = 0x3f & base64decode(c1);
+ t2 = 0x3f & base64decode(c2);
+ t3 = 0x3f & base64decode(c3);
+ t4 = 0x3f & base64decode(c4);
+ cc = ((t1 << 2) & 0x0fc) | ((t2 >> 4) & 0x03);
+ if(c2 != '=') {
+ Fifo(mime_last++) = cc;
+ cc = ((t2 << 4) & 0x0f0) | ((t3 >> 2) & 0x0f);
+ if(c3 != '=') {
+ Fifo(mime_last++) = cc;
+ cc = ((t3 << 6) & 0x0c0) | (t4 & 0x3f);
+ if(c4 != '=')
+ Fifo(mime_last++) = cc;
+ }
+ } else {
+ return c1;
+ }
+ return Fifo(mime_top++);
+}
+
+int
+mime_ungetc(c)
+unsigned int c;
+{
+ Fifo(mime_last++) = c;
+ return c;
+}
+
+
+int
+mime_integrity(p)
+unsigned char *p;
+{
+ int c,d;
+ unsigned int q;
+ /* In buffered mode, read until =? or NL or buffer full
+ */
+ mime_input = mime_top;
+ mime_last = mime_top;
+ while(*p) Fifo(mime_input++) = *p++;
+ d = 0;
+ q = mime_input;
+ while((c=_GETC())!=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;
+}
+
+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);
+}
+
+#ifdef notdef
+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[BQ] MIME decode [B:base64 stream,Q:quoted stream]\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 /* notdef */
+
+#include "ruby.h"
+
+static VALUE
+kconv_kconv(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ struct RString *src, *dst;
+ VALUE in, out;
+ int in_code, out_code;
+
+ rb_scan_args(argc, argv, "12", &src, &out, &in);
+ Check_Type(src, T_STRING);
+
+ if (NIL_P(out)) {
+ out_code = _JIS;
+ }
+ else {
+ out_code = NUM2INT(out);
+ }
+ if (NIL_P(in)) {
+ in_code = _AUTO;
+ }
+ else {
+ in_code = NUM2INT(in);
+ }
+
+ dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
+ dst->len = do_kconv(src->ptr, dst->ptr, dst->len, out_code, in_code);
+
+ return (VALUE)dst;
+}
+
+static VALUE
+kconv_tojis(obj, src)
+ VALUE obj;
+ struct RString *src;
+{
+ struct RString *dst;
+
+ Check_Type(src, T_STRING);
+
+ dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
+ dst->len = do_kconv(src->ptr, dst->ptr, dst->len, _JIS, _AUTO);
+
+ return (VALUE)dst;
+}
+
+static VALUE
+kconv_toeuc(obj, src)
+ VALUE obj;
+ struct RString* src;
+{
+ struct RString *dst;
+
+ Check_Type(src, T_STRING);
+
+ dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
+ dst->len = do_kconv(src->ptr, dst->ptr, dst->len, _EUC, _AUTO);
+
+ return (VALUE)dst;
+}
+
+static VALUE
+kconv_tosjis(obj, src)
+ VALUE obj;
+ struct RString* src;
+{
+ struct RString *dst;
+
+ Check_Type(src, T_STRING);
+
+ dst = RSTRING(str_new(0, src->len*3+10)); /* large enough? */
+ dst->len = do_kconv(src->ptr, dst->ptr, dst->len, _SJIS, _AUTO);
+
+ return (VALUE)dst;
+}
+
+void
+Init_kconv()
+{
+ VALUE mKconv = rb_define_module("Kconv");
+
+ rb_define_module_function(mKconv, "kconv", kconv_kconv, -1);
+ rb_define_module_function(mKconv, "tojis", kconv_tojis, 1);
+ rb_define_module_function(mKconv, "toeuc", kconv_toeuc, 1);
+ rb_define_module_function(mKconv, "tosjis", kconv_tosjis, 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));
+}
+
+/**
+ ** ¥Ñ¥Ã¥ÁÀ©ºî¼Ô
+ ** void@merope.pleiades.or.jp (Kusakabe Youichi)
+ ** NIDE Naoyuki <nide@ics.nara-wu.ac.jp>
+ ** ohta@src.ricoh.co.jp (Junn Ohta)
+ ** inouet@strl.nhk.or.jp (Tomoyuki Inoue)
+ ** kiri@pulser.win.or.jp (Tetsuaki Kiriyama)
+ ** Kimihiko Sato <sato@sail.t.u-tokyo.ac.jp>
+ ** a_kuroe@kuroe.aoba.yokohama.jp (Akihiko Kuroe)
+ ** kono@ie.u-ryukyu.ac.jp (Shinji Kono)
+ ** GHG00637@nifty-serve.or.jp (COW)
+ ** j_kuro@pluto.ai.kyutech.ac.jp (Jun Kuroda)
+ **
+ ** ºÇ½ª¹¹¿·Æü
+ ** 1996.12.18
+ **/
+
+/* end */
diff --git a/ext/marshal/MANIFEST b/ext/marshal/MANIFEST
index 53b0849484..54870ec71f 100644
--- a/ext/marshal/MANIFEST
+++ b/ext/marshal/MANIFEST
@@ -1,4 +1,5 @@
MANIFEST
depend
+extconf.rb
marshal.c
marshal.doc
diff --git a/ext/marshal/extconf.rb b/ext/marshal/extconf.rb
new file mode 100644
index 0000000000..65923049e5
--- /dev/null
+++ b/ext/marshal/extconf.rb
@@ -0,0 +1,2 @@
+have_func("tmpnam")
+create_makefile("marshal")
diff --git a/ext/marshal/marshal.c b/ext/marshal/marshal.c
index 0b29ad5ab8..eae8d7fe09 100644
--- a/ext/marshal/marshal.c
+++ b/ext/marshal/marshal.c
@@ -13,24 +13,52 @@
#include "io.h"
#include "st.h"
+#define MARSHAL_MAJOR 2
+#define MARSHAL_MINOR 1
+
#define TYPE_NIL '0'
+#define TYPE_TRUE 'T'
+#define TYPE_FALSE 'F'
#define TYPE_FIXNUM 'i'
#define TYPE_OBJECT 'o'
-#define TYPE_LINK '@'
+#define TYPE_USERDEF 'u'
#define TYPE_FLOAT 'f'
#define TYPE_BIGNUM 'l'
#define TYPE_STRING '"'
+#define TYPE_STRING2 '\''
#define TYPE_REGEXP '/'
#define TYPE_ARRAY '['
+#define TYPE_ARRAY2 ']'
#define TYPE_HASH '{'
+#define TYPE_HASH2 '}'
#define TYPE_STRUCT 'S'
+#define TYPE_SYMBOL ':'
+#define TYPE_SYMLINK ';'
+
+VALUE cString;
+VALUE cArray;
+VALUE cHash;
+
char *rb_class2path();
VALUE rb_path2class();
static ID s_dump, s_load;
+#if (defined(linux) && defined(USE_DLN_A_OUT)) || !defined(HAVE_TMPNAM)
+#define tmpnam(s) ltmpnam(s)
+static char *
+tmpnam(s)
+ char *s;
+{
+ static int n = 0;
+
+ sprintf(s, "/tmp/rb-mrsr-%x%x", getpid(), n++);
+ return s;
+}
+#endif
+
#define w_byte(c, fp) putc((c), fp)
#define w_bytes(s, n, fp) (w_long((n), fp),fwrite(s, 1, n, fp))
@@ -66,70 +94,119 @@ w_float(d, fp)
}
static void
-w_symbol(id, fp)
+w_symbol(id, fp, table)
ID id;
FILE *fp;
+ st_table *table;
{
char *sym = rb_id2name(id);
+ int num;
- w_bytes(sym, strlen(sym), fp);
+ if (st_lookup(table, id, &num)) {
+ w_byte(TYPE_SYMLINK, fp);
+ w_long(num, fp);
+ }
+ else {
+ w_byte(TYPE_SYMBOL, fp);
+ w_bytes(sym, strlen(sym), fp);
+ st_insert(table, id, table->num_entries);
+ }
+}
+
+static void
+w_unique(s, fp, table)
+ char *s;
+ FILE *fp;
+ st_table *table;
+{
+ w_symbol(rb_intern(s), fp, table);
}
static void w_object();
extern VALUE cBignum, cStruct;
+struct each_arg {
+ FILE *fp;
+ VALUE limit;
+ st_table *table;
+};
+
static int
-hash_each(key, value, fp)
+hash_each(key, value, arg)
VALUE key, value;
- FILE *fp;
+ struct each_arg *arg;
{
- w_object(key, fp);
- w_object(value, fp);
+ w_object(key, arg->fp, arg->limit, arg->table);
+ w_object(value, arg->fp, arg->limit, arg->table);
return ST_CONTINUE;
}
static int
-obj_each(id, value, fp)
+obj_each(id, value, arg)
ID id;
VALUE value;
- FILE *fp;
+ struct each_arg *arg;
{
- w_symbol(id, fp);
- w_object(value, fp);
+ w_symbol(id, arg->fp, arg->table);
+ w_object(value, arg->fp, arg->limit, arg->table);
return ST_CONTINUE;
}
-struct st_table *new_idhash();
-
static void
-w_object(obj, fp, port, table)
- VALUE obj, port;
+w_object(obj, fp, limit, table)
+ VALUE obj;
FILE *fp;
+ int limit;
st_table *table;
{
+ struct each_arg arg;
+ int n;
+
+ if (limit == 0) {
+ Fail("exceed depth limit");
+ }
+ limit--;
+
+ arg.fp = fp;
+ arg.limit = limit;
+ arg.table = table;
+
if (obj == Qnil) {
w_byte(TYPE_NIL, fp);
}
- else if (FIXNUM_P(obj)) {
- w_byte(TYPE_FIXNUM, fp);
- w_long(FIX2INT(obj), fp);
+ else if (obj == TRUE) {
+ w_byte(TYPE_TRUE, fp);
+ }
+ else if (obj == FALSE) {
+ w_byte(TYPE_FALSE, fp);
}
- else if (st_lookup(table, obj, 0)) {
- w_byte(TYPE_LINK, fp);
- w_long(obj, fp);
+ else if (FIXNUM_P(obj)) {
+ if (sizeof(long) == 4) {
+ w_byte(TYPE_FIXNUM, fp);
+ w_long(FIX2INT(obj), fp);
+ }
}
else {
- st_insert(table, obj, 0);
+ if (rb_respond_to(obj, s_dump)) {
+ VALUE v;
+
+ w_byte(TYPE_USERDEF, fp);
+ w_unique(rb_class2path(CLASS_OF(obj)), fp, table);
+ 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, fp);
+ return;
+ }
switch (BUILTIN_TYPE(obj)) {
case T_FLOAT:
w_byte(TYPE_FLOAT, fp);
- w_long(obj, fp);
w_float(RFLOAT(obj)->value, fp);
- break;
+ return;
case T_BIGNUM:
w_byte(TYPE_BIGNUM, fp);
- w_long(obj, fp);
{
char sign = RBIGNUM(obj)->sign?'+':'-';
int len = RBIGNUM(obj)->len;
@@ -142,80 +219,92 @@ w_object(obj, fp, port, table)
d++;
}
}
- break;
+ return;
+ }
+ switch (BUILTIN_TYPE(obj)) {
case T_STRING:
- w_byte(TYPE_STRING, fp);
- w_long(obj, fp);
- w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, fp);
- break;
+ if (CLASS_OF(obj) == cString) {
+ w_byte(TYPE_STRING, fp);
+ w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, fp);
+ }
+ else {
+ w_byte(TYPE_STRING2, fp);
+ w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, fp);
+ w_unique(rb_class2path(CLASS_OF(obj)), fp, table);
+ }
+ return;
case T_REGEXP:
w_byte(TYPE_REGEXP, fp);
- w_long(obj, fp);
w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, fp);
w_byte(FL_TEST(obj, FL_USER1), fp);
- break;
+ return;
case T_ARRAY:
- w_byte(TYPE_ARRAY, fp);
- w_long(obj, fp);
+ if (CLASS_OF(obj) == cArray) w_byte(TYPE_ARRAY, fp);
+ else w_byte(TYPE_ARRAY2, fp);
{
int len = RARRAY(obj)->len;
VALUE *ptr = RARRAY(obj)->ptr;
w_long(len, fp);
while (len--) {
- w_object(*ptr, fp, port, table);
+ w_object(*ptr, fp, limit, table);
ptr++;
}
}
+ if (CLASS_OF(obj) != cArray) {
+ w_unique(rb_class2path(CLASS_OF(obj)), fp, table);
+ }
break;
case T_HASH:
+ if (CLASS_OF(obj) == cHash) w_byte(TYPE_HASH, fp);
+ else w_byte(TYPE_HASH2, fp);
w_byte(TYPE_HASH, fp);
- w_long(obj, fp);
w_long(RHASH(obj)->tbl->num_entries, fp);
- st_foreach(RHASH(obj)->tbl, hash_each, fp);
+ st_foreach(RHASH(obj)->tbl, hash_each, &arg);
+ if (CLASS_OF(obj) != cHash) {
+ w_unique(rb_class2path(CLASS_OF(obj)), fp, table);
+ }
break;
case T_STRUCT:
w_byte(TYPE_STRUCT, fp);
- w_long(obj, fp);
{
int len = RSTRUCT(obj)->len;
char *path = rb_class2path(CLASS_OF(obj));
VALUE mem;
int i;
- w_bytes(path, strlen(path), fp);
+ w_unique(path, fp, table);
w_long(len, fp);
mem = rb_ivar_get(CLASS_OF(obj), rb_intern("__member__"));
if (mem == Qnil) {
- Fail("non-initialized struct");
+ Fatal("non-initialized struct");
}
for (i=0; i<len; i++) {
- w_symbol(FIX2INT(RARRAY(mem)->ptr[i]), fp);
- w_object(RSTRUCT(obj)->ptr[i], fp, port, table);
+ w_symbol(FIX2INT(RARRAY(mem)->ptr[i]), fp, table);
+ w_object(RSTRUCT(obj)->ptr[i], fp, limit, table);
}
}
break;
case T_OBJECT:
w_byte(TYPE_OBJECT, fp);
- w_long(obj, fp);
{
VALUE class = CLASS_OF(obj);
- char *path = rb_class2path(class);
+ char *path;
- w_bytes(path, strlen(path), fp);
- if (rb_responds_to(obj, s_dump)) {
- w_long(-1, fp);
- rb_funcall(obj, s_dump, 1, port);
+ if (FL_TEST(class, FL_SINGLETON)) {
+ TypeError("singleton can't be dumped");
}
- else if (ROBJECT(obj)->iv_tbl) {
+ path = rb_class2path(class);
+ w_unique(path, fp, table);
+ if (ROBJECT(obj)->iv_tbl) {
w_long(ROBJECT(obj)->iv_tbl->num_entries, fp);
- st_foreach(ROBJECT(obj)->iv_tbl, obj_each, fp);
+ st_foreach(ROBJECT(obj)->iv_tbl, obj_each, &arg);
}
else {
w_long(0, fp);
@@ -224,59 +313,108 @@ w_object(obj, fp, port, table)
break;
default:
- Fail("can't dump %s", rb_class2name(CLASS_OF(obj)));
+ TypeError("can't dump %s", rb_class2name(CLASS_OF(obj)));
break;
}
}
}
+struct dump_arg {
+ VALUE obj;
+ FILE *fp;
+ int limit;
+ st_table *table;
+};
+
static VALUE
-marshal_dump(self, obj, port)
- VALUE self, obj, port;
+dump(arg)
+ struct dump_arg *arg;
+{
+ w_object(arg->obj, arg->fp, arg->limit, arg->table);
+}
+
+static VALUE
+dump_ensure(arg)
+ struct dump_arg *arg;
+{
+ st_free_table(arg->table);
+}
+
+static VALUE
+dump_on(obj, port, limit)
+ VALUE obj, port;
+ int limit;
{
extern VALUE cIO;
FILE *fp;
OpenFile *fptr;
- st_table *table;
+ struct dump_arg arg;
if (obj_is_kind_of(port, cIO)) {
GetOpenFile(port, fptr);
- if (!(fptr->mode & FMODE_WRITABLE)) {
- Fail("not opened for writing");
- }
+ io_writable(fptr);
fp = (fptr->f2) ? fptr->f2 : fptr->f;
}
else {
- Fail("instance of IO needed");
+ TypeError("instance of IO needed");
}
- table = new_idhash();
+ w_byte(MARSHAL_MAJOR, fp);
+ w_byte(MARSHAL_MINOR, fp);
- w_object(obj, fp, port, table);
+ arg.obj = obj;
+ arg.fp = fp;
+ arg.limit = limit;
+ arg.table = st_init_numtable();
+ rb_ensure(dump, &arg, dump_ensure, &arg);
- st_free_table(table);
return Qnil;
}
static VALUE
-marshal_dumps(self, obj)
- VALUE self, obj;
+marshal_dump(argc, argv)
+ int argc;
+ VALUE argv;
+{
+ VALUE obj, port, lim;
+ int limit;
+
+ rb_scan_args(argc, argv, "21", &obj, &port, &lim);
+ if (NIL_P(lim)) limit = 100;
+ else limit = NUM2INT(lim);
+
+ dump_on(obj, port, limit);
+}
+
+static VALUE
+marshal_dumps(argc, argv)
+ int argc;
+ VALUE argv;
{
+ VALUE obj, lim;
+ int limit;
VALUE str = str_new(0, 0);
VALUE port;
- FILE *fp = Qnil;
+ FILE *fp = 0;
char buf[BUFSIZ];
int n;
- sprintf(buf, "/tmp/rb-mrsr-%x", getpid()^(int)buf);
+ rb_scan_args(argc, argv, "11", &obj, &lim);
+ if (NIL_P(lim)) limit = 100;
+ else limit = NUM2INT(lim);
+
+ tmpnam(buf);
port = file_open(buf, "w");
- if (!port) rb_sys_fail("tmp file");
- fp = fopen(buf, "r");
- if (!fp) rb_sys_fail("tmp file(read)");
+ fp = rb_fopen(buf, "r");
+#if !defined(MSDOS) && !defined(__BOW__)
unlink(buf);
+#endif
- marshal_dump(self, obj, port);
+ dump_on(obj, port, limit);
io_close(port);
+#if defined(MSDOS) || defined(__BOW__)
+ unlink(buf);
+#endif
while (n = fread(buf, 1, BUFSIZ, fp)) {
str_cat(str, buf, n);
@@ -310,67 +448,96 @@ r_long(fp)
/* XXX If your long is > 32 bits, add sign-extension here!!! */
return x;
}
-#define r_bytes(s, fp) r_bytes0(&s, fp)
-static int
-r_bytes0(s, fp)
- char **s;
+
+#define r_bytes(s, fp) \
+ (s = (char*)r_long(fp), r_bytes0(&s,ALLOCA_N(char,(int)s),(int)s,fp))
+
+static char
+r_bytes0(sp, s, len, fp)
+ char **sp, *s;
+ int len;
FILE *fp;
{
- int len = r_long(fp);
- *s = ALLOC_N(char, len+1);
+ fread(s, 1, len, fp);
+ (s)[len] = '\0';
+ *sp = s;
- fread(*s, 1, len, fp);
- (*s)[len] = '\0';
return len;
}
static ID
-r_symbol(fp)
+r_symbol(fp, table)
FILE *fp;
+ st_table *table;
{
char *buf;
ID id;
+ char type;
+ if (r_byte(fp) == TYPE_SYMLINK) {
+ int num = r_long(fp);
+
+ if (st_lookup(table, num, &id)) {
+ return id;
+ }
+ TypeError("bad symbol");
+ }
r_bytes(buf, fp);
id = rb_intern(buf);
- free(buf);
+ st_insert(table, table->num_entries, id);
+
return id;
}
+static char*
+r_unique(fp, table)
+ FILE *fp;
+ st_table *table;
+{
+ return rb_id2name(r_symbol(fp, table));
+}
+
static VALUE
-r_object(fp, port, table)
+r_string(fp)
+ FILE *fp;
+{
+ char *buf;
+ int len = r_bytes(buf, fp);
+ VALUE v;
+
+ v = str_new(buf, len);
+
+ return v;
+}
+
+static VALUE
+r_object(fp, table)
FILE *fp;
- VALUE port;
st_table *table;
{
VALUE v;
int type = r_byte(fp);
- int id;
switch (type) {
case EOF:
- Fail("EOF read where object expected");
+ eof_error("EOF read where object expected");
return Qnil;
case TYPE_NIL:
return Qnil;
- case TYPE_LINK:
- if (st_lookup(table, r_long(fp), &v)) {
- return v;
- }
- Fail("corrupted marshal file");
- break;
+ case TYPE_TRUE:
+ return TRUE;
+
+ case TYPE_FALSE:
+ return FALSE;
case TYPE_FIXNUM:
{
int i = r_long(fp);
return INT2FIX(i);
}
- }
- id = r_long(fp);
- switch (type) {
case TYPE_FLOAT:
{
double atof();
@@ -378,9 +545,8 @@ r_object(fp, port, table)
r_bytes(buf, fp);
v = float_new(atof(buf));
- free(buf);
+ return v;
}
- break;
case TYPE_BIGNUM:
{
@@ -395,18 +561,16 @@ r_object(fp, port, table)
while (len--) {
*digits++ = r_short(fp);
}
- v = (VALUE)big;
+ return (VALUE)big;
}
- break;
case TYPE_STRING:
- {
- char *buf;
- int len = r_bytes(buf, fp);
- v = str_new(buf, len);
- free(buf);
- }
- break;
+ return r_string(fp);
+
+ case TYPE_STRING2:
+ v = r_string(fp);
+ RBASIC(v)->class = rb_path2class(r_unique(fp, table));
+ return v;
case TYPE_REGEXP:
{
@@ -414,19 +578,18 @@ r_object(fp, port, table)
int len = r_bytes(buf, fp);
int ci = r_byte(fp);
v = reg_new(buf, len, ci);
- free(buf);
+ return v;
}
- break;
case TYPE_ARRAY:
{
int len = r_long(fp);
v = ary_new2(len);
while (len--) {
- ary_push(v, r_object(fp, port, table));
+ ary_push(v, r_object(fp, table));
}
+ return v;
}
- break;
case TYPE_HASH:
{
@@ -434,120 +597,150 @@ r_object(fp, port, table)
v = hash_new();
while (len--) {
- VALUE key = r_object(fp, port, table);
- VALUE value = r_object(fp, port, table);
+ VALUE key = r_object(fp, table);
+ VALUE value = r_object(fp, table);
hash_aset(v, key, value);
}
+ return v;
}
- break;
case TYPE_STRUCT:
{
VALUE class, mem, values;
- char *path;
int i, len;
- r_bytes(path, fp);
- class = rb_path2class(path);
- free(path);
+ class = rb_path2class(r_unique(fp, table));
mem = rb_ivar_get(class, rb_intern("__member__"));
if (mem == Qnil) {
- Fail("non-initialized struct");
+ Fatal("non-initialized struct");
}
len = r_long(fp);
- values = ary_new();
+ values = ary_new2(len);
i = 0;
- while (len--) {
- ID slot = r_symbol(fp);
- if (RARRAY(mem)->ptr[i++] != INT2FIX(slot))
- Fail("struct not compatible");
- ary_push(values, r_object(fp, port, table));
+ for (i=0; i<len; i++) {
+ ID slot = r_symbol(fp, table);
+ if (RARRAY(mem)->ptr[i] != INT2FIX(slot))
+ TypeError("struct not compatible");
+ ary_push(values, r_object(fp, table));
}
v = struct_alloc(class, values);
}
break;
+ case TYPE_USERDEF:
+ {
+ VALUE class;
+ int len;
+
+ class = rb_path2class(r_unique(fp, table));
+ if (rb_respond_to(class, s_load)) {
+ v = rb_funcall(class, s_load, 1, r_string(fp));
+ }
+ else {
+ TypeError("class %s needs to have method `_load_from'",
+ rb_class2name(class));
+ }
+ }
+ break;
case TYPE_OBJECT:
{
VALUE class;
int len;
- char *path;
- r_bytes(path, fp);
- class = rb_path2class(path);
- free(path);
+ class = rb_path2class(r_unique(fp, table));
len = r_long(fp);
- if (len == -1) {
- if (rb_responds_to(class, s_load)) {
- v = rb_funcall(class, s_load, 1, port);
- }
- else {
- Fail("class %s needs to have method `_load_from'",
- rb_class2name(class));
- }
- }
- else {
- v = obj_alloc(class);
- if (len > 0) {
- while (len--) {
- ID id = r_symbol(fp);
- VALUE val = r_object(fp, port, table);
- rb_ivar_set(v, id, val);
- }
+ v = obj_alloc(class);
+ if (len > 0) {
+ while (len--) {
+ ID id = r_symbol(fp, table);
+ VALUE val = r_object(fp, table);
+ rb_ivar_set(v, id, val);
}
}
}
break;
default:
- Fail("dump format error(0x%x)", type);
+ ArgError("dump format error(0x%x)", type);
break;
}
- st_insert(table, id, v);
return v;
}
+struct load_arg {
+ FILE *fp;
+ st_table *table;
+};
+
+static VALUE
+load(arg)
+ struct load_arg *arg;
+{
+ return r_object(arg->fp, arg->table);
+}
+
+static VALUE
+load_ensure(arg)
+ struct load_arg *arg;
+{
+ st_free_table(arg->table);
+}
+
static VALUE
marshal_load(self, port)
VALUE self, port;
{
extern VALUE cIO;
- void *fp;
+ FILE *fp;
+ int major;
VALUE v;
OpenFile *fptr;
- st_table *table;
+ char buf[32];
+#if defined(MSDOS) || defined(__BOW__)
+ int need_unlink_tmp = 0;
+#endif
+ struct load_arg arg;
if (TYPE(port) == T_STRING) {
- char buf[32];
-
- sprintf(buf, "/tmp/rb-mrsw-%x", getpid()^(int)buf);
- fp = fopen(buf, "w");
- if (!fp) rb_sys_fail("tmp file");
+ tmpnam(buf);
+ fp = rb_fopen(buf, "w");
v = file_open(buf, "r");
- if (!v) rb_sys_fail("tmp file(read)");
+#if defined(MSDOS) || defined(__BOW__)
+ need_unlink_tmp = 0;
+#else
unlink(buf);
+#endif
fwrite(RSTRING(port)->ptr, RSTRING(port)->len, 1, fp);
fclose(fp);
port = v;
}
+
if (obj_is_kind_of(port, cIO)) {
GetOpenFile(port, fptr);
- if (!(fptr->mode & FMODE_READABLE)) {
- Fail("not opened for reading");
- }
+ io_readable(fptr);
fp = fptr->f;
}
else {
- Fail("instance of IO needed");
+ TypeError("instance of IO needed");
}
- table = new_idhash();
-
- v = r_object(fp, port, table);
-
- st_free_table(table);
+ major = r_byte(fp);
+ if (major == MARSHAL_MAJOR) {
+ if (r_byte(fp) != MARSHAL_MINOR) {
+ Warning("Old marshal file format (can be read)");
+ }
+ arg.fp = fp;
+ arg.table = st_init_numtable();
+ v = rb_ensure(load, &arg, load_ensure, &arg);
+ }
+#if defined(MSDOS) || defined(__BOW__)
+ if (need_unlink_tmp) unlink(buf);
+#endif
+ if (major != MARSHAL_MAJOR) {
+ TypeError("Old marshal file format (can't read)");
+ }
return v;
}
@@ -558,8 +751,8 @@ Init_marshal()
s_dump = rb_intern("_dump_to");
s_load = rb_intern("_load_from");
- rb_define_module_function(mMarshal, "dump", marshal_dump, 2);
- rb_define_module_function(mMarshal, "dumps", marshal_dumps, 1);
+ rb_define_module_function(mMarshal, "dump", marshal_dump, -1);
+ rb_define_module_function(mMarshal, "dumps", marshal_dumps, -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
index 8c3b63072e..7529e7942f 100644
--- a/ext/marshal/marshal.doc
+++ b/ext/marshal/marshal.doc
@@ -10,7 +10,7 @@ ruby¥ª¥Ö¥¸¥§¥¯¥È¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤·¤¿¤ê¡¤ÆÉ¤ß¤âÅÙ¤·¤¿¤ê¤¹¤ëµ¡Ç½¤òÄó¶¡
Methods:
Single Methods:
- dump(obj, port)
+ dump(obj, port[, limit])
obj¤òºÆµ¢Åª¤Ë¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤¹¡¥¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤»¤Ê¤¤¥¯¥é¥¹¤Î¥¤
¥ó¥¹¥¿¥ó¥¹¤ò¥Õ¥¡¥¤¥ë¤Ë½ñ¤­½Ð¤½¤¦¤È¤¹¤ë¤ÈÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥¥Õ¥¡¥¤¥ë
@@ -28,6 +28,9 @@ Single Methods:
`_dump_to'¤ò»ý¤Ä¥¯¥é¥¹¤Ïɬ¤ºÆ±¤¸¥Õ¥©¡¼¥Þ¥Ã¥È¤òÆÉ¤ßÌ᤹ÆÃ°Û¥á¥½¥Ã¥É
`_load_from'¤òÄêµÁ¤¹¤ëɬÍפ¬¤¢¤ë¡¥
+ limit¤ò»ØÄꤷ¤¿¾ì¹ç¡¤limitÃʰʾ忼¤¯¥ê¥ó¥¯¤·¤¿¥ª¥Ö¥¸¥§¥¯¥È¤ò¥À¥ó¥×
+ ¤Ç¤­¤Ê¤¤(¥Ç¥Õ¥©¥ë¥È¤Ï100¥ì¥Ù¥ë)¡£Éé¤Îlimit¤ò»ØÄꤹ¤ë¤È¿¼¤µ¥Á¥§¥Ã¥¯
+ ¤ò¹Ô¤ï¤Ê¤¤¡£
dumps(obj)
diff --git a/ext/md5/MANIFEST b/ext/md5/MANIFEST
new file mode 100644
index 0000000000..e4f0004b4a
--- /dev/null
+++ b/ext/md5/MANIFEST
@@ -0,0 +1,6 @@
+MANIFEST
+depend
+md5.doc
+md5.h
+md5c.c
+md5init.c
diff --git a/ext/md5/depend b/ext/md5/depend
new file mode 100644
index 0000000000..be56da89b9
--- /dev/null
+++ b/ext/md5/depend
@@ -0,0 +1,2 @@
+md5c.o: md5c.c md5.h
+md5init.o: md5init.c ../../ruby.h ../../config.h ../../defines.h md5.h
diff --git a/ext/md5/md5.doc b/ext/md5/md5.doc
new file mode 100644
index 0000000000..2203404602
--- /dev/null
+++ b/ext/md5/md5.doc
@@ -0,0 +1,36 @@
+.\" md5.doc - -*- Indented-Text -*- created at: Fri Aug 2 12:01:27 JST 1996
+
+** MD5(¥¯¥é¥¹)
+
+RFC1321¤Ëµ­½Ò¤µ¤ì¤Æ¤¤¤ëRSA Data Security, Inc. ¤Î MD5 Message-Digest
+Algorithm¤ò¼ÂÁõ¤¹¤ë¥¯¥é¥¹¡¥
+
+SuperClass: Object
+
+Class Methods:
+
+ new([str])
+ md5([str])
+
+ ¿·¤·¤¤MD5¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤¹¤ë¡¥Ê¸»úÎó°ú¿ô¤¬Í¿¤¨¤é¤ì¤ë¤È¤½¤ì
+ ¤òÄɲ乤ë(see update)¡¥
+
+Methods:
+
+ clone
+
+ MD5¥ª¥Ö¥¸¥§¥¯¥È¤ÎÊ£À½¤òºî¤ë
+
+ digest
+
+ º£¤Þ¤Ç¤ËÄɲä·¤¿Ê¸»úÎó¤ËÂФ¹¤ë¥Ï¥Ã¥·¥åÃͤò16¥Ð¥¤¥ÈŤÎʸ»úÎó¤Ç
+ ÊÖ¤¹¡¥
+
+ update(str)
+
+ key¤ò¥­¡¼¤È¤¹¤ëÃͤòÊÖ¤¹¡¥
+
+-------------------------------------------------------
+Local variables:
+fill-column: 70
+end:
diff --git a/ext/md5/md5.h b/ext/md5/md5.h
new file mode 100644
index 0000000000..81a6d7ff36
--- /dev/null
+++ b/ext/md5/md5.h
@@ -0,0 +1,86 @@
+/* MD5.H - header file for MD5C.C
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+/* ========== include global.h ========== */
+/* GLOBAL.H - RSAREF types and constants
+ */
+
+/* PROTOTYPES should be set to one if and only if the compiler supports
+ function argument prototyping.
+The following makes PROTOTYPES default to 0 if it has not already
+ been defined with C compiler flags.
+ */
+#ifdef HAVE_PROTOTYPES
+#define PROTOTYPES 1
+#endif
+#ifndef PROTOTYPES
+#define PROTOTYPES 0
+#endif
+
+/* POINTER defines a generic pointer type */
+typedef unsigned char *POINTER;
+
+/* UINT2 defines a two byte word */
+typedef unsigned short int UINT2;
+
+#ifdef HAVE_LIMITS_H
+#include <limits.h>
+#else
+/* Wild guess */
+#define LONG_MAX 2147483647L
+#endif
+
+/* UINT4 defines a four byte word */
+#if defined(INT_MAX) && INT_MAX == 2147483647
+typedef unsigned int UINT4;
+#else
+#if defined(LONG_MAX) && LONG_MAX == 2147483647L
+typedef unsigned long int UINT4;
+#endif
+/* Too bad if neither is */
+#endif
+
+/* PROTO_LIST is defined depending on how PROTOTYPES is defined above.
+If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it
+ returns an empty list.
+ */
+#if PROTOTYPES
+#define PROTO_LIST(list) list
+#else
+#define PROTO_LIST(list) ()
+#endif
+/* ========== End global.h; continue md5.h ========== */
+
+/* MD5 context. */
+typedef struct {
+ UINT4 state[4]; /* state (ABCD) */
+ UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
+ unsigned char buffer[64]; /* input buffer */
+} MD5_CTX;
+
+void MD5Init PROTO_LIST ((MD5_CTX *));
+void MD5Update PROTO_LIST
+ ((MD5_CTX *, unsigned char *, unsigned int));
+void MD5Final PROTO_LIST ((unsigned char [16], MD5_CTX *));
diff --git a/ext/md5/md5c.c b/ext/md5/md5c.c
new file mode 100644
index 0000000000..d7c7e4fb27
--- /dev/null
+++ b/ext/md5/md5c.c
@@ -0,0 +1,337 @@
+/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm
+ */
+
+/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
+rights reserved.
+
+License to copy and use this software is granted provided that it
+is identified as the "RSA Data Security, Inc. MD5 Message-Digest
+Algorithm" in all material mentioning or referencing this software
+or this function.
+
+License is also granted to make and use derivative works provided
+that such works are identified as "derived from the RSA Data
+Security, Inc. MD5 Message-Digest Algorithm" in all material
+mentioning or referencing the derived work.
+
+RSA Data Security, Inc. makes no representations concerning either
+the merchantability of this software or the suitability of this
+software for any particular purpose. It is provided "as is"
+without express or implied warranty of any kind.
+
+These notices must be retained in any copies of any part of this
+documentation and/or software.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+#include "md5.h"
+
+/* Constants for MD5Transform routine.
+ */
+
+#define S11 7
+#define S12 12
+#define S13 17
+#define S14 22
+#define S21 5
+#define S22 9
+#define S23 14
+#define S24 20
+#define S31 4
+#define S32 11
+#define S33 16
+#define S34 23
+#define S41 6
+#define S42 10
+#define S43 15
+#define S44 21
+
+static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64]));
+static void Encode PROTO_LIST
+ ((unsigned char *, UINT4 *, unsigned int));
+static void Decode PROTO_LIST
+ ((UINT4 *, unsigned char *, unsigned int));
+static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int));
+static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int));
+
+static unsigned char PADDING[64] = {
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+/* F, G, H and I are basic MD5 functions.
+ */
+#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
+#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
+#define H(x, y, z) ((x) ^ (y) ^ (z))
+#define I(x, y, z) ((y) ^ ((x) | (~z)))
+
+/* ROTATE_LEFT rotates x left n bits.
+ */
+#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
+
+/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
+Rotation is separate from addition to prevent recomputation.
+ */
+#define FF(a, b, c, d, x, s, ac) { \
+ (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define GG(a, b, c, d, x, s, ac) { \
+ (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define HH(a, b, c, d, x, s, ac) { \
+ (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+#define II(a, b, c, d, x, s, ac) { \
+ (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
+ (a) = ROTATE_LEFT ((a), (s)); \
+ (a) += (b); \
+ }
+
+/* MD5 initialization. Begins an MD5 operation, writing a new context.
+ */
+void MD5Init (context)
+MD5_CTX *context; /* context */
+{
+ context->count[0] = context->count[1] = 0;
+ /* Load magic initialization constants.
+*/
+ context->state[0] = 0x67452301;
+ context->state[1] = 0xefcdab89;
+ context->state[2] = 0x98badcfe;
+ context->state[3] = 0x10325476;
+}
+
+/* MD5 block update operation. Continues an MD5 message-digest
+ operation, processing another message block, and updating the
+ context.
+ */
+void MD5Update (context, input, inputLen)
+MD5_CTX *context; /* context */
+unsigned char *input; /* input block */
+unsigned int inputLen; /* length of input block */
+{
+ unsigned int i, index, partLen;
+
+ /* Compute number of bytes mod 64 */
+ index = (unsigned int)((context->count[0] >> 3) & 0x3F);
+
+ /* Update number of bits */
+ if ((context->count[0] += ((UINT4)inputLen << 3))
+ < ((UINT4)inputLen << 3))
+ context->count[1]++;
+ context->count[1] += ((UINT4)inputLen >> 29);
+
+ partLen = 64 - index;
+
+ /* Transform as many times as possible.
+*/
+ if (inputLen >= partLen) {
+ MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)input, partLen);
+ MD5Transform (context->state, context->buffer);
+
+ for (i = partLen; i + 63 < inputLen; i += 64)
+ MD5Transform (context->state, &input[i]);
+
+ index = 0;
+ }
+ else
+ i = 0;
+
+ /* Buffer remaining input */
+ MD5_memcpy
+ ((POINTER)&context->buffer[index], (POINTER)&input[i],
+ inputLen-i);
+}
+
+/* MD5 finalization. Ends an MD5 message-digest operation, writing the
+ the message digest and zeroizing the context.
+ */
+void MD5Final (digest, context)
+unsigned char digest[16]; /* message digest */
+MD5_CTX *context; /* context */
+{
+ unsigned char bits[8];
+ unsigned int index, padLen;
+
+ /* Save number of bits */
+ Encode (bits, context->count, 8);
+
+ /* Pad out to 56 mod 64.
+*/
+ index = (unsigned int)((context->count[0] >> 3) & 0x3f);
+ padLen = (index < 56) ? (56 - index) : (120 - index);
+ MD5Update (context, PADDING, padLen);
+
+ /* Append length (before padding) */
+ MD5Update (context, bits, 8);
+
+ /* Store state in digest */
+ Encode (digest, context->state, 16);
+
+ /* Zeroize sensitive information.
+*/
+ MD5_memset ((POINTER)context, 0, sizeof (*context));
+}
+
+/* MD5 basic transformation. Transforms state based on block.
+ */
+static void MD5Transform (state, block)
+UINT4 state[4];
+unsigned char block[64];
+{
+ UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
+
+ Decode (x, block, 64);
+
+ /* Round 1 */
+ FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
+ FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
+ FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
+ FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
+ FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
+ FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
+ FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
+ FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
+ FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
+ FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
+ FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
+ FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
+ FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
+ FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
+ FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
+ FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
+
+ /* Round 2 */
+ GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
+ GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
+ GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
+ GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
+ GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
+ GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
+ GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
+ GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
+ GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
+ GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
+ GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
+ GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
+ GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
+ GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
+ GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
+ GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
+
+ /* Round 3 */
+ HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
+ HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
+ HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
+ HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
+ HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
+ HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
+ HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
+ HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
+ HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
+ HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
+ HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
+ HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
+ HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
+ HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
+ HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
+ HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
+
+ /* Round 4 */
+ II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
+ II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
+ II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
+ II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
+ II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
+ II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
+ II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
+ II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
+ II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
+ II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
+ II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
+ II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
+ II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
+ II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
+ II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
+ II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
+
+ state[0] += a;
+ state[1] += b;
+ state[2] += c;
+ state[3] += d;
+
+ /* Zeroize sensitive information.
+*/
+ MD5_memset ((POINTER)x, 0, sizeof (x));
+}
+
+/* Encodes input (UINT4) into output (unsigned char). Assumes len is
+ a multiple of 4.
+ */
+static void Encode (output, input, len)
+unsigned char *output;
+UINT4 *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4) {
+ output[j] = (unsigned char)(input[i] & 0xff);
+ output[j+1] = (unsigned char)((input[i] >> 8) & 0xff);
+ output[j+2] = (unsigned char)((input[i] >> 16) & 0xff);
+ output[j+3] = (unsigned char)((input[i] >> 24) & 0xff);
+ }
+}
+
+/* Decodes input (unsigned char) into output (UINT4). Assumes len is
+ a multiple of 4.
+ */
+static void Decode (output, input, len)
+UINT4 *output;
+unsigned char *input;
+unsigned int len;
+{
+ unsigned int i, j;
+
+ for (i = 0, j = 0; j < len; i++, j += 4)
+ output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
+ (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
+}
+
+/* Note: Replace "for loop" with standard memcpy if possible.
+ */
+
+static void MD5_memcpy (output, input, len)
+POINTER output;
+POINTER input;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ output[i] = input[i];
+}
+
+/* Note: Replace "for loop" with standard memset if possible.
+ */
+static void MD5_memset (output, value, len)
+POINTER output;
+int value;
+unsigned int len;
+{
+ unsigned int i;
+
+ for (i = 0; i < len; i++)
+ ((char *)output)[i] = (char)value;
+}
diff --git a/ext/md5/md5init.c b/ext/md5/md5init.c
new file mode 100644
index 0000000000..85f0847e71
--- /dev/null
+++ b/ext/md5/md5init.c
@@ -0,0 +1,90 @@
+/************************************************
+
+ md5init.c -
+
+ $Author: matz $
+ created at: Fri Aug 2 09:24:12 JST 1996
+
+ Copyright (C) 1995 Yukihiro Matsumoto
+
+************************************************/
+/* This module provides an interface to the RSA Data Security,
+ Inc. MD5 Message-Digest Algorithm, described in RFC 1321.
+ It requires the files md5c.c and md5.h (which are slightly changed
+ from the versions in the RFC to avoid the "global.h" file.) */
+
+#include "ruby.h"
+#include "md5.h"
+
+static VALUE cMD5;
+
+static VALUE
+md5_update(obj, str)
+ VALUE obj;
+ struct RString *str;
+{
+ MD5_CTX *md5;
+
+ Check_Type(str, T_STRING);
+ Get_Data_Struct(obj, MD5_CTX, md5);
+ MD5Update(md5, str->ptr, str->len);
+
+ return Qnil;
+}
+static VALUE
+md5_digest(obj)
+ VALUE obj;
+{
+ MD5_CTX *md5, ctx;
+ unsigned char digest[16];
+
+ Get_Data_Struct(obj, MD5_CTX, md5);
+ ctx = *md5;
+ MD5Final(digest, &ctx);
+
+ return str_new(digest, 16);
+}
+
+static VALUE
+md5_clone(obj)
+ VALUE obj;
+{
+ VALUE clone;
+ MD5_CTX *md5, *md5_new;
+
+ Get_Data_Struct(obj, MD5_CTX, md5);
+ obj = Make_Data_Struct(CLASS_OF(obj), MD5_CTX, 0, 0, md5_new);
+ *md5_new = *md5;
+
+ return obj;
+}
+
+static VALUE
+md5_new(argc, argv, class)
+{
+ int i;
+ VALUE arg, obj;
+ MD5_CTX *md5;
+
+ rb_scan_args(argc, argv, "01", &arg);
+ if (!NIL_P(arg)) Check_Type(arg, T_STRING);
+
+ obj = Make_Data_Struct(class, MD5_CTX, 0, 0, md5);
+ MD5Init(md5);
+ if (!NIL_P(arg)) {
+ md5_update(obj, arg);
+ }
+
+ return obj;
+}
+
+Init_md5()
+{
+ cMD5 = rb_define_class("MD5", cObject);
+
+ rb_define_singleton_method(cMD5, "new", md5_new, -1);
+
+ rb_define_method(cMD5, "update", md5_update, 1);
+ rb_define_method(cMD5, "digest", md5_digest, 0);
+ rb_define_method(cMD5, "clone", md5_clone, 0);
+}
diff --git a/ext/socket/MANIFEST b/ext/socket/MANIFEST
index 836caada41..d41d9e0b69 100644
--- a/ext/socket/MANIFEST
+++ b/ext/socket/MANIFEST
@@ -2,4 +2,3 @@ MANIFEST
depend
extconf.rb
socket.c
-socket.doc
diff --git a/ext/socket/extconf.rb b/ext/socket/extconf.rb
index 60d6deeb84..f2ec0578d5 100644
--- a/ext/socket/extconf.rb
+++ b/ext/socket/extconf.rb
@@ -1,6 +1,11 @@
-have_library("inet", "gethostbyname")
have_library("socket", "socket")
+have_library("inet", "gethostbyname")
+have_library("nsl", "gethostbyname")
have_header("sys/un.h")
if have_func("socket")
+ have_func("hsterror")
+ unless have_func("gethostname")
+ have_func("uname")
+ end
create_makefile("socket")
end
diff --git a/ext/socket/socket.c b/ext/socket/socket.c
index 5671b2762c..6b4f0f5559 100644
--- a/ext/socket/socket.c
+++ b/ext/socket/socket.c
@@ -18,11 +18,11 @@
#include <errno.h>
#ifdef HAVE_SYS_UN_H
#include <sys/un.h>
-#else
-#undef AF_UNIX
#endif
extern VALUE cIO;
+extern VALUE cInteger;
+
VALUE cBasicSocket;
VALUE cTCPsocket;
VALUE cTCPserver;
@@ -32,6 +32,9 @@ VALUE cUNIXserver;
#endif
VALUE cSocket;
+extern VALUE eException;
+static VALUE eSocket;
+
FILE *rb_fdopen();
char *strdup();
@@ -52,8 +55,9 @@ sock_new(class, fd)
VALUE class;
int fd;
{
- VALUE sock = obj_alloc(class);
OpenFile *fp;
+ NEWOBJ(sock, struct RFile);
+ OBJSETUP(sock, class, T_FILE);
MakeOpenFile(sock, fp);
#ifdef NT
@@ -64,7 +68,7 @@ sock_new(class, fd)
fp->f2 = rb_fdopen(fd, "w");
fp->mode = FMODE_READWRITE|FMODE_SYNC;
- return sock;
+ return (VALUE)sock;
}
static VALUE
@@ -86,34 +90,53 @@ bsock_shutdown(argc, argv, sock)
}
GetOpenFile(sock, fptr);
if (shutdown(fileno(fptr->f), how) == -1)
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
return INT2FIX(0);
}
static VALUE
-bsock_setopt(sock, lev, optname, val)
+bsock_setsockopt(sock, lev, optname, val)
VALUE sock, lev, optname;
struct RString *val;
{
int level, option;
OpenFile *fptr;
+ int i;
+ char *v;
+ int vlen;
level = NUM2INT(lev);
option = NUM2INT(optname);
- Check_Type(val, T_STRING);
+ switch (TYPE(val)) {
+ case T_FIXNUM:
+ i = FIX2INT(val);
+ goto numval;
+ case T_FALSE:
+ i = 0;
+ goto numval;
+ case T_TRUE:
+ i = 1;
+ numval:
+ v = (char*)&i; vlen = sizeof(i);
+ break;
+ default:
+ Check_Type(val, T_STRING);
+ v = val->ptr; vlen = val->len;
+ }
GetOpenFile(sock, fptr);
- if (setsockopt(fileno(fptr->f), level, option, val->ptr, val->len) < 0)
+ if (setsockopt(fileno(fptr->f), level, option, v, vlen) < 0)
rb_sys_fail(fptr->path);
return INT2FIX(0);
}
static VALUE
-bsock_getopt(sock, lev, optname)
+bsock_getsockopt(sock, lev, optname)
VALUE sock, lev, optname;
{
+#if !defined(__CYGWIN32__)
int level, option, len;
struct RString *val;
OpenFile *fptr;
@@ -128,7 +151,11 @@ bsock_getopt(sock, lev, optname)
if (getsockopt(fileno(fptr->f), level, option, val->ptr, &len) < 0)
rb_sys_fail(fptr->path);
val->len = len;
+
return (VALUE)val;
+#else
+ rb_notimplement();
+#endif
}
static VALUE
@@ -184,8 +211,14 @@ open_inet(class, h, serv, server)
if (hostaddr == -1) {
if (server && !strlen(host))
hostaddr = INADDR_ANY;
- else
- rb_sys_fail(host);
+ else {
+#ifdef HAVE_HSTRERROR
+ extern int h_errno;
+ Raise(eSocket, (char *)hstrerror(h_errno));
+#else
+ Raise(eSocket, "host not found");
+#endif
+ }
}
_hostent.h_addr_list = (char **)hostaddrPtr;
_hostent.h_addr_list[0] = (char *)&hostaddr;
@@ -203,27 +236,31 @@ open_inet(class, h, serv, server)
Check_Type(serv, T_STRING);
servent = getservbyname(RSTRING(serv)->ptr, "tcp");
if (servent == NULL) {
- servport = strtoul(RSTRING(serv)->ptr, Qnil, 0);
- if (servport == -1) Fail("no such servce %s", RSTRING(serv)->ptr);
+ servport = strtoul(RSTRING(serv)->ptr, 0, 0);
+ if (servport == -1) {
+ Raise(eSocket, "no such servce %s", RSTRING(serv)->ptr);
+ }
setup_servent:
- _servent.s_port = servport;
- _servent.s_proto = "tcp";
+ _servent.s_port = htons(servport);
+ _servent.s_proto = "tcp";
servent = &_servent;
}
protoent = getprotobyname(servent->s_proto);
- if (protoent == NULL) Fail("no such proto %s", servent->s_proto);
+ if (protoent == NULL) {
+ Raise(eSocket, "no such proto %s", servent->s_proto);
+ }
fd = socket(PF_INET, SOCK_STREAM, protoent->p_proto);
sockaddr.sin_family = AF_INET;
- if (h == Qnil) {
- sockaddr.sin_addr.s_addr = INADDR_ANY;
- }
- else {
+ if (h) {
memcpy((char *)&(sockaddr.sin_addr.s_addr),
(char *) hostent->h_addr_list[0],
(size_t) hostent->h_length);
}
+ else {
+ sockaddr.sin_addr.s_addr = INADDR_ANY;
+ }
sockaddr.sin_port = servent->s_port;
if (server) {
@@ -248,7 +285,7 @@ open_inet(class, h, serv, server)
}
static VALUE
-tcp_s_sock_open(class, host, serv)
+tcp_s_open(class, host, serv)
VALUE class, host, serv;
{
Check_Type(host, T_STRING);
@@ -266,7 +303,7 @@ tcp_svr_s_open(argc, argv, class)
if (rb_scan_args(argc, argv, "11", &arg1, &arg2) == 2)
return open_inet(class, arg1, arg2, 1);
else
- return open_inet(class, Qnil, arg1, 1);
+ return open_inet(class, 0, arg1, 1);
}
static VALUE
@@ -279,10 +316,15 @@ s_accept(class, fd, sockaddr, len)
int fd2;
retry:
+#ifdef THREAD
+ thread_wait_fd(fd);
+#endif
+ TRAP_BEG;
fd2 = accept(fd, sockaddr, len);
+ TRAP_END;
if (fd2 < 0) {
if (errno == EINTR) goto retry;
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
}
return sock_new(class, fd2);
}
@@ -301,7 +343,7 @@ tcp_accept(sock)
(struct sockaddr*)&from, &fromlen);
}
-#ifdef AF_UNIX
+#ifdef HAVE_SYS_UN_H
static VALUE
open_unix(class, path, server)
VALUE class;
@@ -346,11 +388,63 @@ open_unix(class, path, server)
}
#endif
+static void
+setipaddr(name, addr)
+ char *name;
+ struct sockaddr_in *addr;
+{
+ int d1, d2, d3, d4;
+ char ch;
+ struct hostent *hp;
+ long x;
+ unsigned char *a;
+ char buf[16];
+
+ if (name[0] == 0) {
+ addr->sin_addr.s_addr = INADDR_ANY;
+ }
+ else if (name[0] == '<' && strcmp(name, "<broadcast>") == 0) {
+ addr->sin_addr.s_addr = INADDR_BROADCAST;
+ }
+ else if (sscanf(name, "%d.%d.%d.%d%c", &d1, &d2, &d3, &d4, &ch) == 4 &&
+ 0 <= d1 && d1 <= 255 && 0 <= d2 && d2 <= 255 &&
+ 0 <= d3 && d3 <= 255 && 0 <= d4 && d4 <= 255) {
+ addr->sin_addr.s_addr = htonl(
+ ((long) d1 << 24) | ((long) d2 << 16) |
+ ((long) d3 << 8) | ((long) d4 << 0));
+ }
+ else {
+ hp = gethostbyname(name);
+ if (!hp) {
+#ifdef HAVE_HSTRERROR
+ extern int h_errno;
+ Raise(eSocket, (char *)hstrerror(h_errno));
+#else
+ Raise(eSocket, "host not found");
+#endif
+ }
+ memcpy((char *) &addr->sin_addr, hp->h_addr, hp->h_length);
+ }
+}
+
+static VALUE
+mkipaddr(x)
+ unsigned long x;
+{
+ char buf[16];
+
+ x = ntohl(x);
+ sprintf(buf, "%d.%d.%d.%d",
+ (int) (x>>24) & 0xff, (int) (x>>16) & 0xff,
+ (int) (x>> 8) & 0xff, (int) (x>> 0) & 0xff);
+ return str_new2(buf);
+}
+
static VALUE
tcpaddr(sockaddr)
struct sockaddr_in *sockaddr;
{
- VALUE family, port, addr;
+ VALUE family, port, addr1, addr2;
VALUE ary;
struct hostent *hostent;
@@ -358,17 +452,15 @@ tcpaddr(sockaddr)
hostent = gethostbyaddr((char*)&sockaddr->sin_addr.s_addr,
sizeof(sockaddr->sin_addr),
AF_INET);
+ addr1 = 0;
if (hostent) {
- addr = str_new2(hostent->h_name);
+ addr1 = str_new2(hostent->h_name);
}
- else {
- char buf[16];
- char *a = (char*)&sockaddr->sin_addr;
- sprintf(buf, "%d.%d.%d.%d", a[0], a[1], a[2], a[3]);
- addr = str_new2(buf);
- }
- port = INT2FIX(sockaddr->sin_port);
- ary = ary_new3(3, family, port, addr);
+ addr2 = mkipaddr(sockaddr->sin_addr.s_addr);
+ if (!addr1) addr1 = addr2;
+
+ port = INT2FIX(ntohs(sockaddr->sin_port));
+ ary = ary_new3(4, family, port, addr1, addr2);
return ary;
}
@@ -399,11 +491,30 @@ tcp_peeraddr(sock)
GetOpenFile(sock, fptr);
if (getpeername(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
- rb_sys_fail("getsockname(2)");
+ rb_sys_fail("getpeername(2)");
return tcpaddr(&addr);
}
-#ifdef AF_UNIX
+static VALUE
+tcp_s_getaddress(obj, host)
+ VALUE obj, host;
+{
+ struct sockaddr_in addr;
+ struct hostent *h;
+
+ if (obj_is_kind_of(host, cInteger)) {
+ int i = NUM2INT(host);
+ addr.sin_addr.s_addr = htonl(i);
+ }
+ else {
+ Check_Type(host, T_STRING);
+ setipaddr(RSTRING(host)->ptr, &addr);
+ }
+
+ return mkipaddr(addr.sin_addr.s_addr);
+}
+
+#ifdef HAVE_SYS_UN_H
static VALUE
unix_s_sock_open(sock, path)
VALUE sock, path;
@@ -418,11 +529,11 @@ unix_path(sock)
OpenFile *fptr;
GetOpenFile(sock, fptr);
- if (fptr->path == Qnil) {
+ if (fptr->path == 0) {
struct sockaddr_un addr;
int len = sizeof(addr);
if (getsockname(fileno(fptr->f), (struct sockaddr*)&addr, &len) < 0)
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
fptr->path = strdup(addr.sun_path);
}
return str_new2(fptr->path);
@@ -515,7 +626,7 @@ setup_domain_and_type(domain, dv, type, tv)
*dv = PF_IPX;
#endif
else
- Fail("Unknown socket domain %s", ptr);
+ Raise(eSocket, "Unknown socket domain %s", ptr);
}
else {
*dv = NUM2INT(domain);
@@ -543,7 +654,7 @@ setup_domain_and_type(domain, dv, type, tv)
*tv = SOCK_PACKET;
#endif
else
- Fail("Unknown socket type %s", ptr);
+ Raise(eSocket, "Unknown socket type %s", ptr);
}
else {
*tv = NUM2INT(type);
@@ -559,7 +670,7 @@ sock_s_open(class, domain, type, protocol)
setup_domain_and_type(domain, &d, type, &t);
fd = socket(d, t, NUM2INT(protocol));
- if (fd < 0) rb_sys_fail("socke(2)");
+ if (fd < 0) rb_sys_fail("socket(2)");
return sock_new(class, fd);
}
@@ -574,6 +685,7 @@ static VALUE
sock_s_socketpair(class, domain, type, protocol)
VALUE class, domain, type, protocol;
{
+#if !defined(__CYGWIN32__)
int fd;
int d, t, sp[2];
@@ -582,6 +694,9 @@ sock_s_socketpair(class, domain, type, protocol)
rb_sys_fail("socketpair(2)");
return assoc_new(sock_new(class, sp[0]), sock_new(class, sp[1]));
+#else
+ rb_notimplement();
+#endif
}
static VALUE
@@ -665,6 +780,9 @@ sock_send(argc, argv, sock)
GetOpenFile(sock, fptr);
f = fptr->f2?fptr->f2:fptr->f;
fd = fileno(f);
+#ifdef THREAD
+ thread_fd_writable(fd);
+#endif
if (to) {
Check_Type(to, T_STRING);
n = sendto(fd, msg->ptr, msg->len, NUM2INT(flags),
@@ -703,8 +821,15 @@ s_recv(sock, argc, argv, from)
GetOpenFile(sock, fptr);
fd = fileno(fptr->f);
- if ((str->len = recvfrom(fd, str->ptr, str->len, flags,
- (struct sockaddr*)buf, &alen)) < 0) {
+#ifdef THREAD
+ thread_wait_fd(fd);
+#endif
+ TRAP_BEG;
+ str->len = recvfrom(fd, str->ptr, str->len, flags,
+ (struct sockaddr*)buf, &alen);
+ TRAP_END;
+
+ if (str->len < 0) {
rb_sys_fail("recvfrom(2)");
}
@@ -732,28 +857,173 @@ sock_recvfrom(argc, argv, sock)
return s_recv(sock, argc, argv, 1);
}
+#ifdef HAVE_GETHOSTNAME
+static VALUE
+sock_gethostname(obj)
+ VALUE obj;
+{
+ char buf[1024];
+
+ if (gethostname(buf, (int)sizeof buf - 1) < 0)
+ rb_sys_fail("gethostname");
+
+ buf[sizeof buf - 1] = '\0';
+ return str_new2(buf);
+}
+#else
+#ifdef HAVE_UNAME
+
+#include <sys/utsname.h>
+
+static VALUE
+sock_gethostname(obj)
+ VALUE obj;
+{
+ struct utsname un;
+
+ uname(&un);
+ return str_new2(un.nodename);
+}
+#else
+static VALUE
+sock_gethostname(obj)
+ VALUE obj;
+{
+ rb_notimplement();
+}
+#endif
+#endif
+
+static VALUE
+mkhostent(h)
+ struct hostent *h;
+{
+ struct sockaddr_in addr;
+ char **pch;
+ VALUE ary, names;
+
+ if (h == NULL) {
+#ifdef HAVE_HSTRERROR
+ extern int h_errno;
+ Raise(eSocket, (char *)hstrerror(h_errno));
+#else
+ Raise(eSocket, "host not found");
+#endif
+ }
+ ary = ary_new();
+ ary_push(ary, str_new2(h->h_name));
+ names = ary_new();
+ ary_push(ary, names);
+ for (pch = h->h_aliases; *pch; pch++) {
+ ary_push(names, str_new2(*pch));
+ }
+ ary_push(ary, INT2FIX(h->h_length));
+#ifdef h_addr
+ for (pch = h->h_addr_list; *pch; pch++) {
+ ary_push(ary, str_new(*pch, h->h_length));
+ }
+#else
+ ary_push(ary, str_new(h->h_addr, h->h_length));
+#endif
+
+ return ary;
+}
+
+static VALUE
+sock_s_gethostbyname(obj, host)
+ VALUE obj, host;
+{
+ struct sockaddr_in addr;
+ struct hostent *h;
+
+ if (obj_is_kind_of(host, cInteger)) {
+ int i = NUM2INT(host);
+ addr.sin_addr.s_addr = htonl(i);
+ }
+ else {
+ Check_Type(host, T_STRING);
+ setipaddr(RSTRING(host)->ptr, &addr);
+ }
+ h = gethostbyaddr((char *)&addr.sin_addr,
+ sizeof(addr.sin_addr),
+ AF_INET);
+
+ return mkhostent(h);
+}
+
+sock_s_gethostbyaddr(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE vaddr, vtype;
+ int type;
+
+ struct sockaddr_in *addr;
+ struct hostent *h;
+
+ rb_scan_args(argc, argv, "11", &addr, &type);
+ Check_Type(addr, T_STRING);
+ if (!NIL_P(type)) {
+ type = NUM2INT(vtype);
+ }
+ else {
+ type = AF_INET;
+ }
+
+ h = gethostbyaddr(RSTRING(addr)->ptr, RSTRING(addr)->len, type);
+
+ return mkhostent(h);
+}
+
+static VALUE
+sock_s_getservbyaname(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE service, protocol;
+ char *name, *proto;
+ struct servent *sp;
+ int port;
+
+ rb_scan_args(argc, argv, "11", &service, &protocol);
+ Check_Type(service, T_STRING);
+ if (NIL_P(protocol)) proto = "tcp";
+ else proto = RSTRING(protocol)->ptr;
+
+ sp = getservbyname(RSTRING(service)->ptr, proto);
+ if (!sp) {
+ Raise(eSocket, "service/proto not found");
+ }
+ port = ntohs(sp->s_port);
+
+ return INT2FIX(port);
+}
+
Init_socket ()
{
+ eSocket = rb_define_class("SocketError", eException);
+
cBasicSocket = rb_define_class("BasicSocket", cIO);
rb_undef_method(cBasicSocket, "new");
rb_define_method(cBasicSocket, "shutdown", bsock_shutdown, -1);
- rb_define_method(cBasicSocket, "setopt", bsock_setopt, 3);
- rb_define_method(cBasicSocket, "getopt", bsock_getopt, 2);
+ rb_define_method(cBasicSocket, "setsockopt", bsock_setsockopt, 3);
+ rb_define_method(cBasicSocket, "getsockopt", bsock_getsockopt, 2);
rb_define_method(cBasicSocket, "getsockname", bsock_getsockname, 0);
rb_define_method(cBasicSocket, "getpeername", bsock_getpeername, 0);
cTCPsocket = rb_define_class("TCPsocket", cBasicSocket);
- rb_define_singleton_method(cTCPsocket, "open", tcp_s_sock_open, 2);
- rb_define_singleton_method(cTCPsocket, "new", tcp_s_sock_open, 2);
+ rb_define_singleton_method(cTCPsocket, "open", tcp_s_open, 2);
+ rb_define_singleton_method(cTCPsocket, "new", tcp_s_open, 2);
rb_define_method(cTCPsocket, "addr", tcp_addr, 0);
rb_define_method(cTCPsocket, "peeraddr", tcp_peeraddr, 0);
+ rb_define_singleton_method(cTCPsocket, "getaddress", tcp_s_getaddress, 1);
cTCPserver = rb_define_class("TCPserver", cTCPsocket);
rb_define_singleton_method(cTCPserver, "open", tcp_svr_s_open, -1);
rb_define_singleton_method(cTCPserver, "new", tcp_svr_s_open, -1);
rb_define_method(cTCPserver, "accept", tcp_accept, 0);
-#ifdef AF_UNIX
+#ifdef HAVE_SYS_UN_H
cUNIXsocket = rb_define_class("UNIXsocket", cBasicSocket);
rb_define_singleton_method(cUNIXsocket, "open", unix_s_sock_open, 1);
rb_define_singleton_method(cUNIXsocket, "new", unix_s_sock_open, 1);
@@ -782,4 +1052,64 @@ Init_socket ()
rb_define_method(cSocket, "recvfrom", sock_recv, -1);
rb_define_singleton_method(cSocket, "socketpair", sock_s_socketpair, 3);
+ rb_define_singleton_method(cSocket, "pair", sock_s_socketpair, 3);
+ rb_define_singleton_method(cSocket, "gethostname", sock_gethostname, 0);
+ rb_define_singleton_method(cSocket, "gethostbyname", sock_s_gethostbyname, 1);
+ rb_define_singleton_method(cSocket, "gethostbyaddr", sock_s_gethostbyaddr, -1);
+ rb_define_singleton_method(cSocket, "getservbyname", sock_s_getservbyaname, -1);
+
+ /* constants */
+ rb_define_const(cSocket, "AF_INET", INT2FIX(AF_INET));
+ rb_define_const(cSocket, "PF_INET", INT2FIX(PF_INET));
+#ifdef AF_UNIX
+ rb_define_const(cSocket, "AF_UNIX", INT2FIX(AF_UNIX));
+ rb_define_const(cSocket, "PF_UNIX", INT2FIX(PF_UNIX));
+#endif
+#ifdef AF_IPX
+ rb_define_const(cSocket, "AF_IPX", INT2FIX(AF_IPX));
+ rb_define_const(cSocket, "PF_IPX", INT2FIX(PF_IPX));
+#endif
+#ifdef AF_APPLETALK
+ rb_define_const(cSocket, "AF_APPLETALK", INT2FIX(AF_APPLETALK));
+ rb_define_const(cSocket, "PF_APPLETALK", INT2FIX(PF_APPLETALK));
+#endif
+
+ rb_define_const(cSocket, "MSG_OOB", INT2FIX(MSG_OOB));
+ rb_define_const(cSocket, "MSG_PEEK", INT2FIX(MSG_PEEK));
+ rb_define_const(cSocket, "MSG_DONTROUTE", INT2FIX(MSG_DONTROUTE));
+
+ rb_define_const(cSocket, "SOCK_STREAM", INT2FIX(SOCK_STREAM));
+ rb_define_const(cSocket, "SOCK_DGRAM", INT2FIX(SOCK_DGRAM));
+ rb_define_const(cSocket, "SOCK_RAW", INT2FIX(SOCK_RAW));
+#ifdef SOCK_RDM
+ rb_define_const(cSocket, "SOCK_RDM", INT2FIX(SOCK_RDM));
+#endif
+#ifdef SOCK_SEQPACKET
+ rb_define_const(cSocket, "SOCK_SEQPACKET", INT2FIX(SOCK_SEQPACKET));
+#endif
+#ifdef SOCK_PACKET
+ rb_define_const(cSocket, "SOCK_PACKET", INT2FIX(SOCK_PACKET));
+#endif
+
+ rb_define_const(cSocket, "SOL_SOCKET", INT2FIX(SOL_SOCKET));
+#ifdef SOL_IP
+ rb_define_const(cSocket, "SOL_IP", INT2FIX(SOL_IP));
+#endif
+#ifdef SOL_IPX
+ rb_define_const(cSocket, "SOL_IPX", INT2FIX(SOL_IPX));
+#endif
+#ifdef SOL_ATALK
+ rb_define_const(cSocket, "SOL_ATALK", INT2FIX(SOL_ATALK));
+#endif
+#ifdef SOL_TCP
+ rb_define_const(cSocket, "SOL_TCP", INT2FIX(SOL_TCP));
+#endif
+#ifdef SOL_UDP
+ rb_define_const(cSocket, "SOL_UDP", INT2FIX(SOL_UDP));
+#endif
+
+ rb_define_const(cSocket, "SO_DEBUG", INT2FIX(SO_DEBUG));
+ rb_define_const(cSocket, "SO_REUSEADDR", INT2FIX(SO_REUSEADDR));
+ rb_define_const(cSocket, "SO_KEEPALIVE", INT2FIX(SO_KEEPALIVE));
+ rb_define_const(cSocket, "SO_LINGER", INT2FIX(SO_LINGER));
}
diff --git a/ext/socket/socket.doc b/ext/socket/socket.doc
deleted file mode 100644
index aa5bfedbff..0000000000
--- a/ext/socket/socket.doc
+++ /dev/null
@@ -1,227 +0,0 @@
-.\" socket.doc - -*- Indented-Text -*- created at: Thu Mar 23 20:29:02 JST 1995
-
-** Socket(¥¯¥é¥¹)
-
-SuperClass: BasicSocket
-
-¥½¥±¥Ã¥È¤½¤Î¤â¤Î¤ËÂФ¹¤ë¥·¥¹¥Æ¥à¥³¡¼¥ë¥ì¥Ù¥ë¤Î¥¢¥¯¥»¥¹¤òÄ󶡤¹¤ë¥¯¥é¥¹¡¥
-Perl¤Î¥½¥±¥Ã¥È¤ËÂФ¹¤ë¥¢¥¯¥»¥¹¤ÈƱ¥ì¥Ù¥ë¤Îµ¡Ç½¤òÄ󶡤·¤Æ¤¤¤ë¡¥¤³¤Î¥¯¥é
-¥¹¤Ç¤Ï¥½¥±¥Ã¥È¥¢¥É¥ì¥¹¤Ïpack¤µ¤ì¤¿Ê¸»úÎó¤Ç¡¤»ØÄꤹ¤ë¡¥UDP¥½¥±¥Ã¥È¤Ï¤³
-¤Î¥¯¥é¥¹¤ò»È¤Ã¤ÆÍøÍѤ¹¤ë¡¥
-
-Methods:
-
- accept
-
- ¿·¤·¤¤Àܳ¤ò¼õ¤±ÉÕ¤±¤Æ¡¤¿·¤·¤¤Àܳ¤ËÂФ¹¤ë¥½¥±¥Ã¥È¤È¥¢¥É¥ì¥¹¤Î
- ¥Ú¥¢¤òÊÖ¤¹¡¥accept(2)¤ò»²¾È¡¥
-
- bind(addr)
-
- bind(2)¤ÈƱ¤¸Æ¯¤­¤ò¤¹¤ë¡¥addr¤Ïpack¤µ¤ì¤¿¥½¥±¥Ã¥È¥¢¥É¥ì¥¹¹½Â¤
- ÂΤǤ¢¤ë¡¥
-
- connect(addr)
-
- connect(2)¤ÈƱ¤¸Æ¯¤­¤ò¤¹¤ë¡¥addr¤Ïpack¤µ¤ì¤¿¥½¥±¥Ã¥È¥¢¥É¥ì¥¹¹½
- ¤ÂΤǤ¢¤ë¡¥
-
- listen(backlog)
-
- listen(2)¤ÈƱ¤¸Æ¯¤­¤ò¤¹¤ë¡¥
-
- recv(len[, flags])
-
- ¥½¥±¥Ã¥È¤«¤é¥Ç¡¼¥¿¤ò¼õ¤±¼è¤ê¡¤Ê¸»úÎó¤È¤·¤ÆÊÖ¤¹¡¥len¤Ï¼õ¤±¼è¤ë
- ºÇÂç¤ÎŤµ¤ò»ØÄꤹ¤ë¡¥flags¤Ë¤Ä¤¤¤Æ¤Ïrecv(2)¤ò»²¾È¡¥flags¤Î¥Ç
- ¥Õ¥©¥ë¥ÈÃͤÏ0¤Ç¤¢¤ë¡¥
-
- recvfrom(len[, flags])
-
- recv¤ÈƱÍͤ˥½¥±¥Ã¥È¤«¤é¥Ç¡¼¥¿¤ò¼õ¤±¼è¤ë¤¬¡¤Ìá¤êÃͤÏʸ»úÎó¤ÈÁê
- ¼ê¥½¥±¥Ã¥È¤Î¥¢¥É¥ì¥¹¤Î¥Ú¥¢¤Ç¤¢¤ë¡¥°ú¿ô¤Ë¤Ä¤¤¤Æ¤Ïrecv¤ÈƱÍÍ¡¥
-
- send(mesg, flags[, to])
-
- ¥½¥±¥Ã¥È¤ò²ð¤·¤Æ¥Ç¡¼¥¿¤òÁ÷¤ë¡¥flags¤Ë´Ø¤·¤Æ¤Ïsend(2)¤ò»²¾È¤Î»ö¡¥
- connect¤·¤Æ¤¤¤Ê¤¤¥½¥±¥Ã¥È¤ËÂФ·¤Æ¤ÏÁ÷¤êÀè¤Ç¤¢¤ëto¤ò»ØÄꤹ¤ëɬ
- Íפ¬¤¢¤ë¡¥¼ÂºÝ¤ËÁ÷¤Ã¤¿¥Ç¡¼¥¿¤ÎŤµ¤òÊÖ¤¹¡¥
-
-Single Methods:
-
- open(domain, type, protocol)
- new(domain, type, protocol)
-
- ¿·¤·¤¤¥½¥±¥Ã¥È¤òÀ¸À®¤¹¤ë¡¥domain¡¤type¡¤protocol¤Ï¥¤¥ó¥¯¥ë¡¼¥É
- ¥Õ¥¡¥¤¥ë¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ëÄê¿ôÃͤǻØÄꤹ¤ë¡¥domain¤Ètype¤Ë´Ø¤·¤Æ
- ¤Ï¡¤Ê¸»úÎó¤Ç»ØÄê¤Ç¤­¤ë¤¬¡¤¤¹¤Ù¤Æ¤ò¥«¥Ð¡¼¤·¤Æ¤¤¤ëÊݾڤϤʤ¤¡¥
-
- socketpair(domain, type, protocol)
-
- ¥½¥±¥Ã¥È¤Î¥Ú¥¢¤òÊÖ¤¹¡¥°ú¿ô¤Î»ØÄê¤Ï open¤ÈƱ¤¸¤Ç¤¢¤ë¡¥
-
-** BasicSocket(¥¯¥é¥¹)
-
-¥½¥±¥Ã¥È¤òɽ¤¹Ãê¾Ý¥¯¥é¥¹¡¥¶ñÂÎŪ¤Ê¥½¥±¥Ã¥ÈÁàºî¤Ï¥µ¥Ö¥¯¥é¥¹¤ÇÄêµÁ¤µ¤ì¤ë¡¥
-Î㤨¤Ð¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥É¥á¥¤¥ó¤Î¾ì¹ç¤ÏTCPsocket¤òÍѤ¤¤ë¡¥
-
-SuperClass: IO
-
-Methods:
-
- getopt(level, optname)
-
- ¥½¥±¥Ã¥È¤Î¥ª¥×¥·¥ç¥ó¤ò¼èÆÀ¤¹¤ë¡¥getsockopt(2)¤ò»²¾È¤Î¤³¤È¡¥¼è
- ÆÀ¤·¤¿¥ª¥×¥·¥ç¥ó¤ÎÆâÍÆ¤ò´Þ¤àʸ»úÎó¤òÊÖ¤¹¡¥
-
- getpeername
-
- Àܳ¤ÎÁê¼êÀè¤Î¥½¥±¥Ã¥È¤Î¾ðÊó¤òÆÀ¤ë¡¥¥Ñ¥Ã¥¯¤µ¤ì¤¿sockaddr¹½Â¤ÂÎ
- ¤ò¥Ù¥¿¤Ë¥À¥ó¥×¤·¤¿Ê¸»úÎó¤¬ÊÖ¤µ¤ì¤ë¡¥getpeername(2)¤ò»²¾È¤Î¤³¤È¡¥
-
- getsockname
-
- ¥½¥±¥Ã¥È¤Î¾ðÊó¤òÆÀ¤ë¡¥¥Ñ¥Ã¥¯¤µ¤ì¤¿sockaddr¹½Â¤ÂΤò¥Ù¥¿¤Ë¥À¥ó¥×
- ¤·¤¿Ê¸»úÎó¤¬ÊÖ¤µ¤ì¤ë¡¥getsockname(2)¤ò»²¾È¤Î¤³¤È¡¥
-
- setopt(level, optname, optval)
-
- ¥½¥±¥Ã¥È¤Î¥ª¥×¥·¥ç¥ó¤òÀßÄꤹ¤ë¡¥setsockopt(2)¤ò»²¾È¤Î¤³¤È¡¥
-
- shutdown(how)
-
- ¥½¥±¥Ã¥È¤Î°Ê¹ß¤ÎÀܳ¤ò½ªÎ»¤µ¤»¤ë¡¥how¤¬0¤Ç¤¢¤ë»þ¡¤°Ê¹ß¤Î¼õ¿®¤¬¡¤
- how¤¬1¤Ç¤¢¤ë»þ¤Ï¡¤°Ê¹ß¤ÎÁ÷¿®¤¬µñÈݤµ¤ì¤ë¡¥how¤¬2¤Î»þ¤Ë¤Ï¡¤¤½¤ì
- °Ê¹ß¤ÎÁ÷¿®¡¤¼õ¿®¤È¤â¤ËµñÈݤµ¤ì¤ë¡¥shutdown(2)¤ò»²¾È¡¥
-
-** TCPserver(¥¯¥é¥¹)
-
-TCP/IP¥¹¥È¥ê¡¼¥à·¿Àܳ¤Î¥µ¡¼¥Ð¦¤Î¥½¥±¥Ã¥È¤Î¥¯¥é¥¹¡¥¤³¤Î¥¯¥é¥¹¤Ë¤è¤Ã¤Æ
-´Êñ¤Ë¥½¥±¥Ã¥È¤òÍøÍѤ·¤¿¥µ¡¼¥Ð¤Î¥×¥í¥°¥é¥ß¥ó¥°¤¬¤Ç¤­¤ë¡¥Î㤨¤Ðecho¥µ¡¼
-¥Ð¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡¥
-
- gs = TCPserver.open(4444)
- socks = [gs]
-
- while TRUE
- nsock = select(socks);
- if nsock == nil; continue end
- for s in nsock[0]
- if s == gs
- socks.push(s.accept)
- else
- if s.eof
- s.close
- socks.delete(s)
- else
- str = s.gets
- s.write(str)
- end
- end
- end
- end
-
-SuperClass: TCPsocket
-
-Methods:
-
- accept
-
- ¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤ÎÀܳÍ×µá¤ò¼õ¤±ÉÕ¤±¡¤Àܳ¤·¤¿TCPsocket¤Î¥¤¥ó
- ¥¹¥¿¥ó¥¹¤òÊÖ¤¹¡¥
-
-Single Methods:
-
- new([host, ]service)
- open([host, ]service)
-
- service¤Ï/etc/services(¤Þ¤¿¤ÏNIS)¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ë¥µ¡¼¥Ó¥¹Ì¾¤«
- ¥Ý¡¼¥ÈÈÖ¹æ¤Ç»ØÄꤹ¤ë¡¥host¤ò»ØÄꤷ¤¿»þ¤Ï»ØÄꤷ¤¿¥Û¥¹¥È¤«¤é¤ÎÀÜ
- ³¤À¤±¤ò¼õ¤±ÉÕ¤±¤ë¡¥¾Êά»þ¤ÏÁ´¤Æ¤Î¥Û¥¹¥È¤«¤é¤ÎÀܳÍ×µá¤ò¼õ¤±ÉÕ
- ¤±¤ë¡¥
-
-** TCPsocket
-
-¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥É¥á¥¤¥ó¤Î¥¹¥È¥ê¡¼¥à·¿¥½¥±¥Ã¥È¤Î¥¯¥é¥¹¡¥Ä̾ï¤ÎIO¥¯¥é¥¹¤Î
-¥µ¥Ö¥¯¥é¥¹¤ÈƱÍÍ¤ÎÆþ½ÐÎϤ¬¤Ç¤­¤ë¡¥¤³¤Î¥¯¥é¥¹¤Ë¤è¤Ã¤Æ¥½¥±¥Ã¥È¤òÍѤ¤¤¿¥¯
-¥é¥¤¥¢¥ó¥È¤ò´Êñ¤Ëµ­½Ò¤Ç¤­¤ë¡¥¥æ¡¼¥¶¤ÎÆþÎϤò¤½¤Î¤Þ¤Þ¥µ¡¼¥Ð¤ËžÁ÷¤¹¤ë¥×
-¥í¥°¥é¥à¤Ï°Ê²¼¤Î¤è¤¦¤Ë¤Ê¤ë¡¥
-
- s = TCPsocket("localhost", 4444)
- while gets()
- s.write($_)
- print(s.read)
- end
-
-SuperClass: BasicSocket
-
-Methods:
-
- addr
-
- ¥½¥±¥Ã¥È¤ÎÀܳ¾ðÊó¤òɽ¤¹ÇÛÎó¤òÊÖ¤¹¡¥¤½¤ÎÇÛÎó¤Î³ÆÍ×ÁǤÏÂè1Í×ÁÇ
- ¤¬Ê¸»úÎó "AF_INET"¡¤Âè2Í×ÁǤ¬portÈֹ桤Âè3Í×ÁǤ¬¥Û¥¹¥È¤òɽ¤¹Ê¸
- »úÎó¤Ç¤¢¤ë¡¥
-
- peeraddr
-
- ÀܳÁê¼êÀ襽¥±¥Ã¥È¤Î¾ðÊó¤òɽ¤¹ÇÛÎó¤òÊÖ¤¹¡¥¤½¤ÎÇÛÎó¤Î³ÆÍ×ÁǤÏ
- addr¥á¥½¥Ã¥É¤¬ÊÖ¤¹ÇÛÎó¤ÈƱ¤¸¤Ç¤¢¤ë¡¥
-
-Single Methods:
-
- open(host, service)
- new(host, service)
-
- host¤Ç»ØÄꤷ¤¿¥Û¥¹¥È¤Îservice¤Ç»ØÄꤷ¤¿¥Ý¡¼¥È¤ÈÀܳ¤·¤¿¥½¥±¥Ã
- ¥È¤òÊÖ¤¹¡¥host¤Ï¥Û¥¹¥È̾¡¤¤Þ¤¿¤Ï¥¤¥ó¥¿¡¼¥Í¥Ã¥È¥¢¥É¥ì¥¹¤ò¼¨¤¹Ê¸
- »úÎó¡¤service¤Ï/etc/services(¤Þ¤¿¤ÏNIS)¤ËÅÐÏ¿¤µ¤ì¤Æ¤¤¤ë¥µ¡¼¥Ó
- ¥¹Ì¾¤«¥Ý¡¼¥ÈÈÖ¹æ¤Ç¤¢¤ë¡¥
-
-** UNIXserver
-
-UNIX¥¹¥È¥ê¡¼¥à·¿Àܳ¤Î¥µ¡¼¥Ð¦¤Î¥½¥±¥Ã¥È¤Î¥¯¥é¥¹¡¥
-
-SuperClass: UNIXsocket
-
-Methods:
-
- accept
-
- ¥¯¥é¥¤¥¢¥ó¥È¤«¤é¤ÎÀܳÍ×µá¤ò¼õ¤±ÉÕ¤±¡¤Àܳ¤·¤¿UNIXsocket¤Î¥¤¥ó
- ¥¹¥¿¥ó¥¹¤òÊÖ¤¹¡¥
-
-** UNIXsocket
-
-UNIX¥É¥á¥¤¥ó¤Î¥¹¥È¥ê¡¼¥à·¿¥½¥±¥Ã¥È¤Î¥¯¥é¥¹¡¥Ä̾ï¤ÎIO¥¯¥é¥¹¤Î¥µ¥Ö¥¯¥é¥¹
-¤ÈƱÍÍ¤ÎÆþ½ÐÎϤ¬¤Ç¤­¤ë¡¥
-
-SuperClass: BasicSocket
-
-Methods:
-
- addr
-
- ¥½¥±¥Ã¥È¤ÎÀܳ¾ðÊó¤òɽ¤¹ÇÛÎó¤òÊÖ¤¹¡¥¤½¤ÎÇÛÎó¤Î³ÆÍ×ÁǤÏÂè1Í×ÁÇ
- ¤¬Ê¸»úÎó "AF_UNIX"¡¤Âè2Í×ÁǤ¬path¤Ç¤¢¤ë¡¥
-
- path
-
- UNIX¥½¥±¥Ã¥È¤Î¥Ñ¥¹¤òÊÖ¤¹¡¥
-
- peeraddr
-
- ÀܳÁê¼êÀ襽¥±¥Ã¥È¤Î¾ðÊó¤òɽ¤¹ÇÛÎó¤òÊÖ¤¹¡¥¤½¤ÎÇÛÎó¤Î³ÆÍ×ÁǤÏ
- addr¥á¥½¥Ã¥É¤¬ÊÖ¤¹ÇÛÎó¤ÈƱ¤¸¤Ç¤¢¤ë¡¥
-
-Single Methods:
-
- open(path)
- new(path)
-
- path¤Ç»ØÄꤷ¤¿¥Ñ¥¹Ì¾¤òÍѤ¤¤ÆÀܳ¤·¤¿¥½¥±¥Ã¥È¤òÊÖ¤¹¡¥
-
--------------------------------------------------------
-Local variables:
-fill-column: 70
-end:
diff --git a/ext/tkutil/MANIFEST b/ext/tkutil/MANIFEST
index 98df4663b3..870e04b586 100644
--- a/ext/tkutil/MANIFEST
+++ b/ext/tkutil/MANIFEST
@@ -1,3 +1,3 @@
MANIFEST
-extconf.rb
tkutil.c
+depend
diff --git a/ext/tkutil/depend b/ext/tkutil/depend
new file mode 100644
index 0000000000..ead83eda57
--- /dev/null
+++ b/ext/tkutil/depend
@@ -0,0 +1 @@
+tkutil.o: tkutil.c ../../ruby.h ../../config.h ../../defines.h
diff --git a/ext/tkutil/extconf.rb b/ext/tkutil/extconf.rb
deleted file mode 100644
index b61a7ac01c..0000000000
--- a/ext/tkutil/extconf.rb
+++ /dev/null
@@ -1,11 +0,0 @@
-for dir in ENV['PATH'].split(':')
- if File.exists? "#{dir}/wish"
- $CFLAGS = $CFLAGS + " -DWISHPATH=" + "'\"#{dir}/wish\"'"
- have_wish = TRUE
- break
- end
-end
-
-if have_wish and have_func('pipe')
- create_makefile("tkutil")
-end
diff --git a/ext/tkutil/tkutil.c b/ext/tkutil/tkutil.c
index 2b74b254c2..51e3412ab5 100644
--- a/ext/tkutil/tkutil.c
+++ b/ext/tkutil/tkutil.c
@@ -47,7 +47,6 @@ Init_tkutil()
VALUE mTK = rb_define_module("TkUtil");
VALUE cTK = rb_define_class("TkKernel", cObject);
- rb_define_const(mTK, "WISH_PATH", str_new2(WISHPATH));
rb_define_singleton_method(mTK, "eval_cmd", tk_eval_cmd, -1);
rb_define_singleton_method(cTK, "new", tk_s_new, -1);
diff --git a/file.c b/file.c
index 0691545c6a..447cba5b52 100644
--- a/file.c
+++ b/file.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:36 $
created at: Mon Nov 15 12:24:34 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -26,7 +26,7 @@
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
#else
-struct timeval {
+stuct timeval {
long tv_sec; /* seconds */
long tv_usec; /* and microseconds */
};
@@ -60,28 +60,37 @@ VALUE
file_open(fname, mode)
char *fname, *mode;
{
- VALUE port;
OpenFile *fptr;
-
- port = obj_alloc(cFile);
-
+ NEWOBJ(port, struct RFile);
+ OBJSETUP(port, cFile, T_FILE);
MakeOpenFile(port, fptr);
- fptr->mode = io_mode_flags(mode);
- fptr->f = fopen(fname, mode);
- if (fptr->f == NULL) {
- if (errno == EMFILE) {
- gc();
- fptr->f = fopen(fname, mode);
- }
- if (fptr->f == NULL) {
- rb_sys_fail(fname);
- }
- }
+ fptr->mode = io_mode_flags(mode);
+ fptr->f = rb_fopen(fname, mode);
fptr->path = strdup(fname);
- return port;
+ return (VALUE)port;
+}
+
+static VALUE
+file_s_open(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE fname, vmode;
+ char *mode;
+
+ rb_scan_args(argc, argv, "11", &fname, &mode);
+ Check_Type(fname, T_STRING);
+ if (!NIL_P(mode)) {
+ Check_Type(mode, T_STRING);
+ mode = RSTRING(mode)->ptr;
+ }
+ else {
+ mode = "r";
+ }
+ return file_open(RSTRING(fname)->ptr, mode);
}
static int
@@ -113,7 +122,7 @@ file_tell(obj)
GetOpenFile(obj, fptr);
pos = ftell(fptr->f);
- if (ferror(fptr->f) != 0) rb_sys_fail(Qnil);
+ if (ferror(fptr->f) != 0) rb_sys_fail(0);
return int2inum(pos);
}
@@ -128,7 +137,7 @@ file_seek(obj, offset, ptrname)
GetOpenFile(obj, fptr);
pos = fseek(fptr->f, NUM2INT(offset), NUM2INT(ptrname));
- if (pos != 0) rb_sys_fail(Qnil);
+ if (pos != 0) rb_sys_fail(0);
clearerr(fptr->f);
return obj;
@@ -143,7 +152,7 @@ file_set_pos(obj, offset)
GetOpenFile(obj, fptr);
pos = fseek(fptr->f, NUM2INT(offset), 0);
- if (pos != 0) rb_sys_fail(Qnil);
+ if (pos != 0) rb_sys_fail(0);
clearerr(fptr->f);
return obj;
@@ -156,7 +165,7 @@ file_rewind(obj)
OpenFile *fptr;
GetOpenFile(obj, fptr);
- if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(Qnil);
+ if (fseek(fptr->f, 0L, 0) != 0) rb_sys_fail(0);
clearerr(fptr->f);
return obj;
@@ -191,14 +200,14 @@ file_isatty(obj)
}
#include <sys/types.h>
-#include <sys/stat.h>
#include <sys/file.h>
+#include <sys/stat.h>
static VALUE
stat_new(st)
struct stat *st;
{
- if (st == Qnil) Bug("stat_new() called with nil");
+ if (!st) Bug("stat_new() called with bad value");
return struct_new(sStat,
INT2FIX((int)st->st_dev),
INT2FIX((int)st->st_ino),
@@ -224,26 +233,7 @@ stat_new(st)
#endif
time_new(st->st_atime, 0),
time_new(st->st_mtime, 0),
- time_new(st->st_ctime, 0),
- Qnil);
-}
-
-static struct stat laststat;
-
-int
-cache_stat(path, st)
- char *path;
- struct stat *st;
-{
- if (strcmp("&", path) == 0) {
- *st = laststat;
- return 0;
- }
- if (stat(path, st) == -1)
- return -1;
-
- laststat = *st;
- return 0;
+ time_new(st->st_ctime, 0));
}
static VALUE
@@ -254,7 +244,7 @@ file_s_stat(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) == -1) {
+ if (stat(fname->ptr, &st) == -1) {
rb_sys_fail(fname->ptr);
}
return stat_new(&st);
@@ -265,12 +255,13 @@ file_stat(obj)
VALUE obj;
{
OpenFile *fptr;
+ struct stat st;
GetOpenFile(obj, fptr);
- if (fstat(fileno(fptr->f), &laststat) == -1) {
+ if (fstat(fileno(fptr->f), &st) == -1) {
rb_sys_fail(fptr->path);
}
- return stat_new(&laststat);
+ return stat_new(&st);
}
static VALUE
@@ -278,6 +269,7 @@ file_s_lstat(obj, fname)
VALUE obj;
struct RString *fname;
{
+#if !defined(MSDOS)
struct stat st;
Check_Type(fname, T_STRING);
@@ -285,12 +277,16 @@ file_s_lstat(obj, fname)
rb_sys_fail(fname->ptr);
}
return stat_new(&st);
+#else
+ rb_notimplement();
+#endif
}
static VALUE
file_lstat(obj)
VALUE obj;
{
+#if !defined(MSDOS)
OpenFile *fptr;
struct stat st;
@@ -299,6 +295,9 @@ file_lstat(obj)
rb_sys_fail(fptr->path);
}
return stat_new(&st);
+#else
+ rb_notimplement();
+#endif
}
static int
@@ -339,7 +338,7 @@ eaccess(path, mode)
struct stat st;
static int euid = -1;
- if (cache_stat(path, &st) < 0) return (-1);
+ if (stat(path, &st) < 0) return (-1);
if (euid == -1)
euid = geteuid ();
@@ -378,7 +377,7 @@ test_d(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (S_ISDIR(st.st_mode)) return TRUE;
return FALSE;
}
@@ -396,7 +395,7 @@ test_p(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (S_ISFIFO(st.st_mode)) return TRUE;
#endif
@@ -426,7 +425,7 @@ test_l(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (lstat(fname->ptr, &st) < 0) return FALSE;
if (S_ISLNK(st.st_mode)) return TRUE;
#endif
@@ -456,7 +455,7 @@ test_S(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (S_ISSOCK(st.st_mode)) return TRUE;
#endif
@@ -478,7 +477,7 @@ test_b(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (S_ISBLK(st.st_mode)) return TRUE;
#endif
@@ -497,7 +496,7 @@ test_c(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (S_ISBLK(st.st_mode)) return TRUE;
return FALSE;
@@ -511,7 +510,7 @@ test_e(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
return TRUE;
}
@@ -583,7 +582,7 @@ test_f(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (S_ISREG(st.st_mode)) return TRUE;
return FALSE;
}
@@ -596,7 +595,7 @@ test_z(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (st.st_size == 0) return TRUE;
return FALSE;
}
@@ -609,7 +608,7 @@ test_s(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (st.st_size == 0) return FALSE;
return int2inum(st.st_size);
}
@@ -622,7 +621,7 @@ test_owned(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (st.st_uid == geteuid()) return TRUE;
return FALSE;
}
@@ -635,7 +634,7 @@ test_rowned(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (st.st_uid == getuid()) return TRUE;
return FALSE;
}
@@ -649,7 +648,7 @@ test_grpowned(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) return FALSE;
+ if (stat(fname->ptr, &st) < 0) return FALSE;
if (st.st_gid == getegid()) return TRUE;
#else
Check_Type(fname, T_STRING);
@@ -665,7 +664,7 @@ check3rdbyte(file, mode)
{
struct stat st;
- if (cache_stat(file, &st) < 0) return FALSE;
+ if (stat(file, &st) < 0) return FALSE;
if (st.st_mode & mode) return TRUE;
return FALSE;
}
@@ -719,7 +718,7 @@ file_s_type(obj, fname)
char *t;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
+ if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
if (S_ISREG(st.st_mode)) {
t = "file";
@@ -763,7 +762,7 @@ file_s_atime(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
+ if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
return time_new(st.st_atime, 0);
}
@@ -789,7 +788,7 @@ file_s_mtime(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
+ if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
return time_new(st.st_mtime, 0);
}
@@ -815,7 +814,7 @@ file_s_ctime(obj, fname)
struct stat st;
Check_Type(fname, T_STRING);
- if (cache_stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
+ if (stat(fname->ptr, &st) < 0) rb_sys_fail(fname->ptr);
return time_new(st.st_ctime, 0);
}
@@ -868,8 +867,13 @@ file_chmod(obj, vmode)
mode = NUM2INT(vmode);
GetOpenFile(obj, fptr);
+#if defined(DJGPP) || defined(__CYGWIN32__)
+ if (chmod(fptr->path, mode) == -1)
+ rb_sys_fail(fptr->path);
+#else
if (fchmod(fileno(fptr->f), mode) == -1)
rb_sys_fail(fptr->path);
+#endif
return INT2FIX(0);
}
@@ -897,13 +901,13 @@ file_s_chown(argc, argv)
int n;
rb_scan_args(argc, argv, "2*", &o, &g, &rest);
- if (o == Qnil) {
+ if (NIL_P(o)) {
arg.owner = -1;
}
else {
arg.owner = NUM2INT(o);
}
- if (g == Qnil) {
+ if (NIL_P(g)) {
arg.group = -1;
}
else {
@@ -921,13 +925,18 @@ file_chown(obj, owner, group)
OpenFile *fptr;
GetOpenFile(obj, fptr);
+#if defined(DJGPP) || defined(__CYGWIN32__)
+ if (chown(fptr->path, NUM2INT(owner), NUM2INT(group)) == -1)
+ rb_sys_fail(fptr->path);
+#else
if (fchown(fileno(fptr->f), NUM2INT(owner), NUM2INT(group)) == -1)
rb_sys_fail(fptr->path);
+#endif
return INT2FIX(0);
}
-struct timeval *time_timeval();
+struct timeval time_timeval();
#ifdef HAVE_UTIMES
@@ -951,8 +960,8 @@ file_s_utime(argc, argv)
rb_scan_args(argc, argv, "2*", &atime, &mtime, &rest);
- tvp[0] = *time_timeval(atime);
- tvp[1] = *time_timeval(mtime);
+ tvp[0] = time_timeval(atime);
+ tvp[1] = time_timeval(mtime);
n = apply2files(utime_internal, rest, tvp);
return INT2FIX(n);
@@ -987,15 +996,15 @@ file_s_utime(argc, argv)
{
VALUE atime, mtime, rest;
int n;
- struct timeval *tv;
+ struct timeval tv;
struct utimbuf utbuf;
rb_scan_args(argc, argv, "2*", &atime, &mtime, &rest);
tv = time_timeval(atime);
- utbuf.actime = tv->tv_sec;
+ utbuf.actime = tv.tv_sec;
tv = time_timeval(mtime);
- utbuf.modtime = tv->tv_sec;
+ utbuf.modtime = tv.tv_sec;
n = apply2files(utime_internal, rest, &utbuf);
return INT2FIX(n);
@@ -1021,12 +1030,16 @@ file_s_symlink(obj, from, to)
VALUE obj;
struct RString *from, *to;
{
+#if !defined(MSDOS)
Check_Type(from, T_STRING);
Check_Type(to, T_STRING);
if (symlink(from->ptr, to->ptr) < 0)
rb_sys_fail(from->ptr);
return TRUE;
+#else
+ rb_notimplement();
+#endif
}
static VALUE
@@ -1034,6 +1047,7 @@ file_s_readlink(obj, path)
VALUE obj;
struct RString *path;
{
+#if !defined(MSDOS)
char buf[MAXPATHLEN];
int cc;
@@ -1043,6 +1057,9 @@ file_s_readlink(obj, path)
rb_sys_fail(path->ptr);
return str_new(buf, cc);
+#else
+ rb_notimplement();
+#endif
}
static void
@@ -1060,7 +1077,7 @@ file_s_unlink(obj, args)
{
int n;
- n = apply2files(unlink_internal, args, Qnil);
+ n = apply2files(unlink_internal, args, 0);
return INT2FIX(n);
}
@@ -1093,82 +1110,11 @@ file_s_umask(argc, argv)
omask = umask(NUM2INT(argv[1]));
}
else {
- Fail("wrong # of argument");
+ ArgError("wrong # of argument");
}
return INT2FIX(omask);
}
-#if defined(HAVE_TRUNCATE) || defined(HAVE_CHSIZE)
-static VALUE
-file_s_truncate(obj, path, len)
- VALUE obj, len;
- struct RString *path;
-{
- Check_Type(path, T_STRING);
-
-#ifdef HAVE_TRUNCATE
- if (truncate(path->ptr, NUM2INT(len)) < 0)
- rb_sys_fail(path->ptr);
-#else
-# ifdef HAVE_CHSIZE
- {
- int tmpfd;
-
-#if defined(NT)
- if ((tmpfd = open(path->ptr, O_RDWR)) < 0) {
- rb_sys_fail(path->ptr);
- }
-#else
- if ((tmpfd = open(path->ptr, 0)) < 0) {
- rb_sys_fail(path->ptr);
- }
-#endif
- if (chsize(tmpfd, NUM2INT(len)) < 0) {
- close(tmpfd);
- rb_sys_fail(path->ptr);
- }
- close(tmpfd);
- }
-# endif
-#endif
- return TRUE;
-}
-
-static VALUE
-file_truncate(obj, len)
- VALUE obj, len;
-{
- OpenFile *fptr;
-
- GetOpenFile(obj, fptr);
-
- if (!(fptr->mode & FMODE_WRITABLE)) {
- Fail("not opened for writing");
- }
-#ifdef HAVE_TRUNCATE
- if (ftruncate(fileno(fptr->f), NUM2INT(len)) < 0)
- rb_sys_fail(fptr->path);
-#else
-# ifdef HAVE_CHSIZE
- if (chsize(fileno(fptr->f), NUM2INT(len)) < 0)
- rb_sys_fail(fptr->path);
-# endif
-#endif
- return TRUE;
-}
-#endif
-
-#ifdef HAVE_FCNTL
-static VALUE
-file_fcntl(obj, req, arg)
- VALUE obj, req;
- struct RString *arg;
-{
- io_ctl(obj, req, arg, 0);
- return obj;
-}
-#endif
-
static VALUE
file_s_expand_path(obj, fname)
VALUE obj;
@@ -1218,7 +1164,7 @@ file_s_expand_path(obj, fname)
#ifdef HAVE_GETCWD
getcwd(buf, MAXPATHLEN);
#else
- getwd(buf)l
+ getwd(buf);
#endif
p = &buf[strlen(buf)];
}
@@ -1292,17 +1238,17 @@ file_s_basename(argc, argv)
rb_scan_args(argc, argv, "11", &fname, &ext);
Check_Type(fname, T_STRING);
- if (ext) Check_Type(ext, T_STRING);
+ if (!NIL_P(ext)) Check_Type(ext, T_STRING);
p = strrchr(fname->ptr, '/');
- if (p == Qnil) {
- if (ext) {
+ if (!p) {
+ if (!NIL_P(ext)) {
f = rmext(fname->ptr, ext->ptr);
if (f) return str_new(fname->ptr, f);
}
return (VALUE)fname;
}
p++; /* skip last `/' */
- if (ext) {
+ if (!NIL_P(ext)) {
f = rmext(p, ext->ptr);
if (f) return str_new(p, f);
}
@@ -1315,12 +1261,119 @@ file_s_dirname(obj, fname)
struct RString *fname;
{
char *p;
+
Check_Type(fname, T_STRING);
p = strrchr(fname->ptr, '/');
- if (p == Qnil) return (VALUE)fname;
+ if (!p) {
+ return str_new(0,0);
+ }
return str_new(fname->ptr, p - fname->ptr);
}
+static VALUE separator;
+
+static VALUE
+file_s_split(obj, path)
+ VALUE obj, path;
+{
+ return assoc_new(file_s_dirname(Qnil, path), file_s_basename(1,&path));
+}
+
+static VALUE
+file_s_truncate(obj, path, len)
+ VALUE obj, len;
+ struct RString *path;
+{
+ Check_Type(path, T_STRING);
+
+#ifdef HAVE_TRUNCATE
+ if (truncate(path->ptr, NUM2INT(len)) < 0)
+ rb_sys_fail(path->ptr);
+#else
+# ifdef HAVE_CHSIZE
+ {
+ int tmpfd;
+
+# if defined(NT)
+ if ((tmpfd = open(path->ptr, O_RDWR)) < 0) {
+ rb_sys_fail(path->ptr);
+ }
+# else
+ if ((tmpfd = open(path->ptr, 0)) < 0) {
+ rb_sys_fail(path->ptr);
+ }
+# endif
+ if (chsize(tmpfd, NUM2INT(len)) < 0) {
+ close(tmpfd);
+ rb_sys_fail(path->ptr);
+ }
+ close(tmpfd);
+ }
+# else
+ rb_notimplement();
+# endif
+#endif
+ return TRUE;
+}
+
+static VALUE
+file_truncate(obj, len)
+ VALUE obj, len;
+{
+ OpenFile *fptr;
+
+ GetOpenFile(obj, fptr);
+
+ if (!(fptr->mode & FMODE_WRITABLE)) {
+ Fail("not opened for writing");
+ }
+#ifdef HAVE_TRUNCATE
+ if (ftruncate(fileno(fptr->f), NUM2INT(len)) < 0)
+ rb_sys_fail(fptr->path);
+#else
+# ifdef HAVE_CHSIZE
+ if (chsize(fileno(fptr->f), NUM2INT(len)) < 0)
+ rb_sys_fail(fptr->path);
+# else
+ rb_notimplement();
+# endif
+#endif
+ return TRUE;
+}
+
+static VALUE
+file_fcntl(obj, req, arg)
+ VALUE obj, req;
+ struct RString *arg;
+{
+#ifdef HAVE_FCNTL
+ io_ctl(obj, req, arg, 0);
+#else
+ rb_notimplement();
+#endif
+ return obj;
+}
+
+static VALUE
+file_flock(obj, operation)
+ VALUE obj;
+ VALUE operation;
+{
+ OpenFile *fptr;
+
+ GetOpenFile(obj, fptr);
+
+ if (flock(fileno(fptr->f), NUM2INT(operation)) < 0) {
+#ifdef EWOULDBLOCK
+ if (errno = EWOULDBLOCK) {
+ return FALSE;
+ }
+#endif
+ rb_sys_fail(fptr->path);
+ }
+ return obj;
+}
+
static void
test_check(n, argc, argv)
int n, argc;
@@ -1329,7 +1382,7 @@ test_check(n, argc, argv)
int i;
n+=1;
- if (n < argc) Fail("Wrong # of arguments(%d for %d)", argc, n);
+ if (n < argc) ArgError("Wrong # of arguments(%d for %d)", argc, n);
for (i=1; i<n; i++) {
Check_Type(argv[i], T_STRING);
}
@@ -1344,7 +1397,7 @@ f_test(argc, argv)
{
int cmd;
- if (argc == 0) Fail("Wrong # of arguments");
+ if (argc == 0) ArgError("Wrong # of arguments");
Need_Fixnum(argv[0]);
cmd = FIX2INT(argv[0]);
if (strchr("bcdefgGkloOprRsSuwWxXz", cmd)) {
@@ -1423,7 +1476,7 @@ f_test(argc, argv)
struct stat st;
CHECK(1);
- if (cache_stat(RSTRING(argv[1])->ptr, &st) == -1) {
+ if (stat(RSTRING(argv[1])->ptr, &st) == -1) {
rb_sys_fail(RSTRING(argv[1])->ptr);
}
@@ -1474,7 +1527,8 @@ Init_File()
mFileTest = rb_define_module("FileTest");
rb_define_module_function(mFileTest, "directory?", test_d, 1);
- rb_define_module_function(mFileTest, "exists?", test_e, 1);
+ rb_define_module_function(mFileTest, "exist?", test_e, 1);
+ rb_define_module_function(mFileTest, "exists?", test_e, 1); /* temporary */
rb_define_module_function(mFileTest, "readable?", test_r, 1);
rb_define_module_function(mFileTest, "readable_real?", test_R, 1);
rb_define_module_function(mFileTest, "writable?", test_w, 1);
@@ -1501,9 +1555,11 @@ Init_File()
cFile = rb_define_class("File", cIO);
rb_extend_object(cFile, CLASS_OF(mFileTest));
+ rb_define_singleton_method(cFile, "open", file_s_open, -1);
+
rb_define_singleton_method(cFile, "stat", file_s_stat, 1);
rb_define_singleton_method(cFile, "lstat", file_s_lstat, 1);
- rb_define_singleton_method(cFile, "type", file_s_type, 1);
+ rb_define_singleton_method(cFile, "ftype", file_s_type, 1);
rb_define_singleton_method(cFile, "atime", file_s_atime, 1);
rb_define_singleton_method(cFile, "mtime", file_s_mtime, 1);
@@ -1521,13 +1577,15 @@ Init_File()
rb_define_singleton_method(cFile, "delete", file_s_unlink, -2);
rb_define_singleton_method(cFile, "rename", file_s_rename, 2);
rb_define_singleton_method(cFile, "umask", file_s_umask, -1);
-#if defined(HAVE_TRUNCATE) || defined(HAVE_CHSIZE)
rb_define_singleton_method(cFile, "truncate", file_s_truncate, 2);
-#endif
rb_define_singleton_method(cFile, "expand_path", file_s_expand_path, 1);
rb_define_singleton_method(cFile, "basename", file_s_basename, -1);
rb_define_singleton_method(cFile, "dirname", file_s_dirname, 1);
+ separator = INT2FIX('/');
+ rb_define_const(cFile, "Separator", separator);
+ rb_define_singleton_method(cFile, "split", file_s_split, 1);
+
rb_define_method(cFile, "stat", file_stat, 0);
rb_define_method(cFile, "lstat", file_lstat, 0);
@@ -1537,9 +1595,7 @@ Init_File()
rb_define_method(cFile, "chmod", file_chmod, 1);
rb_define_method(cFile, "chown", file_chown, 2);
-#if defined(HAVE_TRUNCATE) || defined(HAVE_CHSIZE)
rb_define_method(cFile, "truncate", file_truncate, 1);
-#endif
rb_define_method(cFile, "tell", file_tell, 0);
rb_define_method(cFile, "seek", file_seek, 2);
@@ -1553,9 +1609,26 @@ Init_File()
rb_define_method(cFile, "eof", file_eof, 0);
rb_define_method(cFile, "eof?", file_eof, 0);
-#ifdef HAVE_FCNTL
rb_define_method(cIO, "fcntl", file_fcntl, 2);
-#endif
+ rb_define_method(cFile, "flock", file_flock, 1);
+
+# ifndef LOCK_SH
+# define LOCK_SH 1
+# endif
+# ifndef LOCK_EX
+# define LOCK_EX 2
+# endif
+# ifndef LOCK_NB
+# define LOCK_NB 4
+# endif
+# ifndef LOCK_UN
+# define LOCK_UN 8
+# endif
+
+ rb_define_const(cFile, "LOCK_SH", INT2FIX(LOCK_SH));
+ rb_define_const(cFile, "LOCK_EX", INT2FIX(LOCK_EX));
+ rb_define_const(cFile, "LOCK_UN", INT2FIX(LOCK_UN));
+ rb_define_const(cFile, "LOCK_NB", INT2FIX(LOCK_NB));
rb_define_method(cFile, "path", file_path, 0);
@@ -1564,5 +1637,5 @@ Init_File()
sStat = struct_define("Stat", "dev", "ino", "mode",
"nlink", "uid", "gid", "rdev",
"size", "blksize", "blocks",
- "atime", "mtime", "ctime", Qnil);
+ "atime", "mtime", "ctime", 0);
}
diff --git a/gc.c b/gc.c
index e3c809cded..c1817b7cd0 100644
--- a/gc.c
+++ b/gc.c
@@ -6,18 +6,23 @@
$Date: 1995/01/12 08:54:47 $
created at: Tue Oct 5 09:44:46 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
#include "ruby.h"
-#include "env.h"
+#include "sig.h"
#include "st.h"
#include "node.h"
+#include "env.h"
#include "re.h"
#include <stdio.h>
#include <setjmp.h>
+#ifdef _AIX
+#pragma alloca
+#endif
+
void *malloc();
void *calloc();
void *realloc();
@@ -36,10 +41,10 @@ xmalloc(size)
if (size == 0) size = 1;
mem = malloc(size);
- if (mem == Qnil) {
+ if (!mem) {
gc();
mem = malloc(size);
- if (mem == Qnil)
+ if (!mem)
Fatal("failed to allocate memory");
}
@@ -65,12 +70,12 @@ xrealloc(ptr, size)
{
void *mem;
- if (ptr == Qnil) return xmalloc(size);
+ if (!ptr) return xmalloc(size);
mem = realloc(ptr, size);
- if (mem == Qnil) {
+ if (!mem) {
gc();
mem = realloc(ptr, size);
- if (mem == Qnil)
+ if (!mem)
Fatal("failed to allocate memory(realloc)");
}
@@ -107,12 +112,6 @@ Paradigm Associates Inc Phone: 617-492-6079
Cambridge, MA 02138
*/
-#ifdef sparc
-#define FLUSH_REGISTER_WINDOWS asm("ta 3")
-#else
-#define FLUSH_REGISTER_WINDOWS /* empty */
-#endif
-
static int dont_gc;
VALUE
@@ -136,10 +135,9 @@ gc_s_disable()
VALUE mGC;
static struct gc_list {
- int n;
VALUE *varptr;
struct gc_list *next;
-} *Global_List = Qnil;
+} *Global_List = 0;
void
rb_global_variable(var)
@@ -150,7 +148,6 @@ rb_global_variable(var)
tmp = ALLOC(struct gc_list);
tmp->next = Global_List;
tmp->varptr = var;
- tmp->n = 1;
Global_List = tmp;
}
@@ -171,6 +168,7 @@ typedef struct RVALUE {
struct RData data;
struct RStruct rstruct;
struct RBignum bignum;
+ struct RFile file;
struct RNode node;
struct RMatch match;
struct RVarmap varmap;
@@ -236,15 +234,15 @@ newobj()
}
VALUE
-data_new(datap, dmark, dfree)
+data_object_alloc(class, datap, dmark, dfree)
+ VALUE class;
void *datap;
void (*dfree)();
void (*dmark)();
{
- extern VALUE cData;
struct RData *data = (struct RData*)newobj();
- OBJSETUP(data, cData, T_DATA);
+ OBJSETUP(data, class, T_DATA);
data->data = datap;
data->dfree = dfree;
data->dmark = dmark;
@@ -253,9 +251,9 @@ data_new(datap, dmark, dfree)
}
extern st_table *rb_class_tbl;
-static VALUE *stack_start_ptr;
+VALUE *gc_stack_start;
-static long
+static int
looks_pointerp(p)
register RVALUE *p;
{
@@ -288,8 +286,8 @@ mark_locations_array(x, n)
}
}
-static void
-mark_locations(start, end)
+void
+gc_mark_locations(start, end)
VALUE *start, *end;
{
VALUE *tmp;
@@ -351,8 +349,8 @@ gc_mark(obj)
register RVALUE *obj;
{
Top:
- if (obj == Qnil) return; /* nil not marked */
if (FIXNUM_P(obj)) return; /* fixnum not marked */
+ if (rb_special_const_p(obj)) return; /* special const not marked */
if (obj->as.basic.flags == 0) return; /* free cell */
if (obj->as.basic.flags & FL_MARK) return; /* marked */
@@ -408,7 +406,10 @@ gc_mark(obj)
break;
case T_STRING:
- if (obj->as.string.orig) gc_mark(obj->as.string.orig);
+ if (obj->as.string.orig) {
+ obj = (RVALUE*)obj->as.string.orig;
+ goto Top;
+ }
break;
case T_DATA:
@@ -419,6 +420,7 @@ gc_mark(obj)
if (obj->as.object.iv_tbl) mark_tbl(obj->as.object.iv_tbl);
break;
+ case T_FILE:
case T_MATCH:
case T_REGEXP:
case T_FLOAT:
@@ -426,7 +428,9 @@ gc_mark(obj)
break;
case T_VARMAP:
- gc_mark(obj->as.varmap.next);
+ gc_mark(obj->as.varmap.val);
+ obj = (RVALUE*)obj->as.varmap.next;
+ goto Top;
break;
case T_SCOPE:
@@ -435,7 +439,7 @@ gc_mark(obj)
VALUE *tbl = obj->as.scope.local_vars;
while (n--) {
- gc_mark(*tbl);
+ gc_mark_maybe(*tbl);
tbl++;
}
}
@@ -512,12 +516,12 @@ obj_free(obj)
break;
case T_MODULE:
case T_CLASS:
- rb_clear_cache(obj);
+ rb_clear_cache();
st_free_table(obj->as.class.m_tbl);
if (obj->as.object.iv_tbl) st_free_table(obj->as.object.iv_tbl);
break;
case T_STRING:
- if (obj->as.string.orig == Qnil) free(obj->as.string.ptr);
+ if (!obj->as.string.orig) free(obj->as.string.ptr);
break;
case T_ARRAY:
free(obj->as.array.ptr);
@@ -538,17 +542,26 @@ obj_free(obj)
free(obj->as.match.regs);
if (obj->as.match.ptr) free(obj->as.match.ptr);
break;
+ case T_FILE:
+ io_fptr_finalize(obj->as.file.fptr);
+ free(obj->as.file.fptr);
+ break;
case T_ICLASS:
/* iClass shares table with the module */
+ break;
+
case T_FLOAT:
case T_VARMAP:
+ case T_TRUE:
+ case T_FALSE:
break;
+
case T_BIGNUM:
- free(obj->as.bignum.digits);
+ if (obj->as.bignum.digits) free(obj->as.bignum.digits);
break;
case T_NODE:
- if (nd_type(obj) == NODE_SCOPE && obj->as.node.nd_tbl) {
- free(obj->as.node.nd_tbl);
+ if (nd_type(obj) == NODE_SCOPE && obj->as.node.u1.tbl) {
+ free(obj->as.node.u1.tbl);
}
return; /* no need to free iv_tbl */
@@ -576,7 +589,7 @@ gc_mark_frame(frame)
VALUE *tbl = frame->argv;
while (n--) {
- gc_mark(*tbl);
+ gc_mark_maybe(*tbl);
tbl++;
}
}
@@ -601,18 +614,23 @@ gc()
gc_mark_frame(frame);
}
gc_mark(the_scope);
+ gc_mark(the_dyna_vars);
FLUSH_REGISTER_WINDOWS;
/* This assumes that all registers are saved into the jmp_buf */
setjmp(save_regs_gc_mark);
- mark_locations((VALUE*)save_regs_gc_mark,
- (VALUE*)(((char*)save_regs_gc_mark)+sizeof(save_regs_gc_mark)));
- mark_locations(stack_start_ptr, (VALUE*) &stack_end);
-#if defined(THINK_C)
- mark_locations((VALUE*)((char*)stack_start_ptr + 2),
+ gc_mark_locations((VALUE*)save_regs_gc_mark,
+ (VALUE*)(((char*)save_regs_gc_mark)+sizeof(save_regs_gc_mark)));
+ gc_mark_locations(gc_stack_start, (VALUE*) &stack_end);
+#ifdef THINK_C
+ gc_mark_locations((VALUE*)((char*)gc_stack_start + 2),
(VALUE*)((char*)&stack_end + 2));
#endif
+#ifdef THREAD
+ gc_mark_threads();
+#endif
+
/* mark protected global variables */
for (list = Global_List; list; list = list->next) {
gc_mark(*list->varptr);
@@ -631,7 +649,7 @@ init_stack()
{
VALUE start;
- stack_start_ptr = &start;
+ gc_stack_start = &start;
}
void
@@ -641,12 +659,87 @@ init_heap()
add_heap();
}
+static VALUE
+os_live_obj(obj)
+ VALUE obj;
+{
+ int i;
+ int n = 0;
+
+ for (i = 0; i < heaps_used; i++) {
+ RVALUE *p, *pend;
+
+ p = heaps[i]; pend = p + HEAP_SLOTS;
+ for (;p < pend; p++) {
+ if (p->as.basic.flags) {
+ switch (TYPE(p)) {
+ case T_ICLASS:
+ case T_VARMAP:
+ case T_SCOPE:
+ case T_NODE:
+ continue;
+ case T_CLASS:
+ if (FL_TEST(p, FL_SINGLETON)) continue;
+ default:
+ rb_yield(p);
+ n++;
+ }
+ }
+ }
+ }
+
+ return INT2FIX(n);
+}
+
+static VALUE
+os_obj_of(obj, of)
+ VALUE obj, of;
+{
+ int i;
+ int n = 0;
+
+ for (i = 0; i < heaps_used; i++) {
+ RVALUE *p, *pend;
+
+ p = heaps[i]; pend = p + HEAP_SLOTS;
+ for (;p < pend; p++) {
+ if (p->as.basic.flags) {
+ switch (TYPE(p)) {
+ case T_ICLASS:
+ case T_VARMAP:
+ case T_SCOPE:
+ case T_NODE:
+ continue;
+ case T_CLASS:
+ if (FL_TEST(p, FL_SINGLETON)) continue;
+ default:
+ if (obj_is_kind_of(p, of)) {
+ rb_yield(p);
+ n++;
+ }
+ }
+ }
+ }
+ }
+
+ return INT2FIX(n);
+}
+
+extern VALUE cModule;
+
void
Init_GC()
{
+ VALUE mObSpace;
+
mGC = rb_define_module("GC");
rb_define_singleton_method(mGC, "start", gc, 0);
rb_define_singleton_method(mGC, "enable", gc_s_enable, 0);
rb_define_singleton_method(mGC, "disable", gc_s_disable, 0);
rb_define_method(mGC, "garbage_collect", gc, 0);
+
+ mObSpace = rb_define_module("ObjectSpace");
+ rb_define_module_function(mObSpace, "each_live_object", os_live_obj, 0);
+ rb_define_module_function(mObSpace, "each_object_of", os_obj_of, 1);
+ rb_define_module_function(mObSpace, "garbage_collect", gc, 0);
}
diff --git a/glob.c b/glob.c
index b0c750f243..7599c1ca72 100644
--- a/glob.c
+++ b/glob.c
@@ -48,7 +48,7 @@
# endif /* !USG */
#endif /* !HAVE_DIRENT_H */
-#if defined (_POSIX_SOURCE)
+#if defined (_POSIX_SOURCE) || defined(DJGPP)
/* Posix does not require that the d_ino field be present, and some
systems do not provide it. */
# define REAL_DIR_ENTRY(dp) 1
@@ -70,11 +70,15 @@
# define bcopy(s, d, n) (memcpy ((d), (s), (n)))
+#ifdef _AIX
+#pragma alloca
+#else
#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
#include <alloca.h>
#else
char *alloca ();
#endif
+#endif
#include "fnmatch.h"
@@ -376,7 +380,9 @@ char **
glob_filename (pathname)
char *pathname;
{
+#ifndef strrchr
char *strrchr();
+#endif
char **result;
unsigned int result_size;
diff --git a/hash.c b/hash.c
index da4671409f..d2ee598869 100644
--- a/hash.c
+++ b/hash.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:26 $
created at: Mon Nov 22 18:51:18 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -27,38 +27,85 @@ static VALUE envtbl;
static ID hash;
VALUE f_getenv(), f_setenv();
-static VALUE
+static int
rb_cmp(a, b)
VALUE a, b;
{
- return rb_equal(a, b)?0:1;
+ if (FIXNUM_P(a)) {
+ if (FIXNUM_P(b)) return a != b;
+ }
+
+ if (TYPE(a) == T_STRING) {
+ if (TYPE(b) == T_STRING) return str_cmp(a, b);
+ }
+
+ return !rb_eql(a, b);
}
-static VALUE
+static int
rb_hash(a, mod)
VALUE a;
int mod;
{
- return rb_funcall(a, hash, 0) % mod;
+ unsigned int hval;
+
+ switch (TYPE(a)) {
+ case T_FIXNUM:
+ hval = a;
+ break;
+
+ case T_STRING:
+ hval = str_hash(a);
+ break;
+
+ default:
+ hval = rb_funcall(a, hash, 0);
+ hval = FIX2INT(hval);
+ }
+ return hval % mod;
}
-#define ASSOC_KEY(a) RASSOC(a)->car
-#define ASSOC_VAL(a) RASSOC(a)->cdr
+static struct st_hash_type objhash = {
+ rb_cmp,
+ rb_hash,
+};
static VALUE
-hash_s_new(class)
+hash_s_new(argc, argv, class)
+ int argc;
+ VALUE *argv;
VALUE class;
{
+ VALUE sz;
+ int size;
+
NEWOBJ(hash, struct RHash);
OBJSETUP(hash, class, T_HASH);
- hash->tbl = st_init_table(rb_cmp, rb_hash);
+ rb_scan_args(argc, argv, "01", &sz);
+ if (NIL_P(sz)) size = 0;
+ else size = NUM2INT(sz);
+
+ hash->tbl = st_init_table_with_size(&objhash, size);
return (VALUE)hash;
}
static VALUE hash_clone();
+VALUE
+hash_new2(class)
+ VALUE class;
+{
+ return hash_s_new(0, 0, class);
+}
+
+VALUE
+hash_new()
+{
+ return hash_new2(cHash);
+}
+
static VALUE
hash_s_create(argc, argv, class)
int argc;
@@ -80,9 +127,9 @@ hash_s_create(argc, argv, class)
}
if (argc % 2 != 0) {
- Fail("odd number args for Hash");
+ ArgError("odd number args for Hash");
}
- hash = (struct RHash*)hash_s_new(class);
+ hash = (struct RHash*)hash_new2(class);
for (i=0; i<argc; i+=2) {
st_insert(hash->tbl, argv[i], argv[i+1]);
@@ -91,12 +138,6 @@ hash_s_create(argc, argv, class)
return (VALUE)hash;
}
-VALUE
-hash_new()
-{
- return hash_s_new(cHash);
-}
-
static VALUE
hash_clone(hash)
struct RHash *hash;
@@ -109,7 +150,7 @@ hash_clone(hash)
return (VALUE)hash2;
}
-static VALUE
+VALUE
hash_aref(hash, key)
struct RHash *hash;
VALUE key;
@@ -128,29 +169,21 @@ hash_indexes(hash, args)
struct RArray *args;
{
VALUE *p, *pend;
- struct RArray *new_hash;
+ struct RArray *indexes;
int i = 0;
- if (!args || args->len == 0) {
- Fail("wrong # of argment");
- }
- else if (args->len == 1) {
- if (TYPE(args->ptr[0])) {
- args = (struct RArray*)rb_to_a(args->ptr[0]);
- }
- else {
- args = (struct RArray*)args->ptr[0];
- }
+ if (!args || NIL_P(args)) {
+ return ary_new2(0);
}
- new_hash = (struct RArray*)ary_new2(args->len);
+ indexes = (struct RArray*)ary_new2(args->len);
p = args->ptr; pend = p + args->len;
while (p < pend) {
- new_hash->ptr[i++] = hash_aref(hash, *p++);
+ indexes->ptr[i++] = hash_aref(hash, *p++);
}
- new_hash->len = i;
- return (VALUE)new_hash;
+ indexes->len = i;
+ return (VALUE)indexes;
}
static VALUE
@@ -162,6 +195,7 @@ hash_delete(hash, key)
if (st_delete(hash->tbl, &key, &val))
return val;
+ if (iterator_p()) rb_yield(Qnil);
return Qnil;
}
@@ -209,7 +243,7 @@ static VALUE
hash_delete_if(hash)
struct RHash *hash;
{
- st_foreach(hash->tbl, delete_if_i, Qnil);
+ st_foreach(hash->tbl, delete_if_i, 0);
return (VALUE)hash;
}
@@ -235,7 +269,7 @@ hash_aset(hash, key, val)
struct RHash *hash;
VALUE key, val;
{
- if (val == Qnil) {
+ if (NIL_P(val)) {
hash_delete(hash, key);
return Qnil;
}
@@ -253,6 +287,15 @@ hash_length(hash)
return INT2FIX(hash->tbl->num_entries);
}
+VALUE
+hash_empty_p(hash)
+ struct RHash *hash;
+{
+ if (hash->tbl->num_entries == 0)
+ return TRUE;
+ return FALSE;
+}
+
static int
each_value_i(key, value)
VALUE key, value;
@@ -327,15 +370,14 @@ inspect_i(key, value, str)
struct RString *str;
{
VALUE str2;
- ID inspect = rb_intern("inspect");
if (str->len > 1) {
str_cat(str, ", ", 2);
}
- str2 = rb_funcall(key, inspect, 0, 0);
+ str2 = rb_inspect(key);
str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
str_cat(str, "=>", 2);
- str2 = rb_funcall(value, inspect, 0, 0);
+ str2 = rb_inspect(value);
str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
return ST_CONTINUE;
@@ -554,7 +596,7 @@ f_getenv(obj, name)
Check_Type(name, T_STRING);
if (strlen(name->ptr) != name->len)
- Fail("Bad environment name");
+ ArgError("Bad environment name");
env = getenv(name->ptr);
if (env) {
@@ -569,7 +611,7 @@ f_setenv(obj, name, value)
struct RString *name, *value;
{
Check_Type(name, T_STRING);
- if (value == Qnil) {
+ if (NIL_P(value)) {
env_delete(obj, name);
return Qnil;
}
@@ -577,9 +619,9 @@ f_setenv(obj, name, value)
Check_Type(value, T_STRING);
if (strlen(name->ptr) != name->len)
- Fail("Bad environment name");
+ ArgError("Bad environment name");
if (strlen(value->ptr) != value->len)
- Fail("Bad environment value");
+ ArgError("Bad environment value");
setenv(name->ptr, value->ptr, 1);
return TRUE;
@@ -588,7 +630,7 @@ f_setenv(obj, name, value)
static VALUE
env_to_s()
{
- return str_new2("$ENV");
+ return str_new2("ENV");
}
void
@@ -603,7 +645,7 @@ Init_Hash()
rb_include_module(cHash, mEnumerable);
- rb_define_singleton_method(cHash, "new", hash_s_new, 0);
+ rb_define_singleton_method(cHash, "new", hash_s_new, -1);
rb_define_singleton_method(cHash, "[]", hash_s_create, -1);
rb_define_method(cHash,"clone", hash_clone, 0);
@@ -619,6 +661,8 @@ Init_Hash()
rb_define_method(cHash,"indexes", hash_indexes, -2);
rb_define_method(cHash,"length", hash_length, 0);
rb_define_alias(cHash, "size", "length");
+ rb_define_method(cHash,"empty?", hash_empty_p, 0);
+
rb_define_method(cHash,"each", hash_each_pair, 0);
rb_define_method(cHash,"each_value", hash_each_value, 0);
rb_define_method(cHash,"each_key", hash_each_key, 0);
@@ -632,8 +676,11 @@ Init_Hash()
rb_define_method(cHash,"delete_if", hash_delete_if, 0);
rb_define_method(cHash,"clear", hash_clear, 0);
+ rb_define_method(cHash,"include?", hash_has_key, 1);
rb_define_method(cHash,"has_key?", hash_has_key, 1);
rb_define_method(cHash,"has_value?", hash_has_value, 1);
+ rb_define_method(cHash,"key?", hash_has_key, 1);
+ rb_define_method(cHash,"value?", hash_has_value, 1);
envtbl = obj_alloc(cObject);
rb_extend_object(envtbl, mEnumerable);
@@ -645,5 +692,5 @@ Init_Hash()
rb_define_singleton_method(envtbl,"to_s", env_to_s, 0);
rb_define_readonly_variable("$ENV", &envtbl);
- rb_define_const(cKernel, "ENV", envtbl);
+ rb_define_global_const("ENV", envtbl);
}
diff --git a/inits.c b/inits.c
index 673b6eed4b..a6eb7f5150 100644
--- a/inits.c
+++ b/inits.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:38 $
created at: Tue Dec 28 16:01:58 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -18,16 +18,20 @@ rb_call_inits()
Init_sym();
Init_var_tables();
Init_Object();
+#ifdef THREAD
+ Init_Thread();
+#endif
Init_GC();
Init_eval();
Init_Comparable();
Init_Enumerable();
+ Init_String();
+ Init_Exception();
Init_Numeric();
Init_Bignum();
Init_Array();
Init_Hash();
Init_Struct();
- Init_String();
Init_Regexp();
Init_pack();
Init_Range();
diff --git a/io.c b/io.c
index 47bd4b0fb0..43e2458668 100644
--- a/io.c
+++ b/io.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:39 $
created at: Fri Oct 15 18:08:59 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -16,8 +16,9 @@
#include <errno.h>
#include <sys/types.h>
-#include <sys/stat.h>
+#ifndef DJGPP
#include <sys/ioctl.h>
+#endif
#ifdef HAVE_SYS_TIME_H
# include <sys/time.h>
@@ -31,26 +32,94 @@ struct timeval {
#include <vfork.h>
#endif
+#include <sys/stat.h>
+
+#ifdef DJGPP
+#include <fcntl.h>
+#endif
+
VALUE rb_ad_string();
VALUE cIO;
extern VALUE cFile;
+VALUE eEOFError;
+VALUE eIOError;
VALUE rb_stdin, rb_stdout, rb_stderr, rb_defout;
VALUE FS, OFS;
VALUE RS, ORS;
+VALUE RS_default;
static VALUE argf;
ID id_write, id_fd, id_print_on;
+VALUE lastline_get();
+void lastline_set();
+
extern char *inplace;
+struct timeval time_timeval();
+
+#ifdef _STDIO_USES_IOSTREAM /* GNU libc */
+# ifdef _IO_fpos_t
+# define READ_DATA_PENDING(fp) ((fp)->_IO_read_ptr != (fp)->_IO_read_end)
+# else
+# define READ_DATA_PENDING(fp) ((fp)->_gptr < (fp)->_egptr)
+# endif
+#else
+# ifdef FILE_COUNT
+# define READ_DATA_PENDING(fp) ((fp)->FILE_COUNT > 0)
+# else
+/* requires systems own version of the ReadDataPending() */
+extern int ReadDataPending();
+# define READ_DATA_PENDING(fp) ReadDataPending(fp)
+# endif
+#endif
+
+#ifndef THREAD
+# define READ_CHECK(fp) 0
+#else
+# define READ_CHECK(fp) do {\
+ if (!READ_DATA_PENDING(fp)) thread_wait_fd(fileno(fp));\
+} while(0)
+#endif
+
+void
+eof_error()
+{
+ Raise(eEOFError, "End of file reached");
+}
+
+void
+io_writable(fptr)
+ OpenFile *fptr;
+{
+ if (!(fptr->mode & FMODE_WRITABLE)) {
+ Raise(eIOError, "not opened for writing");
+ }
+}
+
+void
+io_readable(fptr)
+ OpenFile *fptr;
+{
+ if (!(fptr->mode & FMODE_READABLE)) {
+ Raise(eIOError, "not opened for reading");
+ }
+}
+
+static void
+closed()
+{
+ Raise(eIOError, "closed stream");
+}
+
/* writing functions */
VALUE
-io_write(obj, str)
- VALUE obj;
+io_write(io, str)
+ VALUE io;
struct RString *str;
{
OpenFile *fptr;
@@ -58,19 +127,17 @@ io_write(obj, str)
VALUE out;
int n;
- GetOpenFile(obj, fptr);
- if (!(fptr->mode & FMODE_WRITABLE)) {
- Fail("not opened for writing");
- }
+ GetOpenFile(io, fptr);
+ io_writable(fptr);
f = (fptr->f2) ? fptr->f2 : fptr->f;
- if (f == NULL) Fail("closed stream");
+ if (f == NULL) closed();
if (TYPE(str) != T_STRING)
str = (struct RString*)obj_as_string(str);
if (str->len == 0) return INT2FIX(0);
- n = fwrite(str->ptr, sizeof(char), str->len, f);
+ n = fwrite(str->ptr, 1, str->len, f);
if (n == 0 || ferror(f)) {
rb_sys_fail(fptr->path);
}
@@ -82,44 +149,43 @@ io_write(obj, str)
}
static VALUE
-io_puts(obj, str)
- VALUE obj, str;
+io_puts(io, str)
+ VALUE io, str;
{
- io_write(obj, str);
- return obj;
+ io_write(io, str);
+ return io;
}
static VALUE
-io_flush(obj)
- VALUE obj;
+io_flush(io)
+ VALUE io;
{
OpenFile *fptr;
FILE *f;
- GetOpenFile(obj, fptr);
- if (!(fptr->mode & FMODE_WRITABLE)) {
- Fail("not opend for writing");
- }
+ GetOpenFile(io, fptr);
+ io_writable(fptr);
f = (fptr->f2) ? fptr->f2 : fptr->f;
- if (f == NULL) Fail("closed stream");
+ if (f == NULL) closed();
- if (fflush(f) == EOF) rb_sys_fail(Qnil);
+ if (fflush(f) == EOF) rb_sys_fail(0);
- return obj;
+ return io;
}
static VALUE
-io_eof(obj)
- VALUE obj;
+io_eof(io)
+ VALUE io;
{
OpenFile *fptr;
int ch;
- GetOpenFile(obj, fptr);
-#ifdef STDSTDIO /* (the code works without this) */
- if (fptr->f->_cnt > 0) /* cheat a little, since */
- return FALSE; /* this is the most usual case */
-#endif
+ GetOpenFile(io, fptr);
+ io_readable(fptr);
+ if (fptr->f == NULL) closed();
+
+ if (READ_DATA_PENDING(fptr->f)) return FALSE;
+ if (feof(fptr->f)) return TRUE;
TRAP_BEG;
ch = getc(fptr->f);
@@ -129,31 +195,27 @@ io_eof(obj)
(void)ungetc(ch, fptr->f);
return FALSE;
}
-#ifdef STDSTDIO
- if (fptr->f->_cnt < -1)
- fptr->f->_cnt = -1;
-#endif
return TRUE;
}
static VALUE
-io_sync(obj)
- VALUE obj;
+io_sync(io)
+ VALUE io;
{
OpenFile *fptr;
- GetOpenFile(obj, fptr);
+ GetOpenFile(io, fptr);
return (fptr->mode & FMODE_SYNC) ? TRUE : FALSE;
}
static VALUE
-io_set_sync(obj, mode)
- VALUE obj, mode;