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;
+io_set_sync(io, mode)
+ VALUE io, mode;
{
OpenFile *fptr;
- GetOpenFile(obj, fptr);
- if (mode) {
+ GetOpenFile(io, fptr);
+ if (RTEST(mode)) {
fptr->mode |= FMODE_SYNC;
}
else {
@@ -163,13 +225,13 @@ io_set_sync(obj, mode)
}
static VALUE
-io_fileno(obj)
- VALUE obj;
+io_fileno(io)
+ VALUE io;
{
OpenFile *fptr;
int fd;
- GetOpenFile(obj, fptr);
+ GetOpenFile(io, fptr);
fd = fileno(fptr->f);
return INT2FIX(fd);
}
@@ -185,54 +247,50 @@ read_all(port)
int n;
GetOpenFile(port, fptr);
- if (!(fptr->mode & FMODE_READABLE)) {
- Fail("not opend for reading");
- }
- if (fptr->f == NULL) Fail("closed stream");
+ io_readable(fptr);
+ if (fptr->f == NULL) closed();
str = str_new(0, 0);
for (;;) {
+ READ_CHECK(fptr->f);
TRAP_BEG;
n = fread(buf, 1, BUFSIZ, fptr->f);
TRAP_END;
- if (n == 0) {
- if (feof(fptr->f)) break;
- rb_sys_fail(Qnil);
- }
+ if (n == 0) break;
+ if (n < 0) rb_sys_fail(0);
str_cat(str, buf, n);
}
return str;
}
static VALUE
-io_read(argc, argv, obj)
+io_read(argc, argv, io)
int argc;
VALUE *argv;
- VALUE obj;
+ VALUE io;
{
OpenFile *fptr;
int n, lgt;
VALUE len, str;
if (rb_scan_args(argc, argv, "01", &len) == 0) {
- return read_all(obj);
+ return read_all(io);
}
lgt = NUM2INT(len);
- GetOpenFile(obj, fptr);
- if (!(fptr->mode & FMODE_READABLE)) {
- Fail("not opend for reading");
- }
- if (fptr->f == NULL) Fail("closed stream");
+ GetOpenFile(io, fptr);
+ io_readable(fptr);
+ if (fptr->f == NULL) closed();
str = str_new(0, lgt);
+ READ_CHECK(fptr->f);
TRAP_BEG;
n = fread(RSTRING(str)->ptr, 1, RSTRING(str)->len, fptr->f);
TRAP_END;
if (n == 0) {
if (feof(fptr->f)) return Qnil;
- rb_sys_fail(Qnil);
+ rb_sys_fail(fptr->path);
}
RSTRING(str)->len = n;
@@ -241,42 +299,54 @@ io_read(argc, argv, obj)
return str;
}
-VALUE rb_lastline;
static VALUE lineno;
-static VALUE
-io_gets(obj)
- VALUE obj;
+VALUE
+io_gets_method(argc, argv, io)
+ int argc;
+ VALUE argv;
+ VALUE io;
{
OpenFile *fptr;
FILE *f;
struct RString *str;
int c, newline;
- int rslen;
+ char *rsptr;
+ int rslen, rspara = 0;
+ VALUE rs;
- GetOpenFile(obj, fptr);
- if (!(fptr->mode & FMODE_READABLE)) {
- Fail("not opend for reading");
+ if (rb_scan_args(argc, argv, "01", &rs) == 1) {
+ if (!NIL_P(rs)) Check_Type(rs, T_STRING);
}
+ else {
+ rs = RS;
+ }
+
+ GetOpenFile(io, fptr);
+ io_readable(fptr);
f = fptr->f;
- if (f == NULL) Fail("closed stream");
+ if (f == NULL) closed();
- if (RS) {
- rslen = RSTRING(RS)->len;
+ if (!NIL_P(rs)) {
+ rslen = RSTRING(rs)->len;
if (rslen == 0) {
- newline = '\n';
+ rsptr = "\n\n";
+ rslen = 2;
+ rspara = 1;
}
else {
- newline = RSTRING(RS)->ptr[rslen-1];
+ rsptr = RSTRING(rs)->ptr;
}
}
else {
- newline = 0777; /* non matching char */
- rslen = 1;
+ rsptr = 0;
+ rslen = 0;
}
+ newline = rslen ? rsptr[rslen - 1] : 0777;
- if (rslen == 0) {
+ if (rspara) {
do {
+ READ_CHECK(f);
TRAP_BEG;
c = getc(f);
TRAP_END;
@@ -290,51 +360,54 @@ io_gets(obj)
{
char buf[8192];
char *bp, *bpe = buf + sizeof buf - 3;
+ int cnt;
int append = 0;
again:
bp = buf;
- retry:
- TRAP_BEG;
- while ((c = getc(f)) != EOF && (*bp++ = c) != newline && bp < bpe)
- ;
- TRAP_END;
+ if (rslen) {
+ for (;;) {
+ READ_CHECK(f);
+ TRAP_BEG;
+ c = getc(f);
+ TRAP_END;
+ if (c == EOF) break;
+ if ((*bp++ = c) == newline) break;
+ if (bp == bpe) break;
+ }
+ cnt = bp - buf;
+ }
+ else {
+ cnt = fread(buf, 1, sizeof(buf), f);
+ c = cnt ? buf[cnt - 1]: EOF;
+ }
if (c == EOF) {
- if (!feof(f)) goto retry;
- if (!append && bp == buf) {
- str = Qnil;
+ if (!append && cnt == 0) {
+ str = RSTRING(Qnil);
goto return_gets;
}
}
if (append)
- str_cat(str, buf, bp - buf);
+ str_cat(str, buf, cnt);
else
- str = (struct RString*)str_new(buf, bp - buf);
-
- if (c != EOF
- &&
- (c != newline
- ||
- (rslen > 1
- &&
- (str->len < rslen
- ||
- memcmp(str->ptr+str->len-rslen, RSTRING(RS)->ptr, rslen)
- )
- )
- )
- ) {
+ str = (struct RString*)str_new(buf, cnt);
+
+ if (c != EOF &&
+ (!rslen ||
+ str->len < rslen ||
+ memcmp(str->ptr+str->len-rslen, rsptr, rslen))) {
append = 1;
goto again;
}
}
return_gets:
- if (rslen == 0) {
+ if (rspara) {
while (c != EOF) {
+ READ_CHECK(f);
TRAP_BEG;
c = getc(f);
TRAP_END;
@@ -349,82 +422,132 @@ io_gets(obj)
fptr->lineno++;
lineno = INT2FIX(fptr->lineno);
}
- return rb_lastline = (VALUE)str;
+ lastline_set(str);
+
+ return (VALUE)str;
+}
+
+VALUE
+io_gets(io)
+ VALUE io;
+{
+ return io_gets_method(0, 0, io);
}
static VALUE
-io_each_line(obj)
- VALUE obj;
+io_readline(argc, argv, io)
+ int argc;
+ VALUE argv;
+ VALUE io;
+{
+ VALUE line = io_gets_method(argc, argv, io);
+
+ if (NIL_P(line)) {
+ eof_error();
+ }
+ return line;
+}
+
+static VALUE
+io_each_line(argc, argv, io)
+ int argc;
+ VALUE argv;
+ VALUE io;
{
VALUE str;
- while (str = io_gets(obj)) {
+ while (!NIL_P(str = io_gets_method(argc, argv, io))) {
rb_yield(str);
}
return Qnil;
}
static VALUE
-io_each_byte(obj)
- VALUE obj;
+io_each_byte(io)
+ VALUE io;
{
OpenFile *fptr;
FILE *f;
int c;
- GetOpenFile(obj, fptr);
- if (!(fptr->mode & FMODE_READABLE)) {
- Fail("not opend for reading");
- }
+ GetOpenFile(io, fptr);
+ io_readable(fptr);
f = fptr->f;
- if (f == NULL) Fail("closed stream");
+ if (f == NULL) closed();
for (;;) {
+ READ_CHECK(f);
TRAP_BEG;
c = getc(f);
TRAP_END;
if (c == EOF) break;
rb_yield(INT2FIX(c & 0xff));
}
- if (ferror(f) != 0) rb_sys_fail(Qnil);
- return obj;
+ if (ferror(f) != 0) rb_sys_fail(fptr->path);
+ return Qnil;
}
-static VALUE
-io_getc(obj)
- VALUE obj;
+VALUE
+io_getc(io)
+ VALUE io;
{
OpenFile *fptr;
FILE *f;
int c;
- GetOpenFile(obj, fptr);
- if (!(fptr->mode & FMODE_READABLE)) {
- Fail("not opend for reading");
- }
+ GetOpenFile(io, fptr);
+ io_readable(fptr);
f = fptr->f;
- if (f == NULL) Fail("closed stream");
+ if (f == NULL) closed();
+ READ_CHECK(f);
TRAP_BEG;
c = getc(f);
TRAP_END;
if (c == EOF) {
- if (ferror(f) != 0) rb_sys_fail(Qnil);
+ if (ferror(f) != 0) rb_sys_fail(fptr->path);
return Qnil;
}
return INT2FIX(c & 0xff);
}
static VALUE
-io_isatty(obj)
- VALUE obj;
+io_readchar(io)
+ VALUE io;
+{
+ VALUE c = io_getc(io);
+
+ if (NIL_P(c)) {
+ eof_error();
+ }
+ return c;
+}
+
+VALUE
+io_ungetc(io, c)
+ VALUE io, c;
+{
+ OpenFile *fptr;
+
+ Check_Type(c, T_FIXNUM);
+ GetOpenFile(io, fptr);
+ io_readable(fptr);
+ if (fptr->f == NULL) closed();
+
+ if (ungetc(FIX2INT(c), fptr->f) == EOF)
+ rb_sys_fail(fptr->path);
+}
+
+static VALUE
+io_isatty(io)
+ VALUE io;
{
OpenFile *fptr;
#ifndef NT
- GetOpenFile(obj, fptr);
- if (fptr->f == NULL) Fail("closed stream");
+ GetOpenFile(io, fptr);
+ if (fptr->f == NULL) closed();
if (isatty(fileno(fptr->f)) == 0)
return FALSE;
#endif
@@ -466,30 +589,30 @@ io_fptr_finalize(fptr)
}
VALUE
-io_close(obj)
- VALUE obj;
+io_close(io)
+ VALUE io;
{
OpenFile *fptr;
- GetOpenFile(obj, fptr);
+ GetOpenFile(io, fptr);
io_fptr_finalize(fptr);
return Qnil;
}
static VALUE
-io_closed(obj)
- VALUE obj;
+io_closed(io)
+ VALUE io;
{
OpenFile *fptr;
- GetOpenFile(obj, fptr);
+ GetOpenFile(io, fptr);
return fptr->f?FALSE:TRUE;
}
static VALUE
-io_syswrite(obj, str)
- VALUE obj, str;
+io_syswrite(io, str)
+ VALUE io, str;
{
OpenFile *fptr;
FILE *f;
@@ -498,43 +621,45 @@ io_syswrite(obj, str)
if (TYPE(str) != T_STRING)
str = obj_as_string(str);
- 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();
+#ifdef THREAD
+ thread_fd_writable(fileno(f));
+#endif
n = write(fileno(f), RSTRING(str)->ptr, RSTRING(str)->len);
- if (n == -1) rb_sys_fail(Qnil);
+ if (n == -1) rb_sys_fail(fptr->path);
return INT2FIX(n);
}
static VALUE
-io_sysread(obj, len)
- VALUE obj, len;
+io_sysread(io, len)
+ VALUE io, len;
{
OpenFile *fptr;
int n, ilen;
VALUE str;
ilen = NUM2INT(len);
- GetOpenFile(obj, fptr);
- if (!(fptr->mode & FMODE_READABLE)) {
- Fail("not opend for reading");
- }
- if (fptr->f == NULL) Fail("closed stream");
+ GetOpenFile(io, fptr);
+ io_readable(fptr);
+ if (fptr->f == NULL) closed();
str = str_new(0, ilen);
+#ifdef THREAD
+ thread_wait_fd(fileno(fptr->f));
+#endif
TRAP_BEG;
n = read(fileno(fptr->f), RSTRING(str)->ptr, RSTRING(str)->len);
TRAP_END;
- if (n == -1) rb_sys_fail(Qnil);
- if (n == 0) return Qnil; /* EOF */
+ if (n == -1) rb_sys_fail(fptr->path);
+ if (n == 0) eof_error();
RSTRING(str)->len = n;
RSTRING(str)->ptr[n] = '\0';
@@ -542,21 +667,21 @@ io_sysread(obj, len)
}
static VALUE
-io_binmode(obj)
- VALUE obj;
+io_binmode(io)
+ VALUE io;
{
-#ifdef NT
+#if defined(NT) || defined(DJGPP)
OpenFile *fptr;
- GetOpenFile(obj, fptr);
- if (setmode(fileno(fptr), O_BINARY) == -1)
- rb_sys_fail(Qnil);
+ GetOpenFile(io, fptr);
+ if (fptr->f && setmode(fileno(fptr->f), O_BINARY) == -1)
+ rb_sys_fail(fptr->path);
+ if (fptr->f2 && setmode(fileno(fptr->f2), O_BINARY) == -1)
+ rb_sys_fail(fptr->path);
#endif
- return obj;
+ return io;
}
-VALUE obj_alloc();
-
int
io_mode_flags(mode)
char *mode;
@@ -574,7 +699,7 @@ io_mode_flags(mode)
flags |= FMODE_WRITABLE;
break;
default:
- Fail("illegal access mode");
+ ArgError("illegal access mode");
}
if (mode[1] == '+') {
flags |= FMODE_READABLE | FMODE_WRITABLE;
@@ -584,6 +709,26 @@ io_mode_flags(mode)
}
FILE *
+rb_fopen(fname, mode)
+ char *fname;
+ char *mode;
+{
+ FILE *f;
+
+ f = fopen(fname, mode);
+ if (f == NULL) {
+ if (errno == EMFILE || errno == ENFILE) {
+ gc();
+ f = fopen(fname, mode);
+ }
+ if (f == NULL) {
+ rb_sys_fail(fname);
+ }
+ }
+ return f;
+}
+
+FILE *
rb_fdopen(fd, mode)
int fd;
char *mode;
@@ -596,13 +741,13 @@ rb_fdopen(fd, mode)
f = fdopen(fd, mode);
}
if (f == NULL) {
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
}
}
return f;
}
-#ifdef NT
+#if defined (NT) || defined(DJGPP)
static void
pipe_finalize(fptr)
OpenFile *fptr;
@@ -619,29 +764,30 @@ pipe_open(pname, mode)
char *pname, *mode;
{
int modef = io_mode_flags(mode);
- VALUE port;
OpenFile *fptr;
-#ifdef NT
+#if defined(NT) || defined(DJGPP)
FILE *f = popen(pname, mode);
if (f == NULL) rb_sys_fail(pname);
+ else {
+ NEWOBJ(port, struct RFile);
+ OBJSETUP(port, cIO, T_FILE);
+ MakeOpenFile(port, fptr);
+ fptr->finalize = pipe_finalize;
- port = obj_alloc(cIO);
- MakeOpenFile(port, fptr);
- fptr->finalize = pipe_finalize;
-
- if (modef & FMODE_READABLE) fptr->f = f;
- if (modef & FMODE_WRITABLE) fptr->f2 = f;
- fptr->mode = modef | FMODE_SYNC;
- return port;
+ if (modef & FMODE_READABLE) fptr->f = f;
+ if (modef & FMODE_WRITABLE) fptr->f2 = f;
+ fptr->mode = modef | FMODE_SYNC;
+ return (VALUE)port;
+ }
#else
int pid, pr[2], pw[2];
volatile int doexec;
if (((modef & FMODE_READABLE) && pipe(pr) == -1) ||
((modef & FMODE_WRITABLE) && pipe(pw) == -1))
- rb_sys_fail(Qnil);
+ rb_sys_fail(pname);
doexec = (strcmp("-", pname) != 0);
if (!doexec) {
@@ -688,28 +834,52 @@ pipe_open(pname, mode)
break;
default: /* parent */
- port = obj_alloc(cIO);
- MakeOpenFile(port, fptr);
- if (modef & FMODE_READABLE) close(pr[1]);
- if (modef & FMODE_WRITABLE) close(pw[0]);
- fptr->mode = modef;
- fptr->mode |= FMODE_SYNC;
+ {
+ NEWOBJ(port, struct RFile);
+ OBJSETUP(port, cIO, T_FILE);
+ MakeOpenFile(port, fptr);
+ if (modef & FMODE_READABLE) close(pr[1]);
+ if (modef & FMODE_WRITABLE) close(pw[0]);
+ fptr->mode = modef;
+ fptr->mode |= FMODE_SYNC;
+ fptr->pid = pid;
+
+ if (modef & FMODE_READABLE) fptr->f = rb_fdopen(pr[0], "r");
+ if (modef & FMODE_WRITABLE) fptr->f2 = rb_fdopen(pw[1], "w");
+
+ return (VALUE)port;
+ }
}
+#endif
+}
- fptr->pid = pid;
- if (modef & FMODE_READABLE) fptr->f = rb_fdopen(pr[0], "r");
- if (modef & FMODE_WRITABLE) fptr->f2 = rb_fdopen(pw[1], "w");
+static VALUE
+io_popen(argc, argv, self)
+ int argc;
+ VALUE *argv;
+ VALUE self;
+{
+ char *mode;
+ VALUE pname, pmode;
- return port;
-#endif
+ rb_scan_args(argc, argv, "11", &pname, &pmode);
+ Check_Type(pname, T_STRING);
+ if (NIL_P(pmode)) {
+ mode = "r";
+ }
+ else {
+ Check_Type(pmode, T_STRING);
+ if (RSTRING(pmode)->len == 0 || RSTRING(pmode)->len > 2)
+ ArgError("illegal access mode");
+ mode = RSTRING(pmode)->ptr;
+ }
+ return pipe_open(RSTRING(pname)->ptr, mode);
}
static VALUE
io_open(fname, mode)
char *fname, *mode;
{
- int pipe = 0;
-
if (fname[0] == '|') {
return pipe_open(fname+1, mode);
}
@@ -725,19 +895,17 @@ f_open(argc, argv, self)
VALUE self;
{
char *mode;
- VALUE port;
- int pipe = 0;
VALUE pname, pmode;
rb_scan_args(argc, argv, "11", &pname, &pmode);
Check_Type(pname, T_STRING);
- if (pmode == Qnil) {
+ if (NIL_P(pmode)) {
mode = "r";
}
else {
Check_Type(pmode, T_STRING);
if (RSTRING(pmode)->len == 0 || RSTRING(pmode)->len > 2)
- Fail("illegal access mode");
+ ArgError("illegal access mode");
mode = RSTRING(pmode)->ptr;
}
return io_open(RSTRING(pname)->ptr, mode);
@@ -765,13 +933,13 @@ f_printf(argc, argv)
if (TYPE(argv[0]) == T_STRING) {
out = rb_defout;
}
- else if (rb_responds_to(argv[0], id_write)) {
+ else if (rb_respond_to(argv[0], id_write)) {
out = argv[0];
argv++;
argc--;
}
else {
- Fail("output must responds to `write'");
+ NameError("output must responds to `write'");
}
rb_funcall(out, id_write, 1, f_sprintf(argc, argv));
@@ -790,30 +958,26 @@ io_print(argc, argv, out)
/* if no argument given, print `$_' */
if (argc == 0) {
argc = 1;
- if (rb_lastline)
- argv = &rb_lastline;
- else {
- line = str_new(0,0);
- argv = &line;
- }
+ line = lastline_get();
+ argv = &line;
}
for (i=0; i<argc; i++) {
- if (OFS && i>0) {
+ if (!NIL_P(OFS) && i>0) {
io_write(out, OFS);
}
switch (TYPE(argv[i])) {
case T_STRING:
io_write(out, argv[i]);
break;
- case T_ARRAY:
- ary_print_on(argv[i], out);
+ case T_NIL:
+ io_write(out, str_new2("nil"));
break;
default:
rb_funcall(argv[i], id_print_on, 1, out);
break;
}
}
- if (ORS) {
+ if (!NIL_P(ORS)) {
io_write(out, ORS);
}
@@ -829,6 +993,17 @@ f_print(argc, argv)
return Qnil;
}
+VALUE
+f_p(obj, val)
+{
+ VALUE str = rb_inspect(val);
+
+ Check_Type(str, T_STRING);
+ io_write(rb_defout, str);
+ io_write(rb_defout, str_new2("\n"));
+ return Qnil;
+}
+
static VALUE
io_defset(val, id)
VALUE val;
@@ -838,7 +1013,7 @@ io_defset(val, id)
val = io_open(RSTRING(val)->ptr, "w");
}
if (!obj_is_kind_of(val, cIO)) {
- Fail("$< must be a file, %s given", rb_class2name(CLASS_OF(val)));
+ TypeError("$< must be a file, %s given", rb_class2name(CLASS_OF(val)));
}
return rb_defout = val;
}
@@ -855,14 +1030,15 @@ prep_stdio(f, mode)
FILE *f;
int mode;
{
- VALUE obj = obj_alloc(cIO);
OpenFile *fp;
+ NEWOBJ(obj, struct RFile);
+ OBJSETUP(obj, cIO, T_FILE);
MakeOpenFile(obj, fp);
fp->f = f;
fp->mode = mode;
- return obj;
+ return (VALUE)obj;
}
static VALUE filename, file;
@@ -900,9 +1076,8 @@ next_argv()
}
}
else {
- FILE *fr = fopen(fn, "r");
+ FILE *fr = rb_fopen(fn, "r");
- if (!fr) rb_sys_fail(fn);
if (inplace) {
struct stat st, st2;
VALUE str;
@@ -919,25 +1094,40 @@ next_argv()
#else
str_cat(str, inplace, strlen(inplace));
#endif
+#if defined(MSDOS) || defined(__BOW__)
+ (void)fclose(fr);
+ (void)unlink(RSTRING(str)->ptr);
+ (void)rename(fn, RSTRING(str)->ptr);
+ fr = rb_fopen(RSTRING(str)->ptr, "r");
+#else
if (rename(fn, RSTRING(str)->ptr) < 0) {
Warning("Can't rename %s to %s: %s, skipping file",
fn, RSTRING(str)->ptr, strerror(errno));
fclose(fr);
goto retry;
}
+#endif
}
- else if (unlink(fn) < 0) {
- Warning("Can't remove %s: %s, skipping file",
+ else {
+#if !defined(MSDOS) && !defined(__BOW__)
+ if (unlink(fn) < 0) {
+ Warning("Can't remove %s: %s, skipping file",
fn, strerror(errno));
- fclose(fr);
- goto retry;
+ fclose(fr);
+ goto retry;
+ }
+#else
+ Fatal("Can't do inplace edit without backup");
+#endif
}
- fw = fopen(fn, "w");
+ fw = rb_fopen(fn, "w");
+#if !defined(DJGPP) && !defined(__CYGWIN32__)
fstat(fileno(fw), &st2);
fchmod(fileno(fw), st.st_mode);
if (st.st_uid!=st2.st_uid || st.st_gid!=st2.st_gid) {
fchown(fileno(fw), st.st_uid, st.st_gid);
}
+#endif
rb_defout = prep_stdio(fw, FMODE_WRITABLE);
}
file = prep_stdio(fr, FMODE_READABLE);
@@ -952,25 +1142,48 @@ next_argv()
}
static VALUE
-f_gets()
+f_gets_method(argc, argv)
+ int argc;
+ VALUE argv;
{
VALUE line;
retry:
if (!next_argv()) return Qnil;
- line = io_gets(file);
- if (line == Qnil && next_p != -1) {
+ line = io_gets_method(argc, argv, file);
+ if (NIL_P(line) && next_p != -1) {
io_close(file);
next_p = 1;
goto retry;
}
-
gets_lineno++;
lineno = INT2FIX(gets_lineno);
return line;
}
+VALUE
+f_gets(argc, argv)
+ int argc;
+ VALUE argv;
+{
+ return f_gets_method(0,0);
+}
+
+static VALUE
+f_readline(argc, argv)
+ int argc;
+ VALUE argv;
+{
+ VALUE line = f_gets_method(argc, argv);
+
+ if (NIL_P(line)) {
+ eof_error();
+ }
+
+ return line;
+}
+
static VALUE
f_eof()
{
@@ -990,13 +1203,36 @@ f_getc()
}
static VALUE
-f_readlines(obj)
- VALUE obj;
+f_ungetc(obj, c)
+ VALUE obj, c;
+{
+ if (!next_argv()) {
+ ArgError("no stream to ungetc");
+ }
+
+ return io_ungetc(file, c);
+}
+
+static VALUE
+f_readchar()
+{
+ VALUE c = f_getc();
+
+ if (NIL_P(c)) {
+ eof_error();
+ }
+ return c;
+}
+
+static VALUE
+f_readlines(argc, argv)
+ int argc;
+ VALUE argv;
{
VALUE line, ary;
ary = ary_new();
- while (line = f_gets(obj)) {
+ while (RTEST(line = f_gets_method(argc, argv))) {
ary_push(ary, line);
}
@@ -1009,14 +1245,15 @@ rb_str_setter(val, id, var)
ID id;
VALUE *var;
{
- if (val && TYPE(val) != T_STRING) {
- Fail("value of %s must be String", rb_id2name(id));
+ if (!NIL_P(val) && TYPE(val) != T_STRING) {
+ TypeError("value of %s must be String", rb_id2name(id));
}
return *var = val;
}
-VALUE
-rb_xstring(str)
+static VALUE
+f_backquote(obj, str)
+ VALUE obj;
struct RString *str;
{
VALUE port, result;
@@ -1031,21 +1268,8 @@ rb_xstring(str)
return result;
}
-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
-extern int ReadDataPending();
-# define READ_DATA_PENDING(fp) ReadDataPending(fp)
-# endif
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
#endif
static VALUE
@@ -1063,28 +1287,31 @@ f_select(argc, argv, obj)
int interrupt = 0;
rb_scan_args(argc, argv, "13", &read, &write, &except, &timeout);
- if (timeout) {
- tp = time_timeval(timeout);
+ if (NIL_P(timeout)) {
+ tp = NULL;
}
else {
- tp = NULL;
+ timerec = time_timeval(timeout);
+ tp = &timerec;
}
FD_ZERO(&pset);
- if (read) {
+ if (!NIL_P(read)) {
int pending = 0;
Check_Type(read, T_ARRAY);
rp = &rset;
FD_ZERO(rp);
for (i=0; i<RARRAY(read)->len; i++) {
+ Check_Type(RARRAY(read)->ptr[i], T_FILE);
GetOpenFile(RARRAY(read)->ptr[i], fptr);
+ if (fptr->f == NULL) closed();
FD_SET(fileno(fptr->f), rp);
if (READ_DATA_PENDING(fptr->f)) { /* check for buffered data */
pending++;
FD_SET(fileno(fptr->f), &pset);
}
- if (max < (int)fileno(fptr->f)) max = fileno(fptr->f);
+ if (max < fileno(fptr->f)) max = fileno(fptr->f);
}
if (pending) { /* no blocking if there's buffered data */
timerec.tv_sec = timerec.tv_usec = 0;
@@ -1094,14 +1321,16 @@ f_select(argc, argv, obj)
else
rp = NULL;
- if (write) {
+ if (!NIL_P(write)) {
Check_Type(write, T_ARRAY);
wp = &wset;
FD_ZERO(wp);
for (i=0; i<RARRAY(write)->len; i++) {
+ Check_Type(RARRAY(write)->ptr[i], T_FILE);
GetOpenFile(RARRAY(write)->ptr[i], fptr);
+ if (fptr->f == NULL) closed();
FD_SET(fileno(fptr->f), wp);
- if (max > (int)fileno(fptr->f)) max = fileno(fptr->f);
+ if (max > fileno(fptr->f)) max = fileno(fptr->f);
if (fptr->f2) {
FD_SET(fileno(fptr->f2), wp);
if (max < (int)fileno(fptr->f2)) max = fileno(fptr->f2);
@@ -1111,14 +1340,16 @@ f_select(argc, argv, obj)
else
wp = NULL;
- if (except) {
+ if (!NIL_P(except)) {
Check_Type(except, T_ARRAY);
ep = &eset;
FD_ZERO(ep);
for (i=0; i<RARRAY(except)->len; i++) {
+ Check_Type(RARRAY(except)->ptr[i], T_FILE);
GetOpenFile(RARRAY(except)->ptr[i], fptr);
+ if (fptr->f == NULL) closed();
FD_SET(fileno(fptr->f), ep);
- if (max < (int)fileno(fptr->f)) max = fileno(fptr->f);
+ if (max < fileno(fptr->f)) max = fileno(fptr->f);
if (fptr->f2) {
FD_SET(fileno(fptr->f2), ep);
if (max > (int)fileno(fptr->f2)) max = fileno(fptr->f2);
@@ -1130,17 +1361,24 @@ f_select(argc, argv, obj)
max++;
+#ifdef THREAD
+ n = thread_select(max, rp, wp, ep, tp);
+ if (n < 0) {
+ rb_sys_fail(0);
+ }
+#else
retry:
TRAP_BEG;
n = select(max, rp, wp, ep, tp);
TRAP_END;
if (n < 0) {
if (errno != EINTR) {
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
}
if (tp == NULL) goto retry;
interrupt = 1;
}
+#endif
res = ary_new2(3);
ary_push(res, rp?ary_new():ary_new2(0));
@@ -1191,16 +1429,17 @@ f_select(argc, argv, obj)
}
void
-io_ctl(obj, req, arg, io_p)
- VALUE obj, req;
+io_ctl(io, req, arg, io_p)
+ VALUE io, req;
struct RString *arg;
int io_p;
{
+#if !defined(MSDOS)
int cmd = NUM2INT(req);
OpenFile *fptr;
int len, fd;
- GetOpenFile(obj, fptr);
+ GetOpenFile(io, fptr);
#ifdef IOCPARM_MASK
#ifndef IOCPARM_LEN
@@ -1216,9 +1455,7 @@ io_ctl(obj, req, arg, io_p)
Check_Type(arg, T_STRING);
str_modify(arg);
- if (arg->len < len) {
- str_grow(arg, len+1);
- }
+ str_resize(arg, len+1);
arg->ptr[len] = 17;
fd = fileno(fptr->f);
#ifdef HAVE_FCNTL
@@ -1227,22 +1464,25 @@ io_ctl(obj, req, arg, io_p)
}
#else
if (!io_p) {
- Bug("fcntl() not implemented");
+ rb_notimplement();
}
if (ioctl(fd, cmd, arg->ptr)<0) rb_sys_fail(fptr->path);
#endif
if (arg->ptr[len] != 17) {
- Fail("Return value overflowed string");
+ ArgError("Return value overflowed string");
}
+#else
+ rb_notimplement();
+#endif
}
static VALUE
-io_ioctl(obj, req, arg)
- VALUE obj, req;
+io_ioctl(io, req, arg)
+ VALUE io, req;
struct RString *arg;
{
- io_ctl(obj, req, arg, 1);
- return obj;
+ io_ctl(io, req, arg, 1);
+ return io;
}
static VALUE
@@ -1279,7 +1519,7 @@ f_syscall(argc, argv)
}
switch (argc) {
case 0:
- Fail("Too few args to syscall");
+ ArgError("Too few args to syscall");
case 1:
retval = syscall(arg[0]);
break;
@@ -1335,13 +1575,57 @@ f_syscall(argc, argv)
if (retval == -1) rb_sys_fail(0);
return INT2FIX(0);
#else
- Fail("syscall() unimplemented");
+ rb_notimplement();
#endif
}
static VALUE
-arg_read(obj)
- VALUE obj;
+io_pipe()
+{
+ int pipes[2];
+ VALUE r, w, ary;
+
+ if (pipe(pipes) == -1)
+ rb_sys_fail(0);
+ r = prep_stdio(fdopen(pipes[0], "r"), FMODE_READABLE);
+ w = prep_stdio(fdopen(pipes[1], "w"), FMODE_WRITABLE);
+
+ ary = ary_new2(2);
+ ary_push(ary, r);
+ ary_push(ary, w);
+
+ return ary;
+}
+
+
+static VALUE
+io_foreach_line(io)
+ VALUE io;
+{
+ VALUE str;
+
+ while (!NIL_P(str = io_gets(io))) {
+ rb_yield(str);
+ }
+ return Qnil;
+}
+
+static VALUE
+io_foreach(io, fname)
+ VALUE io;
+ struct RString *fname;
+{
+ VALUE f, v;
+
+ Check_Type(fname, T_STRING);
+ f = io_open(fname->ptr, "r");
+ return rb_ensure(io_foreach_line, f, io_close, f);
+}
+
+static VALUE
+arg_read(argc, argv)
+ int argc;
+ VALUE argv;
{
VALUE str, str2;
@@ -1349,13 +1633,13 @@ arg_read(obj)
for (;;) {
retry:
if (!next_argv()) return Qnil;
- str2 = io_read(0, Qnil, file);
- if (str2 == Qnil && next_p != -1) {
+ str2 = io_read(argc, argv, file);
+ if (NIL_P(str2) && next_p != -1) {
io_close(file);
next_p = 1;
goto retry;
}
- if (str2 == Qnil) break;
+ if (NIL_P(str2)) break;
str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
}
@@ -1370,7 +1654,7 @@ arg_getc()
retry:
if (!next_argv()) return Qnil;
byte = io_getc(file);
- if (byte == Qnil && next_p != -1) {
+ if (NIL_P(byte) && next_p != -1) {
io_close(file);
next_p = 1;
goto retry;
@@ -1380,11 +1664,13 @@ arg_getc()
}
static VALUE
-arg_each_line()
+arg_each_line(argc, argv)
+ int argc;
+ VALUE argv;
{
VALUE str;
- while (str = f_gets()) {
+ while (RTEST(str = f_gets_method(argc, argv))) {
rb_yield(str);
}
return Qnil;
@@ -1395,7 +1681,7 @@ arg_each_byte()
{
VALUE byte;
- while (byte = arg_getc()) {
+ while (!NIL_P(byte = arg_getc())) {
rb_yield(byte);
}
return Qnil;
@@ -1419,6 +1705,9 @@ void
Init_IO()
{
extern VALUE cKernel;
+ extern VALUE eException;
+
+ eEOFError = rb_define_class("EOFError", eException);
id_write = rb_intern("write");
id_fd = rb_intern("fd");
@@ -1429,32 +1718,46 @@ Init_IO()
rb_define_private_method(cKernel, "open", f_open, -1);
rb_define_private_method(cKernel, "printf", f_printf, -1);
rb_define_private_method(cKernel, "print", f_print, -1);
- rb_define_private_method(cKernel, "gets", f_gets, 0);
- rb_define_alias(cKernel,"readline", "gets");
+ rb_define_private_method(cKernel, "gets", f_gets_method, -1);
+ rb_define_private_method(cKernel, "readline", f_readline, -1);
rb_define_private_method(cKernel, "eof", f_eof, 0);
rb_define_private_method(cKernel, "getc", f_getc, 0);
+ rb_define_private_method(cKernel, "readchar", f_readchar, 0);
rb_define_private_method(cKernel, "select", f_select, -1);
+ rb_define_private_method(cKernel, "ungetc", f_ungetc, 1);
- rb_define_private_method(cKernel, "readlines", f_readlines, 0);
+ rb_define_private_method(cKernel, "readlines", f_readlines, -1);
rb_define_method(cKernel, "print_on", f_print_on, 1);
+ rb_define_private_method(cKernel, "`", f_backquote, 1);
+ rb_define_private_method(cKernel, "pipe", io_pipe, 0);
+
+ rb_define_private_method(cKernel, "p", f_p, 1);
+
cIO = rb_define_class("IO", cObject);
rb_include_module(cIO, mEnumerable);
+ rb_define_singleton_method(cIO, "popen", io_popen, -1);
+ rb_define_singleton_method(cIO, "foreach", io_foreach, 1);
+ rb_define_singleton_method(cIO, "select", f_select, -1);
+
+ FS = OFS = Qnil;
rb_define_hooked_variable("$;", &FS, 0, rb_str_setter);
rb_define_hooked_variable("$,", &OFS, 0, rb_str_setter);
- RS = str_new2("\n");
+ RS = RS_default = str_new2("\n"); ORS = Qnil;
+ rb_global_variable(&RS_default);
rb_define_hooked_variable("$/", &RS, 0, rb_str_setter);
rb_define_hooked_variable("$\\", &ORS, 0, rb_str_setter);
rb_define_variable("$.", &lineno);
- rb_define_variable("$_", &rb_lastline);
+ rb_define_virtual_variable("$_", lastline_get, lastline_set);
rb_define_method(cIO, "print", io_print, -1);
+ rb_define_method(cIO, "printf", io_printf, -1);
- rb_define_method(cIO, "each", io_each_line, 0);
+ rb_define_method(cIO, "each", io_each_line, -1);
rb_define_method(cIO, "each_line", io_each_line, 0);
rb_define_method(cIO, "each_byte", io_each_byte, 0);
@@ -1469,11 +1772,13 @@ Init_IO()
rb_define_alias(cIO, "readlines", "to_a");
- rb_define_method(cIO, "read", io_read, -2);
+ rb_define_method(cIO, "read", io_read, -1);
rb_define_method(cIO, "write", io_write, 1);
- rb_define_method(cIO, "gets", io_gets, 0);
- rb_define_alias(cIO, "readline", "gets");
+ rb_define_method(cIO, "gets", io_gets_method, -1);
+ rb_define_method(cIO, "readline", io_readline, -1);
rb_define_method(cIO, "getc", io_getc, 0);
+ rb_define_method(cIO, "readchar", io_readchar, 0);
+ rb_define_method(cIO, "ungetc",io_ungetc, 1);
rb_define_method(cIO, "puts", io_puts, 1);
rb_define_method(cIO, "<<", io_puts, 1);
rb_define_method(cIO, "flush", io_flush, 0);
@@ -1497,27 +1802,29 @@ Init_IO()
rb_defout = rb_stdout;
rb_define_hooked_variable("$>", &rb_defout, 0, io_defset);
- rb_define_const(cObject, "STDIN", rb_stdin);
- rb_define_const(cObject, "STDOUT", rb_stdout);
- rb_define_const(cObject, "STDERR", rb_stderr);
+ rb_define_global_const("STDIN", rb_stdin);
+ rb_define_global_const("STDOUT", rb_stdout);
+ rb_define_global_const("STDERR", rb_stderr);
argf = obj_alloc(cObject);
rb_extend_object(argf, mEnumerable);
rb_define_readonly_variable("$<", &argf);
rb_define_readonly_variable("$ARGF", &argf);
+ rb_define_global_const("ARGF", argf);
rb_define_singleton_method(argf, "each", arg_each_line, 0);
- rb_define_singleton_method(argf, "each_line", arg_each_line, 0);
+ rb_define_singleton_method(argf, "each_line", arg_each_line, -1);
rb_define_singleton_method(argf, "each_byte", arg_each_byte, 0);
- rb_define_singleton_method(argf, "read", arg_read, 0);
- rb_define_singleton_method(argf, "readlines", f_readlines, 0);
- rb_define_singleton_method(argf, "gets", f_gets, 0);
- rb_define_singleton_method(argf, "readline", f_gets, 0);
+ rb_define_singleton_method(argf, "read", arg_read, -1);
+ rb_define_singleton_method(argf, "readlines", f_readlines, -1);
+ rb_define_singleton_method(argf, "gets", f_gets_method, -1);
+ rb_define_singleton_method(argf, "readline", f_readline, -1);
rb_define_singleton_method(argf, "getc", arg_getc, 0);
rb_define_singleton_method(argf, "eof", f_eof, 0);
rb_define_singleton_method(argf, "eof?", f_eof, 0);
+ rb_define_singleton_method(argf, "ungetc", f_ungetc, 1);
rb_define_singleton_method(argf, "to_s", arg_filename, 0);
rb_define_singleton_method(argf, "filename", arg_filename, 0);
diff --git a/io.h b/io.h
index b3772c9a2f..2817835ef3 100644
--- a/io.h
+++ b/io.h
@@ -7,7 +7,7 @@
$Date: 1994/08/12 11:06:42 $
created at: Fri Nov 12 16:47:09 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -18,7 +18,7 @@
#include <stdio.h>
#include <errno.h>
-typedef struct {
+typedef struct OpenFile {
FILE *f; /* stdio ptr for read/write */
FILE *f2; /* additional ptr for rw pipes */
int mode; /* mode flags */
@@ -33,14 +33,10 @@ typedef struct {
#define FMODE_READWRITE 3
#define FMODE_SYNC 4
-extern ID id_fd;
-
-#define GetOpenFile(obj,fp) Get_Data_Struct(obj, id_fd, OpenFile, fp)
-
-void io_fptr_finalize();
+#define GetOpenFile(obj,fp) fp = RFILE(obj)->fptr
#define MakeOpenFile(obj, fp) do {\
- Make_Data_Struct(obj, id_fd, OpenFile, 0, io_fptr_finalize, fp);\
+ fp = RFILE(obj)->fptr = ALLOC(OpenFile);\
fp->f = fp->f2 = NULL;\
fp->mode = 0;\
fp->pid = 0;\
@@ -49,4 +45,6 @@ void io_fptr_finalize();
fp->finalize = 0;\
} while (0)
+FILE *rb_fopen();
+
#endif
diff --git a/lib/base64.rb b/lib/base64.rb
index a6bf1adf92..9bb6487bee 100644
--- a/lib/base64.rb
+++ b/lib/base64.rb
@@ -46,7 +46,7 @@ def j2e(str)
end
def decode_b(str)
- str.gsub!(/=\?ISO-2022-JP\?B\?([!->@-~]+)\?=/) {
+ str.gsub!(/=\?ISO-2022-JP\?B\?([!->@-~]+)\?=/i) {
decode64($1)
}
str.gsub!(/\n/, ' ')
diff --git a/lib/cgi-lib.rb b/lib/cgi-lib.rb
new file mode 100644
index 0000000000..afadbff3b6
--- /dev/null
+++ b/lib/cgi-lib.rb
@@ -0,0 +1,56 @@
+#!/usr/local/bin/ruby
+#
+# Get CGI String
+#
+# EXAMPLE:
+# require "cgi-lib.rb"
+# foo = CGI.new
+# foo['field'] <== value of 'field'
+# foo.keys <== array of fields
+# foo.inputs <== hash of { <field> => <value> }
+
+class CGI
+ attr("inputs")
+
+ def initialize
+ str = if ENV['REQUEST_METHOD'] == "GET"
+ ENV['QUERY_STRING']
+ elsif ENV['REQUEST_METHOD'] == "POST"
+ $stdin.read ENV['CONTENT_LENGTH'].to_i
+ else
+ ""
+ end
+ arr = str.split(/&/)
+ @inputs = {}
+ arr.each do |x|
+ x.gsub!(/\+/, ' ')
+ key, val = x.split(/=/, 2)
+ val = "" unless val
+
+ key.gsub!(/%(..)/) { [$1.hex].pack("c") }
+ val.gsub!(/%(..)/) { [$1.hex].pack("c") }
+
+ @inputs[key] += "\0" if @inputs[key]
+ @inputs[key] += val
+ end
+ end
+
+ def keys
+ @inputs.keys
+ end
+
+ def [](key)
+ @inputs[key]
+ end
+
+ def CGI.message(msg, title = "")
+ print "Content-type: text/html\n\n"
+ print "<html><head><title>"
+ print title
+ print "</title></head><body>\n"
+ print msg
+ print "</body></html>\n"
+ TRUE
+ end
+
+end
diff --git a/lib/complex.rb b/lib/complex.rb
new file mode 100644
index 0000000000..aa5d219d2f
--- /dev/null
+++ b/lib/complex.rb
@@ -0,0 +1,490 @@
+#
+# complex.rb -
+# $Release Version: 0.5 $
+# $Revision: 1.1 $
+# $Date: 1996/11/11 04:25:19 $
+# by Keiju ISHITSUKA(SHL Japan Inc.)
+#
+# --
+# Usage:
+# class Complex < Numeric
+#
+# Complex(x, y) --> x + yi
+# y.im --> 0 + yi
+#
+# Complex::polar
+#
+# Complex::+
+# Complex::-
+# Complex::*
+# Complex::/
+# Complex::**
+# Complex::%
+# Complex::divmod
+# Complex::abs
+# Complex::abs2
+# Complex::arg
+# Complex::polar
+# Complex::conjugate
+# Complex::<=>
+# Complex::==
+# Complex::to_i
+# Complex::to_f
+# Complex::to_r
+# Complex::to_s
+#
+# Complex::I
+#
+# Numeric::im
+#
+# Math.sqrt
+# Math.exp
+# Math.cos
+# Math.sin
+# Math.tan
+# Math.log
+# Math.log10
+# Math.atan2
+#
+#
+
+def Complex(a, b = 0)
+ if a.kind_of?(Complex) and b == 0
+ a
+ elsif b == 0 and defined? Complex::Unify
+ a
+ else
+ Complex.new(a, b)
+ end
+end
+
+class Complex < Numeric
+
+ def Complex.generic?(other)
+ other.kind_of?(Integer) or
+ other.kind_of?(Float) or
+ (defined?(Rational) and other.kind_of?(Rational))
+ end
+
+ def Complex.polar(r, theta)
+ Complex(r*Math.cos(theta), r*Math.sin(theta))
+ end
+
+ def initialize(a, b = 0)
+ @real = a
+ @image = b
+ end
+
+ def + (other)
+ if other.kind_of?(Complex)
+ re = @real + other.real
+ im = @image + other.image
+ Complex(re, im)
+ elsif Complex.generic?(other)
+ Complex(@real + other, @image)
+ else
+ x , y = a.coerce(self)
+ x + y
+ end
+ end
+
+ def - (other)
+ if other.kind_of?(Complex)
+ re = @real - other.real
+ im = @image - other.image
+ Complex(re, im)
+ elsif Complex.generic?(other)
+ Complex(@real - other, @image)
+ else
+ x , y = a.coerce(self)
+ x - y
+ end
+ end
+
+ def * (other)
+ if other.kind_of?(Complex)
+ re = @real*other.real - @image*other.image
+ im = @real*other.image + @image*other.real
+ Complex(re, im)
+ elsif Complex.generic?(other)
+ Complex(@real * other, @image * other)
+ else
+ x , y = a.coerce(self)
+ x * y
+ end
+ end
+
+ def / (other)
+ if other.kind_of?(Complex)
+ self * other.conjugate / other.abs2
+ elsif Complex.generic?(other)
+ Complex(@real / other, @image / other)
+ else
+ x , y = a.coerce(self)
+ x / y
+ end
+ end
+
+ def ** (other)
+ if other == 0
+ return Complex(1)
+ end
+ if other.kind_of?(Complex)
+ r, theta = polar
+ ore = other.real
+ oim = other.image
+ nr = Math.exp!(ore*Math.log!(r) - oim * theta)
+ ntheta = theta*ore + oim*Math.log!(r)
+ Complex.polar(nr, ntheta)
+ elsif other.kind_of?(Integer)
+ if other > 0
+ x = self
+ z = x
+ n = other - 1
+ while n != 0
+ while (div, mod = n.divmod(2)
+ mod == 0)
+ x = Complex(x.real*x.real - x.image*x.image, 2*x.real*x.image)
+ n = div
+ end
+ z *= x
+ n -= 1
+ end
+ z
+ else
+ if defined? Rational
+ (Rational(1) / self) ** -other
+ else
+ self ** Float(other)
+ end
+ end
+ elsif Complex.generic?(other)
+ r, theta = polar
+ Complex.polar(r.power!(other), theta * other)
+ else
+ x , y = a.coerce(self)
+ x / y
+ end
+ end
+
+ def % (other)
+ if other.kind_of?(Complex)
+ Complex(@real % other.real, @image % other.image)
+ elsif Complex.generic?(other)
+ Complex(@real % other, @image % other)
+ else
+ x , y = a.coerce(self)
+ x % y
+ end
+ end
+
+ def divmod(other)
+ if other.kind_of?(Complex)
+ rdiv, rmod = @real.divmod(other.real)
+ idiv, imod = @image.divmod(other.image)
+ return Complex(rdiv, idiv), Complex(rmod, rdiv)
+ elsif Complex.generic?(other)
+ Complex(@real.divmod(other), @image.divmod(other))
+ else
+ x , y = a.coerce(self)
+ x.divmod(y)
+ end
+ end
+
+ def abs
+ Math.sqrt!((@real*@real + @image*@image).to_f)
+ end
+
+ def abs2
+ @real*@real + @image*@image
+ end
+
+ def arg
+ Math.atan2(@image.to_f, @real.to_f)
+ end
+
+ def polar
+ return abs, arg
+ end
+
+ def conjugate
+ Complex(@real, -@image)
+ end
+
+ def <=> (other)
+ self.abs <=> other.abs
+ end
+
+ def == (other)
+ if other.kind_of?(Complex)
+ @real == other.real and @image == other.image
+ elsif Complex.generic?(other)
+ @real == other and @image == 0
+ else
+ x , y = a.coerce(self)
+ x == y
+ end
+ end
+
+ def coerce(other)
+ if Complex.generic?(other)
+ return Complex.new(other), self
+ else
+ super
+ end
+ end
+
+ def to_i
+ Complex(@real.to_i, @image.to_i)
+ end
+
+ def to_f
+ Complex(@real.to_f, @image.to_f)
+ end
+
+ def to_r
+ Complex(@real.to_r, @image.to_r)
+ end
+
+ def denominator
+ @real.denominator.lcm(@image.denominator)
+ end
+
+ def numerator
+ cd = denominator
+ Complex(@real.numerator*(cd/@real.denominator),
+ @image.numerator*(cd/@image.denominator))
+ end
+
+ def to_s
+ if @real != 0
+ if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
+ if @image >= 0
+ @real.to_s+"+("+@image.to_s+")i"
+ else
+ @real.to_s+"-("+(-@image).to_s+")i"
+ end
+ else
+ if @image >= 0
+ @real.to_s+"+"+@image.to_s+"i"
+ else
+ @real.to_s+"-"+(-@image).to_s+"i"
+ end
+ end
+ else
+ if defined?(Rational) and @image.kind_of?(Rational) and @image.denominator != 1
+ "("+@image.to_s+")i"
+ else
+ @image.to_s+"i"
+ end
+ end
+ end
+
+ def hash
+ @real ^ @image
+ end
+
+ I = Complex(0,1)
+
+ attr :real
+ attr :image
+
+end
+
+class Numeric
+ def im
+ Complex(0, self)
+ end
+
+ def real
+ self
+ end
+
+ def image
+ 0
+ end
+
+ def arg
+ if self >= 0
+ return 0
+ else
+ return Math.atan2(1,1)*4
+ end
+ end
+
+ def polar
+ return abs, arg
+ end
+
+ def conjugate
+ self
+ end
+end
+
+class Fixnum
+ if not defined? Rational
+ alias power! **
+ end
+
+ def ** (other)
+ if self < 0
+ Complex.new(self) ** other
+ else
+ if defined? Rational
+ if other >= 0
+ self.power!(other)
+ else
+ Rational.new!(self,1)**other
+ end
+ else
+ self.power!(other)
+ end
+ end
+ end
+end
+
+class Bignum
+ if not defined? Rational
+ alias power! **
+ end
+end
+
+class Float
+ alias power! **
+end
+
+module Math
+ alias sqrt! sqrt
+ alias exp! exp
+ alias cos! cos
+ alias sin! sin
+ alias tan! tan
+ alias log! log
+ alias log10! log10
+ alias atan2! atan2
+
+ def sqrt(z)
+ if Complex.generic?(z)
+ if z >= 0
+ sqrt!(z)
+ else
+ Complex(0,sqrt!(-z))
+ end
+ else
+ z**Rational(1,2)
+ end
+ end
+
+ def exp(z)
+ if Complex.generic?(z)
+ exp!(z)
+ else
+ Complex(exp!(z.real) * cos!(z.image), exp!(z.real) * sin!(z.image))
+ end
+ end
+
+ def cosh!(x)
+ (exp!(x) + exp!(-x))/2.0
+ end
+
+ def sinh!(x)
+ (exp!(x) - exp!(-x))/2.0
+ end
+
+ def cos(z)
+ if Complex.generic?(z)
+ cos!(z)
+ else
+ Complex(cos!(z.real)*cosh!(z.image),
+ sin!(z.real)*sinh!(z.image))
+ end
+ end
+
+ def sin(z)
+ if Complex.generic?(z)
+ sin!(z)
+ else
+ Complex(sin!(z.real)*cosh!(z.image),
+ -cos!(z.real)*sinh!(z.image))
+ end
+ end
+
+ def tan(z)
+ if Complex.generic?(z)
+ tan!(z)
+ else
+ sin(z)/cos(z)
+ end
+ end
+
+ def log(z)
+ if Complex.generic?(z) and z >= 0
+ log!(z)
+ else
+ r, theta = z.polar
+ Complex(log!(r.abs), theta)
+ end
+ end
+
+ def log10(z)
+ if Complex.generic?(z)
+ log10!(z)
+ else
+ log(z)/log!(10)
+ end
+ end
+
+ def atan2(x, y)
+ if Complex.generic?(x) and Complex.generic?(y)
+ atan2!(x, y)
+ else
+ fail "Not yet implemented."
+ end
+ end
+
+ def atanh!(x)
+ log((1.0 + x.to_f) / ( 1.0 - x.to_f)) / 2.0
+ end
+
+ def atan(z)
+ if Complex.generic?(z)
+ atan2!(z, 1)
+ elsif z.image == 0
+ atan2(z.real,1)
+ else
+ a = z.real
+ b = z.image
+
+ c = (a*a + b*b - 1.0)
+ d = (a*a + b*b + 1.0)
+
+ Complex(atan2!((c + sqrt(c*c + 4.0*a*a)), 2.0*a),
+ atanh!((-d + sqrt(d*d - 4.0*b*b))/(2.0*b)))
+ end
+ end
+
+ module_function :sqrt
+ module_function :sqrt!
+ module_function :exp!
+ module_function :exp
+ module_function :cosh!
+ module_function :cos!
+ module_function :cos
+ module_function :sinh!
+ module_function :sin!
+ module_function :sin
+ module_function :tan!
+ module_function :tan
+ module_function :log!
+ module_function :log
+ module_function :log10!
+ module_function :log
+ module_function :atan2!
+ module_function :atan2
+# module_function :atan!
+ module_function :atan
+ module_function :atanh!
+
+end
+
+
diff --git a/lib/find.rb b/lib/find.rb
index 340461c653..5ecc54329c 100644
--- a/lib/find.rb
+++ b/lib/find.rb
@@ -8,31 +8,32 @@
#
module Find
- extend Find
-
- def findpath(path, ary)
- ary.push(path)
- d = Dir.open(path)
- for f in d
- continue if f =~ /^\.\.?$/
- f = path + "/" + f
- if File.directory? f
- findpath(f, ary)
- else
- ary.push(f)
- end
+ def find(*path)
+ while file = path.shift
+ catch(:prune) {
+ yield file
+ if File.directory? file and not File.symlink? file then
+ d = Dir.open(file)
+ begin
+ for f in d
+ next if f =~ /^\.\.?$/
+ if file == "/" then
+ f = "/" + f
+ else
+ f = file + "/" + f
+ end
+ path.unshift f
+ end
+ ensure
+ d.close
+ end
+ end
+ }
end
end
- private :findpath
- def find(*path)
- ary = []
- for p in path
- findpath(p, ary)
- for f in ary
- yield f
- end
- end
+ def prune
+ throw :prune
end
- module_function :find
+ module_function :find, :prune
end
diff --git a/lib/getopts.rb b/lib/getopts.rb
index 37fd3dc69d..d25437515d 100644
--- a/lib/getopts.rb
+++ b/lib/getopts.rb
@@ -1,117 +1,142 @@
+#!/usr/local/bin/ruby
#
-# getopts.rb - get options
+# getopts.rb -
# $Release Version: $
-# $Revision: 1.2 $
-# $Date: 1994/02/15 05:17:15 $
-# by Yasuo OHBA(STAFS Development Room)
+# $Revision: 1.1 $
+# $Date: 1996/11/10 05:01:15 $
+# by Yasuo OHBA(SHL Japan Inc. Technology Dept.)
#
# --
-# ƒIƒvƒVƒ‡ƒ“‚̉ðÍ‚ð‚µ, $OPT_?? ‚É’l‚ðƒZƒbƒg‚µ‚Ü‚·.
-# Žw’è‚Ì‚È‚¢ƒIƒvƒVƒ‡ƒ“‚ªŽw’肳‚ꂽŽž‚Í nil ‚ð•Ô‚µ‚Ü‚·.
-# ³íI—¹‚µ‚½ê‡‚Í, ƒZƒbƒg‚³‚ꂽƒIƒvƒVƒ‡ƒ“‚Ì”‚ð•Ô‚µ‚Ü‚·.
#
-# getopts(single_opts, *opts)
-#
-# ex. sample [options] filename
-# options ...
-# -f -x --version --geometry 100x200 -d unix:0.0
-# «
-# getopts("fx", "version", "geometry:", "d:")
-#
-# ‘æˆêˆø”:
-# -f ‚â -x (= -fx) ‚Ì—l‚ȈꕶŽš‚̃IƒvƒVƒ‡ƒ“‚ÌŽw’è‚ð‚µ‚Ü‚·.
-# ‚±‚±‚ňø”‚ª‚È‚¢‚Æ‚«‚Í nil ‚ÌŽw’肪•K—v‚Å‚·.
-# ‘æ“ñˆø”ˆÈ~:
-# ƒƒ“ƒOƒl[ƒ€‚̃IƒvƒVƒ‡ƒ“‚â, ˆø”‚Ì”º‚¤ƒIƒvƒVƒ‡ƒ“‚ÌŽw’è‚ð‚µ‚Ü‚·.
-# --version ‚â, --geometry 300x400 ‚â, -d host:0.0 “™‚Å‚·.
-# ˆø”‚𔺂¤Žw’è‚Í ":" ‚ð•K‚¸•t‚¯‚Ä‚­‚¾‚³‚¢.
-#
-# ƒIƒvƒVƒ‡ƒ“‚ÌŽw’肪‚ ‚Á‚½ê‡, •Ï” $OPT_?? ‚É non-nil ‚à‚µ‚­‚Í, ‚»‚̃I
-# ƒvƒVƒ‡ƒ“‚̈ø”‚ªƒZƒbƒg‚³‚ê‚Ü‚·.
-# -f -> $OPT_f = TRUE
-# --geometry 300x400 -> $OPT_geometry = 300x400
-#
-# - ‚à‚µ‚­‚Í -- ‚Í, ‚»‚êˆÈ~, ‘S‚ăIƒvƒVƒ‡ƒ“‚̉ðÍ‚ð‚µ‚Ü‚¹‚ñ.
+#
#
-$RCS_ID="$Header: /var/ohba/RCS/getopts.rb,v 1.2 1994/02/15 05:17:15 ohba Exp ohba $"
+$RCS_ID="$Header: /home/jammy/current/ruby/RCS/getopts.rb,v 1.1 1996/11/10 05:01:15 jammy Exp $"
+
+def isSingle(lopt)
+ if lopt.index(":")
+ if lopt.split(":")[0].length == 1
+ return TRUE
+ end
+ end
+ return nil
+end
+
+def getOptionName(lopt)
+ return lopt.split(":")[0]
+end
+
+def getDefaultOption(lopt)
+ od = lopt.split(":")[1]
+ if od
+ return od
+ end
+ return nil
+end
+
+def setOption(name, value)
+ eval("$OPT_" + name + " = " + 'value')
+end
+
+def setDefaultOption(lopt)
+ d = getDefaultOption(lopt)
+ if d
+ setOption(getOptionName(lopt), d)
+ end
+end
+
+def setNewArgv(newargv)
+ ARGV.clear
+ for na in newargv
+ ARGV << na
+ end
+end
-def getopts(single_opts, *opts)
- if (opts)
+
+def getopts(single_opts, *options)
+ if options
single_colon = ""
long_opts = []
sc = 0
- for option in opts
- if (option.length <= 2)
- single_colon[sc, 0] = option[0, 1]
+ for o in options
+ setDefaultOption(o)
+ if isSingle(o)
+ single_colon[sc, 0] = getOptionName(o)
sc += 1
else
- long_opts.push(option)
+ long_opts.push(o)
end
end
end
-
+
opts = {}
count = 0
- while ($ARGV.length != 0)
+ newargv = []
+ while ARGV.length != 0
compare = nil
- case $ARGV[0]
+ case ARGV[0]
when /^--?$/
- $ARGV.shift
+ ARGV.shift
+ newargv += ARGV
break
when /^--.*/
- compare = $ARGV[0][2, ($ARGV[0].length - 2)]
- if (long_opts != "")
- for option in long_opts
- if (option[(option.length - 1), 1] == ":" &&
- option[0, (option.length - 1)] == compare)
- if ($ARGV.length <= 1)
+ compare = ARGV[0][2, (ARGV[0].length - 2)]
+ if long_opts != ""
+ for lo in long_opts
+ if lo.index(":") && getOptionName(lo) == compare
+ if ARGV.length <= 1
return nil
- end
- eval("$OPT_" + compare + " = " + '$ARGV[1]')
- opts[compare] = TRUE
- $ARGV.shift
+ end
+ setOption(compare, ARGV[1])
+ opts[compare] = TRUE
+ ARGV.shift
count += 1
break
- elsif (option == compare)
- eval("$OPT_" + compare + " = TRUE")
- opts[compare] = TRUE
+ elsif lo == compare
+ setOption(compare, TRUE)
+ opts[compare] = TRUE
count += 1
- break
- end
- end
+ break
+ end
+ end
+ end
+ if compare.length <= 1
+ return nil
end
when /^-.*/
- for index in 1..($ARGV[0].length - 1)
- compare = $ARGV[0][index, 1]
- if (single_opts && compare =~ "[" + single_opts + "]")
- eval("$OPT_" + compare + " = TRUE")
- opts[compare] = TRUE
+ for idx in 1..(ARGV[0].length - 1)
+ compare = ARGV[0][idx, 1]
+ if single_opts && compare =~ "[" + single_opts + "]"
+ setOption(compare, TRUE)
+ opts[compare] = TRUE
count += 1
- elsif (single_colon != "" && compare =~ "[" + single_colon + "]")
- if ($ARGV[0][index..-1].length > 1)
- eval("$OPT_" + compare + " = " + '$ARGV[0][(index + 1)..-1]')
- opts[compare] = TRUE
+ elsif single_colon != "" && compare =~ "[" + single_colon + "]"
+ if ARGV[0][idx..-1].length > 1
+ setOption(compare, ARGV[0][(idx + 1)..-1])
+ opts[compare] = TRUE
count += 1
- elsif ($ARGV.length <= 1)
+ elsif ARGV.length <= 1
return nil
else
- eval("$OPT_" + compare + " = " + '$ARGV[1]')
- opts[compare] = TRUE
- $ARGV.shift
- count = count + 1
+ setOption(compare, ARGV[1])
+ opts[compare] = TRUE
+ ARGV.shift
+ count += 1
end
break
end
end
else
- break
+ compare = ARGV[0]
+ opts[compare] = TRUE
+ newargv << ARGV[0]
end
-
- $ARGV.shift
- if (!opts.includes(compare))
+
+ ARGV.shift
+ if !opts.has_key?(compare)
return nil
end
end
+ setNewArgv(newargv)
return count
end
diff --git a/lib/jcode.rb b/lib/jcode.rb
new file mode 100644
index 0000000000..5b2289932f
--- /dev/null
+++ b/lib/jcode.rb
@@ -0,0 +1,174 @@
+# jcode.rb - ruby code to handle japanese (EUC/SJIS) string
+
+class String
+ printf STDERR, "feel free for some warnings:\n" if $VERBOSE
+
+ alias original_succ succ
+ private :original_succ
+
+ def succ
+ if self[-2] && self[-2] & 0x80 != 0
+ s = self.dup
+ s[-1] += 1
+ return s
+ else
+ original_succ
+ end
+ end
+
+ def upto(to)
+ return if self > to
+
+ curr = self
+ tail = self[-2..-1]
+ if tail.length == 2 and tail =~ /^.$/ then
+ if self[0..-2] == to[0..-2]
+ for c in self[-1] .. to[-1]
+ yield self[0..-2]+c.chr
+ end
+ end
+ else
+ loop do
+ yield curr
+ return if curr == to
+ curr = curr.succ
+ return if curr.length > to.length
+ end
+ end
+ return nil
+ end
+
+ def _expand_ch
+ a = []
+ self.scan(/(.|\n)-(.|\n)|(.|\n)/) do |r|
+ if $3
+ a.push $3
+ elsif $1.length != $2.length
+ next
+ elsif $1.length == 1
+ $1[0].upto($2[0]) { |c| a.push c.chr }
+ else
+ $1.upto($2) { |c| a.push c }
+ end
+ end
+ a
+ end
+
+ def tr!(from, to)
+ return self.delete!(from) if to.length == 0
+
+ if from =~ /^\^/
+ comp=TRUE
+ from = $'
+ end
+ afrom = from._expand_ch
+ ato = to._expand_ch
+ i = 0
+ if comp
+ self.gsub!(/(.|\n)/) do |c|
+ unless afrom.include?(c)
+ ato[-1]
+ else
+ c
+ end
+ end
+ else
+ self.gsub!(/(.|\n)/) do |c|
+ if i = afrom.index(c)
+ if i < ato.size then ato[i] else ato[-1] end
+ else
+ c
+ end
+ end
+ end
+ end
+
+ def tr(from, to)
+ self.dup.tr!(from, to)
+ end
+
+ def delete!(del)
+ if del =~ /^\^/
+ comp=TRUE
+ del = $'
+ end
+ adel = del._expand_ch
+ if comp
+ self.gsub!(/(.|\n)/) do |c|
+ next unless adel.include?(c)
+ c
+ end
+ else
+ self.gsub!(/(.|\n)/) do |c|
+ next if adel.include?(c)
+ c
+ end
+ end
+ end
+
+ def delete(del)
+ self.dup.delete!(del)
+ end
+
+ def squeeze!(del=nil)
+ if del
+ if del =~ /^\^/
+ comp=TRUE
+ del = $'
+ end
+ adel = del._expand_ch
+ if comp
+ self.gsub!(/(.|\n)\1+/) do
+ next unless adel.include?($1)
+ $&
+ end
+ else
+ for c in adel
+ cq = Regexp.quote(c)
+ self.gsub!(/#{cq}(#{cq})+/, cq)
+ end
+ end
+ self
+ else
+ self.gsub!(/(.|\n)\1+/, '\1')
+ end
+ end
+
+ def squeeze(del=nil)
+ self.dup.squeeze!(del)
+ end
+
+ def tr_s!(from, to)
+ return self.delete!(from) if to.length == 0
+ if from =~ /^\^/
+ comp=TRUE
+ from = $'
+ end
+ afrom = from._expand_ch
+ ato = to._expand_ch
+ i = 0
+ c = nil
+ last = nil
+ self.gsub!(/(.|\n)/) do |c|
+ if comp
+ unless afrom.include?(c)
+ ato[-1]
+ else
+ c
+ end
+ elsif i = afrom.index(c)
+ c = if i < ato.size then ato[i] else ato[-1] end
+ next if c == last
+ last = c
+ else
+ last = nil
+ c
+ end
+ end
+ end
+
+ def tr_s(from, to)
+ self.dup.tr_s!(from,to)
+ end
+
+end
diff --git a/lib/mailread.rb b/lib/mailread.rb
index 4b04445beb..d9feffbb7a 100644
--- a/lib/mailread.rb
+++ b/lib/mailread.rb
@@ -1,9 +1,8 @@
class Mail
-
def Mail.new(f)
- if !f.is_kind_of?(IO)
+ unless f.kind_of?(IO)
f = open(f, "r")
- me = super
+ me = super(f)
f.close
else
me = super
@@ -16,17 +15,18 @@ class Mail
@body = []
while f.gets()
$_.chop!
- continue if /^From / # skip From-line
+ next if /^From / # skip From-line
break if /^$/ # end of header
+
if /^(\S+):\s*(.*)/
- @header[attr = $1.capitalize] = $2
+ @header[attr = $1.capitalize!] = $2
elsif attr
- sub(/^\s*/, '')
+ sub!(/^\s*/, '')
@header[attr] += "\n" + $_
end
end
-
- return if ! $_
+
+ return unless $_
while f.gets()
break if /^From /
@@ -42,4 +42,7 @@ class Mail
return @body
end
+ def [](field)
+ @header[field]
+ end
end
diff --git a/lib/mathn.rb b/lib/mathn.rb
new file mode 100644
index 0000000000..359cb45769
--- /dev/null
+++ b/lib/mathn.rb
@@ -0,0 +1,307 @@
+#
+# mathn.rb -
+# $Release Version: 0.5 $
+# $Revision: 1.1 $
+# $Date: 1996/11/11 04:25:24 $
+# by Keiju ISHITSUKA(SHL Japan Inc.)
+#
+# --
+#
+#
+#
+
+require "rational.rb"
+require "complex.rb"
+
+class Integer
+
+ def gcd2(int)
+ a = self.abs
+ b = int.abs
+ a, b = b, a if a < b
+
+ pd_a = a.prime_division
+ pd_b = b.prime_division
+
+ gcd = 1
+ for pair in pd_a
+ as = pd_b.assoc(pair[0])
+ if as
+ gcd *= as[0] ** [as[1], pair[1]].min
+ end
+ end
+ return gcd
+ end
+
+ def Integer.from_prime_division(pd)
+ value = 1
+ for prime, index in pd
+ value *= prime**index
+ end
+ value
+ end
+
+ def prime_division
+ ps = Prime.new
+ value = self
+ pv = []
+ for prime in ps
+ count = 0
+ while (value1, mod = value.divmod(prime)
+ mod) == 0
+ value = value1
+ count += 1
+ end
+ if count != 0
+ pv.push [prime, count]
+ end
+ break if prime * prime >= value
+ end
+ if value > 1
+ pv.push [value, 1]
+ end
+ return pv
+ end
+end
+
+class Prime
+ include Enumerable
+
+ def initialize
+ @seed = 1
+ @primes = []
+ @counts = []
+ end
+
+ def succ
+ i = -1
+ size = @primes.size
+ while i < size
+ if i == -1
+ @seed += 1
+ i += 1
+ else
+ while @seed > @counts[i]
+ @counts[i] += @primes[i]
+ end
+ if @seed != @counts[i]
+ i += 1
+ else
+ i = -1
+ end
+ end
+ end
+ @primes.push @seed
+ @counts.push @seed + @seed
+ return @seed
+ end
+
+ def each
+ loop do
+ yield succ
+ end
+ end
+end
+
+class Fixnum
+ alias divmod! divmod
+ alias / rdiv
+ def divmod(other)
+ a = self.div(other)
+ b = self % other
+ return a,b
+ end
+end
+
+class Bignum
+ alias divmod! divmod
+ alias / rdiv
+end
+
+class Rational
+ Unify = TRUE
+
+ alias power! **
+
+ def ** (other)
+ if other.kind_of?(Rational)
+ if self < 0
+ return Complex(self, 0) ** other
+ elsif other == 0
+ return Rational(1,1)
+ elsif self == 0
+ return Rational(0,1)
+ elsif self == 1
+ return Rational(1,1)
+ end
+
+ npd = @numerator.prime_division
+ dpd = @denominator.prime_division
+ if other < 0
+ other = -other
+ npd, dpd = dpd, npd
+ end
+
+ for elm in npd
+ elm[1] = elm[1] * other
+ if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
+ return Float(self) ** other
+ end
+ elm[1] = elm[1].to_i
+ end
+
+ for elm in dpd
+ elm[1] = elm[1] * other
+ if !elm[1].kind_of?(Integer) and elm[1].denominator != 1
+ return Float(self) ** other
+ end
+ elm[1] = elm[1].to_i
+ end
+
+ num = Integer.from_prime_division(npd)
+ den = Integer.from_prime_division(dpd)
+
+ Rational(num,den)
+
+ elsif other.kind_of?(Integer)
+ if other > 0
+ num = @numerator ** other
+ den = @denominator ** other
+ elsif other < 0
+ num = @denominator ** -other
+ den = @numerator ** -other
+ elsif other == 0
+ num = 1
+ den = 1
+ end
+ Rational.new!(num, den)
+ elsif other.kind_of?(Float)
+ Float(self) ** other
+ else
+ x , y = other.coerce(self)
+ x ** y
+ end
+ end
+
+ def power2(other)
+ if other.kind_of?(Rational)
+ if self < 0
+ return Complex(self, 0) ** other
+ elsif other == 0
+ return Rational(1,1)
+ elsif self == 0
+ return Rational(0,1)
+ elsif self == 1
+ return Rational(1,1)
+ end
+
+ dem = nil
+ x = self.denominator.to_f.to_i
+ neard = self.denominator.to_f ** (1.0/other.denominator.to_f)
+ loop do
+ if (neard**other.denominator == self.denominator)
+ dem = neaed
+ break
+ end
+ end
+ nearn = self.numerator.to_f ** (1.0/other.denominator.to_f)
+ Rational(num,den)
+
+ elsif other.kind_of?(Integer)
+ if other > 0
+ num = @numerator ** other
+ den = @denominator ** other
+ elsif other < 0
+ num = @denominator ** -other
+ den = @numerator ** -other
+ elsif other == 0
+ num = 1
+ den = 1
+ end
+ Rational.new!(num, den)
+ elsif other.kind_of?(Float)
+ Float(self) ** other
+ else
+ x , y = other.coerce(self)
+ x ** y
+ end
+ end
+end
+
+module Math
+ def sqrt(a)
+ if a.kind_of?(Complex)
+ abs = sqrt(a.real*a.real + a.image*a.image)
+# if not abs.kind_of?(Rational)
+# return a**Rational(1,2)
+# end
+ x = sqrt((a.real + abs)/Rational(2))
+ y = sqrt((-a.real + abs)/Rational(2))
+# if !(x.kind_of?(Rational) and y.kind_of?(Rational))
+# return a**Rational(1,2)
+# end
+ if a.image >= 0
+ Complex(x, y)
+ else
+ Complex(x, -y)
+ end
+ elsif a >= 0
+ rsqrt(a)
+ else
+ Complex(0,rsqrt(-a))
+ end
+ end
+
+ def rsqrt(a)
+ if a.kind_of?(Float)
+ sqrt!(a)
+ elsif a.kind_of?(Rational)
+ rsqrt(a.numerator)/rsqrt(a.denominator)
+ else
+ src = a
+ max = 2 ** 32
+ byte_a = [src & 0xffffffff]
+ # ruby's bug
+ while (src >= max) and (src >>= 32)
+ byte_a.unshift src & 0xffffffff
+ end
+
+ answer = 0
+ main = 0
+ side = 0
+ for elm in byte_a
+ main = (main << 32) + elm
+ side <<= 16
+ if answer != 0
+ if main * 4 < side * side
+ applo = main.div(side)
+ else
+ applo = ((sqrt!(side * side + 4 * main) - side)/2.0).to_i + 1
+ end
+ else
+ applo = sqrt!(main).to_i + 1
+ end
+
+ while (x = (side + applo) * applo) > main
+ applo -= 1
+ end
+ main -= x
+ answer = (answer << 16) + applo
+ side += applo * 2
+ end
+ if main == 0
+ answer
+ else
+ sqrt!(a)
+ end
+ end
+ end
+
+ module_function :sqrt
+ module_function :rsqrt
+end
+
+class Complex
+ Unify = TRUE
+end
+
diff --git a/lib/observer.rb b/lib/observer.rb
new file mode 100644
index 0000000000..9a753939a2
--- /dev/null
+++ b/lib/observer.rb
@@ -0,0 +1,40 @@
+# Observable Mixin
+#
+# Observers must respond to update
+
+module Observable
+ def add_observer(observer)
+ @observer_peers = [] unless @observer_peers
+ unless defined? observer.update
+ raise NameError, "observer needs to respond to `update'"
+ end
+ @observer_peers.push observer
+ end
+ def delete_observer(observer)
+ @observer_peers.delete observer if @observer_peers
+ end
+ def delete_observers
+ @observer_peers.clear if @observer_peers
+ end
+ def count_observers
+ if @observer_peers
+ @observer_peers.size
+ else
+ 0
+ end
+ end
+ def changed(state=TRUE)
+ @observer_state = state
+ end
+ def changed?
+ @observer_state
+ end
+ def notify_observers(*arg)
+ if @observer_state
+ for i in @observer_peers
+ i.update(*arg)
+ end
+ @observer_state = FALSE
+ end
+ end
+end
diff --git a/lib/parsearg.rb b/lib/parsearg.rb
index e7e2b7a7f3..569ed260f7 100644
--- a/lib/parsearg.rb
+++ b/lib/parsearg.rb
@@ -1,68 +1,83 @@
+#!/usr/local/bin/ruby
#
-# parseargs.rb - parse arguments
+# parsearg.rb - parse arguments
# $Release Version: $
# $Revision: 1.3 $
-# $Date: 1994/02/15 05:16:21 $
-# by Yasuo OHBA(STAFS Development Room)
+# $Date: 1996/11/12 06:48:51 $
+# by Yasuo OHBA(SHL Japan Inc. Technology Dept.)
#
# --
-# ˆø”‚̉ðÍ‚ð‚µ, $OPT_?? ‚É’l‚ðƒZƒbƒg‚µ‚Ü‚·.
-# ³íI—¹‚µ‚½ê‡‚Í, ƒZƒbƒg‚³‚ꂽƒIƒvƒVƒ‡ƒ“‚Ì”‚ð•Ô‚µ‚Ü‚·.
#
-# parseArgs(argc, single_opts, *opts)
-#
-# ex. sample [options] filename
-# options ...
-# -f -x --version --geometry 100x200 -d unix:0.0
-# «
-# parseArgs(1, nil, "fx", "version", "geometry:", "d:")
-#
-# ‘æˆêˆø”:
-# ƒIƒvƒVƒ‡ƒ“ˆÈŠO‚ÌÅ’áˆø”‚Ì”
-# ‘æ“ñˆø”:
-# ƒIƒvƒVƒ‡ƒ“‚Ì•K—v«c•K‚¸•K—v‚È‚ç %TRUE ‚»‚¤‚Å‚È‚¯‚ê‚Î %FALSE.
-# ‘æŽOˆø”:
-# -f ‚â -x (= -fx) ‚Ì—l‚ȈꕶŽš‚̃IƒvƒVƒ‡ƒ“‚ÌŽw’è‚ð‚µ‚Ü‚·.
-# ‚±‚±‚ňø”‚ª‚È‚¢‚Æ‚«‚Í nil ‚ÌŽw’肪•K—v‚Å‚·.
-# ‘æŽlˆø”ˆÈ~:
-# ƒƒ“ƒOƒl[ƒ€‚̃IƒvƒVƒ‡ƒ“‚â, ˆø”‚Ì”º‚¤ƒIƒvƒVƒ‡ƒ“‚ÌŽw’è‚ð‚µ‚Ü‚·.
-# --version ‚â, --geometry 300x400 ‚â, -d host:0.0 “™‚Å‚·.
-# ˆø”‚𔺂¤Žw’è‚Í ":" ‚ð•K‚¸•t‚¯‚Ä‚­‚¾‚³‚¢.
-#
-# ƒIƒvƒVƒ‡ƒ“‚ÌŽw’肪‚ ‚Á‚½ê‡, •Ï” $OPT_?? ‚É non-nil ‚à‚µ‚­‚Í, ‚»‚̃I
-# ƒvƒVƒ‡ƒ“‚̈ø”‚ªƒZƒbƒg‚³‚ê‚Ü‚·.
-# -f -> $OPT_f = %TRUE
-# --geometry 300x400 -> $OPT_geometry = 300x400
-#
-# usage ‚ðŽg‚¢‚½‚¢ê‡‚Í, $USAGE ‚É usage() ‚ðŽw’肵‚Ü‚·.
-# def usage()
-# c
-# end
-# $USAGE = 'usage'
-# usage ‚Í, --help ‚ªŽw’肳‚ꂽŽž, ŠÔˆá‚Á‚½Žw’è‚ð‚µ‚½Žž‚É•\Ž¦‚µ‚Ü‚·.
-#
-# - ‚à‚µ‚­‚Í -- ‚Í, ‚»‚êˆÈ~, ‘S‚ăIƒvƒVƒ‡ƒ“‚̉ðÍ‚ð‚µ‚Ü‚¹‚ñ.
+#
#
-$RCS_ID="$Header: /var/ohba/RCS/parseargs.rb,v 1.3 1994/02/15 05:16:21 ohba Exp ohba $"
+$RCS_ID="$Header: /home/jammy/current/ruby/RCS/parsearg.rb,v 1.3 1996/11/12 06:48:51 jammy Exp $"
load("getopts.rb")
def printUsageAndExit()
if $USAGE
- apply($USAGE)
+ eval($USAGE)
end
exit()
end
+def setParenthesis(ex, opt, c)
+ if opt != ""
+ ex = sprintf("%s$OPT_%s%s", ex, opt, c)
+ else
+ ex = sprintf("%s%s", ex, c)
+ end
+ return ex
+end
+
+def setOrAnd(ex, opt, c)
+ if opt != ""
+ ex = sprintf("%s$OPT_%s %s%s ", ex, opt, c, c)
+ else
+ ex = sprintf("%s %s%s ", ex, c, c)
+ end
+ return ex
+end
+
+def setExpression(ex, opt, op)
+ if !op
+ ex = sprintf("%s$OPT_%s", ex, opt)
+ return ex
+ end
+ case op.chr
+ when "(", ")"
+ ex = setParenthesis(ex, opt, op.chr)
+ when "|", "&"
+ ex = setOrAnd(ex, opt, op.chr)
+ else
+ return nil
+ end
+ return ex
+end
+
def parseArgs(argc, nopt, single_opts, *opts)
- if ((noOptions = getopts(single_opts, *opts)) == nil)
+ if (noOptions = getopts(single_opts, *opts)) == nil
printUsageAndExit()
end
- if (nopt && noOptions == 0)
- printUsageAndExit()
+ if nopt
+ ex = nil
+ pos = 0
+ for o in nopt.split(/[()|&]/)
+ pos += o.length
+ ex = setExpression(ex, o, nopt[pos])
+ pos += 1
+ end
+ begin
+ if !eval(ex)
+ printUsageAndExit()
+ end
+ rescue
+ print "Format Error!! : \"" + nopt + "\"\t[parseArgs]\n"
+ exit! -1
+ end
end
- if ($ARGV.length < argc)
+ if ARGV.length < argc
printUsageAndExit()
end
return noOptions
diff --git a/lib/rational.rb b/lib/rational.rb
new file mode 100644
index 0000000000..d4112c2956
--- /dev/null
+++ b/lib/rational.rb
@@ -0,0 +1,361 @@
+#
+# rational.rb -
+# $Release Version: 0.5 $
+# $Revision: 1.1 $
+# $Date: 1996/11/11 04:25:14 $
+# by Keiju ISHITSUKA(SHL Japan Inc.)
+#
+# --
+# Usage:
+# class Rational < Numeric
+# (include Compareable)
+#
+# Rational(a, b) --> a/b
+#
+# Rational::+
+# Rational::-
+# Rational::*
+# Rational::/
+# Rational::**
+# Rational::%
+# Rational::divmod
+# Rational::abs
+# Rational::<=>
+# Rational::to_i
+# Rational::to_f
+# Rational::to_s
+#
+# Integer::gcd
+# Integer::lcm
+# Integer::gcdlcm
+# Integer::to_r
+#
+# Fixnum::**
+# Bignum::**
+#
+#
+
+def Rational(a, b = 1)
+ if a.kind_of?(Rational) && b == 1
+ a
+ else
+ Rational.reduce(a, b)
+ end
+end
+
+class Rational < Numeric
+ def Rational.reduce(num, den = 1)
+ if den < 0
+ num = -num
+ den = -den
+ end
+ gcd = num.gcd(den)
+ num = num.div(gcd)
+ den = den.div(gcd)
+ if den == 1 && defined?(Unify)
+ num
+ else
+ new!(num, den)
+ end
+ end
+
+ def Rational.new!(num, den = 1)
+ new(num, den)
+ end
+
+ def initialize(num, den)
+ if den < 0
+ num = -num
+ den = -den
+ end
+ if num.kind_of?(Integer) and den.kind_of?(Integer)
+ @numerator = num
+ @denominator = den
+ else
+ @numerator = num.to_i
+ @denoninator = den.to_i
+ end
+ end
+
+ def + (a)
+ if a.kind_of?(Rational)
+ num = @numerator * a.denominator
+ num_a = a.numerator * @denominator
+ Rational(num + num_a, @denominator * a.denominator)
+ elsif a.kind_of?(Integer)
+ self + Rational.new!(a, 1)
+ elsif a.kind_of?(Float)
+ Float(self) + a
+ else
+ x , y = a.coerce(self)
+ x + y
+ end
+ end
+
+ def - (a)
+ if a.kind_of?(Rational)
+ num = @numerator * a.denominator
+ num_a = a.numerator * @denominator
+ Rational(num - num_a, @denominator*a.denominator)
+ elsif a.kind_of?(Integer)
+ self - Rational.new!(a, 1)
+ elsif a.kind_of?(Float)
+ Float(self) - a
+ else
+ x , y = a.coerce(self)
+ x - y
+ end
+ end
+
+ def * (a)
+ if a.kind_of?(Rational)
+ num = @numerator * a.numerator
+ den = @denominator * a.denominator
+ Rational(num, den)
+ elsif a.kind_of?(Integer)
+ self * Rational.new!(a, 1)
+ elsif a.kind_of?(Float)
+ Float(self) * a
+ else
+ x , y = a.coerce(self)
+ x * y
+ end
+ end
+
+ def / (a)
+ if a.kind_of?(Rational)
+ num = @numerator * a.denominator
+ den = @denominator * a.numerator
+ Rational(num, den)
+ elsif a.kind_of?(Integer)
+ self / Rational.new!(a, 1)
+ elsif a.kind_of?(Float)
+ Float(self) / a
+ else
+ x , y = a.coerce(self)
+ x / y
+ end
+ end
+
+ def ** (other)
+ if other.kind_of?(Rational)
+ Float(self) ** other
+ elsif other.kind_of?(Integer)
+ if other > 0
+ num = @numerator ** other
+ den = @denominator ** other
+ elsif other < 0
+ num = @denominator ** -other
+ den = @numerator ** -other
+ elsif other == 0
+ num = 1
+ den = 1
+ end
+ Rational.new!(num, den)
+ elsif other.kind_of?(Float)
+ Float(self) ** other
+ else
+ x , y = other.coerce(self)
+ x ** y
+ end
+ end
+
+ def % (other)
+ value = (self / other).to_i
+ return self - other * value
+ end
+
+ def divmod(other)
+ value = (self / other).to_i
+ return value, self - other * value
+ end
+
+ def abs
+ if @numerator > 0
+ Rational.new!(@numerator, @denominator)
+ else
+ Rational.new!(-@numerator, @denominator)
+ end
+ end
+
+ def <=> (other)
+ if other.kind_of?(Rational)
+ num = @numerator * other.denominator
+ num_a = other.numerator * @denominator
+ v = num - num_a
+ if v > 0
+ return 1
+ elsif v < 0
+ return -1
+ else
+ return 0
+ end
+ elsif other.kind_of?(Integer)
+ return self <=> Rational.new!(other, 1)
+ elsif other.kind_of?(Float)
+ return Float(self) <=> other
+ else
+ x , y = other.coerce(self)
+ return x <=> y
+ end
+ end
+
+ def coerce(other)
+ if other.kind_of?(Float)
+ return other, self.to_f
+ elsif other.kind_of?(Integer)
+ return Rational.new!(other, 1), self
+ else
+ super
+ end
+ end
+
+ def to_i
+ Integer(@numerator.div(@denominator))
+ end
+
+ def to_f
+ @numerator.to_f/@denominator.to_f
+ end
+
+ def to_s
+ if @denominator == 1
+ @numerator.to_s
+ else
+ @numerator.to_s+"/"+@denominator.to_s
+ end
+ end
+
+ def to_r
+ self
+ end
+
+ def hash
+ @numerator ^ @denominator
+ end
+
+ attr :numerator
+ attr :denominator
+
+ private :initialize
+end
+
+class Integer
+ def numerator
+ self
+ end
+
+ def denomerator
+ 1
+ end
+
+ def to_r
+ Rational(self, 1)
+ end
+
+ def gcd(int)
+ a = self.abs
+ b = int.abs
+
+ a, b = b, a if a < b
+
+ while b != 0
+ void, a = a.divmod(b)
+ a, b = b, a
+ end
+ return a
+ end
+
+ def lcm(int)
+ a = self.abs
+ b = int.abs
+ gcd = a.gcd(b)
+ (a.div(gcd)) * b
+ end
+
+ def gcdlcm(int)
+ a = self.abs
+ b = int.abs
+ gcd = a.gcd(b)
+ return gcd, (a.div(gcd)) * b
+ end
+
+end
+
+class Fixnum
+ alias div! /;
+ def div(other)
+ if other.kind_of?(Fixnum)
+ self.div!(other)
+ elsif other.kind_of?(Bignum)
+ x, y = other.coerce(self)
+ x.div!(y)
+ else
+ x, y = other.coerce(self)
+ x / y
+ end
+ end
+
+# alias divmod! divmod
+
+ if not defined? Complex
+ alias power! **;
+ end
+
+# def rdiv(other)
+# if other.kind_of?(Fixnum)
+# Rational(self, other)
+# elsif
+# x, y = other.coerce(self)
+# if defined?(x.div())
+# x.div(y)
+# else
+# x / y
+# end
+# end
+ # end
+
+ def rdiv(other)
+ Rational.new!(self,1) / other
+ end
+
+ def rpower (other)
+ if other >= 0
+ self.power!(other)
+ else
+ Rational.new!(self,1)**other
+ end
+ end
+
+ if not defined? Complex
+ alias ** rpower
+ end
+end
+
+class Bignum
+ alias div! /;
+ alias div /;
+ alias divmod! divmod
+
+ if not defined? power!
+ alias power! **
+ end
+
+ def rdiv(other)
+ Rational.new!(self,1) / other
+ end
+
+ def rpower (other)
+ if other >= 0
+ self.power!(other)
+ else
+ Rational.new!(self, 1)**other
+ end
+ end
+
+ if not defined? Complex
+ alias ** rpower
+ end
+
+end
+
diff --git a/lib/safe.rb b/lib/safe.rb
new file mode 100644
index 0000000000..7c95555495
--- /dev/null
+++ b/lib/safe.rb
@@ -0,0 +1,78 @@
+# this is a safe-mode for ruby, which is still incomplete.
+
+unless defined? SecurityError
+ class SecurityError<Exception
+ end
+end
+
+module Restricted
+
+ printf STDERR, "feel free for some warnings:\n" if $VERBOSE
+ module Bastion
+ include Restricted
+ extend Restricted
+ BINDING = binding
+ def Bastion.to_s; "main" end
+ end
+
+ class R_File<File
+ NG_FILE_OP = []
+ def R_File.open(*args)
+ raise SecurityError, "can't use File.open() in safe mode" #'
+ end
+ end
+
+ IO = nil
+ File = R_File
+ FileTest = nil
+ Dir = nil
+ ObjectSpace = nil
+
+ def eval(string)
+ begin
+ super(string, Bastion::BINDING)
+ rescue
+ $@ = caller
+ raise
+ end
+ end
+ module_function :eval
+
+ DEFAULT_SECURITY_MANAGER = Object.new
+
+ def Restricted.set_securuty_manager(sec_man)
+ if @sec_man
+ raise SecurityError, "cannot change security manager"
+ end
+ @sec_man = sec_man
+ end
+
+ def Restricted.securuty_manager
+ return @sec_man if @sec_man
+ return DEFAULT_SECURITY_MANAGER
+ end
+
+ for cmd in ["test", "require", "load", "open", "system"]
+ eval format("def DEFAULT_SECURITY_MANAGER.%s(*args)
+ raise SecurityError, \"can't use %s() in safe mode\"
+ end", cmd, cmd) #'
+ eval format("def %s(*args)
+ Restricted.securuty_manager.%s(*args)
+ end", cmd, cmd)
+ end
+
+ def `(arg) #`
+ Restricted.securuty_manager.send(:`, arg) #`)
+ end
+
+ def DEFAULT_SECURITY_MANAGER.`(arg) #`
+ raise SecurityError, "can't use backquote(``) in safe mode"
+ end
+end
+
+if $DEBUG
+ p eval("File.open('/dev/null')")
+ p Restricted.eval("self")
+ p Restricted.eval("open('/dev/null')")
+ p Restricted.eval("File.open('/dev/null')")
+end
diff --git a/lib/thread.rb b/lib/thread.rb
new file mode 100644
index 0000000000..c3347b60b4
--- /dev/null
+++ b/lib/thread.rb
@@ -0,0 +1,153 @@
+#
+# thread.rb - thread support classes
+# $Date: 1996/05/21 09:29:21 $
+# by Yukihiro Matsumoto <matz@caelum.co.jp>
+#
+
+unless defined? Thread
+ fail "Thread not available for this ruby interpreter"
+end
+
+unless defined? ThreadError
+ class ThreadError<Exception
+ end
+end
+
+class Mutex
+ def initialize
+ @waiting = []
+ @locked = FALSE;
+ end
+
+ def locked?
+ @locked
+ end
+
+ def try_lock
+ Thread.exclusive do
+ if not @locked
+ @locked=TRUE
+ return TRUE
+ end
+ end
+ FALSE
+ end
+
+ def lock
+ while not try_lock
+ @waiting.push Thread.current
+ Thread.stop
+ end
+ end
+
+ def unlock
+ @locked = FALSE
+ if w = @waiting.shift
+ w.run
+ end
+ end
+
+ def synchronize
+ begin
+ lock
+ yield
+ ensure
+ unlock
+ end
+ end
+end
+
+class SharedMutex<Mutex
+ def initialize
+ @locking = nil
+ @num_locks = 0;
+ super
+ end
+ def try_lock
+ if @locking == Thread.current
+ @num_locks += 1
+ return TRUE
+ end
+ if super
+ @num_locks = 1
+ @locking = Thread.current
+ TRUE
+ else
+ FALSE
+ end
+ end
+ def unlock
+ unless @locking == Thread.current
+ raise ThreadError, "cannot release shared mutex"
+ end
+ @num_locks -= 1
+ if @num_locks == 0
+ @locking = nil
+ super
+ end
+ end
+end
+
+class Queue
+ def initialize
+ @que = []
+ @waiting = []
+ end
+
+ def push(obj)
+ @que.push obj
+ if t = @waiting.shift
+ t.run
+ end
+ end
+
+ def pop non_block=FALSE
+ if @que.length == 0
+ raise ThreadError, "queue empty" if non_block
+ @waiting.push Thread.current
+ Thread.stop
+ end
+ @que.shift
+ end
+
+ def empty?
+ @que.length == 0
+ end
+
+ def length
+ @que.length
+ end
+end
+
+class Condition
+ def initialize
+ @waiting = []
+ end
+
+ def wait(mut)
+ Thread.exclusive do
+ mut.unlock
+ @waiting.push Thread.current
+ end
+ Thread.sleep
+ mut.lock
+ end
+
+ def signal
+ th = nil
+ Thread.exclusive do
+ th = @waiting.pop
+ end
+ th.run
+ end
+
+ def broadcast
+ w = @waiting
+ Thread.exclusive do
+ th = []
+ end
+ for th in w
+ th.run
+ end
+ end
+end
diff --git a/lib/tk.rb b/lib/tk.rb
index 9c61269881..5a725aac11 100644
--- a/lib/tk.rb
+++ b/lib/tk.rb
@@ -3,477 +3,10 @@
# $Date: 1995/11/03 08:17:15 $
# by Yukihiro Matsumoto <matz@caelum.co.jp>
-require "tkutil"
-
-trap "PIPE", proc{exit 0}
-trap "EXIT", proc{Tk.tk_exit}
-
-module Tk
- include TkUtil
- extend Tk
-
- $0 =~ /\/(.*$)/
-
- PORT = open(format("|%s -n %s", WISH_PATH, $1), "w+");
- def tk_write(*args)
- printf PORT, *args;
- PORT.print "\n"
- PORT.flush
- end
- tk_write '\
-wm withdraw .
-proc rb_out args {
- puts [format %%s $args]
- flush stdout
-}
-proc tkerror args { exit }
-proc keepalive {} { rb_out alive; after 120000 keepalive}
-after 120000 keepalive'
-
- READABLE = []
- READ_CMD = {}
-
- def file_readable(port, cmd)
- READABLE.push port
- READ_CMD[port] = cmd
- end
-
- WRITABLE = []
- WRITE_CMD = {}
- def file_writable
- WRITABLE.push port
- WRITE_CMD[port] = cmd
- end
- module_function :file_readable, :file_writable
-
- file_readable PORT, proc {
- exit if not PORT.gets
- Tk.dispatch($_.chop!)
- }
-
- def tk_exit
- PORT.print "exit\n"
- PORT.close
- end
-
- def error_at
- n = 1
- while c = caller(n)
- break if c !~ /tk\.rb:/
- n+=1
- end
- c
- end
-
- def tk_tcl2ruby(val)
- case val
- when /^-?\d+$/
- val.to_i
- when /^\./
- $tk_window_list[val]
- when /^rb_out (c\d+)/
- $tk_cmdtbl[$1]
- when / /
- val.split.collect{|elt|
- tk_tcl2ruby(elt)
- }
- when /^-?\d+\.\d*$/
- val.to_f
- else
- val
- end
- end
-
- def tk_split_list(str)
- idx = str.index('{')
- return tk_tcl2ruby(str) if not idx
-
- list = tk_tcl2ruby(str[0,idx])
- str = str[idx+1..-1]
- i = -1
- brace = 1
- str.each_byte {|c|
- i += 1
- brace += 1 if c == ?{
- brace -= 1 if c == ?}
- break if brace == 0
- }
- if str[0, i] == ' '
- list.push ' '
- else
- list.push tk_split_list(str[0, i])
- end
- list += tk_split_list(str[i+1..-1])
- list
- end
- private :tk_tcl2ruby, :tk_split_list
-
- def bool(val)
- case bool
- when "1", 1, 'yes', 'true'
- TRUE
- else
- FALSE
- end
- end
- def number(val)
- case val
- when /^-?\d+$/
- val.to_i
- when /^-?\d+\.\d*$/
- val.to_f
- else
- val
- end
- end
- def string(val)
- if val == "{}"
- ''
- elsif val[0] == ?{
- val[1..-2]
- else
- val
- end
- end
- def list(val)
- tk_split_list(val)
- end
- def window(val)
- $tk_window_list[val]
- end
- def procedure(val)
- if val =~ /^rb_out (c\d+)/
- $tk_cmdtbl[$1]
- else
- nil
- end
- end
- private :bool, :number, :string, :list, :window, :procedure
-
- # mark for non-given arguments
- None = Object.new
- def None.to_s
- 'None'
- end
-
- $tk_event_queue = []
- def tk_call(*args)
- args = args.collect{|s|
- continue if s == None
- if s == FALSE
- s = "0"
- elsif s == TRUE
- s = "1"
- elsif s.is_kind_of?(TkObject)
- s = s.path
- else
- s = s.to_s
- s.gsub!(/[{}]/, '\\\\\0')
- end
- "{#{s}}"
- }
- str = args.join(" ")
- tk_write 'if [catch {%s} var] {puts "!$var"} {puts "=$var@@"};flush stdout', str
- while PORT.gets
- $_.chop!
- if /^=(.*)@@$/
- val = $1
- break
- elsif /^=/
- val = $' + "\n"
- while TRUE
- PORT.gets
- fail 'wish closed' if not $_
- if ~/@@$/
- val += $'
- return val
- else
- val += $_
- end
- end
- elsif /^!/
- $@ = error_at
- msg = $'
- if msg =~ /unknown option "-(.*)"/
- fail format("undefined method `%s' for %s(%s)'", $1, self, self.type)
- else
- fail format("%s - %s", self.type, msg)
- end
- end
- $tk_event_queue.push $_
- end
-
- while ev = $tk_event_queue.shift
- Tk.dispatch ev
- end
- fail 'wish closed' if not $_
-# tk_split_list(val)
- val
- end
-
- def hash_kv(keys)
- conf = []
- if keys
- for k, v in keys
- conf.push("-#{k}")
- v = install_cmd(v) if v.type == Proc
- conf.push(v)
- end
- end
- conf
- end
- private :tk_call, :error_at, :hash_kv
-
- $tk_cmdid = "c00000"
- def install_cmd(cmd)
- return '' if cmd == '' # uninstall cmd
- id = $tk_cmdid
- $tk_cmdid = $tk_cmdid.next
- $tk_cmdtbl[id] = cmd
- @cmdtbl = [] if not @cmdtbl
- @cmdtbl.push id
- return format('rb_out %s', id)
- end
- def uninstall_cmd(id)
- $tk_cmdtbl[id] = nil
- end
- private :install_cmd, :uninstall_cmd
-
- $tk_window_list = {}
- class Event
- def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy)
- @serial = seq
- @num = b
- @focus = (f == 1)
- @height = h
- @keycode = k
- @state = s
- @time = t
- @width = w
- @x = x
- @y = y
- @char = aa
- @send_event = (ee == 1)
- @keysym = kk
- @keysym_num = nn
- @type = tt
- @widget = ww
- @x_root = xx
- @y_root = yy
- end
- attr :serial
- attr :num
- attr :focus
- attr :height
- attr :keycode
- attr :state
- attr :time
- attr :width
- attr :x
- attr :y
- attr :char
- attr :send_event
- attr :keysym
- attr :keysym_num
- attr :type
- attr :widget
- attr :x_root
- attr :y_root
- end
-
- def install_bind(cmd)
- id = install_cmd(proc{|args|
- TkUtil.eval_cmd cmd, Event.new(*args)
- })
- id + " %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y"
- end
-
- def _bind(path, context, cmd)
- begin
- id = install_bind(cmd)
- tk_call 'bind', path, "<#{context}>", id
- rescue
- $tk_cmdtbl[id] = nil
- fail
- end
- end
- private :install_bind, :_bind
-
- def bind_all(context, cmd=Proc.new)
- _bind 'all', context, cmd
- end
-
- $tk_cmdtbl = {}
-
- def after(ms, cmd=Proc.new)
- myid = $tk_cmdid
- tk_call 'after', ms,
- install_cmd(proc{
- TkUtil.eval_cmd cmd
- uninstall_cmd myid
- })
- end
-
- def update(idle=nil)
- if idle
- tk_call 'update', 'idletasks'
- else
- tk_call 'update'
- end
- end
-
- def dispatch(line)
- if line =~ /^c\d+/
- cmd = $&
- fail "no command `#{cmd}'" if not $tk_cmdtbl[cmd]
- args = tk_split_list($')
- TkUtil.eval_cmd $tk_cmdtbl[cmd], *args
- elsif line =~ /^alive$/
- # keep alive, do nothing
- else
- fail "malformed line <#{line}>"
- end
- end
-
- def mainloop
- begin
- tk_write 'after idle {wm deiconify .}'
- while TRUE
- rf, wf = select(READABLE, WRITABLE)
- for f in rf
- READ_CMD[f].call(f) if READ_CMD[f]
- if f.closed?
- READABLE.delete f
- READ_CMD[f] = nil
- end
- end
- for f in wf
- WRITE_CMD[f].call(f) if WRITE_CMD[f]
- if f.closed?
- WRITABLE.delete f
- WRITE_CMD[f] = nil
- end
- end
- end
- rescue
- exit if $! =~ /^Interrupt/
- fail
- ensure
- tk_exit
- end
- end
-
- def root
- $tk_root
- end
-
- module_function :after, :update, :dispatch, :mainloop, :root
-
- module Scrollable
- def xscrollcommand(cmd)
- configure_cmd 'xscrollcommand', cmd
- end
- def yscrollcommand(cmd)
- configure_cmd 'yscrollcommand', cmd
- end
- end
-
- module Wm
- def aspect(*args)
- w = window(tk_call('wm', 'grid', path, *args))
- w.split.collect{|s|s.to_i} if args.length == 0
- end
- def client(name=None)
- tk_call 'wm', 'client', path, name
- end
- def colormapwindows(*args)
- list(tk_call('wm', 'colormapwindows', path, *args))
- end
- def wm_command(value=None)
- string(tk_call('wm', 'command', path, value))
- end
- def deiconify
- tk_call 'wm', 'deiconify', path
- end
- def focusmodel(*args)
- tk_call 'wm', 'focusmodel', path, *args
- end
- def frame
- tk_call 'wm', 'frame', path
- end
- def geometry(*args)
- list(tk_call('wm', 'geometry', path, *args))
- end
- def grid(*args)
- w = tk_call('wm', 'grid', path, *args)
- list(w) if args.size == 0
- end
- def group(*args)
- tk_call 'wm', 'path', path, *args
- end
- def iconbitmap(*args)
- tk_call 'wm', 'bitmap', path, *args
- end
- def iconify
- tk_call 'wm', 'iconify'
- end
- def iconmask(*args)
- tk_call 'wm', 'iconmask', path, *args
- end
- def iconname(*args)
- tk_call 'wm', 'iconname', path, *args
- end
- def iconposition(*args)
- w = tk_call('wm', 'iconposition', path, *args)
- list(w) if args.size == 0
- end
- def iconwindow(*args)
- tk_call 'wm', 'iconwindow', path, *args
- end
- def maxsize(*args)
- w = tk_call('wm', 'maxsize', path, *args)
- list(w) if not args.size == 0
- end
- def minsize(*args)
- w = tk_call('wm', 'minsize', path, *args)
- list(w) if args.size == 0
- end
- def overrideredirect(bool=None)
- if bool == None
- bool(tk_call('wm', 'overrideredirect', path))
- else
- tk_call 'wm', 'overrideredirect', path, bool
- end
- end
- def positionfrom(*args)
- tk_call 'wm', 'positionfrom', path, *args
- end
- def protocol(name, func=None)
- func = install_cmd(func) if not func == None
- tk_call 'wm', 'command', path, name, func
- end
- def resizable(*args)
- w = tk_call('wm', 'resizable', path, *args)
- if args.length == 0
- list(w).collect{|e| bool(e)}
- end
- end
- def sizefrom(*args)
- list(tk_call('wm', 'sizefrom', path, *args))
- end
- def state
- tk_call 'wm', 'state', path
- end
- def title(*args)
- tk_call 'wm', 'title', path, *args
- end
- def transient(*args)
- tk_call 'wm', 'transient', path, *args
- end
- def withdraw
- tk_call 'wm', 'withdraw', path
- end
- end
+if defined? Thread and $tk_thread_safe
+ require "tkthcore"
+else
+ require "tkcore"
end
module TkSelection
@@ -550,11 +83,11 @@ module TkWinfo
def winfo_depth(window)
TkWinfo.depth self
end
- def TkWinfo.exists(window)
+ def TkWinfo.exist?(window)
bool(tk_call('winfo', 'exists', window.path))
end
- def winfo_exists(window)
- TkWinfo.exists self
+ def winfo_exist?(window)
+ TkWinfo.exist? self
end
def TkWinfo.fpixels(window, number)
number(tk_call('winfo', 'fpixels', window.path, number))
@@ -580,11 +113,11 @@ module TkWinfo
def winfo_id(window)
TkWinfo.id self
end
- def TkWinfo.ismapped(window)
+ def TkWinfo.mapped?(window)
bool(tk_call('winfo', 'ismapped', window.path))
end
- def winfo_ismapped(window)
- TkWinfo.ismapped self
+ def winfo_mapped?(window)
+ TkWinfo.mapped? self
end
def TkWinfo.parent(window)
window(tk_call('winfo', 'parent', window.path))
@@ -742,7 +275,7 @@ module TkPack
include Tk
extend Tk
def configure(win, *args)
- if args[-1].is_kind_of(Hash)
+ if args[-1].kind_of?(Hash)
keys = args.pop
end
wins = [win.epath]
@@ -780,7 +313,7 @@ module TkOption
module_function :add, :clear, :get, :readfile
end
-class TkObject:TkKernel
+class TkObject<TkKernel
include Tk
def path
@@ -822,16 +355,16 @@ class TkObject:TkKernel
configure slot, install_cmd(value)
end
- def bind(context, cmd=Proc.new)
- _bind path, context, cmd
+ def bind(context, cmd=Proc.new, args=nil)
+ _bind path, context, cmd, args
end
end
-class TkWindow:TkObject
+class TkWindow<TkObject
$tk_window_id = "w00000"
def initialize(parent=nil, keys=nil)
id = $tk_window_id
- $tk_window_id = $tk_window_id.next
+ $tk_window_id = $tk_window_id.succ
if !parent or parent == Tk.root
@path = format(".%s", id);
else
@@ -880,7 +413,7 @@ class TkWindow:TkObject
return val
end
else
- fail 'wrong # of args'
+ fail ArgumentError, 'wrong # of args'
end
end
@@ -913,7 +446,7 @@ class TkWindow:TkObject
end
end
-class TkRoot:TkWindow
+class TkRoot<TkWindow
include Wm
def TkRoot.new
return $tk_root if $tk_root
@@ -926,7 +459,7 @@ class TkRoot:TkWindow
$tk_window_list['.'] = $tk_root
end
-class TkToplevel:TkWindow
+class TkToplevel<TkWindow
include Wm
def initialize(parent=nil, screen=nil, classname=nil)
@screen = screen if screen
@@ -942,20 +475,21 @@ class TkToplevel:TkWindow
end
end
-class TkFrame:TkWindow
+class TkFrame<TkWindow
def create_self
tk_call 'frame', @path
end
end
-class TkLabel:TkWindow
+class TkLabel<TkWindow
def create_self
tk_call 'label', @path
end
def textvariable(v)
- vn = @path + v.id2name
+ v = v.id2name unless v.kind_of "String"
+ vn = @path + v
vset = format("global {%s}; set {%s}", vn, vn)
- tk_call vset, eval(v.id2name).inspect
+ tk_call vset, eval(v).inspect
trace_var v, proc{|val|
tk_call vset, val.inspect
}
@@ -963,7 +497,7 @@ class TkLabel:TkWindow
end
end
-class TkButton:TkLabel
+class TkButton<TkLabel
def create_self
tk_call 'button', @path
end
@@ -975,7 +509,7 @@ class TkButton:TkLabel
end
end
-class TkRadioButton:TkButton
+class TkRadioButton<TkButton
def create_self
tk_call 'radiobutton', @path
end
@@ -986,8 +520,13 @@ class TkRadioButton:TkButton
tk_send 'select'
end
def variable(v)
- vn = v.id2name; vn =~ /^./
- vn = 'btns_selected_' + $'
+ v = v.id2name unless v.kind_of "String"
+ if v =~ /^\$/
+ v = $'
+ else
+ fail ArgumentError, "variable must be global(%s)", v
+ end
+ vn = 'btns_selected_' + v
trace_var v, proc{|val|
tk_call 'set', vn, val
}
@@ -1004,7 +543,7 @@ class TkRadioButton:TkButton
end
end
-class TkCheckButton:TkRadioButton
+class TkCheckButton<TkRadioButton
def create_self
tk_call 'checkbutton', @path
end
@@ -1013,13 +552,13 @@ class TkCheckButton:TkRadioButton
end
end
-class TkMessage:TkLabel
+class TkMessage<TkLabel
def create_self
tk_call 'message', @path
end
end
-class TkScale:TkWindow
+class TkScale<TkWindow
def create_self
tk_call 'scale', path
end
@@ -1041,11 +580,23 @@ class TkScale:TkWindow
end
end
-class TkScrollbar:TkWindow
+class TkScrollbar<TkWindow
def create_self
tk_call 'scrollbar', path
end
+ def delta(deltax=None, deltay=None)
+ number(tk_send('delta', deltax, deltay))
+ end
+
+ def fraction(x=None, y=None)
+ number(tk_send('fraction', x, y))
+ end
+
+ def identify(x=None, y=None)
+ tk_send('fraction', x, y)
+ end
+
def get
ary1 = tk_send('get', path).split
ary2 = []
@@ -1061,7 +612,7 @@ class TkScrollbar:TkWindow
end
# abstract class for Text and Listbox
-class TkTextWin:TkWindow
+class TkTextWin<TkWindow
def bbox(index)
tk_send 'bbox', index
end
@@ -1091,7 +642,7 @@ class TkTextWin:TkWindow
end
end
-class TkListbox:TkTextWin
+class TkListbox<TkTextWin
def create_self
tk_call 'listbox', path
end
@@ -1119,7 +670,7 @@ class TkListbox:TkTextWin
end
end
-class TkMenu:TkWindow
+class TkMenu<TkWindow
def create_self
tk_call 'menu', path
end
@@ -1158,7 +709,7 @@ class TkMenu:TkWindow
end
end
-class TkMenubutton:TkLabel
+class TkMenubutton<TkLabel
def create_self
tk_call 'menubutton', path
end
@@ -1181,7 +732,7 @@ module TkComposite
def delegate(option, *wins)
@delegates = {} if not @delegates
@delegates['DEFAULT'] = @frame
- if option.is_kind_of? String
+ if option.kind_of? String
@delegates[option] = wins
else
for i in option
diff --git a/lib/tkcanvas.rb b/lib/tkcanvas.rb
index 33b28e3eff..b0ae8b1daa 100644
--- a/lib/tkcanvas.rb
+++ b/lib/tkcanvas.rb
@@ -5,12 +5,12 @@
require "tk"
-class TkCanvas:TkWindow
+class TkCanvas<TkWindow
def create_self
tk_call 'canvas', path
end
def tagid(tag)
- if tag.is_kind_of?(TkcItem)
+ if tag.kind_of?(TkcItem)
tag.id
else
tag
@@ -89,6 +89,9 @@ class TkCanvas:TkWindow
def move(tag, x, y)
tk_send 'move', tagid(tag), x, y
end
+ def itemtype(tag)
+ tk_send 'type', tagid(tag)
+ end
def postscript(keys=None)
tk_call "pack", *hash_kv(keys)
end
@@ -115,9 +118,9 @@ class TkCanvas:TkWindow
end
end
-class TkcItem:TkObject
+class TkcItem<TkObject
def initialize(parent, *args)
- if not parent.is_kind_of?(TkCanvas)
+ if not parent.kind_of?(TkCanvas)
fail format("%s need to be TkCanvas", parent.inspect)
end
@c = parent
@@ -137,7 +140,7 @@ class TkcItem:TkObject
end
def configure(slot, value)
- tk_call path, 'itemconfigure', id, "-#{slot}", value
+ tk_call path, 'itemconfigure', @id, "-#{slot}", value
end
def addtag(tag)
@@ -185,59 +188,59 @@ class TkcItem:TkObject
def scale(xorigin, yorigin, xscale, yscale)
@c.scale @id, xorigin, yorigin, xscale, yscale
end
- def type
- @c.type @id
+ def itemtype
+ @c.itemtype @id
end
def destroy
tk_call path, 'delete', @id
end
end
-class TkcArc:TkcItem
+class TkcArc<TkcItem
def create_self(*args)
tk_call(@path, 'create', 'arc', *args)
end
end
-class TkcBitmap:TkcItem
+class TkcBitmap<TkcItem
def create_self(*args)
tk_call(@path, 'create', 'bitmap', *args)
end
end
-class TkcImage:TkcItem
+class TkcImage<TkcItem
def create_self(*args)
tk_call(@path, 'create', 'image', *args)
end
end
-class TkcLine:TkcItem
+class TkcLine<TkcItem
def create_self(*args)
tk_call(@path, 'create', 'line', *args)
end
end
-class TkcOval:TkcItem
+class TkcOval<TkcItem
def create_self(*args)
tk_call(@path, 'create', 'oval', *args)
end
end
-class TkcPolygon:TkcItem
+class TkcPolygon<TkcItem
def create_self(*args)
tk_call(@path, 'create', 'polygon', *args)
end
end
-class TkcText:TkcItem
+class TkcText<TkcItem
def create_self(*args)
tk_call(@path, 'create', 'text', *args)
end
end
-class TkcWindow:TkcItem
+class TkcWindow<TkcItem
def create_self(*args)
tk_call(@path, 'create', 'window', *args)
end
end
-class TkcGroup:TkcItem
+class TkcGroup<TkcItem
$tk_group_id = 'tkg00000'
def create_self(*args)
@id = $tk_group_id
- $tk_group_id = $tk_group_id.next
+ $tk_group_id = $tk_group_id.succ
end
def add(*tags)
@@ -262,20 +265,20 @@ class TkcGroup:TkcItem
end
-class TkImage:TkObject
+class TkImage<TkObject
include Tk
$tk_image_id = 'i00000'
def initialize(keys=nil)
@path = $tk_image_id
- $tk_image_id = $tk_image_id.next
+ $tk_image_id = $tk_image_id.succ
tk_call 'image', @type, @path, *hash_kv(keys)
end
def height
number(tk_call('image', 'height', @path))
end
- def type
+ def itemtype
tk_call('image', 'type', @path)
end
def width
@@ -290,14 +293,14 @@ class TkImage:TkObject
end
end
-class TkBitmapImage:TkImage
+class TkBitmapImage<TkImage
def initialize(*args)
@type = 'bitmap'
super
end
end
-class TkPhotoImage:TkImage
+class TkPhotoImage<TkImage
def initialize(*args)
@type = 'bitmap'
super
diff --git a/lib/tkcore.rb b/lib/tkcore.rb
new file mode 100644
index 0000000000..df4af669ba
--- /dev/null
+++ b/lib/tkcore.rb
@@ -0,0 +1,521 @@
+#
+# tkcore.rb - Tk interface modue without thread
+# $Date: 1996/11/09 22:51:15 $
+# by Yukihiro Matsumoto <matz@caelum.co.jp>
+
+require "tkutil"
+if defined? Thread
+ require "thread"
+end
+
+module Tk
+ include TkUtil
+ extend Tk
+
+ wish_path = nil
+ ENV['PATH'].split(":").each {|path|
+ for wish in ['wish4.2', 'wish4.1', 'wish4.0', 'wish']
+ if File.exist? path+'/'+wish
+ wish_path = path+'/'+wish
+ break
+ end
+ break if wish_path
+ end
+ }
+ fail 'can\'t find wish' if not wish_path
+
+ def Tk.tk_exit
+ if not PORT.closed?
+ PORT.print "exit\n"
+ PORT.close
+ end
+ end
+
+ PORT = open(format("|%s -n %s", wish_path, File.basename($0)), "w+");
+ trap "EXIT", proc{Tk.tk_exit}
+ trap "PIPE", ""
+
+ def tk_write(*args)
+ printf PORT, *args;
+ PORT.print "\n"
+ PORT.flush
+ end
+ tk_write '\
+wm withdraw .
+proc rb_out args {
+ puts [format %%s $args]
+ flush stdout
+}
+proc rb_ans args {
+ if [catch "$args" var] {puts "!$var"} {puts "=$var@@"}
+ flush stdout
+}
+proc tkerror args { exit }
+proc keepalive {} { rb_out alive; after 120000 keepalive}
+after 120000 keepalive'
+
+ READABLE = []
+ READ_CMD = {}
+
+ def file_readable(port, cmd)
+ if cmd == nil
+ READABLE.delete port
+ else
+ READABLE.push port
+ end
+ READ_CMD[port] = cmd
+ end
+
+ WRITABLE = []
+ WRITE_CMD = {}
+ def file_writable(port, cmd)
+ if cmd == nil
+ WRITABLE.delete port
+ else
+ WRITABLE.push port
+ end
+ WRITE_CMD[port] = cmd
+ end
+ module_function :file_readable, :file_writable
+
+ file_readable PORT, proc {
+ line = PORT.gets
+ exit if not line
+ Tk.dispatch(line.chop!)
+ }
+
+ def error_at
+ n = 1
+ while c = caller(n)
+ break if c !~ /tk\.rb:/
+ n+=1
+ end
+ c
+ end
+
+ def tk_tcl2ruby(val)
+ case val
+ when /^-?\d+$/
+ val.to_i
+ when /^\./
+ $tk_window_list[val]
+ when /^rb_out (c\d+)/
+ $tk_cmdtbl[$1]
+ when / /
+ val.split.collect{|elt|
+ tk_tcl2ruby(elt)
+ }
+ when /^-?\d+\.\d*$/
+ val.to_f
+ else
+ val
+ end
+ end
+
+ def tk_split_list(str)
+ idx = str.index('{')
+ return tk_tcl2ruby(str) if not idx
+
+ list = tk_tcl2ruby(str[0,idx])
+ str = str[idx+1..-1]
+ i = -1
+ brace = 1
+ str.each_byte {|c|
+ i += 1
+ brace += 1 if c == ?{
+ brace -= 1 if c == ?}
+ break if brace == 0
+ }
+ if str[0, i] == ' '
+ list.push ' '
+ else
+ list.push tk_split_list(str[0, i])
+ end
+ list += tk_split_list(str[i+1..-1])
+ list
+ end
+ private :tk_tcl2ruby, :tk_split_list
+
+ def bool(val)
+ case bool
+ when "1", 1, 'yes', 'true'
+ TRUE
+ else
+ FALSE
+ end
+ end
+ def number(val)
+ case val
+ when /^-?\d+$/
+ val.to_i
+ when /^-?\d+\.\d*$/
+ val.to_f
+ else
+ val
+ end
+ end
+ def string(val)
+ if val == "{}"
+ ''
+ elsif val[0] == ?{
+ val[1..-2]
+ else
+ val
+ end
+ end
+ def list(val)
+ tk_split_list(val)
+ end
+ def window(val)
+ $tk_window_list[val]
+ end
+ def procedure(val)
+ if val =~ /^rb_out (c\d+)/
+ $tk_cmdtbl[$1]
+ else
+ nil
+ end
+ end
+ private :bool, :number, :string, :list, :window, :procedure
+
+ # mark for non-given arguments
+ None = Object.new
+ def None.to_s
+ 'None'
+ end
+
+ $tk_event_queue = []
+ def tk_call(*args)
+ args = args.collect{|s|
+ next if s == None
+ if s.kind_of?(Hash)
+ s = hash_kv(s).join(" ")
+ else
+ if not s
+ s = "0"
+ elsif s == TRUE
+ s = "1"
+ elsif s.kind_of?(TkObject)
+ s = s.path
+ else
+ s = s.to_s
+ s.gsub!(/[{}]/, '\\\\\0')
+ end
+ "{#{s}}"
+ end
+ }
+ str = args.join(" ")
+ print str, "\n" if $DEBUG
+ tk_write 'rb_ans %s', str
+ while PORT.gets
+ print $_ if $DEBUG
+ $_.chop!
+ if /^=(.*)@@$/
+ val = $1
+ break
+ elsif /^=/
+ val = $' + "\n"
+ while TRUE
+ PORT.readline
+ if ~/@@$/
+ val += $'
+ return val
+ else
+ val += $_
+ end
+ end
+ elsif /^!/
+ $@ = error_at
+ msg = $'
+ if msg =~ /unknown option "-(.*)"/
+ fail NameError, format("undefined method `%s' for %s(%s)", $1, self, self.type) #`'
+ else
+ fail format("%s - %s", self.type, msg)
+ end
+ end
+ $tk_event_queue.push $_
+ end
+
+ while ev = $tk_event_queue.shift
+ Tk.dispatch ev
+ end
+ fail 'wish closed' if PORT.closed?
+# tk_split_list(val)
+ val
+ end
+
+ def hash_kv(keys)
+ conf = []
+ if keys
+ for k, v in keys
+ conf.push("-#{k}")
+ v = install_cmd(v) if v.type == Proc
+ conf.push(v)
+ end
+ end
+ conf
+ end
+ private :tk_call, :error_at, :hash_kv
+
+ $tk_cmdid = 0
+ def install_cmd(cmd)
+ return '' if cmd == '' # uninstall cmd
+ id = format("c%.4d", $tk_cmdid)
+ $tk_cmdid += 1
+ $tk_cmdtbl[id] = cmd
+ @cmdtbl = [] if not @cmdtbl
+ @cmdtbl.push id
+ return format('rb_out %s', id)
+ end
+ def uninstall_cmd(id)
+ $tk_cmdtbl[id] = nil
+ end
+ private :install_cmd, :uninstall_cmd
+
+ $tk_window_list = {}
+ class Event
+ def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy)
+ @serial = seq
+ @num = b
+ @focus = (f == 1)
+ @height = h
+ @keycode = k
+ @state = s
+ @time = t
+ @width = w
+ @x = x
+ @y = y
+ @char = aa
+ @send_event = (ee == 1)
+ @keysym = kk
+ @keysym_num = nn
+ @type = tt
+ @widget = ww
+ @x_root = xx
+ @y_root = yy
+ end
+ attr :serial
+ attr :num
+ attr :focus
+ attr :height
+ attr :keycode
+ attr :state
+ attr :time
+ attr :width
+ attr :x
+ attr :y
+ attr :char
+ attr :send_event
+ attr :keysym
+ attr :keysym_num
+ attr :type
+ attr :widget
+ attr :x_root
+ attr :y_root
+ end
+
+ def install_bind(cmd, args=nil)
+ if args
+ id = install_cmd(proc{|arg|
+ TkUtil.eval_cmd cmd, *arg
+ })
+ id + " " + args
+ else
+ id = install_cmd(proc{|arg|
+ TkUtil.eval_cmd cmd, Event.new(*arg)
+ })
+ id + " %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y"
+ end
+ end
+
+ def _bind(path, context, cmd, args=nil)
+ begin
+ id = install_bind(cmd, args)
+ tk_call 'bind', path, "<#{context}>", id
+ rescue
+ $tk_cmdtbl[id] = nil
+ fail
+ end
+ end
+ private :install_bind, :_bind
+
+ def bind_all(context, cmd=Proc.new, args=nil)
+ _bind 'all', context, cmd, args
+ end
+
+ def pack(*args)
+ TkPack.configure *args
+ end
+
+ $tk_cmdtbl = {}
+
+ def after(ms, cmd=Proc.new)
+ myid = format("c%.4d", $tk_cmdid)
+ tk_call 'after', ms,
+ install_cmd(proc{
+ TkUtil.eval_cmd cmd
+ uninstall_cmd myid
+ })
+ end
+
+ def update(idle=nil)
+ if idle
+ tk_call 'update', 'idletasks'
+ else
+ tk_call 'update'
+ end
+ end
+
+ def dispatch(line)
+ if line =~ /^c\d+/
+ cmd = $&
+ fail "no command `#{cmd}'" if not $tk_cmdtbl[cmd]
+ args = tk_split_list($')
+ TkUtil.eval_cmd $tk_cmdtbl[cmd], *args
+ elsif line =~ /^alive$/
+ # keep alive, do nothing
+ else
+ fail "malformed line <#{line}>"
+ end
+ end
+
+ def mainloop
+ begin
+ tk_write 'after idle {wm deiconify .}'
+ while TRUE
+ rf, wf = select(READABLE, WRITABLE)
+ for f in rf
+ READ_CMD[f].call(f) if READ_CMD[f]
+ if f.closed?
+ READABLE.delete f
+ READ_CMD[f] = nil
+ end
+ end
+ for f in wf
+ WRITE_CMD[f].call(f) if WRITE_CMD[f]
+ if f.closed?
+ WRITABLE.delete f
+ WRITE_CMD[f] = nil
+ end
+ end
+ end
+ ensure
+ Tk.tk_exit
+ end
+ end
+
+ def root
+ $tk_root
+ end
+
+ def bell
+ tk_call 'bell'
+ end
+ module_function :after, :update, :dispatch, :mainloop, :root, :bell
+
+ module Scrollable
+ def xscrollcommand(cmd)
+ configure_cmd 'xscrollcommand', cmd
+ end
+ def yscrollcommand(cmd)
+ configure_cmd 'yscrollcommand', cmd
+ end
+ end
+
+ module Wm
+ def aspect(*args)
+ w = window(tk_call('wm', 'grid', path, *args))
+ w.split.collect{|s|s.to_i} if args.length == 0
+ end
+ def client(name=None)
+ tk_call 'wm', 'client', path, name
+ end
+ def colormapwindows(*args)
+ list(tk_call('wm', 'colormapwindows', path, *args))
+ end
+ def wm_command(value=None)
+ string(tk_call('wm', 'command', path, value))
+ end
+ def deiconify
+ tk_call 'wm', 'deiconify', path
+ end
+ def focusmodel(*args)
+ tk_call 'wm', 'focusmodel', path, *args
+ end
+ def frame
+ tk_call 'wm', 'frame', path
+ end
+ def geometry(*args)
+ list(tk_call('wm', 'geometry', path, *args))
+ end
+ def grid(*args)
+ w = tk_call('wm', 'grid', path, *args)
+ list(w) if args.size == 0
+ end
+ def group(*args)
+ tk_call 'wm', 'path', path, *args
+ end
+ def iconbitmap(*args)
+ tk_call 'wm', 'bitmap', path, *args
+ end
+ def iconify
+ tk_call 'wm', 'iconify'
+ end
+ def iconmask(*args)
+ tk_call 'wm', 'iconmask', path, *args
+ end
+ def iconname(*args)
+ tk_call 'wm', 'iconname', path, *args
+ end
+ def iconposition(*args)
+ w = tk_call('wm', 'iconposition', path, *args)
+ list(w) if args.size == 0
+ end
+ def iconwindow(*args)
+ tk_call 'wm', 'iconwindow', path, *args
+ end
+ def maxsize(*args)
+ w = tk_call('wm', 'maxsize', path, *args)
+ list(w) if not args.size == 0
+ end
+ def minsize(*args)
+ w = tk_call('wm', 'minsize', path, *args)
+ list(w) if args.size == 0
+ end
+ def overrideredirect(bool=None)
+ if bool == None
+ bool(tk_call('wm', 'overrideredirect', path))
+ else
+ tk_call 'wm', 'overrideredirect', path, bool
+ end
+ end
+ def positionfrom(*args)
+ tk_call 'wm', 'positionfrom', path, *args
+ end
+ def protocol(name, func=None)
+ func = install_cmd(func) if not func == None
+ tk_call 'wm', 'command', path, name, func
+ end
+ def resizable(*args)
+ w = tk_call('wm', 'resizable', path, *args)
+ if args.length == 0
+ list(w).collect{|e| bool(e)}
+ end
+ end
+ def sizefrom(*args)
+ list(tk_call('wm', 'sizefrom', path, *args))
+ end
+ def state
+ tk_call 'wm', 'state', path
+ end
+ def title(*args)
+ tk_call 'wm', 'title', path, *args
+ end
+ def transient(*args)
+ tk_call 'wm', 'transient', path, *args
+ end
+ def withdraw
+ tk_call 'wm', 'withdraw', path
+ end
+ end
+end
diff --git a/lib/tkentry.rb b/lib/tkentry.rb
index dbd848d0ca..9a03c34058 100644
--- a/lib/tkentry.rb
+++ b/lib/tkentry.rb
@@ -5,7 +5,7 @@
require 'tk.rb'
-class TkEntry:TkLabel
+class TkEntry<TkLabel
def create_self
tk_call 'entry', @path
end
diff --git a/lib/tkscrollbox.rb b/lib/tkscrollbox.rb
new file mode 100644
index 0000000000..b8dbe9b236
--- /dev/null
+++ b/lib/tkscrollbox.rb
@@ -0,0 +1,27 @@
+#
+# tkscrollbox.rb - Tk Listbox with Scrollbar
+# as an example of Composite Widget
+# $Date: 1995/12/12 18:21:01 $
+# by Yukihiro Matsumoto <matz@caelum.co.jp>
+
+require 'tk.rb'
+
+class TkScrollbox<TkListbox
+ include TkComposite
+ def initialize_composite
+ list = TkListbox.new(@frame)
+ scroll = TkScrollbar.new(@frame)
+ @path = list.path
+
+ list.configure 'yscroll', scroll.path+" set"
+ list.pack 'side'=>'left','fill'=>'both','expand'=>'yes'
+ scroll.configure 'command', list.path+" yview"
+ scroll.pack 'side'=>'right','fill'=>'y'
+
+ delegate('DEFALUT', list)
+ delegate('foreground', list, scroll)
+ delegate('background', list, scroll)
+ delegate('borderwidth', @frame)
+ delegate('relief', @frame)
+ end
+end
diff --git a/lib/tktext.rb b/lib/tktext.rb
index e7a2be950f..55e396c497 100644
--- a/lib/tktext.rb
+++ b/lib/tktext.rb
@@ -5,7 +5,7 @@
require 'tk.rb'
-class TkText:TkTextWin
+class TkText<TkTextWin
include Scrollable
def create_self
tk_call 'text', @path
@@ -77,16 +77,16 @@ class TkText:TkTextWin
end
end
-class TkTextTag:TkObject
+class TkTextTag<TkObject
$tk_text_tag = 'tag0000'
def initialize(parent)
- if not parent.is_kind_of?(TkText)
+ if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
@path = parent.path
@id = $tk_text_tag
- $tk_text_tag = $tk_text_tag.next
+ $tk_text_tag = $tk_text_tag.succ
@t._addtag id, self
end
def id
@@ -116,16 +116,16 @@ class TkTextTag:TkObject
end
end
-class TkTextMark:TkObject
+class TkTextMark<TkObject
$tk_text_mark = 'mark0000'
def initialize(parent, index)
- if not parent.is_kind_of?(TkText)
+ if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
@path = parent.path
@id = $tk_text_mark
- $tk_text_mark = $tk_text_mark.next
+ $tk_text_mark = $tk_text_mark.succ
tk_call @t, 'set', @id, index
@t._addtag id, self
end
@@ -143,9 +143,9 @@ class TkTextMark:TkObject
alias destroy unset
end
-class TkTextWindow:TkObject
+class TkTextWindow<TkObject
def initialize(parent, index, *args)
- if not parent.is_kind_of?(TkText)
+ if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
diff --git a/lib/tkthcore.rb b/lib/tkthcore.rb
new file mode 100644
index 0000000000..adbad775d0
--- /dev/null
+++ b/lib/tkthcore.rb
@@ -0,0 +1,546 @@
+#
+# tkthcore.rb - Tk interface modue using thread
+# $Date: 1996/11/09 22:49:15 $
+# by Yukihiro Matsumoto <matz@caelum.co.jp>
+
+require "tkutil"
+require "thread"
+
+module Tk
+ include TkUtil
+ extend Tk
+
+ def Tk.tk_exit
+ if not PORT.closed?
+ tk_write "exit"
+ PORT.close
+ end
+ end
+
+ trap "EXIT", proc{Tk.tk_exit}
+ trap "PIPE", ''
+
+ wish_path = nil
+ ENV['PATH'].split(":").each {|path|
+ for wish in ['wish4.2', 'wish4.1', 'wish4.0', 'wish']
+ if File.exist? path+'/'+wish
+ wish_path = path+'/'+wish
+ break
+ end
+ break if wish_path
+ end
+ }
+ fail 'can\'t find wish' if not wish_path
+
+ # mark for non-given arguments
+ None = Object.new
+ def None.to_s
+ 'None'
+ end
+
+ Qin = Queue.new
+ Qout = Queue.new
+ Qwish = Queue.new
+ Qcmd = Queue.new
+ PORT = open(format("|%s -n %s", wish_path, File.basename($0)), "w+");
+
+ $tk_not_init = TRUE
+
+ def Tk.init
+ $tk_not_init = FALSE
+ Thread.start do
+ loop do
+ while line = PORT.gets
+ line.chop!
+ if line =~ /^[=!]/
+ Qwish.push line
+ else
+ Qcmd.push line
+ end
+ end
+ exit
+ end
+ end
+
+ Thread.start do
+ ary = [PORT]
+ loop do
+ str = Qin.pop
+ print str, "\n" if $DEBUG
+ tk_write 'if [catch {%s} var] {puts "!$var"} {puts "=$var@@"};flush stdout', str
+ Qout.push(tk_recv)
+ end
+ end
+ end
+
+ $tk_event_queue = []
+ def tk_recv()
+ val = nil
+ $_ = Qwish.pop
+ loop do
+ if /^=(.*)@@$/
+ val = $1
+ break
+ elsif /^=/
+ val = $' + "\n"
+ while TRUE
+ PORT.readline
+ if ~/@@$/
+ val += $'
+ return val
+ else
+ v>al += $_
+ end
+ end
+ elsif /^!/
+ $@ = error_at
+ msg = $'
+ if msg =~ /unknown option "-(.*)"/
+ fail NameError, format("undefined method `%s' for %s(%s)", $1, self, self.type) #`'
+ else
+ fail format("%s - %s", self.type, msg)
+ end
+ end
+ Qcmd.push line
+ end
+
+ fail 'wish closed' if PORT.closed?
+# tk_split_list(val)
+ val
+ end
+
+ def tk_call(*args)
+ Tk.init if $tk_not_init
+ args = args.collect{|s|
+ next if s == None
+ if s.kind_of?(Hash)
+ s = hash_kv(s).join(" ")
+ else
+ if not s
+ s = "0"
+ elsif s == TRUE
+ s = "1"
+ elsif s.kind_of?(TkObject)
+ s = s.path
+ else
+ s = s.to_s
+ s.gsub!(/[{}]/, '\\\\\0')
+ end
+ "{#{s}}"
+ end
+ }
+ str = args.join(" ")
+ Qin.push str
+ return Qout.pop
+ end
+
+ def tk_write(*args)
+ PORT.printf *args; PORT.print "\n"
+ PORT.flush
+ end
+ module_function :tk_write, :tk_recv
+ tk_write '\
+wm withdraw .
+proc rb_out args {
+ puts [format %%s $args]
+ flush stdout
+}
+proc tkerror args { exit }
+proc keepalive {} { rb_out alive; after 120000 keepalive}
+after 120000 keepalive'
+
+ READ_TH = {}
+ def file_readable(port, cmd)
+ if cmd == nil
+ if READ_TH[port].has_key?
+ READ_TH[port].exit
+ READ_TH[port] = nil
+ end
+ else
+ READ_TH[port] = Thread.start{
+ loop do
+ TkUtil.eval_cmd cmd
+ end
+ }
+ end
+ end
+
+ WRITE_TH = {}
+ def file_writable(port, cmd)
+ if cmd == nil
+ if WRITE_TH[port].has_key?
+ WRITE_TH[port].exit
+ end
+ else
+ WRITE_TH[port] = Thread.start{
+ loop do
+ TkUtil.eval_cmd cmd
+ end
+ }
+ end
+ end
+ module_function :file_readable, :file_writable
+
+ def tk_tcl2ruby(val)
+ case val
+ when /^-?\d+$/
+ val.to_i
+ when /^\./
+ $tk_window_list[val]
+ when /^rb_out (c\d+)/
+ $tk_cmdtbl[$1]
+ when / /
+ val.split.collect{|elt|
+ tk_tcl2ruby(elt)
+ }
+ when /^-?\d+\.\d*$/
+ val.to_f
+ else
+ val
+ end
+ end
+
+ def tk_split_list(str)
+ idx = str.index('{')
+ return tk_tcl2ruby(str) if not idx
+
+ list = tk_tcl2ruby(str[0,idx])
+ str = str[idx+1..-1]
+ i = -1
+ brace = 1
+ str.each_byte {|c|
+ i += 1
+ brace += 1 if c == ?{
+ brace -= 1 if c == ?}
+ break if brace == 0
+ }
+ if str[0, i] == ' '
+ list.push ' '
+ else
+ list.push tk_split_list(str[0, i])
+ end
+ list += tk_split_list(str[i+1..-1])
+ list
+ end
+ private :tk_tcl2ruby, :tk_split_list
+
+ def dispatch(line)
+ if line =~ /^c\d+/
+ cmd = $&
+ fail "no command `#{cmd}'" if not $tk_cmdtbl[cmd]
+ args = tk_split_list($')
+ TkUtil.eval_cmd $tk_cmdtbl[cmd], *args
+ elsif line =~ /^alive$/
+ # keep alive, do nothing
+ else
+ fail "malformed line <#{line}>"
+ end
+ end
+ module_function :dispatch
+
+ def error_at
+ n = 1
+ while c = caller(n)
+ break if c !~ /tk\.rb:/
+ n+=1
+ end
+ c
+ end
+
+ def bool(val)
+ case bool
+ when "1", 1, 'yes', 'true'
+ TRUE
+ else
+ FALSE
+ end
+ end
+ def number(val)
+ case val
+ when /^-?\d+$/
+ val.to_i
+ when /^-?\d+\.\d*$/
+ val.to_f
+ else
+ val
+ end
+ end
+ def string(val)
+ if val == "{}"
+ ''
+ elsif val[0] == ?{
+ val[1..-2]
+ else
+ val
+ end
+ end
+ def list(val)
+ tk_split_list(val)
+ end
+ def window(val)
+ $tk_window_list[val]
+ end
+ def procedure(val)
+ if val =~ /^rb_out (c\d+)/
+ $tk_cmdtbl[$1]
+ else
+ nil
+ end
+ end
+ private :bool, :number, :string, :list, :window, :procedure
+
+ def hash_kv(keys)
+ conf = []
+ if keys
+ for k, v in keys
+ conf.push("-#{k}")
+ v = install_cmd(v) if v.type == Proc
+ conf.push(v)
+ end
+ end
+ conf
+ end
+ private :tk_call, :error_at, :hash_kv
+
+ $tk_cmdid = 0
+ def install_cmd(cmd)
+ return '' if cmd == '' # uninstall cmd
+ id = format("c%.4d", $tk_cmdid)
+ $tk_cmdid += 1
+ $tk_cmdtbl[id] = cmd
+ @cmdtbl = [] if not @cmdtbl
+ @cmdtbl.push id
+ return format('rb_out %s', id)
+ end
+ def uninstall_cmd(id)
+ $tk_cmdtbl[id] = nil
+ end
+ private :install_cmd, :uninstall_cmd
+
+ $tk_window_list = {}
+ class Event
+ def initialize(seq,b,f,h,k,s,t,w,x,y,aa,ee,kk,nn,ww,tt,xx,yy)
+ @serial = seq
+ @num = b
+ @focus = (f == 1)
+ @height = h
+ @keycode = k
+ @state = s
+ @time = t
+ @width = w
+ @x = x
+ @y = y
+ @char = aa
+ @send_event = (ee == 1)
+ @keysym = kk
+ @keysym_num = nn
+ @type = tt
+ @widget = ww
+ @x_root = xx
+ @y_root = yy
+ end
+ attr :serial
+ attr :num
+ attr :focus
+ attr :height
+ attr :keycode
+ attr :state
+ attr :time
+ attr :width
+ attr :x
+ attr :y
+ attr :char
+ attr :send_event
+ attr :keysym
+ attr :keysym_num
+ attr :type
+ attr :widget
+ attr :x_root
+ attr :y_root
+ end
+
+ def install_bind(cmd, args=nil)
+ if args
+ id = install_cmd(proc{|arg|
+ TkUtil.eval_cmd cmd, *arg
+ })
+ id + " " + args
+ else
+ id = install_cmd(proc{|arg|
+ TkUtil.eval_cmd cmd, Event.new(*arg)
+ })
+ id + " %# %b %f %h %k %s %t %w %x %y %A %E %K %N %W %T %X %Y"
+ end
+ end
+
+ def _bind(path, context, cmd, args=nil)
+ begin
+ id = install_bind(cmd, args)
+ tk_call 'bind', path, "<#{context}>", id
+ rescue
+ $tk_cmdtbl[id] = nil
+ fail
+ end
+ end
+ private :install_bind, :_bind
+
+ def bind_all(context, cmd=Proc.new, args=nil)
+ _bind 'all', context, cmd, args
+ end
+
+ def pack(*args)
+ TkPack.configure *args
+ end
+
+ $tk_cmdtbl = {}
+
+ Qafter = Queue.new
+ def after(ms, cmd=Proc.new)
+ unless $tk_after_thread
+ $tk_after_thread = Thread.start{
+ loop do
+ cmd = Qafter.pop
+ TkUtil.eval_cmd cmd
+ end
+ }
+ end
+ Thread.start do
+ sleep Float(ms)/1000
+ Qafter.push cmd
+ end
+ end
+
+ def update(idle=nil)
+ if idle
+ tk_call 'update', 'idletasks'
+ else
+ tk_call 'update'
+ end
+ end
+
+ def root
+ $tk_root
+ end
+
+ def bell
+ tk_call 'bell'
+ end
+
+ def mainloop
+ begin
+ tk_call 'after', 'idle', 'wm deiconify .'
+ loop do
+ dispatch Qcmd.pop
+ end
+ ensure
+ Tk.tk_exit
+ end
+ end
+ module_function :after, :update, :dispatch, :mainloop, :root, :bell
+
+ module Scrollable
+ def xscrollcommand(cmd)
+ configure_cmd 'xscrollcommand', cmd
+ end
+ def yscrollcommand(cmd)
+ configure_cmd 'yscrollcommand', cmd
+ end
+ end
+
+ module Wm
+ def aspect(*args)
+ w = window(tk_call('wm', 'grid', path, *args))
+ w.split.collect{|s|s.to_i} if args.length == 0
+ end
+ def client(name=None)
+ tk_call 'wm', 'client', path, name
+ end
+ def colormapwindows(*args)
+ list(tk_call('wm', 'colormapwindows', path, *args))
+ end
+ def wm_command(value=None)
+ string(tk_call('wm', 'command', path, value))
+ end
+ def deiconify
+ tk_call 'wm', 'deiconify', path
+ end
+ def focusmodel(*args)
+ tk_call 'wm', 'focusmodel', path, *args
+ end
+ def frame
+ tk_call 'wm', 'frame', path
+ end
+ def geometry(*args)
+ list(tk_call('wm', 'geometry', path, *args))
+ end
+ def grid(*args)
+ w = tk_call('wm', 'grid', path, *args)
+ list(w) if args.size == 0
+ end
+ def group(*args)
+ tk_call 'wm', 'path', path, *args
+ end
+ def iconbitmap(*args)
+ tk_call 'wm', 'bitmap', path, *args
+ end
+ def iconify
+ tk_call 'wm', 'iconify'
+ end
+ def iconmask(*args)
+ tk_call 'wm', 'iconmask', path, *args
+ end
+ def iconname(*args)
+ tk_call 'wm', 'iconname', path, *args
+ end
+ def iconposition(*args)
+ w = tk_call('wm', 'iconposition', path, *args)
+ list(w) if args.size == 0
+ end
+ def iconwindow(*args)
+ tk_call 'wm', 'iconwindow', path, *args
+ end
+ def maxsize(*args)
+ w = tk_call('wm', 'maxsize', path, *args)
+ list(w) if not args.size == 0
+ end
+ def minsize(*args)
+ w = tk_call('wm', 'minsize', path, *args)
+ list(w) if args.size == 0
+ end
+ def overrideredirect(bool=None)
+ if bool == None
+ bool(tk_call('wm', 'overrideredirect', path))
+ else
+ tk_call 'wm', 'overrideredirect', path, bool
+ end
+ end
+ def positionfrom(*args)
+ tk_call 'wm', 'positionfrom', path, *args
+ end
+ def protocol(name, func=None)
+ func = install_cmd(func) if not func == None
+ tk_call 'wm', 'command', path, name, func
+ end
+ def resizable(*args)
+ w = tk_call('wm', 'resizable', path, *args)
+ if args.length == 0
+ list(w).collect{|e| bool(e)}
+ end
+ end
+ def sizefrom(*args)
+ list(tk_call('wm', 'sizefrom', path, *args))
+ end
+ def state
+ tk_call 'wm', 'state', path
+ end
+ def title(*args)
+ tk_call 'wm', 'title', path, *args
+ end
+ def transient(*args)
+ tk_call 'wm', 'transient', path, *args
+ end
+ def withdraw
+ tk_call 'wm', 'withdraw', path
+ end
+ end
+end
diff --git a/main.c b/main.c
index 3630f8aa7b..5bc0ecf62f 100644
--- a/main.c
+++ b/main.c
@@ -8,6 +8,10 @@
************************************************/
+#ifdef DJGPP
+unsigned int _stklen = 0x100000;
+#endif
+
void
main(argc, argv, envp)
int argc;
diff --git a/math.c b/math.c
index 41a4232083..db4e4afc7e 100644
--- a/math.c
+++ b/math.c
@@ -6,7 +6,7 @@
$Date: 1994/11/01 08:28:03 $
created at: Tue Jan 25 14:12:56 JST 1994
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -15,12 +15,13 @@
VALUE mMath;
VALUE float_new();
+VALUE f_float();
#define Need_Float(x) \
if (FIXNUM_P(x)) {\
(x) = (struct RFloat*)float_new((double)FIX2INT(x));\
} else {\
- Check_Type(x, T_FLOAT);\
+ (x) = (struct RFloat*)f_float(x, x);\
}
#define Need_Float2(x,y) {\
@@ -34,7 +35,7 @@ math_atan2(obj, x, y)
struct RFloat *x, *y;
{
Need_Float2(x, y);
- return float_new(atan2(x->value, x->value));
+ return float_new(atan2(x->value, y->value));
}
static VALUE
@@ -101,7 +102,7 @@ math_sqrt(obj, x)
{
Need_Float(x);
- if (x->value < 0.0) Fail("square root for negative number");
+ if (x->value < 0.0) ArgError("square root for negative number");
return float_new(sqrt(x->value));
}
diff --git a/missing/flock.c b/missing/flock.c
new file mode 100644
index 0000000000..a4a9544b56
--- /dev/null
+++ b/missing/flock.c
@@ -0,0 +1,90 @@
+#include "config.h"
+
+#if defined(HAVE_LOCKF)
+
+#include <unistd.h>
+#include <errno.h>
+
+/* Emulate flock() with lockf() or fcntl(). This is just to increase
+ portability of scripts. The calls might not be completely
+ interchangeable. What's really needed is a good file
+ locking module.
+*/
+
+# ifndef F_ULOCK
+# define F_ULOCK 0 /* Unlock a previously locked region */
+# endif
+# ifndef F_LOCK
+# define F_LOCK 1 /* Lock a region for exclusive use */
+# endif
+# ifndef F_TLOCK
+# define F_TLOCK 2 /* Test and lock a region for exclusive use */
+# endif
+# ifndef F_TEST
+# define F_TEST 3 /* Test a region for other processes locks */
+# endif
+
+/* These are the flock() constants. Since this sytems doesn't have
+ flock(), the values of the constants are probably not available.
+*/
+# 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
+
+int
+flock(fd, operation)
+ int fd;
+ int operation;
+{
+ int i;
+ switch (operation) {
+
+ /* LOCK_SH - get a shared lock */
+ case LOCK_SH:
+ /* LOCK_EX - get an exclusive lock */
+ case LOCK_EX:
+ i = lockf (fd, F_LOCK, 0);
+ break;
+
+ /* LOCK_SH|LOCK_NB - get a non-blocking shared lock */
+ case LOCK_SH|LOCK_NB:
+ /* LOCK_EX|LOCK_NB - get a non-blocking exclusive lock */
+ case LOCK_EX|LOCK_NB:
+ i = lockf (fd, F_TLOCK, 0);
+ if (i == -1)
+ if ((errno == EAGAIN) || (errno == EACCES))
+ errno = EWOULDBLOCK;
+ break;
+
+ /* LOCK_UN - unlock */
+ case LOCK_UN:
+ i = lockf (fd, F_ULOCK, 0);
+ break;
+
+ /* Default - can't decipher operation */
+ default:
+ i = -1;
+ errno = EINVAL;
+ break;
+ }
+ return i;
+}
+#else
+int
+flock(fd, operation)
+ int fd;
+ int operation;
+{
+ rb_notimplement();
+ return -1;
+}
+#endif
diff --git a/missing/mkdir.c b/missing/mkdir.c
index 5225e586d9..b581a5e467 100644
--- a/missing/mkdir.c
+++ b/missing/mkdir.c
@@ -1,4 +1,4 @@
-/*
+*
* Written by Robert Rother, Mariah Corporation, August 1985.
*
* If you want it, it's yours. All I ask in return is that if you
@@ -96,7 +96,7 @@ rmdir (dpath)
if (WIFSIGNALED (status) || WEXITSTATUS (status) != 0)
{
errno = EIO; /* We don't know why, but */
- return -1; /* /bin/mkdir failed */
+ return -1; /* /bin/rmdir failed */
}
return 0;
diff --git a/missing/setenv.c b/missing/setenv.c
index 6211bcf02b..16ecbc6090 100644
--- a/missing/setenv.c
+++ b/missing/setenv.c
@@ -19,8 +19,8 @@ char *nam;
register int i, len = strlen(nam);
for (i = 0; environ[i]; i++) {
- if (memcmp(environ[i],nam,len) && environ[i][len] == '=')
- break; /* strnEQ must come first to avoid */
+ if (memcmp(environ[i],nam,len) == 0 && environ[i][len] == '=')
+ break; /* memcmp must come first to avoid */
} /* potential SEGV's */
return i;
}
diff --git a/missing/strftime.c b/missing/strftime.c
index 1e668ef2ae..478471c37d 100644
--- a/missing/strftime.c
+++ b/missing/strftime.c
@@ -10,9 +10,12 @@
* For extensions from SunOS, add SUNOS_EXT.
* For stuff needed to implement the P1003.2 date command, add POSIX2_DATE.
* For VMS dates, add VMS_EXT.
+ * For a an RFC822 time format, add MAILHEADER_EXT.
+ * For ISO week years, add ISO_DATE_EXT.
* For complete POSIX semantics, add POSIX_SEMANTICS.
*
- * The code for %c, %x, and %X is my best guess as to what's "appropriate".
+ * The code for %c, %x, and %X now follows the 1003.2 specification for
+ * the POSIX locale.
* This version ignores LOCALE information.
* It also doesn't worry about multi-byte characters.
* So there.
@@ -26,6 +29,9 @@
* Updated April, 1993
* Updated February, 1994
* Updated May, 1994
+ * Updated January, 1995
+ * Updated September, 1995
+ * Updated January, 1996
*
* Fixes from ado@elsie.nci.nih.gov
* February 1991, May 1992
@@ -33,36 +39,46 @@
* May, 1993
* Further fixes from ado@elsie.nci.nih.gov
* February 1994
+ * %z code from chip@chinacat.unicom.com
+ * Applied September 1995
+ * %V code fixed (again) and %G, %g added,
+ * January 1996
*/
-#include "config.h"
-
+#ifndef GAWK
#include <stdio.h>
#include <ctype.h>
-#if defined (HAVE_STRING_H)
-# include <string.h>
-#else /* !HAVE_STRING_H */
-# include <strings.h>
-#endif /* !HAVE_STRING_H */
+#include <string.h>
#include <time.h>
+#endif
+#if defined(TM_IN_SYS_TIME) || ! defined(GAWK)
#include <sys/types.h>
#include <sys/time.h>
+#endif
/* defaults: season to taste */
-#define SYSV_EXT 1 /* stuff in System V ascftime routine */
-#define SUNOS_EXT 1 /* stuff in SunOS strftime routine */
-#define POSIX2_DATE 1 /* stuff in Posix 1003.2 date command */
-#define VMS_EXT 1 /* include %v for VMS date format */
-#ifndef RUBY
-#define POSIX_SEMANTICS 1 /* call tzset() if TZ changes */
+#define SYSV_EXT 1 /* stuff in System V ascftime routine */
+#define SUNOS_EXT 1 /* stuff in SunOS strftime routine */
+#define POSIX2_DATE 1 /* stuff in Posix 1003.2 date command */
+#define VMS_EXT 1 /* include %v for VMS date format */
+#define MAILHEADER_EXT 1 /* add %z for HHMM format */
+#define ISO_DATE_EXT 1 /* %G and %g for year of ISO week */
+#ifndef GAWK
+#define POSIX_SEMANTICS 1 /* call tzset() if TZ changes */
+#endif
+
+#if defined(ISO_DATE_EXT)
+#if ! defined(POSIX2_DATE)
+#define POSIX2_DATE 1
+#endif
#endif
#if defined(POSIX2_DATE)
#if ! defined(SYSV_EXT)
-#define SYSV_EXT 1
+#define SYSV_EXT 1
#endif
#if ! defined(SUNOS_EXT)
-#define SUNOS_EXT 1
+#define SUNOS_EXT 1
#endif
#endif
@@ -103,11 +119,16 @@ adddecl(static int iso8601wknum(const struct tm *timeptr);)
#if !defined(OS2) && !defined(MSDOS) && defined(HAVE_TZNAME)
extern char *tzname[2];
-# ifdef HAVE_DAYLIGHT
extern int daylight;
-# endif
+#ifdef SOLARIS
+extern long timezone, altzone;
+#else
+extern int timezone, altzone;
+#endif
#endif
+#undef min /* just in case */
+
/* min --- return minimum of two numbers */
#ifndef __STDC__
@@ -119,9 +140,11 @@ static inline int
min(int a, int b)
#endif
{
- return (a < b ? a : b);
+ return (a < b ? a : b);
}
+#undef max /* also, just in case */
+
/* max --- return maximum of two numbers */
#ifndef __STDC__
@@ -133,7 +156,7 @@ static inline int
max(int a, int b)
#endif
{
- return (a > b ? a : b);
+ return (a > b ? a : b);
}
/* strftime --- produce formatted time */
@@ -150,360 +173,417 @@ size_t
strftime(char *s, size_t maxsize, const char *format, const struct tm *timeptr)
#endif
{
- char *endp = s + maxsize;
- char *start = s;
- auto char tbuf[100];
- int i;
- static short first = 1;
+ char *endp = s + maxsize;
+ char *start = s;
+ auto char tbuf[100];
+ long off;
+ int i, w, y;
+ static short first = 1;
#ifdef POSIX_SEMANTICS
- static char *savetz = NULL;
- static int savetzlen = 0;
- char *tz;
+ static char *savetz = NULL;
+ static int savetzlen = 0;
+ char *tz;
#endif /* POSIX_SEMANTICS */
#ifndef HAVE_TM_ZONE
- extern char *timezone();
- struct timeval tv;
- struct timezone zone;
+#ifndef HAVE_TM_NAME
+#ifndef HAVE_TZNAME
+ extern char *timezone();
+ struct timeval tv;
+ struct timezone zone;
+#endif /* HAVE_TZNAME */
+#endif /* HAVE_TM_NAME */
#endif /* HAVE_TM_ZONE */
- /* various tables, useful in North America */
- static const char *days_a[] = {
- "Sun", "Mon", "Tue", "Wed",
- "Thu", "Fri", "Sat",
- };
- static const char *days_l[] = {
- "Sunday", "Monday", "Tuesday", "Wednesday",
- "Thursday", "Friday", "Saturday",
- };
- static const char *months_a[] = {
- "Jan", "Feb", "Mar", "Apr", "May", "Jun",
- "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
- };
- static const char *months_l[] = {
- "January", "February", "March", "April",
- "May", "June", "July", "August", "September",
- "October", "November", "December",
- };
- static const char *ampm[] = { "AM", "PM", };
-
- if (s == NULL || format == NULL || timeptr == NULL || maxsize == 0)
- return 0;
-
- /* quick check if we even need to bother */
- if (strchr(format, '%') == NULL && strlen(format) + 1 >= maxsize)
- return 0;
+ /* various tables, useful in North America */
+ static const char *days_a[] = {
+ "Sun", "Mon", "Tue", "Wed",
+ "Thu", "Fri", "Sat",
+ };
+ static const char *days_l[] = {
+ "Sunday", "Monday", "Tuesday", "Wednesday",
+ "Thursday", "Friday", "Saturday",
+ };
+ static const char *months_a[] = {
+ "Jan", "Feb", "Mar", "Apr", "May", "Jun",
+ "Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
+ };
+ static const char *months_l[] = {
+ "January", "February", "March", "April",
+ "May", "June", "July", "August", "September",
+ "October", "November", "December",
+ };
+ static const char *ampm[] = { "AM", "PM", };
+
+ if (s == NULL || format == NULL || timeptr == NULL || maxsize == 0)
+ return 0;
+
+ /* quick check if we even need to bother */
+ if (strchr(format, '%') == NULL && strlen(format) + 1 >= maxsize)
+ return 0;
#ifndef POSIX_SEMANTICS
- if (first) {
- tzset();
- first = 0;
- }
+ if (first) {
+ tzset();
+ first = 0;
+ }
#else /* POSIX_SEMANTICS */
- tz = getenv("TZ");
- if (first) {
- if (tz != NULL) {
- int tzlen = strlen(tz);
-
- savetz = (char *) malloc(tzlen + 1);
- if (savetz != NULL) {
- savetzlen = tzlen + 1;
- strcpy(savetz, tz);
- }
+ tz = getenv("TZ");
+ if (first) {
+ if (tz != NULL) {
+ int tzlen = strlen(tz);
+
+ savetz = (char *) malloc(tzlen + 1);
+ if (savetz != NULL) {
+ savetzlen = tzlen + 1;
+ strcpy(savetz, tz);
+ }
+ }
+ tzset();
+ first = 0;
+ }
+ /* if we have a saved TZ, and it is different, recapture and reset */
+ if (tz && savetz && (tz[0] != savetz[0] || strcmp(tz, savetz) != 0)) {
+ i = strlen(tz) + 1;
+ if (i > savetzlen) {
+ savetz = (char *) realloc(savetz, i);
+ if (savetz) {
+ savetzlen = i;
+ strcpy(savetz, tz);
+ }
+ } else
+ strcpy(savetz, tz);
+ tzset();
}
- tzset();
- first = 0;
- }
- /* if we have a saved TZ, and it is different, recapture and reset */
- if (tz && savetz && (tz[0] != savetz[0] || strcmp(tz, savetz) != 0)) {
- i = strlen(tz) + 1;
- if (i > savetzlen) {
- savetz = (char *) realloc(savetz, i);
- if (savetz) {
- savetzlen = i;
- strcpy(savetz, tz);
- }
- } else
- strcpy(savetz, tz);
- tzset();
- }
#endif /* POSIX_SEMANTICS */
- for (; *format && s < endp - 1; format++) {
- tbuf[0] = '\0';
- if (*format != '%') {
- *s++ = *format;
- continue;
- }
- again:
- switch (*++format) {
- case '\0':
- *s++ = '%';
- goto out;
-
- case '%':
- *s++ = '%';
- continue;
-
- case 'a': /* abbreviated weekday name */
- if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
- strcpy(tbuf, "?");
- else
- strcpy(tbuf, days_a[timeptr->tm_wday]);
- break;
-
- case 'A': /* full weekday name */
- if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
- strcpy(tbuf, "?");
- else
- strcpy(tbuf, days_l[timeptr->tm_wday]);
- break;
+ for (; *format && s < endp - 1; format++) {
+ tbuf[0] = '\0';
+ if (*format != '%') {
+ *s++ = *format;
+ continue;
+ }
+ again:
+ switch (*++format) {
+ case '\0':
+ *s++ = '%';
+ goto out;
+
+ case '%':
+ *s++ = '%';
+ continue;
+
+ case 'a': /* abbreviated weekday name */
+ if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
+ strcpy(tbuf, "?");
+ else
+ strcpy(tbuf, days_a[timeptr->tm_wday]);
+ break;
+
+ case 'A': /* full weekday name */
+ if (timeptr->tm_wday < 0 || timeptr->tm_wday > 6)
+ strcpy(tbuf, "?");
+ else
+ strcpy(tbuf, days_l[timeptr->tm_wday]);
+ break;
#ifdef SYSV_EXT
- case 'h': /* abbreviated month name */
+ case 'h': /* abbreviated month name */
#endif
- case 'b': /* abbreviated month name */
- if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
- strcpy(tbuf, "?");
- else
- strcpy(tbuf, months_a[timeptr->tm_mon]);
- break;
-
- case 'B': /* full month name */
- if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
- strcpy(tbuf, "?");
- else
- strcpy(tbuf, months_l[timeptr->tm_mon]);
- break;
-
- case 'c': /* appropriate date and time representation */
- sprintf(tbuf, "%s %s %2d %02d:%02d:%02d %d",
- days_a[range(0, timeptr->tm_wday, 6)],
- months_a[range(0, timeptr->tm_mon, 11)],
- range(1, timeptr->tm_mday, 31),
- range(0, timeptr->tm_hour, 23),
- range(0, timeptr->tm_min, 59),
- range(0, timeptr->tm_sec, 61),
- timeptr->tm_year + 1900);
- break;
-
- case 'd': /* day of the month, 01 - 31 */
- i = range(1, timeptr->tm_mday, 31);
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'H': /* hour, 24-hour clock, 00 - 23 */
- i = range(0, timeptr->tm_hour, 23);
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'I': /* hour, 12-hour clock, 01 - 12 */
- i = range(0, timeptr->tm_hour, 23);
- if (i == 0)
- i = 12;
- else if (i > 12)
- i -= 12;
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'j': /* day of the year, 001 - 366 */
- sprintf(tbuf, "%03d", timeptr->tm_yday + 1);
- break;
-
- case 'm': /* month, 01 - 12 */
- i = range(0, timeptr->tm_mon, 11);
- sprintf(tbuf, "%02d", i + 1);
- break;
-
- case 'M': /* minute, 00 - 59 */
- i = range(0, timeptr->tm_min, 59);
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'p': /* am or pm based on 12-hour clock */
- i = range(0, timeptr->tm_hour, 23);
- if (i < 12)
- strcpy(tbuf, ampm[0]);
- else
- strcpy(tbuf, ampm[1]);
- break;
-
- case 'S': /* second, 00 - 61 */
- i = range(0, timeptr->tm_sec, 61);
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'U': /* week of year, Sunday is first day of week */
- sprintf(tbuf, "%02d", weeknumber(timeptr, 0));
- break;
-
- case 'w': /* weekday, Sunday == 0, 0 - 6 */
- i = range(0, timeptr->tm_wday, 6);
- sprintf(tbuf, "%d", i);
- break;
-
- case 'W': /* week of year, Monday is first day of week */
- sprintf(tbuf, "%02d", weeknumber(timeptr, 1));
- break;
-
- case 'x': /* appropriate date representation */
- sprintf(tbuf, "%s %s %2d %d",
- days_a[range(0, timeptr->tm_wday, 6)],
- months_a[range(0, timeptr->tm_mon, 11)],
- range(1, timeptr->tm_mday, 31),
- timeptr->tm_year + 1900);
- break;
-
- case 'X': /* appropriate time representation */
- sprintf(tbuf, "%02d:%02d:%02d",
- range(0, timeptr->tm_hour, 23),
- range(0, timeptr->tm_min, 59),
- range(0, timeptr->tm_sec, 61));
- break;
-
- case 'y': /* year without a century, 00 - 99 */
- i = timeptr->tm_year % 100;
- sprintf(tbuf, "%02d", i);
- break;
-
- case 'Y': /* year with century */
- sprintf(tbuf, "%d", 1900 + timeptr->tm_year);
- break;
-
- case 'Z': /* time zone name or abbrevation */
+ case 'b': /* abbreviated month name */
+ if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
+ strcpy(tbuf, "?");
+ else
+ strcpy(tbuf, months_a[timeptr->tm_mon]);
+ break;
+
+ case 'B': /* full month name */
+ if (timeptr->tm_mon < 0 || timeptr->tm_mon > 11)
+ strcpy(tbuf, "?");
+ else
+ strcpy(tbuf, months_l[timeptr->tm_mon]);
+ break;
+
+ case 'c': /* appropriate date and time representation */
+ strftime(tbuf, sizeof tbuf, "%a %b %e %H:%M:%S %Y", timeptr);
+ break;
+
+ case 'd': /* day of the month, 01 - 31 */
+ i = range(1, timeptr->tm_mday, 31);
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'H': /* hour, 24-hour clock, 00 - 23 */
+ i = range(0, timeptr->tm_hour, 23);
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'I': /* hour, 12-hour clock, 01 - 12 */
+ i = range(0, timeptr->tm_hour, 23);
+ if (i == 0)
+ i = 12;
+ else if (i > 12)
+ i -= 12;
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'j': /* day of the year, 001 - 366 */
+ sprintf(tbuf, "%03d", timeptr->tm_yday + 1);
+ break;
+
+ case 'm': /* month, 01 - 12 */
+ i = range(0, timeptr->tm_mon, 11);
+ sprintf(tbuf, "%02d", i + 1);
+ break;
+
+ case 'M': /* minute, 00 - 59 */
+ i = range(0, timeptr->tm_min, 59);
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'p': /* am or pm based on 12-hour clock */
+ i = range(0, timeptr->tm_hour, 23);
+ if (i < 12)
+ strcpy(tbuf, ampm[0]);
+ else
+ strcpy(tbuf, ampm[1]);
+ break;
+
+ case 'S': /* second, 00 - 61 */
+ i = range(0, timeptr->tm_sec, 61);
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'U': /* week of year, Sunday is first day of week */
+ sprintf(tbuf, "%02d", weeknumber(timeptr, 0));
+ break;
+
+ case 'w': /* weekday, Sunday == 0, 0 - 6 */
+ i = range(0, timeptr->tm_wday, 6);
+ sprintf(tbuf, "%d", i);
+ break;
+
+ case 'W': /* week of year, Monday is first day of week */
+ sprintf(tbuf, "%02d", weeknumber(timeptr, 1));
+ break;
+
+ case 'x': /* appropriate date representation */
+ strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);
+ break;
+
+ case 'X': /* appropriate time representation */
+ strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);
+ break;
+
+ case 'y': /* year without a century, 00 - 99 */
+ i = timeptr->tm_year % 100;
+ sprintf(tbuf, "%02d", i);
+ break;
+
+ case 'Y': /* year with century */
+ sprintf(tbuf, "%d", 1900 + timeptr->tm_year);
+ break;
+
+#ifdef MAILHEADER_EXT
+ /*
+ * From: Chip Rosenthal <chip@chinacat.unicom.com>
+ * Date: Sun, 19 Mar 1995 00:33:29 -0600 (CST)
+ *
+ * Warning: the %z [code] is implemented by inspecting the
+ * timezone name conditional compile settings, and
+ * inferring a method to get timezone offsets. I've tried
+ * this code on a couple of machines, but I don't doubt
+ * there is some system out there that won't like it.
+ * Maybe the easiest thing to do would be to bracket this
+ * with an #ifdef that can turn it off. The %z feature
+ * would be an admittedly obscure one that most folks can
+ * live without, but it would be a great help to those of
+ * us that muck around with various message processors.
+ */
+ case 'z': /* time zone offset east of GMT e.g. -0600 */
+#ifdef HAVE_TM_NAME
+ /*
+ * Systems with tm_name probably have tm_tzadj as
+ * secs west of GMT. Convert to mins east of GMT.
+ */
+ off = -timeptr->tm_tzadj / 60;
+#else /* !HAVE_TM_NAME */
+#ifdef HAVE_TM_ZONE
+ /*
+ * Systems with tm_zone probably have tm_gmtoff as
+ * secs east of GMT. Convert to mins east of GMT.
+ */
+ off = timeptr->tm_gmtoff / 60;
+#else /* !HAVE_TM_ZONE */
+#if HAVE_TZNAME
+ /*
+ * Systems with tzname[] probably have timezone as
+ * secs west of GMT. Convert to mins east of GMT.
+ */
+ off = -(daylight ? timezone : altzone) / 60;
+#else /* !HAVE_TZNAME */
+ off = -zone.tz_minuteswest;
+#endif /* !HAVE_TZNAME */
+#endif /* !HAVE_TM_ZONE */
+#endif /* !HAVE_TM_NAME */
+ if (off < 0) {
+ tbuf[0] = '-';
+ off = -off;
+ } else {
+ tbuf[0] = '+';
+ }
+ sprintf(tbuf+1, "%02d%02d", off/60, off%60);
+ break;
+#endif /* MAILHEADER_EXT */
+
+ case 'Z': /* time zone name or abbrevation */
#ifdef HAVE_TZNAME
-#ifdef HAVE_DAYLIGHT
- i = (daylight && timeptr->tm_isdst); /* 0 or 1 */
-#else
- i = timeptr->tm_isdst;
-#endif
- strcpy(tbuf, tzname[i]);
+ i = (daylight && timeptr->tm_isdst > 0); /* 0 or 1 */
+ strcpy(tbuf, tzname[i]);
#else
#ifdef HAVE_TM_ZONE
- strcpy(tbuf, timeptr->tm_zone);
+ strcpy(tbuf, timeptr->tm_zone);
#else
- gettimeofday(& tv, & zone);
- strcpy(tbuf, timezone(zone.tz_minuteswest,
- timeptr->tm_isdst));
-#endif
-#endif
- break;
+#ifdef HAVE_TM_NAME
+ strcpy(tbuf, timeptr->tm_name);
+#else
+ gettimeofday(& tv, & zone);
+ strcpy(tbuf, timezone(zone.tz_minuteswest,
+ timeptr->tm_isdst > 0));
+#endif /* HAVE_TM_NAME */
+#endif /* HAVE_TM_ZONE */
+#endif /* HAVE_TZNAME */
+ break;
#ifdef SYSV_EXT
- case 'n': /* same as \n */
- tbuf[0] = '\n';
- tbuf[1] = '\0';
- break;
-
- case 't': /* same as \t */
- tbuf[0] = '\t';
- tbuf[1] = '\0';
- break;
-
- case 'D': /* date as %m/%d/%y */
- strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);
- break;
-
- case 'e': /* day of month, blank padded */
- sprintf(tbuf, "%2d", range(1, timeptr->tm_mday, 31));
- break;
-
- case 'r': /* time as %I:%M:%S %p */
- strftime(tbuf, sizeof tbuf, "%I:%M:%S %p", timeptr);
- break;
-
- case 'R': /* time as %H:%M */
- strftime(tbuf, sizeof tbuf, "%H:%M", timeptr);
- break;
-
- case 'T': /* time as %H:%M:%S */
- strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);
- break;
+ case 'n': /* same as \n */
+ tbuf[0] = '\n';
+ tbuf[1] = '\0';
+ break;
+
+ case 't': /* same as \t */
+ tbuf[0] = '\t';
+ tbuf[1] = '\0';
+ break;
+
+ case 'D': /* date as %m/%d/%y */
+ strftime(tbuf, sizeof tbuf, "%m/%d/%y", timeptr);
+ break;
+
+ case 'e': /* day of month, blank padded */
+ sprintf(tbuf, "%2d", range(1, timeptr->tm_mday, 31));
+ break;
+
+ case 'r': /* time as %I:%M:%S %p */
+ strftime(tbuf, sizeof tbuf, "%I:%M:%S %p", timeptr);
+ break;
+
+ case 'R': /* time as %H:%M */
+ strftime(tbuf, sizeof tbuf, "%H:%M", timeptr);
+ break;
+
+ case 'T': /* time as %H:%M:%S */
+ strftime(tbuf, sizeof tbuf, "%H:%M:%S", timeptr);
+ break;
#endif
#ifdef SUNOS_EXT
- case 'k': /* hour, 24-hour clock, blank pad */
- sprintf(tbuf, "%2d", range(0, timeptr->tm_hour, 23));
- break;
-
- case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */
- i = range(0, timeptr->tm_hour, 23);
- if (i == 0)
- i = 12;
- else if (i > 12)
- i -= 12;
- sprintf(tbuf, "%2d", i);
- break;
+ case 'k': /* hour, 24-hour clock, blank pad */
+ sprintf(tbuf, "%2d", range(0, timeptr->tm_hour, 23));
+ break;
+
+ case 'l': /* hour, 12-hour clock, 1 - 12, blank pad */
+ i = range(0, timeptr->tm_hour, 23);
+ if (i == 0)
+ i = 12;
+ else if (i > 12)
+ i -= 12;
+ sprintf(tbuf, "%2d", i);
+ break;
#endif
#ifdef VMS_EXT
- case 'v': /* date as dd-bbb-YYYY */
- sprintf(tbuf, "%02d-%3.3s-%4d",
- range(1, timeptr->tm_mday, 31),
- months_a[range(0, timeptr->tm_mon, 11)],
- timeptr->tm_year + 1900);
- for (i = 3; i < 6; i++)
- if (islower(tbuf[i]))
- tbuf[i] = toupper(tbuf[i]);
- break;
+ case 'v': /* date as dd-bbb-YYYY */
+ sprintf(tbuf, "%02d-%3.3s-%4d",
+ range(1, timeptr->tm_mday, 31),
+ months_a[range(0, timeptr->tm_mon, 11)],
+ timeptr->tm_year + 1900);
+ for (i = 3; i < 6; i++)
+ if (islower(tbuf[i]))
+ tbuf[i] = toupper(tbuf[i]);
+ break;
#endif
#ifdef POSIX2_DATE
- case 'C':
- sprintf(tbuf, "%02d", (timeptr->tm_year + 1900) / 100);
- break;
-
-
- case 'E':
- case 'O':
- /* POSIX locale extensions, ignored for now */
- goto again;
-
- case 'V': /* week of year according ISO 8601 */
-#if defined(GAWK) && defined(VMS_EXT)
- {
- extern int do_lint;
- extern void warning();
- static int warned = 0;
-
- if (! warned && do_lint) {
- warned = 1;
- warning(
- "conversion %%V added in P1003.2; for VMS style date, use %%v");
- }
- }
-#endif
- sprintf(tbuf, "%02d", iso8601wknum(timeptr));
- break;
-
- case 'u':
- /* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
- sprintf(tbuf, "%d", timeptr->tm_wday == 0 ? 7 :
- timeptr->tm_wday);
- break;
+ case 'C':
+ sprintf(tbuf, "%02d", (timeptr->tm_year + 1900) / 100);
+ break;
+
+
+ case 'E':
+ case 'O':
+ /* POSIX locale extensions, ignored for now */
+ goto again;
+
+ case 'V': /* week of year according ISO 8601 */
+ sprintf(tbuf, "%02d", iso8601wknum(timeptr));
+ break;
+
+ case 'u':
+ /* ISO 8601: Weekday as a decimal number [1 (Monday) - 7] */
+ sprintf(tbuf, "%d", timeptr->tm_wday == 0 ? 7 :
+ timeptr->tm_wday);
+ break;
#endif /* POSIX2_DATE */
- default:
- tbuf[0] = '%';
- tbuf[1] = *format;
- tbuf[2] = '\0';
- break;
- }
- i = strlen(tbuf);
- if (i) {
- if (s + i < endp - 1) {
- strcpy(s, tbuf);
- s += i;
- } else
- return 0;
+
+#ifdef ISO_DATE_EXT
+ case 'G':
+ case 'g':
+ /*
+ * Year of ISO week.
+ *
+ * If it's December but the ISO week number is one,
+ * that week is in next year.
+ * If it's January but the ISO week number is 52 or
+ * 53, that week is in last year.
+ * Otherwise, it's this year.
+ */
+ w = iso8601wknum(timeptr);
+ if (timeptr->tm_mon == 11 && w == 1)
+ y = 1900 + timeptr->tm_year + 1;
+ else if (timeptr->tm_mon == 0 && w >= 52)
+ y = 1900 + timeptr->tm_year - 1;
+ else
+ y = 1900 + timeptr->tm_year;
+
+ if (*format == 'G')
+ sprintf(tbuf, "%d", y);
+ else
+ sprintf(tbuf, "%02d", y % 100);
+ break;
+#endif ISO_DATE_EXT
+ default:
+ tbuf[0] = '%';
+ tbuf[1] = *format;
+ tbuf[2] = '\0';
+ break;
+ }
+ i = strlen(tbuf);
+ if (i) {
+ if (s + i < endp - 1) {
+ strcpy(s, tbuf);
+ s += i;
+ } else
+ return 0;
+ }
}
- }
out:
- if (s < endp && *format == '\0') {
- *s = '\0';
- return (s - start);
- } else
- return 0;
+ if (s < endp && *format == '\0') {
+ *s = '\0';
+ return (s - start);
+ } else
+ return 0;
}
/* isleap --- is a year a leap year? */
@@ -517,7 +597,7 @@ static int
isleap(int year)
#endif
{
- return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
+ return ((year % 4 == 0 && year % 100 != 0) || year % 400 == 0);
}
@@ -533,85 +613,108 @@ static int
iso8601wknum(const struct tm *timeptr)
#endif
{
- /*
- * From 1003.2:
- * If the week (Monday to Sunday) containing January 1
- * has four or more days in the new year, then it is week 1;
- * otherwise it is the highest numbered week of the previous
- * (52 or 53) year, and the next week is week 1.
- *
- * ADR: This means if Jan 1 was Monday through Thursday,
- * it was week 1, otherwise week 52 or 53.
- *
- * XPG4 erroneously included POSIX.2 rationale text in the
- * main body of the standard. Thus it requires week 53.
- */
-
- int weeknum, jan1day, diff;
-
- /* get week number, Monday as first day of the week */
- weeknum = weeknumber(timeptr, 1);
-
- /*
- * With thanks and tip of the hatlo to tml@tik.vtt.fi
- *
- * What day of the week does January 1 fall on?
- * We know that
- * (timeptr->tm_yday - jan1.tm_yday) MOD 7 ==
- * (timeptr->tm_wday - jan1.tm_wday) MOD 7
- * and that
- * jan1.tm_yday == 0
- * and that
- * timeptr->tm_wday MOD 7 == timeptr->tm_wday
- * from which it follows that. . .
- */
- jan1day = timeptr->tm_wday - (timeptr->tm_yday % 7);
- if (jan1day < 0)
- jan1day += 7;
-
- /*
- * If Jan 1 was a Monday through Thursday, it was in
- * week 1. Otherwise it was last year's highest week, which is
- * this year's week 0.
- *
- * What does that mean?
- * If Jan 1 was Monday, the week number is exactly right, it can
- * never be 0.
- * If it was Tuesday through Thursday, the weeknumber is one
- * less than it should be, so we add one.
- * Otherwise, Friday, Saturday or Sunday, the week number is
- * OK, but if it is 0, it needs to be 52 or 53.
- */
- switch (jan1day) {
- case 1: /* Monday */
- break;
- case 2: /* Tuesday */
- case 3: /* Wednedsday */
- case 4: /* Thursday */
- weeknum++;
- break;
- case 5: /* Friday */
- case 6: /* Saturday */
- case 0: /* Sunday */
- if (weeknum == 0) {
+ /*
+ * From 1003.2:
+ * If the week (Monday to Sunday) containing January 1
+ * has four or more days in the new year, then it is week 1;
+ * otherwise it is the highest numbered week of the previous
+ * year (52 or 53), and the next week is week 1.
+ *
+ * ADR: This means if Jan 1 was Monday through Thursday,
+ * it was week 1, otherwise week 52 or 53.
+ *
+ * XPG4 erroneously included POSIX.2 rationale text in the
+ * main body of the standard. Thus it requires week 53.
+ */
+
+ int weeknum, jan1day, diff;
+
+ /* get week number, Monday as first day of the week */
+ weeknum = weeknumber(timeptr, 1);
+
+ /*
+ * With thanks and tip of the hatlo to tml@tik.vtt.fi
+ *
+ * What day of the week does January 1 fall on?
+ * We know that
+ * (timeptr->tm_yday - jan1.tm_yday) MOD 7 ==
+ * (timeptr->tm_wday - jan1.tm_wday) MOD 7
+ * and that
+ * jan1.tm_yday == 0
+ * and that
+ * timeptr->tm_wday MOD 7 == timeptr->tm_wday
+ * from which it follows that. . .
+ */
+ jan1day = timeptr->tm_wday - (timeptr->tm_yday % 7);
+ if (jan1day < 0)
+ jan1day += 7;
+
+ /*
+ * If Jan 1 was a Monday through Thursday, it was in
+ * week 1. Otherwise it was last year's highest week, which is
+ * this year's week 0.
+ *
+ * What does that mean?
+ * If Jan 1 was Monday, the week number is exactly right, it can
+ * never be 0.
+ * If it was Tuesday through Thursday, the weeknumber is one
+ * less than it should be, so we add one.
+ * Otherwise, Friday, Saturday or Sunday, the week number is
+ * OK, but if it is 0, it needs to be 52 or 53.
+ */
+ switch (jan1day) {
+ case 1: /* Monday */
+ break;
+ case 2: /* Tuesday */
+ case 3: /* Wednesday */
+ case 4: /* Thursday */
+ weeknum++;
+ break;
+ case 5: /* Friday */
+ case 6: /* Saturday */
+ case 0: /* Sunday */
+ if (weeknum == 0) {
#ifdef USE_BROKEN_XPG4
- /* XPG4 (as of March 1994) says 53 unconditionally */
- weeknum = 53;
+ /* XPG4 (as of March 1994) says 53 unconditionally */
+ weeknum = 53;
#else
- /* get week number of last week of last year */
- struct tm dec31ly; /* 12/31 last year */
- dec31ly = *timeptr;
- dec31ly.tm_year--;
- dec31ly.tm_mon = 11;
- dec31ly.tm_mday = 31;
- dec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1;
- dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900);
- weeknum = iso8601wknum(& dec31ly);
+ /* get week number of last week of last year */
+ struct tm dec31ly; /* 12/31 last year */
+ dec31ly = *timeptr;
+ dec31ly.tm_year--;
+ dec31ly.tm_mon = 11;
+ dec31ly.tm_mday = 31;
+ dec31ly.tm_wday = (jan1day == 0) ? 6 : jan1day - 1;
+ dec31ly.tm_yday = 364 + isleap(dec31ly.tm_year + 1900);
+ weeknum = iso8601wknum(& dec31ly);
#endif
+ }
+ break;
}
- break;
- }
- return weeknum;
+
+ if (timeptr->tm_mon == 11) {
+ /*
+ * The last week of the year
+ * can be in week 1 of next year.
+ * Sigh.
+ *
+ * This can only happen if
+ * M T W
+ * 29 30 31
+ * 30 31
+ * 31
+ */
+ int wday, mday;
+
+ wday = timeptr->tm_wday;
+ mday = timeptr->tm_mday;
+ if ( (wday == 1 && (mday >= 29 && mday <= 31))
+ || (wday == 2 && (mday == 30 || mday == 31))
+ || (wday == 3 && mday == 31))
+ weeknum = 1;
+ }
+
+ return weeknum;
}
#endif
@@ -629,25 +732,25 @@ static int
weeknumber(const struct tm *timeptr, int firstweekday)
#endif
{
- int wday = timeptr->tm_wday;
- int ret;
-
- if (firstweekday == 1) {
- if (wday == 0) /* sunday */
- wday = 6;
- else
- wday--;
- }
- ret = ((timeptr->tm_yday + 7 - wday) / 7);
- if (ret < 0)
- ret = 0;
- return ret;
+ int wday = timeptr->tm_wday;
+ int ret;
+
+ if (firstweekday == 1) {
+ if (wday == 0) /* sunday */
+ wday = 6;
+ else
+ wday--;
+ }
+ ret = ((timeptr->tm_yday + 7 - wday) / 7);
+ if (ret < 0)
+ ret = 0;
+ return ret;
}
#if 0
/* ADR --- I'm loathe to mess with ado's code ... */
-Date: Wed, 24 Apr 91 20:54:08 MDT
+Date: Wed, 24 Apr 91 20:54:08 MDT
From: Michal Jaegermann <audfax!emory!vm.ucs.UAlberta.CA!NTOMCZAK>
To: arnold@audiofax.com
@@ -661,7 +764,7 @@ in the following form:
*/
{
return (timeptr->tm_yday - timeptr->tm_wday +
- (firstweekday ? (timeptr->tm_wday ? 8 : 1) : 7)) / 7;
+ (firstweekday ? (timeptr->tm_wday ? 8 : 1) : 7)) / 7;
}
How nicer it depends on a compiler, of course, but always a tiny bit.
@@ -674,38 +777,38 @@ How nicer it depends on a compiler, of course, but always a tiny bit.
/*
* NAME:
- * tst
+ * tst
*
* SYNOPSIS:
- * tst
+ * tst
*
* DESCRIPTION:
- * "tst" is a test driver for the function "strftime".
+ * "tst" is a test driver for the function "strftime".
*
* OPTIONS:
- * None.
+ * None.
*
* AUTHOR:
- * Karl Vogel
- * Control Data Systems, Inc.
- * vogelke@c-17igp.wpafb.af.mil
+ * Karl Vogel
+ * Control Data Systems, Inc.
+ * vogelke@c-17igp.wpafb.af.mil
*
* BUGS:
- * None noticed yet.
+ * None noticed yet.
*
* COMPILE:
- * cc -o tst -DTEST_STRFTIME strftime.c
+ * cc -o tst -DTEST_STRFTIME strftime.c
*/
/* ADR: I reformatted this to my liking, and deleted some unneeded code. */
#ifndef NULL
-#include <stdio.h>
+#include <stdio.h>
#endif
-#include <sys/time.h>
-#include <string.h>
+#include <sys/time.h>
+#include <string.h>
-#define MAXTIME 132
+#define MAXTIME 132
/*
* Array of time formats.
@@ -713,42 +816,43 @@ How nicer it depends on a compiler, of course, but always a tiny bit.
static char *array[] =
{
- "(%%A) full weekday name, var length (Sunday..Saturday) %A",
- "(%%B) full month name, var length (January..December) %B",
- "(%%C) Century %C",
- "(%%D) date (%%m/%%d/%%y) %D",
- "(%%E) Locale extensions (ignored) %E",
- "(%%H) hour (24-hour clock, 00..23) %H",
- "(%%I) hour (12-hour clock, 01..12) %I",
- "(%%M) minute (00..59) %M",
- "(%%O) Locale extensions (ignored) %O",
- "(%%R) time, 24-hour (%%H:%%M) %R",
- "(%%S) second (00..61) %S",
- "(%%T) time, 24-hour (%%H:%%M:%%S) %T",
- "(%%U) week of year, Sunday as first day of week (00..53) %U",
- "(%%V) week of year according to ISO 8601 %V",
- "(%%W) week of year, Monday as first day of week (00..53) %W",
- "(%%X) appropriate locale time representation (%H:%M:%S) %X",
- "(%%Y) year with century (1970...) %Y",
- "(%%Z) timezone (EDT), or blank if timezone not determinable %Z",
- "(%%a) locale's abbreviated weekday name (Sun..Sat) %a",
- "(%%b) locale's abbreviated month name (Jan..Dec) %b",
- "(%%c) full date (Sat Nov 4 12:02:33 1989)%n%t%t%t %c",
- "(%%d) day of the month (01..31) %d",
- "(%%e) day of the month, blank-padded ( 1..31) %e",
- "(%%h) should be same as (%%b) %h",
- "(%%j) day of the year (001..366) %j",
- "(%%k) hour, 24-hour clock, blank pad ( 0..23) %k",
- "(%%l) hour, 12-hour clock, blank pad ( 0..12) %l",
- "(%%m) month (01..12) %m",
- "(%%p) locale's AM or PM based on 12-hour clock %p",
- "(%%r) time, 12-hour (same as %%I:%%M:%%S %%p) %r",
- "(%%u) ISO 8601: Weekday as decimal number [1 (Monday) - 7] %u",
- "(%%v) VAX date (dd-bbb-YYYY) %v",
- "(%%w) day of week (0..6, Sunday == 0) %w",
- "(%%x) appropriate locale date representation %x",
- "(%%y) last two digits of year (00..99) %y",
- (char *) NULL
+ "(%%A) full weekday name, var length (Sunday..Saturday) %A",
+ "(%%B) full month name, var length (January..December) %B",
+ "(%%C) Century %C",
+ "(%%D) date (%%m/%%d/%%y) %D",
+ "(%%E) Locale extensions (ignored) %E",
+ "(%%H) hour (24-hour clock, 00..23) %H",
+ "(%%I) hour (12-hour clock, 01..12) %I",
+ "(%%M) minute (00..59) %M",
+ "(%%O) Locale extensions (ignored) %O",
+ "(%%R) time, 24-hour (%%H:%%M) %R",
+ "(%%S) second (00..61) %S",
+ "(%%T) time, 24-hour (%%H:%%M:%%S) %T",
+ "(%%U) week of year, Sunday as first day of week (00..53) %U",
+ "(%%V) week of year according to ISO 8601 %V",
+ "(%%W) week of year, Monday as first day of week (00..53) %W",
+ "(%%X) appropriate locale time representation (%H:%M:%S) %X",
+ "(%%Y) year with century (1970...) %Y",
+ "(%%Z) timezone (EDT), or blank if timezone not determinable %Z",
+ "(%%a) locale's abbreviated weekday name (Sun..Sat) %a",
+ "(%%b) locale's abbreviated month name (Jan..Dec) %b",
+ "(%%c) full date (Sat Nov 4 12:02:33 1989)%n%t%t%t %c",
+ "(%%d) day of the month (01..31) %d",
+ "(%%e) day of the month, blank-padded ( 1..31) %e",
+ "(%%h) should be same as (%%b) %h",
+ "(%%j) day of the year (001..366) %j",
+ "(%%k) hour, 24-hour clock, blank pad ( 0..23) %k",
+ "(%%l) hour, 12-hour clock, blank pad ( 0..12) %l",
+ "(%%m) month (01..12) %m",
+ "(%%p) locale's AM or PM based on 12-hour clock %p",
+ "(%%r) time, 12-hour (same as %%I:%%M:%%S %%p) %r",
+ "(%%u) ISO 8601: Weekday as decimal number [1 (Monday) - 7] %u",
+ "(%%v) VMS date (dd-bbb-YYYY) %v",
+ "(%%w) day of week (0..6, Sunday == 0) %w",
+ "(%%x) appropriate locale date representation %x",
+ "(%%y) last two digits of year (00..99) %y",
+ "(%%z) timezone offset east of GMT as HHMM (e.g. -0500) %z",
+ (char *) NULL
};
/* main routine. */
@@ -758,28 +862,28 @@ main(argc, argv)
int argc;
char **argv;
{
- long time();
+ long time();
- char *next;
- char string[MAXTIME];
+ char *next;
+ char string[MAXTIME];
- int k;
- int length;
+ int k;
+ int length;
- struct tm *tm;
+ struct tm *tm;
- long clock;
+ long clock;
- /* Call the function. */
+ /* Call the function. */
- clock = time((long *) 0);
- tm = localtime(&clock);
+ clock = time((long *) 0);
+ tm = localtime(&clock);
- for (k = 0; next = array[k]; k++) {
- length = strftime(string, MAXTIME, next, tm);
- printf("%s\n", string);
- }
+ for (k = 0; next = array[k]; k++) {
+ length = strftime(string, MAXTIME, next, tm);
+ printf("%s\n", string);
+ }
- exit(0);
+ exit(0);
}
#endif /* TEST_STRFTIME */
diff --git a/node.h b/node.h
index f69258ab4c..eb91c01196 100644
--- a/node.h
+++ b/node.h
@@ -6,14 +6,14 @@
$Date: 1995/01/10 10:42:41 $
created at: Fri May 28 15:14:02 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
#ifndef NODE_H
#define NODE_H
-struct global_entry* rb_global_entry();
+struct global_entry *rb_global_entry();
enum node_type {
NODE_METHOD,
@@ -22,13 +22,18 @@ enum node_type {
NODE_SCOPE,
NODE_BLOCK,
NODE_IF,
+ NODE_UNLESS,
NODE_CASE,
NODE_WHEN,
+ NODE_OPT_N,
NODE_WHILE,
- NODE_WHILE2,
+ NODE_UNTIL,
NODE_ITER,
NODE_FOR,
NODE_BEGIN,
+ NODE_RESCUE,
+ NODE_RESBODY,
+ NODE_ENSURE,
NODE_AND,
NODE_OR,
NODE_NOT,
@@ -47,12 +52,7 @@ enum node_type {
NODE_ARRAY,
NODE_ZARRAY,
NODE_HASH,
- NODE_REDO,
- NODE_BREAK,
- NODE_CONTINUE,
NODE_RETURN,
- NODE_RETRY,
- NODE_FAIL,
NODE_YIELD,
NODE_LVAR,
NODE_DVAR,
@@ -62,12 +62,17 @@ enum node_type {
NODE_CONST,
NODE_NTH_REF,
NODE_BACK_REF,
+ NODE_MATCH_REF,
+ NODE_LASTLINE,
+ NODE_MATCH,
NODE_LIT,
NODE_STR,
- NODE_STR2,
+ NODE_DSTR,
NODE_XSTR,
- NODE_XSTR2,
+ NODE_DXSTR,
+ NODE_EVSTR,
NODE_DREGX,
+ NODE_DREGX_ONCE,
NODE_ARGS,
NODE_DEFN,
NODE_DEFS,
@@ -76,6 +81,7 @@ enum node_type {
NODE_CLASS,
NODE_MODULE,
NODE_COLON2,
+ NODE_CNAME,
NODE_CREF,
NODE_DOT2,
NODE_DOT3,
@@ -85,12 +91,12 @@ enum node_type {
NODE_SELF,
NODE_NIL,
NODE_DEFINED,
+ NODE_TAG,
};
typedef struct RNode {
UINT flags;
char *file;
- unsigned int line;
union {
struct RNode *node;
ID id;
@@ -102,6 +108,7 @@ typedef struct RNode {
struct RNode *node;
ID id;
int argc;
+ VALUE value;
} u2;
union {
struct RNode *node;
@@ -115,9 +122,13 @@ typedef struct RNode {
#define RNODE(obj) (R_CAST(RNode)(obj))
-#define nd_type(n) (((RNODE(n))->flags>>10)&0xff)
+#define nd_type(n) (((RNODE(n))->flags>>10)&0x7f)
#define nd_set_type(n,t) \
- RNODE(n)->flags=((RNODE(n)->flags&~FL_UMASK)|(((t)<<10)&FL_UMASK))
+ RNODE(n)->flags=(RNODE(n)->flags&~FL_UMASK|(((t)<<10)&FL_UMASK))
+
+#define nd_line(n) (((RNODE(n))->flags>>17)&0x7fff)
+#define nd_set_line(n,l) \
+ RNODE(n)->flags=(RNODE(n)->flags&~(-1<<17)|(((l)&0x7fff)<<17))
#define nd_head u1.node
#define nd_alen u2.argc
@@ -126,7 +137,6 @@ typedef struct RNode {
#define nd_cond u1.node
#define nd_body u2.node
#define nd_else u3.node
-#define nd_break u3.state
#define nd_orig u3.value
@@ -181,40 +191,42 @@ typedef struct RNode {
#define nd_beg u1.node
#define nd_end u2.node
#define nd_state u3.state
-#define nd_rval u3.node
+#define nd_rval u3.value
#define nd_nth u2.argc
+#define nd_tag u1.id
+#define nd_tlev u3.cnt
+#define nd_tval u2.value
+
#define NEW_METHOD(n,x) newnode(NODE_METHOD,x,n,0)
#define NEW_FBODY(n,i,o) newnode(NODE_FBODY,n,i,o)
#define NEW_DEFN(i,a,d,p) newnode(NODE_DEFN,p,i,NEW_RFUNC(a,d))
#define NEW_DEFS(r,i,a,d) newnode(NODE_DEFS,r,i,NEW_RFUNC(a,d))
#define NEW_CFUNC(f,c) newnode(NODE_CFUNC,f,c,0)
#define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2))
-#define NEW_SCOPE(b) newnode(NODE_SCOPE,local_tbl(),(b),local_cnt(0))
+#define NEW_SCOPE(b) newnode(NODE_SCOPE,local_tbl(),(b),cur_cref)
#define NEW_BLOCK(a) newnode(NODE_BLOCK,a,1,0)
#define NEW_IF(c,t,e) newnode(NODE_IF,c,t,e)
+#define NEW_UNLESS(c,t,e) newnode(NODE_UNLESS,c,t,e)
#define NEW_EXNOT(c) newnode(NODE_EXNOT,c,0,0)
#define NEW_CASE(h,b) newnode(NODE_CASE,h,b,0)
#define NEW_WHEN(c,t,e) newnode(NODE_WHEN,c,t,e)
-#define NEW_WHILE(c,b) newnode(NODE_WHILE,c,b,0)
-#define NEW_WHILE2(c,b) newnode(NODE_WHILE2,c,b,0)
+#define NEW_OPT_N(b) newnode(NODE_OPT_N,0,b,0)
+#define NEW_WHILE(c,b,n) newnode(NODE_WHILE,c,b,n)
+#define NEW_UNTIL(c,b,n) newnode(NODE_UNTIL,c,b,n)
#define NEW_FOR(v,i,b) newnode(NODE_FOR,v,b,i)
#define NEW_ITER(v,i,b) newnode(NODE_ITER,v,b,i)
-#define NEW_BEGIN(b,ex,en) newnode(NODE_BEGIN,b,ex,en)
-#define NEW_REDO() newnode(NODE_REDO,0,0,0)
-#define NEW_BREAK() newnode(NODE_BREAK,0,0,0)
-#define NEW_CONT() newnode(NODE_CONTINUE,0,0,0)
-#define NEW_RETRY() newnode(NODE_RETRY,0,0,0)
+#define NEW_BEGIN(b) newnode(NODE_BEGIN,0,b,0)
+#define NEW_RESCUE(b,res) newnode(NODE_RESCUE,b,res,0)
+#define NEW_RESBODY(a,ex,n) newnode(NODE_RESBODY,n,ex,a)
+#define NEW_ENSURE(b,en) newnode(NODE_ENSURE,b,0,en)
#define NEW_RET(s) newnode(NODE_RETURN,s,0,0)
-#define NEW_FAIL(s) newnode(NODE_FAIL,s,0,0)
#define NEW_YIELD(a) newnode(NODE_YIELD,a,0,0)
#define NEW_LIST(a) NEW_ARRAY(a)
#define NEW_ARRAY(a) newnode(NODE_ARRAY,a,1,0)
#define NEW_ZARRAY() newnode(NODE_ZARRAY,0,0,0)
#define NEW_HASH(a) newnode(NODE_HASH,a,0,0)
-#define NEW_AND(a,b) newnode(NODE_AND,a,b,0)
-#define NEW_OR(a,b) newnode(NODE_OR,a,b,0)
#define NEW_NOT(a) newnode(NODE_NOT,0,a,0)
#define NEW_MASGN(l,r) newnode(NODE_MASGN,l,0,r)
#define NEW_GASGN(v,val) newnode(NODE_GASGN,v,val,rb_global_entry(v))
@@ -223,19 +235,22 @@ typedef struct RNode {
#define NEW_IASGN(v,val) newnode(NODE_IASGN,v,val,0)
#define NEW_CASGN(v,val) newnode(NODE_CASGN,v,val,0)
#define NEW_OP_ASGN1(p,id,a) newnode(NODE_OP_ASGN1,p,id,a)
-#define NEW_OP_ASGN2(r,i,val) newnode(NODE_OP_ASGN1,r,val,i)
+#define NEW_OP_ASGN2(r,i,o,val) newnode(NODE_OP_ASGN2,r,val,NEW_OP_ASGN3(i,o))
+#define NEW_OP_ASGN3(i,o) newnode(NODE_OP_ASGN2,i,o,0)
#define NEW_GVAR(v) newnode(NODE_GVAR,v,0,rb_global_entry(v))
#define NEW_LVAR(v) newnode(NODE_LVAR,v,0,local_cnt(v))
#define NEW_DVAR(v) newnode(NODE_DVAR,v,0,0);
#define NEW_IVAR(v) newnode(NODE_IVAR,v,0,0)
-#define NEW_CVAR(v) newnode(NODE_CVAR,v,0,cref_list)
+#define NEW_CVAR(v) newnode(NODE_CVAR,v,0,0)
#define NEW_NTH_REF(n) newnode(NODE_NTH_REF,0,n,local_cnt('~'))
#define NEW_BACK_REF(n) newnode(NODE_BACK_REF,0,n,local_cnt('~'))
+#define NEW_MATCH(c) newnode(NODE_MATCH,c,0,0)
#define NEW_LIT(l) newnode(NODE_LIT,l,0,0)
#define NEW_STR(s) newnode(NODE_STR,s,0,0)
-#define NEW_STR2(s) newnode(NODE_STR2,s,0,0)
+#define NEW_DSTR(s) newnode(NODE_DSTR,s,0,0)
#define NEW_XSTR(s) newnode(NODE_XSTR,s,0,0)
-#define NEW_XSTR2(s) newnode(NODE_XSTR2,s,0,0)
+#define NEW_DXSTR(s) newnode(NODE_DXSTR,s,0,0)
+#define NEW_EVSTR(s,l) newnode(NODE_EVSTR,str_new(s,l),0,0)
#define NEW_CALL(r,m,a) newnode(NODE_CALL,r,m,a)
#define NEW_FCALL(m,a) newnode(NODE_FCALL,0,m,a)
#define NEW_SUPER(a) newnode(NODE_SUPER,0,0,a)
@@ -246,9 +261,9 @@ typedef struct RNode {
#define NEW_CLASS(n,b,s) newnode(NODE_CLASS,n,NEW_CBODY(b),s)
#define NEW_MODULE(n,b) newnode(NODE_MODULE,n,NEW_CBODY(b),0)
#define NEW_COLON2(c,i) newnode(NODE_COLON2,c,i,0)
-#define NEW_CREF0() (cref_list=newnode(NODE_CREF,the_class,0,0))
-#define NEW_CREF(b) (cref_list=newnode(NODE_CREF,0,0,cref_list))
-#define NEW_CBODY(b) (cref_list->nd_body=NEW_SCOPE(b),cref_list)
+#define NEW_CREF0() (cur_cref=newnode(NODE_CREF,RNODE(the_frame->cbase)->nd_clss,0,0))
+#define NEW_CREF() (cur_cref=newnode(NODE_CREF,0,0,cur_cref))
+#define NEW_CBODY(b) (cur_cref->nd_body=NEW_SCOPE(b),cur_cref)
#define NEW_DOT2(b,e) newnode(NODE_DOT2,b,e,0)
#define NEW_DOT3(b,e) newnode(NODE_DOT3,b,e,0)
#define NEW_ATTRSET(a) newnode(NODE_ATTRSET,a,0,0)
@@ -262,4 +277,7 @@ VALUE rb_method_booundp();
#define NOEX_PUBLIC 0
#define NOEX_PRIVATE 1
+NODE *compile_string();
+NODE *compile_file();
+
#endif
diff --git a/numeric.c b/numeric.c
index ba91d0de21..0ff94dc046 100644
--- a/numeric.c
+++ b/numeric.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:42 $
created at: Fri Aug 13 18:33:09 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -21,114 +21,64 @@ VALUE cFloat;
VALUE cInteger;
VALUE cFixnum;
+VALUE eZeroDiv;
+
ID rb_frame_last_func();
+VALUE float_new();
double big2dbl();
-VALUE
-float_new(d)
- double d;
+void
+num_zerodiv()
{
- NEWOBJ(flt, struct RFloat);
- OBJSETUP(flt, cFloat, T_FLOAT);
-
- flt->value = d;
- return (VALUE)flt;
+ rb_raise(exc_new(eZeroDiv, "divided by 0"));
}
static VALUE
-num_coerce_bin(x, y)
+num_coerce(x, y)
VALUE x, y;
{
- return rb_funcall(rb_funcall(y, coerce, 1, x),
- rb_frame_last_func(), 1, y);
-}
-
-static VALUE
-num_uplus(num)
- VALUE num;
-{
- return num;
-}
-
-static VALUE
-num_uminus(num)
- VALUE num;
-{
- return rb_funcall(rb_funcall(num, coerce, 1, INT2FIX(0)), 1, num);
-}
-
-static VALUE
-num_next(num)
- VALUE num;
-{
- num = rb_funcall(num, rb_intern("to_i"), 0);
- return rb_funcall(num, '+', 1, INT2FIX(1));
+ return assoc_new(f_float(x,x),f_float(y,y));
}
VALUE
-num_upto(from, to)
- VALUE from, to;
+num_coerce_bin(x, y)
+ VALUE x, y;
{
- int i, end;
+ VALUE ary;
- end = NUM2INT(to);
- for (i = NUM2INT(from); i <= end; i++) {
- rb_yield(INT2FIX(i));
+ ary = rb_funcall(y, coerce, 1, x);
+ if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) {
+ TypeError("coerce must return [x, y]");
}
- return from;
-}
-
-static VALUE
-num_downto(from, to)
- VALUE from, to;
-{
- int i, end;
-
- end = NUM2INT(to);
- for (i=NUM2INT(from); i >= end; i--) {
- rb_yield(INT2FIX(i));
- }
+ x = RARRAY(ary)->ptr[0];
+ y = RARRAY(ary)->ptr[1];
- return from;
+ return rb_funcall(x, rb_frame_last_func(), 1, y);
}
static VALUE
-num_step(from, to, step)
- VALUE from, to, step;
+num_uplus(num)
+ VALUE num;
{
- int i, end, diff;
-
- end = NUM2INT(to);
- diff = NUM2INT(step);
-
- if (diff == 0) {
- Fail("step cannot be 0");
- }
- else if (diff > 0) {
- for (i=NUM2INT(from); i <= end; i+=diff) {
- rb_yield(INT2FIX(i));
- }
- }
- else {
- for (i=NUM2INT(from); i >= end; i+=diff) {
- rb_yield(INT2FIX(i));
- }
- }
- return from;
+ return num;
}
static VALUE
-num_dotimes(num)
+num_uminus(num)
VALUE num;
{
- int i, end;
+ VALUE ary, x, y;
- end = NUM2INT(num);
- for (i=0; i<end; i++) {
- rb_yield(INT2FIX(i));
+ ary = rb_funcall(num, coerce, 1, INT2FIX(0));
+ if (TYPE(ary) != T_ARRAY || RARRAY(ary)->len != 2) {
+ TypeError("coerce must return [x, y]");
}
- return num;
+
+ x = RARRAY(ary)->ptr[0];
+ y = RARRAY(ary)->ptr[1];
+
+ return rb_funcall(x, '-', 1, y);
}
static VALUE
@@ -170,12 +120,45 @@ num_chr(num)
}
static VALUE
+num_abs(num)
+ VALUE num;
+{
+ if (RTEST(rb_funcall(num, '<', 1, INT2FIX(0)))) {
+ return rb_funcall(num, rb_intern("-@"), 0);
+ }
+ return num;
+}
+
+VALUE
+float_new(d)
+ double d;
+{
+ NEWOBJ(flt, struct RFloat);
+ OBJSETUP(flt, cFloat, T_FLOAT);
+
+ flt->value = d;
+ return (VALUE)flt;
+}
+
+static VALUE
flo_to_s(flt)
struct RFloat *flt;
{
char buf[32];
sprintf(buf, "%g", flt->value);
+ if (index(buf, '.') == 0) {
+ int len = strlen(buf);
+
+ if (len > 1 && buf[1] == 'e') {
+ memmove(buf+3, buf+1, len-1);
+ buf[1] = '.';
+ buf[2] = '0';
+ }
+ else {
+ strcat(buf, ".0");
+ }
+ }
return str_new2(buf);
}
@@ -184,18 +167,7 @@ static VALUE
flo_coerce(x, y)
VALUE x, y;
{
- switch (TYPE(y)) {
- case T_FIXNUM:
- return float_new((double)FIX2INT(y));
- case T_FLOAT:
- return y;
- case T_BIGNUM:
- return big_to_f(y);
- default:
- Fail("can't coerce %s to Float", rb_class2name(CLASS_OF(y)));
- }
- /* not reached */
- return Qnil;
+ return assoc_new(f_float(x, y), x);
}
static VALUE
@@ -267,14 +239,14 @@ flo_div(x, y)
switch (TYPE(y)) {
case T_FIXNUM:
f_y = FIX2INT(y);
- if (f_y == 0) Fail("devided by 0");
+ if (f_y == 0) num_zerodiv();
return float_new(x->value / (double)f_y);
case T_BIGNUM:
d = big2dbl(y);
- if (d == 0.0) Fail("devided by 0");
- return float_new(x->value + d);
+ if (d == 0.0) num_zerodiv();
+ return float_new(x->value / d);
case T_FLOAT:
- if (y->value == 0.0) Fail("devided by 0");
+ if (y->value == 0.0) num_zerodiv();
return float_new(x->value / y->value);
default:
return num_coerce_bin(x, y);
@@ -333,30 +305,21 @@ flo_pow(x, y)
}
}
-struct xy {
- VALUE x, y;
-};
-
static VALUE
-eq(arg)
- struct xy *arg;
+num_eql(x, y)
+ VALUE x, y;
{
- return rb_funcall(arg->y, rb_intern("=="), 1, arg->x);
-}
+ if (TYPE(x) != TYPE(y)) return FALSE;
-static VALUE
-eq_rescue()
-{
- return FALSE;
+ return rb_equal(x, y);
}
+
static VALUE
num_equal(x, y)
VALUE x, y;
{
- struct xy arg;
- arg.x = x; arg.y = y;
- return rb_rescue(eq, &arg, eq_rescue, Qnil);
+ return rb_equal(y, x);
}
static VALUE
@@ -364,13 +327,11 @@ flo_eq(x, y)
struct RFloat *x, *y;
{
switch (TYPE(y)) {
- case T_NIL:
- return Qnil;
case T_FIXNUM:
if (x->value == FIX2INT(y)) return TRUE;
return FALSE;
case T_BIGNUM:
- return float_new(x->value == big2dbl(y));
+ return (x->value == big2dbl(y))?TRUE:FALSE;
case T_FLOAT:
return (x->value == y->value)?TRUE:FALSE;
default:
@@ -463,14 +424,15 @@ static VALUE
fail_to_integer(val)
VALUE val;
{
- Fail("failed to convert %s into integer", rb_class2name(CLASS_OF(val)));
+ TypeError("failed to convert %s into Integer",
+ rb_class2name(CLASS_OF(val)));
}
int
num2int(val)
VALUE val;
{
- if (val == Qnil) return 0;
+ if (NIL_P(val)) return 0;
switch (TYPE(val)) {
case T_FIXNUM:
@@ -483,7 +445,6 @@ num2int(val)
}
else {
Fail("float %g out of rang of integer", RFLOAT(val)->value);
- return Qnil; /* not reached */
}
case T_BIGNUM:
@@ -501,7 +462,7 @@ num2fix(val)
{
int v;
- if (val == Qnil) return INT2FIX(0);
+ if (NIL_P(val)) return INT2FIX(0);
switch (TYPE(val)) {
case T_FIXNUM:
return val;
@@ -511,7 +472,7 @@ num2fix(val)
default:
v = num2int(val);
if (!FIXABLE(v))
- Fail("integer %d out of rang of Fixnum", v);
+ Fail("integer %d out of range of Fixnum", v);
return INT2FIX(v);
}
}
@@ -524,6 +485,13 @@ int_int_p(num)
}
static VALUE
+int_succ(num)
+ VALUE num;
+{
+ return rb_funcall(num, '+', 1, INT2FIX(1));
+}
+
+static VALUE
fix_uminus(num)
VALUE num;
{
@@ -541,7 +509,7 @@ fix2str(x, base)
if (base == 10) fmt[1] = 'd';
else if (base == 16) fmt[1] = 'x';
else if (base == 8) fmt[1] = 'o';
- else Fail("fixnum cannot treat base %d", base);
+ else Fatal("fixnum cannot treat base %d", base);
sprintf(buf, fmt, FIX2INT(x));
return str_new2(buf);
@@ -618,11 +586,17 @@ fix_mul(x, y)
switch (TYPE(y)) {
case T_FIXNUM:
{
- int a = FIX2INT(x), b = FIX2INT(y);
- int c = a * b;
- VALUE r = INT2FIX(c);
+ int a, b, c;
+ VALUE r;
- if (FIX2INT(r) != c) {
+ a = FIX2INT(x);
+ if (a == 0) return x;
+
+ b = FIX2INT(y);
+ c = a * b;
+ r = INT2FIX(c);
+
+ if (FIX2INT(r) != c || c/a != b) {
r = big_mul(int2big(a), int2big(b));
}
return r;
@@ -643,7 +617,7 @@ fix_div(x, y)
if (TYPE(y) == T_FIXNUM) {
i = FIX2INT(y);
- if (i == 0) Fail("devided by 0");
+ if (i == 0) num_zerodiv();
i = FIX2INT(x)/i;
return INT2FIX(i);
}
@@ -658,7 +632,7 @@ fix_mod(x, y)
if (TYPE(y) == T_FIXNUM) {
i = FIX2INT(y);
- if (i == 0) Fail("devided by 0");
+ if (i == 0) num_zerodiv();
i = FIX2INT(x)%i;
return INT2FIX(i);
}
@@ -669,8 +643,6 @@ static VALUE
fix_pow(x, y)
VALUE x, y;
{
- extern double pow();
-
if (FIXNUM_P(y)) {
int a, b;
@@ -695,9 +667,6 @@ fix_equal(x, y)
if (FIXNUM_P(y)) {
return (FIX2INT(x) == FIX2INT(y))?TRUE:FALSE;
}
- else if (NIL_P(y)) {
- return Qnil;
- }
else {
return num_equal(x, y);
}
@@ -837,7 +806,7 @@ fix_lshift(x, y)
val = NUM2INT(x);
width = NUM2INT(y);
if (width > (sizeof(VALUE)*CHAR_BIT-1)
- || (unsigned)val>>(sizeof(VALUE)*CHAR_BIT-width) > 0) {
+ || (unsigned)val>>(sizeof(VALUE)*CHAR_BIT-1-width) > 0) {
return big_lshift(int2big(val), y);
}
val = val << width;
@@ -848,10 +817,15 @@ static VALUE
fix_rshift(x, y)
VALUE x, y;
{
- long val;
+ long i, val;
- val = RSHIFT(NUM2INT(x), NUM2INT(y));
- return INT2FIX(val);
+ i = NUM2INT(y);
+ if (y < 32) {
+ val = RSHIFT(FIX2INT(x), i);
+ return INT2FIX(val);
+ }
+
+ return INT2FIX(0);
}
static VALUE
@@ -890,7 +864,7 @@ static VALUE
fix_type(fix)
VALUE fix;
{
- return cFixnum;
+ return str_new2("Fixnum");
}
static VALUE
@@ -914,7 +888,7 @@ fix_id2name(fix)
}
static VALUE
-fix_next(fix)
+fix_succ(fix)
VALUE fix;
{
int i = FIX2INT(fix) + 1;
@@ -922,7 +896,153 @@ fix_next(fix)
return int2inum(i);
}
+static VALUE
+fix_size(fix)
+ VALUE fix;
+{
+ return INT2FIX(sizeof(VALUE));
+}
+
+VALUE
+num_upto(from, to)
+ VALUE from, to;
+{
+ VALUE i = from;
+
+ for (;;) {
+ if (RTEST(rb_funcall(i, '>', 1, to))) break;
+ rb_yield(i);
+ i = rb_funcall(i, '+', 1, INT2FIX(1));
+ }
+ return from;
+}
+
+static VALUE
+num_downto(from, to)
+ VALUE from, to;
+{
+ VALUE i = from;
+
+ for (;;) {
+ if (RTEST(rb_funcall(i, '<', 1, to))) break;
+ rb_yield(i);
+ i = rb_funcall(i, '-', 1, INT2FIX(1));
+ }
+ return from;
+}
+
+static VALUE
+num_step(from, to, step)
+ VALUE from, to, step;
+{
+ VALUE i = from;
+ ID cmp;
+
+ if (step == INT2FIX(0)) {
+ IndexError("step cannot be 0");
+ }
+
+ if (RTEST(rb_funcall(step, '>', 1, INT2FIX(0)))) {
+ cmp = '>';
+ }
+ else {
+ cmp = '<';
+ }
+ for (;;) {
+ if (RTEST(rb_funcall(i, cmp, 1, to))) break;
+ rb_yield(i);
+ i = rb_funcall(i, '+', 1, step);
+ }
+ return from;
+}
+
+static VALUE
+num_dotimes(num)
+ VALUE num;
+{
+ VALUE i = INT2FIX(0);
+
+ for (;;) {
+ if (!RTEST(rb_funcall(i, '<', 1, num))) break;
+ rb_yield(i);
+ i = rb_funcall(i, '+', 1, INT2FIX(1));
+ }
+ return num;
+}
+
+VALUE
+fix_upto(from, to)
+ VALUE from, to;
+{
+ int i, end;
+
+ if (!FIXNUM_P(to)) return num_upto(from, to);
+ end = FIX2INT(to);
+ for (i = FIX2INT(from); i <= end; i++) {
+ rb_yield(INT2FIX(i));
+ }
+
+ return from;
+}
+
+static VALUE
+fix_downto(from, to)
+ VALUE from, to;
+{
+ int i, end;
+
+ if (!FIXNUM_P(to)) return num_downto(from, to);
+ end = FIX2INT(to);
+ for (i=FIX2INT(from); i >= end; i--) {
+ rb_yield(INT2FIX(i));
+ }
+
+ return from;
+}
+
+static VALUE
+fix_step(from, to, step)
+ VALUE from, to, step;
+{
+ int i, end, diff;
+
+ if (!FIXNUM_P(to) || !FIXNUM_P(step))
+ return num_step(from, to, step);
+
+ end = FIX2INT(to);
+ diff = FIX2INT(step);
+
+ if (diff == 0) {
+ ArgError("step cannot be 0");
+ }
+ else if (diff > 0) {
+ for (i=FIX2INT(from); i <= end; i+=diff) {
+ rb_yield(INT2FIX(i));
+ }
+ }
+ else {
+ for (i=FIX2INT(from); i >= end; i+=diff) {
+ rb_yield(INT2FIX(i));
+ }
+ }
+ return from;
+}
+
+static VALUE
+fix_dotimes(num)
+ VALUE num;
+{
+ int i, end;
+
+ end = FIX2INT(num);
+ for (i=0; i<end; i++) {
+ rb_yield(INT2FIX(i));
+ }
+ return num;
+}
+
extern VALUE mComparable;
+extern VALUE eException;
void
Init_Numeric()
@@ -930,16 +1050,18 @@ Init_Numeric()
coerce = rb_intern("coerce");
to_i = rb_intern("to_i");
+ eZeroDiv = rb_define_class("ZeroDivisionError", eException);
cNumeric = rb_define_class("Numeric", cObject);
- rb_undef_method(CLASS_OF(cNumeric), "new");
-
rb_include_module(cNumeric, mComparable);
+ rb_define_method(cNumeric, "coerce", num_coerce, 1);
+
rb_define_method(cNumeric, "+@", num_uplus, 0);
rb_define_method(cNumeric, "-@", num_uminus, 0);
+ rb_define_method(cNumeric, "eql?", num_eql, 1);
rb_define_method(cNumeric, "divmod", num_divmod, 1);
+ rb_define_method(cNumeric, "abs", num_abs, 0);
- rb_define_method(cNumeric, "next", num_next, 0);
rb_define_method(cNumeric, "upto", num_upto, 1);
rb_define_method(cNumeric, "downto", num_downto, 1);
rb_define_method(cNumeric, "step", num_step, 2);
@@ -949,9 +1071,12 @@ Init_Numeric()
cInteger = rb_define_class("Integer", cNumeric);
rb_define_method(cInteger, "integer?", int_int_p, 0);
+ rb_define_method(cInteger, "succ", int_succ, 0);
cFixnum = rb_define_class("Fixnum", cInteger);
+ rb_undef_method(CLASS_OF(cFixnum), "new");
+
rb_define_method(cFixnum, "to_s", fix_to_s, 0);
rb_define_method(cFixnum, "type", fix_type, 0);
@@ -986,10 +1111,18 @@ Init_Numeric()
rb_define_method(cFixnum, "to_i", fix_to_i, 0);
rb_define_method(cFixnum, "to_f", fix_to_f, 0);
- rb_define_method(cFixnum, "next", fix_next, 0);
+ rb_define_method(cFixnum, "succ", fix_succ, 0);
+ rb_define_method(cFixnum, "size", fix_size, 0);
+
+ rb_define_method(cFixnum, "upto", fix_upto, 1);
+ rb_define_method(cFixnum, "downto", fix_downto, 1);
+ rb_define_method(cFixnum, "step", fix_step, 2);
+ rb_define_method(cFixnum, "times", fix_dotimes, 0);
cFloat = rb_define_class("Float", cNumeric);
+ rb_undef_method(CLASS_OF(cFloat), "new");
+
rb_define_method(cFloat, "to_s", flo_to_s, 0);
rb_define_method(cFloat, "coerce", flo_coerce, 1);
rb_define_method(cFloat, "-@", flo_uminus, 0);
diff --git a/object.c b/object.c
index 74324b77e7..5b18835613 100644
--- a/object.c
+++ b/object.c
@@ -6,7 +6,7 @@
$Date: 1995/01/12 08:54:49 $
created at: Thu Jul 15 12:01:24 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -18,24 +18,39 @@ VALUE cKernel;
VALUE cObject;
VALUE cModule;
VALUE cClass;
-VALUE cNil;
+VALUE cFixnum;
VALUE cData;
+static VALUE cNil;
+static VALUE cTrue;
+static VALUE cFalse;
+
struct st_table *new_idhash();
VALUE f_sprintf();
VALUE obj_alloc();
-static ID eq;
-
-static ID init;
+static ID eq, eql;
+static ID inspect;
-VALUE
+int
rb_equal(obj1, obj2)
VALUE obj1, obj2;
{
- return rb_funcall(obj1, eq, 1, obj2);
+ VALUE result;
+
+ result = rb_funcall(obj1, eq, 1, obj2);
+ if (result == FALSE || NIL_P(result))
+ return FALSE;
+ return TRUE;
+}
+
+int
+rb_eql(obj1, obj2)
+ VALUE obj1, obj2;
+{
+ return rb_funcall(obj1, eql, 1, obj2);
}
static VALUE
@@ -67,11 +82,13 @@ krn_id(obj)
return obj | FIXNUM_FLAG;
}
+char *rb_class2path();
+
static VALUE
krn_type(obj)
struct RBasic *obj;
{
- return obj->class;
+ return rb_class_path(obj->class);
}
static VALUE
@@ -81,7 +98,7 @@ krn_clone(obj)
VALUE clone;
if (TYPE(obj) != T_OBJECT) {
- Fail("can't clone %s", rb_class2name(CLASS_OF(obj)));
+ TypeError("can't clone %s", rb_class2name(CLASS_OF(obj)));
}
clone = obj_alloc(RBASIC(obj)->class);
@@ -89,6 +106,7 @@ krn_clone(obj)
ROBJECT(clone)->iv_tbl = st_copy(ROBJECT(obj)->iv_tbl);
}
RBASIC(clone)->class = singleton_class_clone(RBASIC(obj)->class);
+ RBASIC(clone)->flags = RBASIC(obj)->flags;
return clone;
}
@@ -111,6 +129,13 @@ krn_to_s(obj)
}
VALUE
+rb_inspect(obj)
+ VALUE obj;
+{
+ return rb_funcall(obj, inspect, 0, 0);
+}
+
+static VALUE
krn_inspect(obj)
VALUE obj;
{
@@ -126,8 +151,11 @@ inspect_i(id, value, str)
VALUE str2;
char *ivname;
+ /* need not to show internal data */
+ if (TYPE(value) == T_DATA) return ST_CONTINUE;
if (str->ptr[0] == '-') {
str->ptr[0] = '#';
+ str_cat(str, ": ", 2);
}
else {
str_cat(str, ", ", 2);
@@ -135,7 +163,12 @@ inspect_i(id, value, str)
ivname = rb_id2name(id);
str_cat(str, ivname, strlen(ivname));
str_cat(str, "=", 1);
- str2 = rb_funcall(value, rb_intern("inspect"), 0, 0);
+ if (TYPE(value) == T_OBJECT) {
+ str2 = krn_to_s(value);
+ }
+ else {
+ str2 = rb_inspect(value);
+ }
str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
return ST_CONTINUE;
@@ -145,25 +178,20 @@ static VALUE
obj_inspect(obj)
struct RObject *obj;
{
- VALUE str;
- char buf[256];
+ if (TYPE(obj) == T_OBJECT && obj->iv_tbl) {
+ VALUE str;
+ char buf[256];
- switch (TYPE(obj)) {
- case T_OBJECT:
- case T_MODULE:
- case T_CLASS:
- if (obj->iv_tbl) break;
- /* fall through */
- default:
- return krn_inspect(obj);
- }
+ sprintf(buf, "-<%s", rb_class2name(CLASS_OF(obj)));
+ str = str_new2(buf);
+ st_foreach(obj->iv_tbl, inspect_i, str);
+ str_cat(str, ">", 1);
+ if (RSTRING(str)->ptr[0] == '-') /* no instance-var */
+ return krn_inspect(obj);
- sprintf(buf, "-<%s: ", rb_class2name(CLASS_OF(obj)));
- str = str_new2(buf);
- st_foreach(obj->iv_tbl, inspect_i, str);
- str_cat(str, ">", 1);
-
- return str;
+ return str;
+ }
+ return krn_inspect(obj);
}
VALUE
@@ -177,10 +205,10 @@ obj_is_instance_of(obj, c)
case T_CLASS:
break;
default:
- Fail("class or module required");
+ TypeError("class or module required");
}
- while (FL_TEST(class, FL_SINGLE)) {
+ while (FL_TEST(class, FL_SINGLETON)) {
class = class->super;
}
if (c == (VALUE)class) return TRUE;
@@ -198,7 +226,7 @@ obj_is_kind_of(obj, c)
case T_CLASS:
break;
default:
- Fail("class or module required");
+ TypeError("class or module required");
}
while (class) {
@@ -234,14 +262,21 @@ static VALUE
nil_to_s(obj)
VALUE obj;
{
+ return str_new2("");
+}
+
+static VALUE
+nil_inspect(obj)
+ VALUE obj;
+{
return str_new2("nil");
}
static VALUE
-nil_type(nil)
- VALUE nil;
+nil_type(obj)
+ VALUE obj;
{
- return cNil;
+ return str_new2("Nil");
}
static VALUE
@@ -256,10 +291,10 @@ nil_plus(x, y)
case T_ARRAY:
return y;
default:
- Fail("tried to add %s(%s) to nil",
- RSTRING(obj_as_string(y))->ptr, rb_class2name(CLASS_OF(y)));
+ TypeError("tried to add %s(%s) to nil",
+ RSTRING(obj_as_string(y))->ptr, rb_class2name(CLASS_OF(y)));
}
- return Qnil; /* not reached */
+ /* not reached */
}
static VALUE
@@ -273,29 +308,38 @@ static VALUE
true_to_s(obj)
VALUE obj;
{
- return str_new2("t");
+ return str_new2("TRUE");
}
-VALUE
-obj_alloc(class)
- VALUE class;
+static VALUE
+true_type(obj)
+ VALUE obj;
{
- NEWOBJ(obj, struct RObject);
- OBJSETUP(obj, class, T_OBJECT);
+ return str_new2("TRUE");
+}
- return (VALUE)obj;
+static VALUE
+false_to_s(obj)
+ VALUE obj;
+{
+ return str_new2("FALSE");
}
static VALUE
-mod_new(argc, argv, class)
- int argc;
- VALUE *argv;
+false_type(obj)
+ VALUE obj;
+{
+ return str_new2("FALSE");
+}
+
+VALUE
+obj_alloc(class)
VALUE class;
{
- VALUE obj = obj_alloc(class);
+ NEWOBJ(obj, struct RObject);
+ OBJSETUP(obj, class, T_OBJECT);
- rb_funcall2(obj, init, argc, argv);
- return obj;
+ return (VALUE)obj;
}
static VALUE
@@ -311,8 +355,6 @@ mod_clone(module)
return (VALUE)clone;
}
-char *rb_class2path();
-
static VALUE
mod_to_s(class)
VALUE class;
@@ -320,6 +362,20 @@ mod_to_s(class)
return rb_class_path(class);
}
+VALUE class_s_new(); /* moved to eval.c */
+
+static VALUE
+class_superclass(class)
+ struct RClass *class;
+{
+ struct RClass *super = class->super;
+
+ while (TYPE(super) == T_ICLASS)
+ super = super->super;
+
+ return (VALUE)super;
+}
+
ID
rb_to_id(name)
VALUE name;
@@ -327,7 +383,8 @@ rb_to_id(name)
if (TYPE(name) == T_STRING) {
return rb_intern(RSTRING(name)->ptr);
}
- return NUM2INT(name);
+ Check_Type(name, T_FIXNUM);
+ return FIX2INT(name);
}
static VALUE
@@ -360,8 +417,82 @@ mod_private_attr(class, name)
return Qnil;
}
-static
-VALUE boot_defclass(name, super)
+static VALUE
+f_integer(obj, arg)
+ VALUE obj, arg;
+{
+ int i;
+
+ switch (TYPE(arg)) {
+ case T_FLOAT:
+ if (RFLOAT(arg)->value <= (double)FIXNUM_MAX
+ && RFLOAT(arg)->value >= (double)FIXNUM_MIN) {
+ i = (int)RFLOAT(arg)->value;
+ break;
+ }
+ return dbl2big(RFLOAT(arg)->value);
+
+ case T_BIGNUM:
+ return arg;
+
+ case T_STRING:
+ return str2inum(RSTRING(arg)->ptr, 0);
+
+ default:
+ i = NUM2INT(arg);
+ }
+ return INT2NUM(i);
+}
+
+static VALUE
+to_flo(val)
+ VALUE val;
+{
+ return rb_funcall(val, rb_intern("to_f"), 0);
+}
+
+static VALUE
+fail_to_flo(val)
+ VALUE val;
+{
+ TypeError("failed to convert %s into Float", rb_class2name(CLASS_OF(val)));
+}
+
+double big2dbl();
+
+VALUE
+f_float(obj, arg)
+ VALUE obj, arg;
+{
+
+ switch (TYPE(arg)) {
+ case T_FLOAT:
+ return arg;
+
+ case T_BIGNUM:
+ return float_new(big2dbl(arg));
+
+ default:
+ return rb_rescue(to_flo, arg, fail_to_flo, arg);
+ }
+}
+
+static VALUE
+f_string(obj, arg)
+ VALUE obj, arg;
+{
+ return rb_funcall(arg, rb_intern("to_s"), 0);
+}
+
+static VALUE
+f_array(obj, arg)
+ VALUE obj, arg;
+{
+ return rb_funcall(arg, rb_intern("to_a"), 0);
+}
+
+static VALUE
+boot_defclass(name, super)
char *name;
VALUE super;
{
@@ -371,19 +502,53 @@ VALUE boot_defclass(name, super)
rb_name_class(obj, id);
st_add_direct(rb_class_tbl, id, obj);
- rb_set_class_path(obj, 0, name);
return (VALUE)obj;
}
+VALUE
+rb_class_of(obj)
+ VALUE obj;
+{
+ if (FIXNUM_P(obj)) return cFixnum;
+ if (obj == Qnil) return cNil;
+ if (obj == FALSE) return cFalse;
+ if (obj == TRUE) return cTrue;
+
+ return RBASIC(obj)->class;
+}
+
+int
+rb_type(obj)
+ VALUE obj;
+{
+ if (FIXNUM_P(obj)) return T_FIXNUM;
+ if (obj == Qnil) return T_NIL;
+ if (obj == FALSE) return T_FALSE;
+ if (obj == TRUE) return T_TRUE;
+
+ return BUILTIN_TYPE(obj);
+}
+
+int
+rb_special_const_p(obj)
+ VALUE obj;
+{
+ if (FIXNUM_P(obj)) return TRUE;
+ if (obj == Qnil) return TRUE;
+ if (obj == FALSE) return TRUE;
+ if (obj == TRUE) return TRUE;
+
+ return FALSE;
+}
+
VALUE TopSelf;
-VALUE TRUE = INT2FIX(1);
void
Init_Object()
{
VALUE metaclass;
- cKernel = boot_defclass("Kernel", Qnil);
+ cKernel = boot_defclass("kernel", 0);
cObject = boot_defclass("Object", cKernel);
cModule = boot_defclass("Module", cObject);
cClass = boot_defclass("Class", cModule);
@@ -396,39 +561,40 @@ Init_Object()
/*
* Ruby's Class Hierarchy Chart
*
- * +-------nil +---------------------+
- * | ^ | |
- * | | | |
- * | Kernel----->(Kernel) |
- * | ^ ^ ^ ^ |
- * | | | | | |
- * | +---+ +----+ | +---+ |
- * | | +-----|----+ | |
- * | | | | | |
- * +->Nil->(Nil) Object---->(Object) |
- * ^ ^ ^ ^ |
- * | | | | |
- * | | +-------+ | |
- * | | | | |
- * | +---------+ +------+ |
- * | | | | |
- * +---------+ | Module--->(Module) |
- * | | ^ ^ |
- * OtherClass-->(OtherClass) | | |
- * Class---->(Class) |
- * ^ |
- * | |
- * +----------------+
+ * +------------------------+
+ * | |
+ * kernel----->(kernel) |
+ * ^ ^ ^ ^ |
+ * | | | | |
+ * +---+ +----+ | +---+ |
+ * | +-----|----+ | |
+ * | | | | |
+ * Nil->(Nil) Object---->(Object) |
+ * ^ ^ ^ ^ |
+ * | | | | |
+ * | | +-----+ +---------+ |
+ * | | | | |
+ * | +-----------+ | |
+ * | | | | |
+ * +------+ | Module--->(Module) |
+ * | | ^ ^ |
+ * OtherClass-->(OtherClass) | | |
+ * Class---->(Class) |
+ * ^ |
+ * | |
+ * +----------------+
*
* + All metaclasses are instances of the class `Class'.
*/
-
rb_define_method(cKernel, "nil?", krn_nil_p, 0);
rb_define_method(cKernel, "==", krn_equal, 1);
rb_define_alias(cKernel, "equal?", "==");
+ rb_define_alias(cKernel, "===", "==");
rb_define_alias(cKernel, "=~", "==");
+ rb_define_method(cKernel, "eql?", rb_equal, 1);
+
rb_define_method(cKernel, "hash", krn_id, 0);
rb_define_method(cKernel, "id", krn_id, 0);
rb_define_method(cKernel, "type", krn_type, 0);
@@ -440,14 +606,32 @@ Init_Object()
rb_define_method(cKernel, "to_s", krn_to_s, 0);
rb_define_method(cKernel, "inspect", krn_inspect, 0);
+ rb_define_method(cKernel, "instance_of?", obj_is_instance_of, 1);
+ rb_define_method(cKernel, "kind_of?", obj_is_kind_of, 1);
+ rb_define_method(cKernel, "is_a?", obj_is_kind_of, 1);
+
rb_define_private_method(cKernel, "sprintf", f_sprintf, -1);
rb_define_alias(cKernel, "format", "sprintf");
+ rb_define_private_method(cKernel, "Integer", f_integer, 1);
+ rb_define_private_method(cKernel, "Float", f_float, 1);
+
+ rb_define_private_method(cKernel, "String", f_string, 1);
+ rb_define_private_method(cKernel, "Array", f_array, 1);
+
+ cNil = rb_define_class("nil", cKernel);
+ rb_define_method(cNil, "type", nil_type, 0);
+ rb_define_method(cNil, "to_s", nil_to_s, 0);
+ rb_define_method(cNil, "inspect", nil_inspect, 0);
+
+ rb_define_method(cNil, "nil?", nil_nil_p, 0);
+
+ /* default addition */
+ rb_define_method(cNil, "+", nil_plus, 1);
+
rb_define_private_method(cObject, "initialize", obj_initialize, -1);
rb_define_private_method(cObject, "singleton_method_added", obj_s_added, 1);
- rb_define_method(cObject, "is_instance_of?", obj_is_instance_of, 1);
- rb_define_method(cObject, "is_kind_of?", obj_is_kind_of, 1);
rb_define_method(cObject, "inspect", obj_inspect, 0);
rb_define_method(cModule, "to_s", mod_to_s, 0);
@@ -455,29 +639,27 @@ Init_Object()
rb_define_private_method(cModule, "attr", mod_attr, -1);
rb_define_private_method(cModule, "public_attr", mod_public_attr, -1);
rb_define_private_method(cModule, "private_attr", mod_private_attr, -1);
+ rb_define_private_method(cModule, "object_extended", obj_s_added, 1);
- rb_define_method(cClass, "new", mod_new, -1);
-
- cNil = rb_define_class("Nil", cKernel);
- rb_define_method(cNil, "to_s", nil_to_s, 0);
- rb_define_method(cNil, "type", nil_type, 0);
-
- rb_define_method(cNil, "nil?", nil_nil_p, 0);
-
- /* default addition */
- rb_define_method(cNil, "+", nil_plus, 1);
+ rb_define_method(cClass, "new", class_s_new, -1);
+ rb_define_method(cClass, "superclass", class_superclass, -1);
cData = rb_define_class("Data", cKernel);
- eq = rb_intern("==");
-
- Qself = TopSelf = obj_alloc(cObject);
+ TopSelf = obj_alloc(cObject);
rb_define_singleton_method(TopSelf, "to_s", main_to_s, 0);
- TRUE = obj_alloc(cObject);
- rb_define_singleton_method(TRUE, "to_s", true_to_s, 0);
- rb_define_const(cKernel, "TRUE", TRUE);
- rb_define_const(cKernel, "FALSE", FALSE);
+ cTrue = rb_define_class("true", cKernel);
+ rb_define_method(cTrue, "to_s", true_to_s, 0);
+ rb_define_method(cTrue, "type", true_type, 0);
+ rb_define_global_const("TRUE", TRUE);
- init = rb_intern("initialize");
+ cFalse = rb_define_class("false", cKernel);
+ rb_define_method(cFalse, "to_s", false_to_s, 0);
+ rb_define_method(cFalse, "type", false_type, 0);
+ rb_define_global_const("FALSE", FALSE);
+
+ eq = rb_intern("==");
+ eql = rb_intern("eql?");
+ inspect = rb_intern("inspect");
}
diff --git a/pack.c b/pack.c
index ed98970d36..3e54b2ba3a 100644
--- a/pack.c
+++ b/pack.c
@@ -6,7 +6,7 @@
$Date: 1994/12/09 09:40:22 $
created at: Thu Feb 10 15:17:05 JST 1994
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -20,19 +20,23 @@
+(((x)&0x0000FF00)<<8) \
+(((x)&0x00FF0000)>>8) )
#ifdef WORDS_BIGENDIAN
+#ifndef ntohs
#define ntohs(x) (x)
#define ntohl(x) (x)
#define htons(x) (x)
#define htonl(x) (x)
+#endif
#define htovs(x) swaps(x)
#define htovl(x) swapl(x)
#define vtohs(x) swaps(x)
#define vtohl(x) swapl(x)
#else /* LITTLE ENDIAN */
+#ifndef ntohs
#define ntohs(x) swaps(x)
#define ntohl(x) swapl(x)
#define htons(x) swaps(x)
#define htonl(x) swapl(x)
+#endif
#define htovs(x) (x)
#define htovl(x) (x)
#define vtohs(x) (x)
@@ -70,7 +74,7 @@ pack_pack(ary, fmt)
items = ary->len;
idx = 0;
-#define NEXTFROM (items-- > 0 ? ary->ptr[idx++] : (Fail(toofew),0))
+#define NEXTFROM (items-- > 0 ? ary->ptr[idx++] : (ArgError(toofew),0))
while (p < pend) {
type = *p++; /* get data type */
@@ -91,7 +95,7 @@ pack_pack(ary, fmt)
case 'B': case 'b':
case 'H': case 'h':
from = NEXTFROM;
- if (from == Qnil) {
+ if (NIL_P(from)) {
ptr = 0;
plen = 0;
}
@@ -106,30 +110,20 @@ pack_pack(ary, fmt)
switch (type) {
case 'a':
- if (plen > len)
- str_cat(res, ptr, len);
- else {
- str_cat(res, ptr, plen);
- len = plen;
- while (len >= 10) {
- str_cat(res, nul10, 10);
- len -= 10;
- }
- str_cat(res, nul10, len);
- }
- break;
-
case 'A':
- if (plen > len)
+ if (plen >= len)
str_cat(res, ptr, len);
else {
str_cat(res, ptr, plen);
- len = plen;
+ len -= plen;
while (len >= 10) {
- str_cat(res, spc10, 10);
+ if (type == 'A')
+ str_cat(res, spc10, 10);
+ else
+ str_cat(res, nul10, 10);
len -= 10;
}
- str_cat(res, spc10, len);
+ str_cat(res, nul10, len);
}
break;
@@ -244,7 +238,7 @@ pack_pack(ary, fmt)
char c;
from = NEXTFROM;
- if (from == Qnil) c = 0;
+ if (NIL_P(from)) c = 0;
else {
c = NUM2INT(from);
}
@@ -258,7 +252,7 @@ pack_pack(ary, fmt)
short s;
from = NEXTFROM;
- if (from == Qnil) s = 0;
+ if (NIL_P(from)) s = 0;
else {
s = NUM2INT(from);
}
@@ -272,7 +266,7 @@ pack_pack(ary, fmt)
int i;
from = NEXTFROM;
- if (from == Qnil) i = 0;
+ if (NIL_P(from)) i = 0;
else {
i = NUM2INT(from);
}
@@ -286,7 +280,7 @@ pack_pack(ary, fmt)
long l;
from = NEXTFROM;
- if (from == Qnil) l = 0;
+ if (NIL_P(from)) l = 0;
else {
l = NUM2INT(from);
}
@@ -299,7 +293,7 @@ pack_pack(ary, fmt)
short s;
from = NEXTFROM;
- if (from == Qnil) s = 0;
+ if (NIL_P(from)) s = 0;
else {
s = NUM2INT(from);
}
@@ -313,7 +307,7 @@ pack_pack(ary, fmt)
long l;
from = NEXTFROM;
- if (from == Qnil) l = 0;
+ if (NIL_P(from)) l = 0;
else {
l = NUM2INT(from);
}
@@ -367,7 +361,7 @@ pack_pack(ary, fmt)
short s;
from = NEXTFROM;
- if (from == Qnil) s = 0;
+ if (NIL_P(from)) s = 0;
else {
s = NUM2INT(from);
}
@@ -381,7 +375,7 @@ pack_pack(ary, fmt)
long l;
from = NEXTFROM;
- if (from == Qnil) l = 0;
+ if (NIL_P(from)) l = 0;
else {
l = NUM2INT(from);
}
@@ -402,7 +396,7 @@ pack_pack(ary, fmt)
case 'X':
shrink:
if (RSTRING(res)->len < len)
- Fail("X outside of string");
+ ArgError("X outside of string");
RSTRING(res)->len -= len;
RSTRING(res)->ptr[RSTRING(res)->len] = '\0';
break;
@@ -415,7 +409,7 @@ pack_pack(ary, fmt)
break;
case '%':
- Fail("% may only be used in unpack");
+ ArgError("% may only be used in unpack");
break;
case 'u':
@@ -457,7 +451,6 @@ encodes(str, s, len)
char hunk[4];
char *p, *pend;
- p = str->ptr + str->len;
*hunk = len + ' ';
str_cat(str, hunk, 1);
while (len > 0) {
@@ -469,6 +462,7 @@ encodes(str, s, len)
s += 3;
len -= 3;
}
+ p = str->ptr;
pend = str->ptr + str->len;
while (p < pend) {
if (*p == ' ')
@@ -512,7 +506,7 @@ pack_unpack(str, fmt)
switch (type) {
case '%':
- Fail("% is not supported(yet)");
+ ArgError("% is not supported(yet)");
break;
case 'A':
@@ -616,7 +610,10 @@ pack_unpack(str, fmt)
if (len > send - s)
len = send - s;
while (len-- > 0) {
- char c = *s++;
+ int c = *s++;
+#ifdef __CHAR_UNSIGNED__
+ if (c > (char)127) c-=256;
+#endif
ary_push(ary, INT2FIX(c));
}
break;
@@ -781,6 +778,7 @@ pack_unpack(str, fmt)
hunk[3] = '\0';
len = (*s++ - ' ') & 077;
total += len;
+
while (len > 0) {
if (s < send && *s >= ' ')
a = (*s++ - ' ') & 077;
@@ -805,10 +803,10 @@ pack_unpack(str, fmt)
ptr += 3;
len -= 3;
}
- if (*s == '\n')
+ if (*s == '\n' || *s == '\r')
s++;
- else if (s[1] == '\n') /* possible checksum byte */
- s += 2;
+ else if (s+1 == send || s[1] == '\n' || s[1] == '\r')
+ s += 2; /* possible checksum byte */
}
RSTRING(str)->len = total;
ary_push(ary, str);
@@ -821,13 +819,13 @@ pack_unpack(str, fmt)
case 'X':
if (len > s - str->ptr)
- Fail("X outside of string");
+ ArgError("X outside of string");
s -= len;
break;
case 'x':
if (len > send - s)
- Fail("x outside of string");
+ ArgError("x outside of string");
s += len;
break;
diff --git a/parse.y b/parse.y
index cdecb958bc..741dd2573b 100644
--- a/parse.y
+++ b/parse.y
@@ -6,7 +6,7 @@
$Date: 1995/01/12 08:54:50 $
created at: Fri May 28 18:02:42 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -26,11 +26,11 @@
#define ID_SCOPE_SHIFT 3
#define ID_SCOPE_MASK 0x07
-#define ID_LOCAL 0x00
-#define ID_INSTANCE 0x01
-#define ID_GLOBAL 0x02
-#define ID_ATTRSET 0x03
-#define ID_CONST 0x04
+#define ID_LOCAL 0x01
+#define ID_INSTANCE 0x02
+#define ID_GLOBAL 0x03
+#define ID_ATTRSET 0x04
+#define ID_CONST 0x05
#define is_id_nonop(id) ((id)>LAST_TOKEN)
#define is_local_id(id) (is_id_nonop(id)&&((id)&ID_SCOPE_MASK)==ID_LOCAL)
@@ -50,6 +50,7 @@ char *sourcefile; /* current source file */
int sourceline; /* current line no. */
static int yylex();
+static int yyerror();
static enum lex_state {
EXPR_BEG, /* ignore newline, +/- is a sign. */
@@ -65,6 +66,7 @@ static ID cur_mid = 0;
static int value_expr();
static NODE *cond();
+static NODE *logop();
static NODE *block_append();
static NODE *list_append();
@@ -90,12 +92,12 @@ static struct RVarmap *dyna_push();
static void dyna_pop();
static int dyna_in_block();
-VALUE dyna_var_ref();
-#define dyna_id(id) dyna_var_ref(id)
+VALUE dyna_var_asgn();
+VALUE dyna_var_defined();
-#define cref_push() NEW_CREF(0)
+#define cref_push() NEW_CREF()
static void cref_pop();
-static NODE *cref_list;
+static NODE *cur_cref;
static void top_local_init();
static void top_local_setup();
@@ -118,46 +120,45 @@ static void top_local_setup();
ENSURE
END
IF
+ UNLESS
THEN
ELSIF
ELSE
CASE
WHEN
WHILE
+ UNTIL
FOR
IN
- REDO
- BREAK
- CONTINUE
+ DO
RETURN
- FAIL
YIELD
SUPER
- RETRY
SELF
NIL
AND
OR
NOT
- _FILE_
- _LINE_
IF_MOD
+ UNLESS_MOD
WHILE_MOD
+ UNTIL_MOD
ALIAS
DEFINED
%token <id> IDENTIFIER FID GVAR IVAR CONSTANT
%token <val> INTEGER FLOAT STRING XSTRING REGEXP
-%token <node> STRING2 XSTRING2 DREGEXP NTH_REF BACK_REF
+%token <node> DSTRING DXSTRING DREGEXP NTH_REF BACK_REF
%type <node> singleton
%type <val> literal numeric
-%type <node> compexpr exprs expr arg primary var_ref
-%type <node> if_tail opt_else case_body cases rescue ensure
-%type <node> call_args call_args0 args args2 opt_args
+%type <node> compexpr exprs expr arg primary command_call method_call
+%type <node> if_tail opt_else case_body cases rescue ensure iterator
+%type <node> call_args call_args0 args args2 opt_args var_ref
%type <node> superclass f_arglist f_args f_optarg f_opt
%type <node> array assoc_list assocs assoc undef_list
-%type <node> mlhs mlhs_head mlhs_tail lhs iter_var opt_iter_var backref
+%type <node> iter_var opt_iter_var iter_block iter_do_block
+%type <node> mlhs mlhs_head mlhs_tail lhs backref
%type <id> variable symbol operation
%type <id> cname fname op rest_arg
%type <num> f_arg
@@ -166,6 +167,7 @@ static void top_local_setup();
%token POW /* ** */
%token CMP /* <=> */
%token EQ /* == */
+%token EQQ /* === */
%token NEQ /* != <> */
%token GEQ /* >= */
%token LEQ /* <= */
@@ -187,14 +189,15 @@ static void top_local_setup();
* precedence table
*/
-%left IF_MOD WHILE_MOD
-%right NOT
+%left IF_MOD UNLESS_MOD WHILE_MOD UNTIL_MOD
%left OR AND
+%right NOT
+%nonassoc DEFINED
%right '=' OP_ASGN
%nonassoc DOT2 DOT3
%left OROP
%left ANDOP
-%nonassoc CMP EQ NEQ MATCH NMATCH
+%nonassoc CMP EQ EQQ NEQ MATCH NMATCH
%left '>' GEQ '<' LEQ
%left '|' '^'
%left '&'
@@ -203,7 +206,6 @@ static void top_local_setup();
%left '*' '/' '%'
%right '!' '~' UPLUS UMINUS
%right POW
-%left COLON2
%token LAST_TOKEN
@@ -211,32 +213,29 @@ static void top_local_setup();
program : {
lex_state = EXPR_BEG;
top_local_init();
+ NEW_CREF0(); /* initialize constant c-ref */
}
compexpr
{
eval_tree = block_append(eval_tree, $2);
top_local_setup();
+ cur_cref = 0;
}
-compexpr : exprs opt_term
+compexpr : exprs opt_terms
exprs : /* none */
{
- $$ = Qnil;
+ $$ = 0;
}
| expr
- | exprs term expr
+ | exprs terms expr
{
$$ = block_append($1, $3);
}
- | exprs error
- {
- lex_state = EXPR_BEG;
- }
- expr
+ | error expr
{
- yyerrok;
- $$ = block_append($1, $4);
+ $$ = $2;
}
expr : mlhs '=' args2
@@ -253,41 +252,18 @@ expr : mlhs '=' args2
{
value_expr($2);
if (!cur_mid && !in_single)
- Error("return appeared outside of method");
+ yyerror("return appeared outside of method");
$$ = NEW_RET($2);
}
- | FAIL args2
- {
- value_expr($2);
- $$ = NEW_FAIL($2);
- }
| YIELD args2
{
value_expr($2);
$$ = NEW_YIELD($2);
}
- | DEFINED {in_defined = 1;} arg
- {
- in_defined = 0;
- $$ = NEW_DEFINED($3);
- }
- | operation call_args0
- {
- $$ = NEW_FCALL($1, $2);
- }
- | primary '.' operation call_args0
- {
- value_expr($1);
- $$ = NEW_CALL($1, $3, $4);
- }
- | SUPER call_args0
- {
- if (!cur_mid && !in_single && !in_defined)
- Error("super called outside of method");
- $$ = NEW_SUPER($2);
- }
- | UNDEF undef_list
+ | command_call
+ | iterator iter_do_block
{
+ $2->nd_iter = $1;
$$ = $2;
}
| ALIAS fname {lex_state = EXPR_FNAME;} fname
@@ -297,38 +273,76 @@ expr : mlhs '=' args2
| expr IF_MOD expr
{
value_expr($3);
- $$ = NEW_IF(cond($3), $1, Qnil);
+ $$ = NEW_IF(cond($3), $1, 0);
+ }
+ | expr UNLESS_MOD expr
+ {
+ value_expr($3);
+ $$ = NEW_UNLESS(cond($3), $1, 0);
}
| expr WHILE_MOD expr
{
value_expr($3);
if (nd_type($1) == NODE_BEGIN) {
- $$ = NEW_WHILE2(cond($3), $1);
+ $$ = NEW_WHILE(cond($3), $1->nd_body, 0);
}
else {
- $$ = NEW_WHILE(cond($3), $1);
+ $$ = NEW_WHILE(cond($3), $1, 1);
+ }
+ }
+ | expr UNTIL_MOD expr
+ {
+ value_expr($3);
+ if (nd_type($1) == NODE_BEGIN) {
+ $$ = NEW_UNTIL(cond($3), $1->nd_body, 0);
+ }
+ else {
+ $$ = NEW_UNTIL(cond($3), $1, 1);
}
}
| expr AND expr
{
- value_expr($1);
- $$ = NEW_AND(cond($1), cond($3));
+ $$ = logop(NODE_AND, $1, $3);
}
| expr OR expr
{
- value_expr($1);
- $$ = NEW_OR(cond($1), cond($3));
+ $$ = logop(NODE_OR, $1, $3);
}
| NOT expr
{
value_expr($2);
$$ = NEW_NOT(cond($2));
}
+ | '!' command_call
+ {
+ value_expr($2);
+ $$ = NEW_NOT(cond($2));
+ }
| arg
+command_call : operation call_args0
+ {
+ $$ = NEW_FCALL($1, $2);
+ }
+ | primary '.' operation call_args0
+ {
+ value_expr($1);
+ $$ = NEW_CALL($1, $3, $4);
+ }
+ | SUPER call_args0
+ {
+ if (!cur_mid && !in_single && !in_defined)
+ yyerror("super called outside of method");
+ $$ = NEW_SUPER($2);
+ }
+ | UNDEF undef_list
+ {
+ $$ = $2;
+ }
+
mlhs : mlhs_head
{
- $$ = NEW_MASGN(NEW_LIST($1), Qnil);
+ $$ = NEW_MASGN(NEW_LIST($1), 0);
}
| mlhs_head STAR lhs
{
@@ -336,51 +350,55 @@ mlhs : mlhs_head
}
| mlhs_head mlhs_tail
{
- $$ = NEW_MASGN(list_concat(NEW_LIST($1),$2),Qnil);
+ $$ = NEW_MASGN(list_concat(NEW_LIST($1),$2), 0);
}
- | mlhs_head mlhs_tail comma STAR lhs
+ | mlhs_head mlhs_tail ',' STAR lhs
{
$$ = NEW_MASGN(list_concat(NEW_LIST($1),$2),$5);
}
+ | STAR lhs
+ {
+ $$ = NEW_MASGN(0, $2);
+ }
-mlhs_head : lhs comma
+mlhs_head : lhs ','
mlhs_tail : lhs
{
$$ = NEW_LIST($1);
}
- | mlhs_tail comma lhs
+ | mlhs_tail ',' lhs
{
$$ = list_append($1, $3);
}
lhs : variable
{
- $$ = asignable($1, Qnil);
+ $$ = asignable($1, 0);
}
- | primary '[' opt_args opt_nl rbracket
+ | primary '[' opt_args opt_nl ']'
{
- $$ = aryset($1, $3, Qnil);
+ $$ = aryset($1, $3, 0);
}
| primary '.' IDENTIFIER
{
- $$ = attrset($1, $3, Qnil);
+ $$ = attrset($1, $3, 0);
}
| backref
{
backref_error($1);
- $$ = Qnil;
+ $$ = 0;
}
cname : IDENTIFIER
{
- Error("class/module name must be CONSTANT");
+ yyerror("class/module name must be CONSTANT");
}
| CONSTANT
fname : IDENTIFIER
- | FID
| CONSTANT
+ | FID
| op
{
lex_state = EXPR_END;
@@ -391,9 +409,9 @@ undef_list : fname
{
$$ = NEW_UNDEF($1);
}
- | undef_list ',' fname
+ | undef_list ',' {lex_state = EXPR_FNAME;} fname
{
- $$ = block_append($1, NEW_UNDEF($3));
+ $$ = block_append($1, NEW_UNDEF($4));
}
op : DOT2 { $$ = DOT2; }
@@ -402,6 +420,7 @@ op : DOT2 { $$ = DOT2; }
| '&' { $$ = '&'; }
| CMP { $$ = CMP; }
| EQ { $$ = EQ; }
+ | EQQ { $$ = EQQ; }
| MATCH { $$ = MATCH; }
| '>' { $$ = '>'; }
| GEQ { $$ = GEQ; }
@@ -421,13 +440,14 @@ op : DOT2 { $$ = DOT2; }
| UMINUS { $$ = UPLUS; }
| AREF { $$ = AREF; }
| ASET { $$ = ASET; }
+ | '`' { $$ = '`'; }
arg : variable '=' arg
{
value_expr($3);
$$ = asignable($1, $3);
}
- | primary '[' opt_args opt_nl rbracket '=' arg
+ | primary '[' opt_args opt_nl ']' '=' arg
{
$$ = aryset($1, $3, $7);
}
@@ -439,29 +459,16 @@ arg : variable '=' arg
{
value_expr($3);
backref_error($1);
- $$ = Qnil;
+ $$ = 0;
}
| variable OP_ASGN arg
{
- NODE *val;
-
value_expr($3);
- if (is_local_id($1)) {
- if (local_id($1)) val = NEW_LVAR($1);
- else val = NEW_DVAR($1);
- }
- else if (is_global_id($1)) {
- val = NEW_GVAR($1);
- }
- else if (is_instance_id($1)) {
- val = NEW_IVAR($1);
- }
- else {
- val = NEW_CVAR($1);
- }
- $$ = asignable($1, call_op(val, $2, 1, $3));
+ if (is_local_id($1)&&!local_id($1)&&dyna_in_block())
+ dyna_var_asgn($1, TRUE);
+ $$ = asignable($1, call_op(gettable($1), $2, 1, $3));
}
- | primary '[' opt_args opt_nl rbracket OP_ASGN arg
+ | primary '[' opt_args opt_nl ']' OP_ASGN arg
{
NODE *args = NEW_LIST($7);
@@ -470,12 +477,12 @@ arg : variable '=' arg
}
| primary '.' IDENTIFIER OP_ASGN arg
{
- $$ = NEW_OP_ASGN2($1, $4, $5);
+ $$ = NEW_OP_ASGN2($1, $3, $4, $5);
}
| backref OP_ASGN arg
{
backref_error($1);
- $$ = Qnil;
+ $$ = 0;
}
| arg DOT2 arg
{
@@ -553,6 +560,10 @@ arg : variable '=' arg
{
$$ = call_op($1, EQ, 1, $3);
}
+ | arg EQQ arg
+ {
+ $$ = call_op($1, EQQ, 1, $3);
+ }
| arg NEQ arg
{
$$ = NEW_NOT(call_op($1, EQ, 1, $3));
@@ -582,19 +593,18 @@ arg : variable '=' arg
{
$$ = call_op($1, RSHFT, 1, $3);
}
- | arg COLON2 cname
- {
- $$ = NEW_COLON2($1, $3);
- }
| arg ANDOP arg
{
- value_expr($1);
- $$ = NEW_AND(cond($1), cond($3));
+ $$ = logop(NODE_AND, $1, $3);
}
| arg OROP arg
{
- value_expr($1);
- $$ = NEW_OR(cond($1), cond($3));
+ $$ = logop(NODE_OR, $1, $3);
+ }
+ | DEFINED {in_defined = 1;} arg
+ {
+ in_defined = 0;
+ $$ = NEW_DEFINED($3);
}
| primary
{
@@ -603,25 +613,34 @@ arg : variable '=' arg
call_args : /* none */
{
- $$ = Qnil;
+ $$ = 0;
}
| call_args0 opt_nl
call_args0 : args
+ | command_call
+ {
+ value_expr($1);
+ $$ = NEW_LIST($1);
+ }
| assocs
{
$$ = NEW_LIST(NEW_HASH($1));
}
- | args comma assocs
+ | args ',' command_call
+ {
+ $$ = list_append($1, $3);
+ }
+ | args ',' assocs
{
$$ = list_append($1, NEW_HASH($3));
}
- | args comma assocs comma STAR arg
+ | args ',' assocs ',' STAR arg
{
$$ = list_append($1, NEW_HASH($3));
$$ = call_op($$, '+', 1, $6);
}
- | args comma STAR arg
+ | args ',' STAR arg
{
$$ = call_op($1, '+', 1, $4);
}
@@ -632,7 +651,7 @@ call_args0 : args
opt_args : /* none */
{
- $$ = Qnil;
+ $$ = 0;
}
| args
@@ -641,7 +660,7 @@ args : arg
value_expr($1);
$$ = NEW_LIST($1);
}
- | args comma arg
+ | args ',' arg
{
value_expr($3);
$$ = list_append($1, $3);
@@ -649,7 +668,7 @@ args : arg
args2 : args
{
- if ($1 && $1->nd_next == Qnil) {
+ if ($1 && $1->nd_next == 0) {
$$ = $1->nd_head;
}
else {
@@ -659,7 +678,7 @@ args2 : args
array : /* none */
{
- $$ = Qnil;
+ $$ = 0;
}
| args trailer
@@ -667,85 +686,57 @@ primary : literal
{
$$ = NEW_LIT($1);
}
+ | primary COLON2 cname
+ {
+ $$ = NEW_COLON2($1, $3);
+ }
| STRING
{
$$ = NEW_STR($1);
}
- | STRING2
+ | DSTRING
| XSTRING
{
$$ = NEW_XSTR($1);
}
- | XSTRING2
+ | DXSTRING
| DREGEXP
| var_ref
| backref
- | SUPER '(' call_args rparen
+ | SUPER '(' call_args ')'
{
if (!cur_mid && !in_single && !in_defined)
- Error("super called outside of method");
+ yyerror("super called outside of method");
$$ = NEW_SUPER($3);
}
| SUPER
{
if (!cur_mid && !in_single && !in_defined)
- Error("super called outside of method");
+ yyerror("super called outside of method");
$$ = NEW_ZSUPER();
}
- | primary '[' opt_args opt_nl rbracket
+ | primary '[' opt_args opt_nl ']'
{
value_expr($1);
$$ = NEW_CALL($1, AREF, $3);
}
- | LBRACK array rbracket
+ | LBRACK array ']'
{
- if ($2 == Qnil)
+ if ($2 == 0)
$$ = NEW_ZARRAY(); /* zero length array*/
else {
$$ = $2;
}
}
- | LBRACE assoc_list rbrace
+ | LBRACE assoc_list '}'
{
$$ = NEW_HASH($2);
}
- | REDO
- {
- $$ = NEW_REDO();
- }
- | BREAK
- {
- $$ = NEW_BREAK();
- }
- | CONTINUE
- {
- $$ = NEW_CONT();
- }
- | RETRY
- {
- $$ = NEW_RETRY();
- }
| RETURN
{
if (!cur_mid && !in_single)
- Error("return appeared outside of method");
- $$ = NEW_RET(Qnil);
- }
- | FAIL '(' args2 ')'
- {
- if (nd_type($3) == NODE_ARRAY) {
- Error("wrong number of argument to fail(0 or 1)");
- }
- value_expr($3);
- $$ = NEW_FAIL($3);
- }
- | FAIL '(' ')'
- {
- $$ = NEW_FAIL(Qnil);
- }
- | FAIL
- {
- $$ = NEW_FAIL(Qnil);
+ yyerror("return appeared outside of method");
+ $$ = NEW_RET(0);
}
| YIELD '(' args2 ')'
{
@@ -754,48 +745,31 @@ primary : literal
}
| YIELD '(' ')'
{
- $$ = NEW_YIELD(Qnil);
+ $$ = NEW_YIELD(0);
}
| YIELD
{
- $$ = NEW_YIELD(Qnil);
- }
- | DEFINED '(' {in_defined = 1;} arg ')'
+ $$ = NEW_YIELD(0);
+ }
+ | DEFINED '(' {in_defined = 1;} expr ')'
{
in_defined = 0;
$$ = NEW_DEFINED($4);
}
- | primary '{'
- {
- $<vars>$ = dyna_push();
- }
- opt_iter_var
- compexpr rbrace
- {
- if (nd_type($1) == NODE_LVAR
- || nd_type($1) == NODE_CVAR) {
- $1 = NEW_FCALL($1->nd_vid, Qnil);
- }
- $$ = NEW_ITER($4, $1, $5);
- dyna_pop($<vars>3);
- }
| FID
{
- $$ = NEW_FCALL($1, Qnil);
- }
- | operation '(' call_args rparen
- {
- $$ = NEW_FCALL($1, $3);
+ $$ = NEW_FCALL($1, 0);
}
- | primary '.' operation '(' call_args rparen
+ | operation iter_block
{
- value_expr($1);
- $$ = NEW_CALL($1, $3, $5);
+ $2->nd_iter = NEW_FCALL($1, 0);
+ $$ = $2;
}
- | primary '.' operation
+ | method_call
+ | method_call iter_block
{
- value_expr($1);
- $$ = NEW_CALL($1, $3, Qnil);
+ $2->nd_iter = $1;
+ $$ = $2;
}
| IF expr then
compexpr
@@ -805,10 +779,23 @@ primary : literal
value_expr($2);
$$ = NEW_IF(cond($2), $4, $5);
}
+ | UNLESS expr then
+ compexpr
+ opt_else
+ END
+ {
+ value_expr($2);
+ $$ = NEW_UNLESS(cond($2), $4, $5);
+ }
| WHILE expr term compexpr END
{
value_expr($2);
- $$ = NEW_WHILE(cond($2), $4);
+ $$ = NEW_WHILE(cond($2), $4, 1);
+ }
+ | UNTIL expr term compexpr END
+ {
+ value_expr($2);
+ $$ = NEW_UNTIL(cond($2), $4, 1);
}
| CASE compexpr
case_body
@@ -828,16 +815,22 @@ primary : literal
ensure
END
{
- $$ = NEW_BEGIN($2, $3, $4);
+ if (!$3 && !$4)
+ $$ = NEW_BEGIN($2);
+ else {
+ if ($3) $2 = NEW_RESCUE($2, $3);
+ if ($4) $2 = NEW_ENSURE($2, $4);
+ $$ = $2;
+ }
}
- | LPAREN exprs opt_nl rparen
+ | LPAREN compexpr ')'
{
$$ = $2;
}
| CLASS cname superclass
{
if (cur_mid || in_single)
- Error("class definition in method body");
+ yyerror("class definition in method body");
class_nest++;
cref_push();
@@ -854,7 +847,7 @@ primary : literal
| MODULE cname
{
if (cur_mid || in_single)
- Error("module definition in method body");
+ yyerror("module definition in method body");
class_nest++;
cref_push();
local_push();
@@ -870,7 +863,7 @@ primary : literal
| DEF fname
{
if (cur_mid || in_single)
- Error("nested method definition");
+ yyerror("nested method definition");
cur_mid = $2;
local_push();
}
@@ -882,7 +875,7 @@ primary : literal
local_pop();
cur_mid = 0;
}
- | DEF singleton '.' fname
+ | DEF singleton '.' {lex_state = EXPR_FNAME;} fname
{
value_expr($2);
in_single++;
@@ -893,7 +886,7 @@ primary : literal
compexpr
END
{
- $$ = NEW_DEFS($2, $4, $6, $7);
+ $$ = NEW_DEFS($2, $5, $7, $8);
local_pop();
in_single--;
}
@@ -913,7 +906,7 @@ if_tail : opt_else
opt_else : /* none */
{
- $$ = Qnil;
+ $$ = 0;
}
| ELSE compexpr
{
@@ -925,21 +918,79 @@ iter_var : lhs
opt_iter_var : /* node */
{
- $$ = Qnil;
+ $$ = 0;
}
| '|' /* none */ '|'
{
- $$ = Qnil;
+ $$ = 0;
}
| OROP
{
- $$ = Qnil;
+ $$ = 0;
}
| '|' iter_var '|'
{
$$ = $2;
}
+iter_do_block : DO
+ {
+ $<vars>$ = dyna_push();
+ }
+ opt_iter_var
+ compexpr
+ END
+ {
+ $$ = NEW_ITER($3, 0, $4);
+ dyna_pop($<vars>2);
+ }
+
+iter_block : '{'
+ {
+ $<vars>$ = dyna_push();
+ }
+ opt_iter_var
+ compexpr '}'
+ {
+ $$ = NEW_ITER($3, 0, $4);
+ dyna_pop($<vars>2);
+ }
+
+iterator : IDENTIFIER
+ {
+ $$ = NEW_FCALL($1, 0);
+ }
+ | CONSTANT
+ {
+ $$ = NEW_FCALL($1, 0);
+ }
+ | FID
+ {
+ $$ = NEW_FCALL($1, 0);
+ }
+ | method_call
+ | command_call
+
+method_call : operation '(' call_args ')'
+ {
+ $$ = NEW_FCALL($1, $3);
+ }
+ | primary '.' operation '(' call_args ')'
+ {
+ value_expr($1);
+ $$ = NEW_CALL($1, $3, $5);
+ }
+ | primary '.' operation
+ {
+ value_expr($1);
+ $$ = NEW_CALL($1, $3, 0);
+ }
+ | primary COLON2 operation '(' call_args ')'
+ {
+ value_expr($1);
+ $$ = NEW_CALL($1, $3, $5);
+ }
+
case_body : WHEN args then
compexpr
cases
@@ -950,21 +1001,19 @@ case_body : WHEN args then
cases : opt_else
| case_body
-rescue : /* none */
+rescue : RESCUE opt_args term compexpr
+ rescue
{
- $$ = Qnil;
+ $$ = NEW_RESBODY($2, $4, $5);
}
- | RESCUE compexpr
+ | /* none */
{
- if ($2 == Qnil)
- $$ = (NODE*)1;
- else
- $$ = $2;
+ $$ = 0;
}
ensure : /* none */
{
- $$ = Qnil;
+ $$ = 0;
}
| ENSURE compexpr
{
@@ -972,9 +1021,9 @@ ensure : /* none */
}
literal : numeric
- | SYMBEG symbol
+ | SYMBEG {lex_state = EXPR_FNAME;} symbol
{
- $$ = INT2FIX($2);
+ $$ = INT2FIX($3);
}
| REGEXP
@@ -1008,9 +1057,9 @@ backref : NTH_REF
superclass : term
{
- $$ = Qnil;
+ $$ = 0;
}
- | colon
+ | '<'
{
lex_state = EXPR_BEG;
}
@@ -1018,10 +1067,12 @@ superclass : term
{
$$ = $3;
}
+ | error term {yyerrok;}
-f_arglist : '(' f_args rparen
+f_arglist : '(' f_args ')'
{
$$ = $2;
+ lex_state = EXPR_BEG;
}
| f_args term
{
@@ -1036,15 +1087,15 @@ f_args : /* no arg */
{
$$ = NEW_ARGS($1, 0, -1);
}
- | f_arg comma rest_arg
+ | f_arg ',' rest_arg
{
$$ = NEW_ARGS($1, 0, $3);
}
- | f_arg comma f_optarg
+ | f_arg ',' f_optarg
{
$$ = NEW_ARGS($1, $3, -1);
}
- | f_arg comma f_optarg comma rest_arg
+ | f_arg ',' f_optarg ',' rest_arg
{
$$ = NEW_ARGS($1, $3, $5);
}
@@ -1052,7 +1103,7 @@ f_args : /* no arg */
{
$$ = NEW_ARGS(0, $1, -1);
}
- | f_optarg comma rest_arg
+ | f_optarg ',' rest_arg
{
$$ = NEW_ARGS(0, $1, $3);
}
@@ -1060,23 +1111,18 @@ f_args : /* no arg */
{
$$ = NEW_ARGS(0, 0, $1);
}
- | error
- {
- lex_state = EXPR_BEG;
- $$ = NEW_ARGS(0, 0, -1);
- }
f_arg : IDENTIFIER
{
if (!is_local_id($1))
- Error("formal argument must be local variable");
+ yyerror("formal argument must be local variable");
local_cnt($1);
$$ = 1;
}
- | f_arg comma IDENTIFIER
+ | f_arg ',' IDENTIFIER
{
if (!is_local_id($3))
- Error("formal argument must be local variable");
+ yyerror("formal argument must be local variable");
local_cnt($3);
$$ += 1;
}
@@ -1084,7 +1130,7 @@ f_arg : IDENTIFIER
f_opt : IDENTIFIER '=' arg
{
if (!is_local_id($1))
- Error("formal argument must be local variable");
+ yyerror("formal argument must be local variable");
$$ = asignable($1, $3);
}
@@ -1092,7 +1138,7 @@ f_optarg : f_opt
{
$$ = NEW_BLOCK($1);
}
- | f_optarg comma f_opt
+ | f_optarg ',' f_opt
{
$$ = block_append($1, $3);
}
@@ -1100,7 +1146,7 @@ f_optarg : f_opt
rest_arg : STAR IDENTIFIER
{
if (!is_local_id($2))
- Error("rest argument must be local variable");
+ yyerror("rest argument must be local variable");
$$ = local_cnt($2);
}
@@ -1110,25 +1156,25 @@ singleton : var_ref
$$ = NEW_SELF();
}
else if (nd_type($1) == NODE_NIL) {
- Error("Can't define single method for nil.");
- $$ = Qnil;
+ yyerror("Can't define single method for nil.");
+ $$ = 0;
}
else {
$$ = $1;
}
}
- | LPAREN expr opt_nl rparen
+ | LPAREN expr opt_nl ')'
{
switch (nd_type($2)) {
case NODE_STR:
- case NODE_STR2:
+ case NODE_DSTR:
case NODE_XSTR:
- case NODE_XSTR2:
+ case NODE_DXSTR:
case NODE_DREGX:
case NODE_LIT:
case NODE_ARRAY:
case NODE_ZARRAY:
- Error("Can't define single method for literals.");
+ yyerror("Can't define single method for literals.");
default:
break;
}
@@ -1137,7 +1183,7 @@ singleton : var_ref
assoc_list : /* none */
{
- $$ = Qnil;
+ $$ = 0;
}
| assocs trailer
{
@@ -1146,13 +1192,13 @@ assoc_list : /* none */
| args trailer
{
if ($1->nd_alen%2 != 0) {
- Error("odd number list for Hash");
+ yyerror("odd number list for Hash");
}
$$ = $1;
}
assocs : assoc
- | assocs comma assoc
+ | assocs ',' assoc
{
$$ = list_concat($1, $3);
}
@@ -1163,32 +1209,24 @@ assoc : arg ASSOC arg
}
operation : IDENTIFIER
+ | CONSTANT
| FID
-opt_term : /* none */
- | term
+opt_terms : /* none */
+ | terms
opt_nl : /* none */
- | nl
+ | '\n'
trailer : /* none */
- | nl
- | comma
-
-term : sc
- | nl
+ | '\n'
+ | ','
-sc : ';' { yyerrok; }
-nl : '\n' { yyerrok; }
-
-colon : ':'
- | SYMBEG
-
-rparen : ')' { yyerrok; }
-rbracket : ']' { yyerrok; }
-rbrace : '}' { yyerrok; }
-comma : ',' { yyerrok; }
+term : ';' {yyerrok;}
+ | '\n'
+terms : term
+ | terms ';' {yyerrok;}
%%
#include <ctype.h>
#include <sys/types.h>
@@ -1206,51 +1244,138 @@ VALUE newfloat();
VALUE newinteger();
char *strdup();
-static NODE *var_extend();
+static NODE *str_extend();
#define LEAVE_BS 1
+static VALUE lex_input; /* non-nil if File */
+static char *lex_pbeg;
static char *lex_p;
-static int lex_len;
+static char *lex_pend;
-void
-lex_setsrc(src, ptr, len)
- char *src;
- char *ptr;
+static int
+yyerror(msg)
+ char *msg;
+{
+ char *p, *pe, *buf;
+ int len, i;
+
+ Error("%s", msg);
+ p = lex_p;
+ while (lex_pbeg <= p) {
+ if (*p == '\n') break;
+ p--;
+ }
+ p++;
+
+ pe = lex_p;
+ while (pe < lex_pend) {
+ if (*pe == '\n') break;
+ pe++;
+ }
+
+ len = pe - p;
+ if (len > 4) {
+ buf = ALLOCA_N(char, len+2);
+ MEMCPY(buf, p, char, len);
+ buf[len] = '\0';
+ Error_Append("%s", buf);
+
+ i = lex_p - p;
+ p = buf; pe = p + len;
+
+ while (p < pe) {
+ if (*p != '\t') *p = ' ';
+ p++;
+ }
+ buf[i] = '^';
+ buf[i+1] = '\0';
+ Error_Append("%s", buf);
+ }
+
+ return 0;
+}
+
+static int newline_seen;
+
+static NODE*
+yycompile(f)
+ char *f;
+{
+ int n;
+
+ newline_seen = 0;
+ sourcefile = strdup(f);
+ eval_tree = 0;
+ n = yyparse();
+ if (n == 0) return eval_tree;
+
+ return 0;
+}
+
+NODE*
+compile_string(f, s, len)
+ char *f, *s;
int len;
{
- sourcefile = strdup(src);
+ lex_pbeg = lex_p = s;
+ lex_pend = s + len;
+ lex_input = 0;
+ if (!sourcefile || strcmp(f, sourcefile)) /* not in eval() */
+ sourceline = 1;
- sourceline = 1;
- lex_p = ptr;
- lex_len = len;
+ return yycompile(f);
}
-#define nextc() ((--lex_len>=0)?(*lex_p++):-1)
-#define pushback() (lex_len++, lex_p--)
-
-#define SCAN_HEX(i) \
-do { \
- int numlen; \
- i=scan_hex(lex_p, 2, &numlen); \
- lex_p += numlen; \
- lex_len -= numlen; \
-} while (0)
-
-#define SCAN_OCT(i) \
-do { \
- int numlen; \
- i=scan_oct(lex_p, 3, &numlen); \
- lex_p += numlen; \
- lex_len -= numlen; \
-} while (0)
+NODE*
+compile_file(f, file, start)
+ char *f;
+ VALUE file;
+ int start;
+{
+ lex_input = file;
+ lex_pbeg = lex_p = lex_pend = 0;
+ sourceline = start;
+
+ return yycompile(f);
+}
+
+int
+nextc()
+{
+ int c;
+
+ if (lex_p == lex_pend) {
+ if (lex_input) {
+ VALUE v = io_gets(lex_input);
+
+ if (NIL_P(v)) return -1;
+ lex_pbeg = lex_p = RSTRING(v)->ptr;
+ lex_pend = lex_p + RSTRING(v)->len;
+ }
+ else {
+ return -1;
+ }
+ }
+ c = *lex_p++;
+
+ return c;
+}
+
+void
+pushback(c)
+ int c;
+{
+ if (c == -1) return;
+ lex_p--;
+}
#define tokfix() (tokenbuf[tokidx]='\0')
#define tok() tokenbuf
#define toklen() tokidx
#define toklast() (tokidx>0?tokenbuf[tokidx-1]:0)
-char *
+char*
newtok()
{
tokidx = 0;
@@ -1307,12 +1432,38 @@ read_escape()
case '0': case '1': case '2': case '3': /* octal constant */
case '4': case '5': case '6': case '7':
- pushback();
- SCAN_OCT(c);
+ pushback(c);
+ {
+ char buf[3];
+ int i;
+
+ for (i=0; i<3; i++) {
+ buf[i] = nextc();
+ if (buf[i] == -1) goto eof;
+ if (buf[i] < '0' || '7' < buf[i]) {
+ pushback(buf[i]);
+ break;
+ }
+ }
+ c = scan_oct(buf, i+1, &i);
+ }
return c;
case 'x': /* hex constant */
- SCAN_HEX(c);
+ {
+ char buf[2];
+ int i;
+
+ for (i=0; i<2; i++) {
+ buf[i] = nextc();
+ if (buf[i] == -1) goto eof;
+ if (!isxdigit(buf[i])) {
+ pushback(buf[i]);
+ break;
+ }
+ }
+ c = scan_hex(buf, i+1, &i);
+ }
return c;
case 'b': /* backspace */
@@ -1320,7 +1471,8 @@ read_escape()
case 'M':
if ((c = nextc()) != '-') {
- Error("Invalid escape character syntax");
+ yyerror("Invalid escape character syntax");
+ pushback(c);
return '\0';
}
if ((c = nextc()) == '\\') {
@@ -1333,7 +1485,8 @@ read_escape()
case 'C':
if ((c = nextc()) != '-') {
- Error("Invalid escape character syntax");
+ yyerror("Invalid escape character syntax");
+ pushback(c);
return '\0';
}
case 'c':
@@ -1348,8 +1501,7 @@ read_escape()
eof:
case -1:
- Error("Invalid escape character syntax");
- pushback();
+ yyerror("Invalid escape character syntax");
return '\0';
default:
@@ -1358,16 +1510,23 @@ read_escape()
}
static int
-parse_regx()
+parse_regx(term)
+ int term;
{
register int c;
int casefold = 0;
int in_brack = 0;
int re_start = sourceline;
- NODE *list = Qnil;
+ int once = 0;
+ int quote = 0;
+ NODE *list = 0;
newtok();
while ((c = nextc()) != -1) {
+ if (!in_brack && c == term) {
+ goto regx_end;
+ }
+
switch (c) {
case '[':
in_brack = 1;
@@ -1377,7 +1536,7 @@ parse_regx()
break;
case '#':
- list = var_extend(list, '/');
+ list = str_extend(list, term);
if (list == (NODE*)-1) return 0;
continue;
@@ -1405,6 +1564,11 @@ parse_regx()
tokadd(c);
break;
+ case '^': /* no \^ escape in regexp */
+ tokadd('\\');
+ tokadd('^');
+ break;
+
case 'b':
if (!in_brack) {
tokadd('\\');
@@ -1413,22 +1577,44 @@ parse_regx()
}
/* fall through */
default:
- pushback();
- tokadd('\\');
- tokadd(read_escape());
+ if (c == '\n') {
+ sourceline++;
+ }
+ else if (c == term) {
+ tokadd(c);
+ }
+ else {
+ pushback(c);
+ tokadd('\\');
+ tokadd(read_escape());
+ }
}
continue;
- case '/': /* end of the regexp */
- if (in_brack)
- break;
+ case -1:
+ Error("unterminated regexp");
+ return 0;
- if ('i' == nextc()) {
- casefold = 1;
+ default:
+ if (ismbchar(c)) {
+ tokadd(c);
+ c = nextc();
}
- else {
- casefold = 0;
- pushback();
+ break;
+
+ regx_end:
+ for (;;) {
+ c = nextc();
+ if (c == 'i') {
+ casefold = 1;
+ }
+ else if (c == 'o') {
+ once = 1;
+ }
+ else {
+ pushback(c);
+ break;
+ }
}
tokfix();
@@ -1438,8 +1624,8 @@ parse_regx()
VALUE ss = str_new(tok(), toklen());
list_append(list, NEW_STR(ss));
}
- nd_set_type(list, NODE_DREGX);
- if (casefold) list->nd_cflag = 1;
+ nd_set_type(list, once?NODE_DREGX_ONCE:NODE_DREGX);
+ list->nd_cflag = casefold;
yylval.node = list;
return DREGEXP;
}
@@ -1447,16 +1633,6 @@ parse_regx()
yylval.val = reg_new(tok(), toklen(), casefold);
return REGEXP;
}
- case -1:
- Error("unterminated regexp");
- return 0;
-
- default:
- if (ismbchar(c)) {
- tokadd(c);
- c = nextc();
- }
- break;
}
tokadd(c);
}
@@ -1465,16 +1641,18 @@ parse_regx()
}
static int
-parse_string(term)
- int term;
+parse_string(func,term)
+ int func, term;
{
int c;
- NODE *list = Qnil;
+ NODE *list = 0;
int strstart;
strstart = sourceline;
newtok();
+
while ((c = nextc()) != term) {
+ str_retry:
if (c == -1) {
unterm_str:
sourceline = strstart;
@@ -1489,7 +1667,7 @@ parse_string(term)
sourceline++;
}
else if (c == '#') {
- list = var_extend(list, term);
+ list = str_extend(list, term);
if (list == (NODE*)-1) goto unterm_str;
continue;
}
@@ -1502,34 +1680,89 @@ parse_string(term)
tokadd(c);
}
else {
- pushback();
- if (term != '"') tokadd('\\');
+ pushback(c);
+ if (func != '"') tokadd('\\');
tokadd(read_escape());
}
continue;
}
tokadd(c);
}
+
tokfix();
lex_state = EXPR_END;
- if (list == Qnil) {
- yylval.val = str_new(tok(), toklen());
- return (term == '`') ? XSTRING : STRING;
- }
- else {
+ if (list) {
if (toklen() > 0) {
VALUE ss = str_new(tok(), toklen());
list_append(list, NEW_STR(ss));
}
yylval.node = list;
- if (term == '`') {
- nd_set_type(list, NODE_XSTR2);
- return XSTRING2;
+ if (func == '`') {
+ nd_set_type(list, NODE_DXSTR);
+ return DXSTRING;
}
else {
- return STRING2;
+ return DSTRING;
}
}
+ else {
+ yylval.val = str_new(tok(), toklen());
+ return (func == '`') ? XSTRING : STRING;
+ }
+}
+
+static int
+parse_qstring(term)
+ int term;
+{
+ int quote = 0;
+ int strstart;
+ int c;
+
+ strstart = sourceline;
+ newtok();
+ while ((c = nextc()) != term) {
+ qstr_retry:
+ if (c == -1) {
+ sourceline = strstart;
+ Error("unterminated string meets end of file");
+ return 0;
+ }
+ if (ismbchar(c)) {
+ tokadd(c);
+ c = nextc();
+ }
+ else if (c == '\n') {
+ sourceline++;
+ }
+ else if (c == '\\') {
+ c = nextc();
+ switch (c) {
+ case '\n':
+ sourceline++;
+ continue;
+
+ case '\\':
+ c = '\\';
+ break;
+
+ case '\'':
+ if (term == '\'') {
+ c = '\'';
+ break;
+ }
+ /* fall through */
+ default:
+ tokadd('\\');
+ }
+ }
+ tokadd(c);
+ }
+
+ tokfix();
+ yylval.val = str_new(tok(), toklen());
+ lex_state = EXPR_END;
+ return STRING;
}
#define LAST(v) ((v)-1 + sizeof(v)/sizeof(v[0]))
@@ -1540,22 +1773,18 @@ static struct kwtable {
enum lex_state state;
} kwtable [] = {
"__END__", 0, EXPR_BEG,
- "__FILE__", _FILE_, EXPR_END,
- "__LINE__", _LINE_, EXPR_END,
"alias", ALIAS, EXPR_FNAME,
"and", AND, EXPR_BEG,
"begin", BEGIN, EXPR_BEG,
- "break", BREAK, EXPR_END,
"case", CASE, EXPR_BEG,
"class", CLASS, EXPR_BEG,
- "continue", CONTINUE, EXPR_END,
"def", DEF, EXPR_FNAME,
"defined?", DEFINED, EXPR_END,
+ "do", DO, EXPR_BEG,
"else", ELSE, EXPR_BEG,
"elsif", ELSIF, EXPR_BEG,
"end", END, EXPR_END,
"ensure", ENSURE, EXPR_BEG,
- "fail", FAIL, EXPR_END,
"for", FOR, EXPR_BEG,
"if", IF, EXPR_BEG,
"in", IN, EXPR_BEG,
@@ -1563,14 +1792,14 @@ static struct kwtable {
"nil", NIL, EXPR_END,
"not", NOT, EXPR_BEG,
"or", OR, EXPR_BEG,
- "redo", REDO, EXPR_END,
- "rescue", RESCUE, EXPR_BEG,
- "retry", RETRY, EXPR_END,
+ "rescue", RESCUE, EXPR_MID,
"return", RETURN, EXPR_MID,
"self", SELF, EXPR_END,
"super", SUPER, EXPR_END,
"then", THEN, EXPR_BEG,
"undef", UNDEF, EXPR_FNAME,
+ "unless", UNLESS, EXPR_BEG,
+ "until", UNTIL, EXPR_BEG,
"when", WHEN, EXPR_BEG,
"while", WHILE, EXPR_BEG,
"yield", YIELD, EXPR_END,
@@ -1589,6 +1818,11 @@ yylex()
int space_seen = 0;
struct kwtable *low = kwtable, *mid, *high = LAST(kwtable);
+ if (newline_seen) {
+ sourceline++;
+ newline_seen = 0;
+ }
+
retry:
switch (c = nextc()) {
case '\0': /* NUL */
@@ -1614,10 +1848,11 @@ retry:
}
/* fall through */
case '\n':
- sourceline++;
- if (lex_state == EXPR_BEG
- || lex_state == EXPR_FNAME)
+ if (lex_state == EXPR_BEG || lex_state == EXPR_FNAME) {
+ sourceline++;
goto retry;
+ }
+ newline_seen++;
lex_state = EXPR_BEG;
return '\n';
@@ -1628,7 +1863,7 @@ retry:
yylval.id = POW;
return OP_ASGN;
}
- pushback();
+ pushback(c);
return POW;
}
if (c == '=') {
@@ -1636,7 +1871,7 @@ retry:
lex_state = EXPR_BEG;
return OP_ASGN;
}
- pushback();
+ pushback(c);
if (lex_state == EXPR_ARG && space_seen && !isspace(c)){
arg_ambiguous();
lex_state = EXPR_BEG;
@@ -1656,12 +1891,16 @@ retry:
if (c == '~') {
return NMATCH;
}
- pushback();
+ pushback(c);
return '!';
case '=':
lex_state = EXPR_BEG;
if ((c = nextc()) == '=') {
+ if ((c = nextc()) == '=') {
+ return EQQ;
+ }
+ pushback(c);
return EQ;
}
if (c == '~') {
@@ -1670,7 +1909,7 @@ retry:
else if (c == '>') {
return ASSOC;
}
- pushback();
+ pushback(c);
return '=';
case '<':
@@ -1679,7 +1918,7 @@ retry:
if ((c = nextc()) == '>') {
return CMP;
}
- pushback();
+ pushback(c);
return LEQ;
}
if (c == '<') {
@@ -1687,10 +1926,10 @@ retry:
yylval.id = LSHFT;
return OP_ASGN;
}
- pushback();
+ pushback(c);
return LSHFT;
}
- pushback();
+ pushback(c);
return '<';
case '>':
@@ -1699,64 +1938,24 @@ retry:
return GEQ;
}
if (c == '>') {
- if (nextc() == '=') {
+ if ((c = nextc()) == '=') {
yylval.id = RSHFT;
return OP_ASGN;
}
- pushback();
+ pushback(c);
return RSHFT;
}
- pushback();
+ pushback(c);
return '>';
case '"':
+ return parse_string(c,c);
case '`':
- return parse_string(c);
+ if (lex_state == EXPR_FNAME) return c;
+ return parse_string(c,c);
case '\'':
- {
- int strstart;
-
- strstart = sourceline;
- newtok();
- while ((c = nextc()) != '\'') {
- if (c == -1) {
- sourceline = strstart;
- Error("unterminated string meets end of file");
- return 0;
- }
- if (ismbchar(c)) {
- tokadd(c);
- c = nextc();
- }
- else if (c == '\n') {
- sourceline++;
- }
- else if (c == '\\') {
- c = nextc();
- switch (c) {
- case '\n':
- sourceline++;
- continue;
-
- case '\'':
- c = '\'';
- break;
- case '\\':
- c = '\\';
- break;
-
- default:
- tokadd('\\');
- }
- }
- tokadd(c);
- }
- tokfix();
- yylval.val = str_new(tok(), toklen());
- lex_state = EXPR_END;
- return STRING;
- }
+ return parse_qstring(c);
case '?':
if ((c = nextc()) == '\\') {
@@ -1776,7 +1975,7 @@ retry:
yylval.id = '&';
return OP_ASGN;
}
- pushback();
+ pushback(c);
return '&';
case '|':
@@ -1788,7 +1987,7 @@ retry:
yylval.id = '|';
return OP_ASGN;
}
- pushback();
+ pushback(c);
return '|';
case '+':
@@ -1797,29 +1996,32 @@ retry:
if (c == '@') {
return UPLUS;
}
- pushback();
+ pushback(c);
return '+';
}
+ if (c == '=') {
+ lex_state = EXPR_BEG;
+ yylval.id = '+';
+ return OP_ASGN;
+ }
if (lex_state == EXPR_ARG) {
- if (!space_seen || c == '=' || isspace(c)) {
+ if (space_seen && !isspace(c)) {
arg_ambiguous();
+ }
+ else {
lex_state = EXPR_END;
}
}
if (lex_state != EXPR_END) {
- pushback();
- if (isdigit(c)) {
+ if (isdigit(c)) {
goto start_num;
}
+ pushback(c);
lex_state = EXPR_BEG;
return UPLUS;
}
lex_state = EXPR_BEG;
- if (c == '=') {
- yylval.id = '+';
- return OP_ASGN;
- }
- pushback();
+ pushback(c);
return '+';
case '-':
@@ -1828,31 +2030,34 @@ retry:
if (c == '@') {
return UMINUS;
}
- pushback();
+ pushback(c);
return '-';
}
+ if (c == '=') {
+ lex_state = EXPR_BEG;
+ yylval.id = '-';
+ return OP_ASGN;
+ }
if (lex_state == EXPR_ARG) {
- if (!space_seen || c == '=' || isspace(c)) {
+ if (space_seen && !isspace(c)) {
arg_ambiguous();
+ }
+ else {
lex_state = EXPR_END;
}
}
if (lex_state != EXPR_END) {
if (isdigit(c)) {
- pushback();
+ pushback(c);
c = '-';
goto start_num;
}
lex_state = EXPR_BEG;
- pushback();
+ pushback(c);
return UMINUS;
}
lex_state = EXPR_BEG;
- if (c == '=') {
- yylval.id = '-';
- return OP_ASGN;
- }
- pushback();
+ pushback(c);
return '-';
case '.':
@@ -1861,10 +2066,10 @@ retry:
if ((c = nextc()) == '.') {
return DOT3;
}
- pushback();
+ pushback(c);
return DOT2;
}
- pushback();
+ pushback(c);
if (!isdigit(c)) {
return '.';
}
@@ -1877,6 +2082,7 @@ retry:
{
int is_float, seen_point, seen_e;
+ is_float = seen_point = seen_e = 0;
lex_state = EXPR_END;
newtok();
if (c == '0') {
@@ -1887,30 +2093,39 @@ retry:
if (!isxdigit(c)) break;
tokadd(c);
}
- pushback();
+ pushback(c);
tokfix();
yylval.val = str2inum(tok(), 16);
return INTEGER;
}
- else if (c >= '0' && c <= '9') {
+ else if (c >= '0' && c <= '7') {
/* octal */
do {
tokadd(c);
c = nextc();
} while (c >= '0' && c <= '9');
- pushback();
+ pushback(c);
tokfix();
yylval.val = str2inum(tok(), 8);
return INTEGER;
}
+ else if (c > '7' && c <= '9') {
+ Error("Illegal octal digit");
+ }
+ else if (c == '.') {
+ tokadd('0');
+ }
+ else {
+ pushback(c);
+ yylval.val = INT2FIX(0);
+ return INTEGER;
+ }
}
if (c == '-' || c == '+') {
tokadd(c);
c = nextc();
}
- is_float = seen_point = seen_e = 0;
-
for (;;) {
switch (c) {
case '0': case '1': case '2': case '3': case '4':
@@ -1922,10 +2137,13 @@ retry:
if (seen_point) {
goto decode_num;
}
- c = nextc();
- if (!isdigit(c)) {
- pushback();
- goto decode_num;
+ else {
+ int c0 = nextc();
+ if (!isdigit(c0)) {
+ pushback(c0);
+ goto decode_num;
+ }
+ c = c0;
}
tokadd('.');
tokadd(c);
@@ -1957,7 +2175,7 @@ retry:
}
decode_num:
- pushback();
+ pushback(c);
tokfix();
if (is_float) {
double atof();
@@ -1981,30 +2199,29 @@ retry:
lex_state = EXPR_BEG;
return COLON2;
}
- pushback();
+ pushback(c);
if (isspace(c))
return ':';
return SYMBEG;
case '/':
- if (lex_state == EXPR_BEG
- || lex_state == EXPR_MID) {
- return parse_regx();
+ if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
+ return parse_regx('/');
+ }
+ if ((c = nextc()) == '=') {
+ lex_state = EXPR_BEG;
+ yylval.id = '/';
+ return OP_ASGN;
}
- c = nextc();
if (lex_state == EXPR_ARG) {
- if (space_seen && c != '=' && !isspace(c)) {
- pushback();
+ if (space_seen && !isspace(c)) {
+ pushback(c);
arg_ambiguous();
- return parse_regx();
+ return parse_regx('/');
}
}
lex_state = EXPR_BEG;
- if (c == '=') {
- yylval.id = '/';
- return OP_ASGN;
- }
- pushback();
+ pushback(c);
return '/';
case '^':
@@ -2013,7 +2230,7 @@ retry:
yylval.id = '^';
return OP_ASGN;
}
- pushback();
+ pushback(c);
return c;
case ',':
@@ -2027,15 +2244,14 @@ retry:
case '~':
if (lex_state == EXPR_FNAME) {
if ((c = nextc()) != '@') {
- pushback();
+ pushback(c);
}
}
lex_state = EXPR_BEG;
return c;
case '(':
- if (lex_state == EXPR_BEG
- || lex_state == EXPR_MID) {
+ if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
c = LPAREN;
lex_state = EXPR_BEG;
}
@@ -2055,14 +2271,13 @@ retry:
if ((c = nextc()) == '=') {
return ASET;
}
- pushback();
+ pushback(c);
return AREF;
}
- pushback();
+ pushback(c);
return '[';
}
- else if (lex_state == EXPR_BEG
- || lex_state == EXPR_MID) {
+ else if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
c = LBRACK;
}
else if (lex_state == EXPR_ARG && space_seen) {
@@ -2085,25 +2300,71 @@ retry:
space_seen = 1;
goto retry; /* skip \\n */
}
- pushback();
+ pushback(c);
return '\\';
case '%':
- lex_state = EXPR_BEG;
- if (nextc() == '=') {
+ if (lex_state == EXPR_BEG || lex_state == EXPR_MID) {
+ int term;
+
+ c = nextc();
+ quotation:
+ if (!isalnum(c)) {
+ term = c;
+ c = '"';
+ }
+ else {
+ term = nextc();
+ }
+ if (c == -1 || term == -1) {
+ Error("unterminated quoted string meets end of file");
+ return 0;
+ }
+ if (term == '(') term = ')';
+ else if (term == '[') term = ']';
+ else if (term == '{') term = '}';
+ else if (term == '<') term = '>';
+
+ switch (c) {
+ case 'Q':
+ return parse_string('"', term);
+
+ case 'q':
+ return parse_qstring(term);
+
+ case 'x':
+ return parse_string('`', term);
+
+ case 'r':
+ return parse_regx(term);
+
+ default:
+ Error("unknown type of string `%c'", c);
+ return 0;
+ }
+ }
+ if ((c = nextc()) == '=') {
yylval.id = '%';
return OP_ASGN;
}
- pushback();
- return c;
+ if (lex_state == EXPR_ARG) {
+ if (space_seen && !isspace(c)) {
+ arg_ambiguous();
+ goto quotation;
+ }
+ }
+ lex_state = EXPR_BEG;
+ pushback(c);
+ return '%';
case '$':
lex_state = EXPR_END;
newtok();
c = nextc();
switch (c) {
+ case '_': /* $_: last read line string */
case '~': /* $~: match-data */
- local_cnt('~');
+ local_cnt(c);
/* fall through */
case '*': /* $*: argv */
case '$': /* $$: pid */
@@ -2112,9 +2373,9 @@ retry:
case '@': /* $@: error position */
case '/': /* $/: input record separator */
case '\\': /* $\: output record separator */
+ case ';': /* $;: field separator */
case ',': /* $,: output field separator */
case '.': /* $.: last read line number */
- case '_': /* $_: last read line string */
case '=': /* $=: ignorecase */
case ':': /* $:: load path */
case '<': /* $<: reading filename */
@@ -2140,14 +2401,14 @@ retry:
tokadd(c);
c = nextc();
}
- pushback();
+ pushback(c);
tokfix();
yylval.node = NEW_NTH_REF(atoi(tok()));
return NTH_REF;
default:
if (!is_identchar(c)) {
- pushback();
+ pushback(c);
return '$';
}
case '0':
@@ -2158,7 +2419,7 @@ retry:
case '@':
c = nextc();
if (!is_identchar(c)) {
- pushback();
+ pushback(c);
return '@';
}
newtok();
@@ -2187,7 +2448,7 @@ retry:
tokadd(c);
}
else {
- pushback();
+ pushback(c);
}
tokfix();
@@ -2213,7 +2474,9 @@ retry:
if (state != EXPR_BEG
&& state != EXPR_BEG) {
if (mid->id == IF) return IF_MOD;
+ if (mid->id == UNLESS) return UNLESS_MOD;
if (mid->id == WHILE) return WHILE_MOD;
+ if (mid->id == UNTIL) return UNTIL_MOD;
}
return mid->id;
}
@@ -2231,7 +2494,7 @@ retry:
tokadd(c);
}
else {
- pushback();
+ pushback(c);
}
}
else if (lex_state == EXPR_BEG){
@@ -2255,68 +2518,43 @@ retry:
}
static NODE*
-var_extend(list, term)
+str_extend(list, term)
NODE *list;
char term;
{
- int c, t, brace;
+ int c;
VALUE ss;
NODE *node;
ID id;
+ int nest;
c = nextc();
switch (c) {
case '$':
+ case '@':
case '{':
break;
- case '@':
- t = nextc();
- pushback();
- if (!is_identchar(t)) {
- tokadd('#');
- tokadd(c);
- return list;
- }
default:
tokadd('#');
- pushback();
+ pushback(c);
return list;
}
ss = str_new(tok(), toklen());
- if (list == Qnil) {
- list = NEW_STR2(ss);
+ if (list == 0) {
+ list = NEW_DSTR(ss);
}
else if (toklen() > 0) {
list_append(list, NEW_STR(ss));
}
newtok();
- if (c == '{') {
- brace = 1;
- c = nextc();
- }
- else {
- brace = 0;
- }
switch (c) {
case '$':
+ tokadd('$');
c = nextc();
if (c == -1) return (NODE*)-1;
switch (c) {
- case '&':
- case '`':
- case '\'':
- case '+':
- node = NEW_BACK_REF(c);
- c = nextc();
- goto append_node;
-
- case '~':
- local_cnt('~');
- id = '~';
- goto id_node;
-
case '1': case '2': case '3':
case '4': case '5': case '6':
case '7': case '8': case '9':
@@ -2324,55 +2562,108 @@ var_extend(list, term)
tokadd(c);
c = nextc();
}
- tokfix();
- node = NEW_NTH_REF(atoi(tok()));
- goto append_node;
- }
+ pushback(c);
+ goto fetch_id;
- tokadd('$');
- if (!is_identchar(c)) {
+ case '&': case '+':
+ case '_': case '~':
+ case '*': case '$': case '?':
+ case '!': case '@': case ',':
+ case '.': case '=': case ':':
+ case '<': case '>': case '\\':
+ refetch:
tokadd(c);
goto fetch_id;
+
+ default:
+ if (c == term) {
+ list_append(list, NEW_STR(str_new2("#$")));
+ pushback(c);
+ return list;
+ }
+ switch (c) {
+ case '\"':
+ case '/':
+ case '\'':
+ case '`':
+ goto refetch;
+ }
+ if (!is_identchar(c)) {
+ yyerror("bad global variable in string");
+ newtok();
+ return list;
+ }
}
/* through */
- case '@':
+
+ case '@':
tokadd(c);
c = nextc();
- break;
- }
- while (is_identchar(c)) {
- tokadd(c);
- if (ismbchar(c)) {
- c = nextc();
+ while (is_identchar(c)) {
tokadd(c);
+ if (ismbchar(c)) {
+ c = nextc();
+ tokadd(c);
+ }
+ c = nextc();
}
- c = nextc();
+ pushback(c);
+ break;
+
+ case '{':
+ nest = 0;
+ do {
+ loop_again:
+ c = nextc();
+ switch (c) {
+ case -1:
+ if (nest > 0) {
+ bad_sub:
+ Error("bad substitution in string");
+ newtok();
+ return list;
+ }
+ return (NODE*)-1;
+ case '}':
+ if (nest == 0) break;
+ nest--;
+ tokadd(c);
+ goto loop_again;
+ case '\\':
+ c = read_escape();
+ tokadd(c);
+ goto loop_again;
+ case '{':
+ nest++;
+ case '\"':
+ case '/':
+ case '`':
+ if (c == term) {
+ pushback(c);
+ list_append(list, NEW_STR(str_new2("#")));
+ Warning("bad substitution in string");
+ tokfix();
+ list_append(list, NEW_STR(str_new(tok(), toklen())));
+ newtok();
+ return list;
+ }
+ add_char:
+ default:
+ tokadd(c);
+ break;
+ }
+ } while (c != '}');
}
fetch_id:
tokfix();
- if (strcmp("__LINE__", tok()) == 0)
- id = _LINE_;
- else if (strcmp("__FILE__", tok()) == 0)
- id = _FILE_;
- else
- id = rb_intern(tok());
- id_node:
- node = gettable(id);
-
- append_node:
- if (brace) {
- if (c != '}')
- Error("Invalid variable name in string");
- }
- else pushback();
-
+ node = NEW_EVSTR(tok(),toklen());
list_append(list, node);
newtok();
+
return list;
}
-
NODE*
newnode(type, a0, a1, a2)
enum node_type type;
@@ -2382,7 +2673,7 @@ newnode(type, a0, a1, a2)
n->flags |= T_NODE;
nd_set_type(n, type);
- n->line = sourceline;
+ nd_set_line(n, sourceline);
n->file = sourcefile;
n->u1.node = a0;
@@ -2406,8 +2697,8 @@ block_append(head, tail)
extern int verbose;
NODE *last;
- if (tail == Qnil) return head;
- if (head == Qnil) return tail;
+ if (tail == 0) return head;
+ if (head == 0) return tail;
if (nd_type(head) != NODE_BLOCK)
head = last = NEW_BLOCK(head);
@@ -2420,11 +2711,7 @@ block_append(head, tail)
if (verbose) {
switch (nd_type(last->nd_head)) {
- case NODE_BREAK:
- case NODE_CONTINUE:
- case NODE_REDO:
case NODE_RETURN:
- case NODE_RETRY:
Warning("statement not reached");
break;
@@ -2447,7 +2734,7 @@ list_append(head, tail)
{
NODE *last;
- if (head == Qnil) return NEW_LIST(tail);
+ if (head == 0) return NEW_LIST(tail);
last = head;
while (last->nd_next) {
@@ -2465,11 +2752,6 @@ list_concat(head, tail)
{
NODE *last;
-#if 0
- if (nd_type(head) != NODE_ARRAY || nd_type(tail) != NODE_ARRAY)
- Bug("list_concat() called with non-list");
-#endif
-
last = head;
while (last->nd_next) {
last = last->nd_next;
@@ -2493,7 +2775,7 @@ call_op(recv, id, narg, arg1)
value_expr(arg1);
}
- return NEW_CALL(recv, id, narg==1?NEW_LIST(arg1):Qnil);
+ return NEW_CALL(recv, id, narg==1?NEW_LIST(arg1):0);
}
static NODE*
@@ -2506,19 +2788,11 @@ gettable(id)
else if (id == NIL) {
return NEW_NIL();
}
- else if (id == _LINE_) {
- return NEW_LIT(INT2FIX(sourceline));
- }
- else if (id == _FILE_) {
- VALUE s = str_new2(sourcefile);
-
- return NEW_STR(s);
- }
else if (is_local_id(id)) {
if (local_id(id)) return NEW_LVAR(id);
- if (dyna_id(id)) return NEW_DVAR(id);
+ if (dyna_var_defined(id)) return NEW_DVAR(id);
/* method call without arguments */
- return NEW_FCALL(id, Qnil);
+ return NEW_FCALL(id, 0);
}
else if (is_global_id(id)) {
return NEW_GVAR(id);
@@ -2530,7 +2804,7 @@ gettable(id)
return NEW_CVAR(id);
}
Bug("invalid id for gettable");
- return Qnil;
+ return 0;
}
static NODE*
@@ -2538,17 +2812,13 @@ asignable(id, val)
ID id;
NODE *val;
{
- extern VALUE dyna_var_asgn();
- NODE *lhs = Qnil;
+ NODE *lhs = 0;
if (id == SELF) {
- Error("Can't change the value of self");
+ yyerror("Can't change the value of self");
}
else if (id == NIL) {
- Error("Can't asign to nil");
- }
- else if (id == _LINE_ || id == _FILE_) {
- Error("Can't asign to special identifier");
+ yyerror("Can't asign to nil");
}
else if (is_local_id(id)) {
if (local_id(id) || !dyna_in_block())
@@ -2566,7 +2836,7 @@ asignable(id, val)
}
else if (is_const_id(id)) {
if (cur_mid || in_single)
- Error("class constant asigned in method body");
+ yyerror("dynamic constant asignment");
lhs = NEW_CASGN(id, val);
}
else {
@@ -2625,22 +2895,17 @@ static int
value_expr(node)
NODE *node;
{
- if (node == Qnil) return TRUE;
+ if (node == 0) return TRUE;
switch (nd_type(node)) {
case NODE_RETURN:
- case NODE_CONTINUE:
- case NODE_BREAK:
- case NODE_REDO:
- case NODE_RETRY:
- case NODE_FAIL:
case NODE_WHILE:
- case NODE_WHILE2:
+ case NODE_UNTIL:
case NODE_CLASS:
case NODE_MODULE:
case NODE_DEFN:
case NODE_DEFS:
- Error("void value expression");
+ yyerror("void value expression");
return FALSE;
break;
@@ -2666,19 +2931,26 @@ cond0(node)
{
enum node_type type = nd_type(node);
- if (type == NODE_STR || type == NODE_STR2 || type == NODE_DREGX) {
+ switch (type) {
+ case NODE_DREGX:
+ case NODE_DREGX_ONCE:
return call_op(NEW_GVAR(rb_intern("$_")),MATCH,1,node);
- }
- else if (type == NODE_LIT && TYPE(node->nd_lit) == T_REGEXP) {
- return call_op(node,MATCH,1,NEW_GVAR(rb_intern("$_")));
- }
- else if (type == NODE_DOT2 || type == NODE_DOT3) {
+
+ case NODE_DOT2:
+ case NODE_DOT3:
node->nd_beg = cond2(node->nd_beg);
node->nd_end = cond2(node->nd_end);
if (type == NODE_DOT2) nd_set_type(node,NODE_FLIP2);
else if (type == NODE_DOT3) nd_set_type(node, NODE_FLIP3);
+ return node;
+
+ case NODE_LIT:
+ if (TYPE(node->nd_lit) == T_REGEXP) {
+ return NEW_MATCH(node);
+ }
+ default:
+ return node;
}
- return node;
}
static NODE*
@@ -2700,7 +2972,7 @@ cond(node)
node = cond0(node);
if (type == NODE_CALL && node->nd_mid == '!') {
- if (node->nd_args || node->nd_recv == Qnil) {
+ if (node->nd_args || node->nd_recv == 0) {
Bug("method `!' called with wrong # of operand");
}
node->nd_recv = cond0(node->nd_recv);
@@ -2719,6 +2991,16 @@ cond2(node)
return node;
}
+static NODE*
+logop(type, left, right)
+ enum node_type type;
+ NODE *left, *right;
+{
+ value_expr(left);
+
+ return newnode(type, cond(left), cond(right));
+}
+
st_table *new_idhash();
static struct local_vars {
@@ -2797,10 +3079,8 @@ local_id(id)
static void
top_local_init()
{
- if (lvtbl == 0) {
- local_push();
- }
- else if (the_scope->local_tbl) {
+ local_push();
+ if (the_scope->local_tbl) {
lvtbl->cnt = the_scope->local_tbl[0];
}
else {
@@ -2813,7 +3093,6 @@ top_local_init()
else {
lvtbl->tbl = 0;
}
- NEW_CREF0(); /* initialize constant c-ref */
lvtbl->dlev = (the_dyna_vars?1:0);
}
@@ -2832,26 +3111,23 @@ top_local_setup()
the_scope->local_vars = ALLOC_N(VALUE, len);
if (vars) {
MEMCPY(the_scope->local_vars, vars, VALUE, i);
- MEMZERO(the_scope->local_vars+i, VALUE, len-i);
+ memclear(the_scope->local_vars+i, len-i);
}
else {
- MEMZERO(the_scope->local_vars, VALUE, len);
+ memclear(the_scope->local_vars, len);
}
the_scope->flag = SCOPE_MALLOC;
}
else {
REALLOC_N(the_scope->local_vars, VALUE, len);
- MEMZERO(the_scope->local_vars+i, VALUE, len-i);
+ memclear(the_scope->local_vars+i, len-i);
free(the_scope->local_tbl);
}
lvtbl->tbl[0] = len;
the_scope->local_tbl = lvtbl->tbl;
}
- else if (lvtbl->tbl) {
- free(lvtbl->tbl);
- }
}
- cref_list = Qnil;
+ local_pop();
}
static struct RVarmap*
@@ -2878,10 +3154,9 @@ dyna_in_block()
static void
cref_pop()
{
- NODE *cref = cref_list;
+ NODE *cref = cur_cref;
- cref_list = cref_list->nd_next;
- cref->nd_next = Qnil;
+ cur_cref = cur_cref->nd_next;
}
void
@@ -2893,22 +3168,22 @@ yyappend_print()
}
void
-yywhole_loop(chop, split)
+yywhile_loop(chop, split)
int chop, split;
{
if (split) {
eval_tree =
block_append(NEW_GASGN(rb_intern("$F"),
NEW_CALL(NEW_GVAR(rb_intern("$_")),
- rb_intern("split"), Qnil)),
+ rb_intern("split"), 0)),
eval_tree);
}
if (chop) {
eval_tree =
block_append(NEW_CALL(NEW_GVAR(rb_intern("$_")),
- rb_intern("chop!"), Qnil), eval_tree);
+ rb_intern("chop!"), 0), eval_tree);
}
- eval_tree = NEW_WHILE(NEW_FCALL(rb_intern("gets"),0),eval_tree);
+ eval_tree = NEW_OPT_N(eval_tree);
}
static struct op_tbl rb_op_tbl[] = {
@@ -2934,6 +3209,7 @@ static struct op_tbl rb_op_tbl[] = {
'<', "<",
LEQ, "<=",
EQ, "==",
+ EQQ, "===",
NEQ, "!=",
MATCH, "=~",
NMATCH, "!~",
@@ -2948,7 +3224,8 @@ static struct op_tbl rb_op_tbl[] = {
LSHFT, "<<",
RSHFT, ">>",
COLON2, "::",
- Qnil, Qnil,
+ '`', "`",
+ 0, 0,
};
char *rb_id2name();
@@ -2963,8 +3240,8 @@ Init_sym()
{
int strcmp();
- sym_tbl = st_init_table(strcmp, st_strhash);
- rb_global_variable(&cref_list);
+ sym_tbl = st_init_strtable();
+ rb_global_variable(&cur_cref);
}
ID
@@ -3027,15 +3304,19 @@ rb_intern(name)
return id;
}
-static char *find_ok;
+struct find_ok {
+ ID id;
+ char *name;
+};
static int
-id_find(name, id1, id2)
+id_find(name, id1, ok)
char *name;
- ID id1, id2;
+ ID id1;
+ struct find_ok *ok;
{
- if (id1 == id2) {
- find_ok = name;
+ if (id1 == ok->id) {
+ ok->name = name;
return ST_STOP;
}
return ST_CONTINUE;
@@ -3045,7 +3326,7 @@ char *
rb_id2name(id)
ID id;
{
- find_ok = 0;
+ struct find_ok ok;
if (id < LAST_TOKEN) {
int i = 0;
@@ -3056,8 +3337,10 @@ rb_id2name(id)
}
}
- st_foreach(sym_tbl, id_find, id);
- if (!find_ok && is_attrset_id(id)) {
+ ok.name = 0;
+ ok.id = id;
+ st_foreach(sym_tbl, id_find, &ok);
+ if (!ok.name && is_attrset_id(id)) {
char *res;
ID id2;
@@ -3073,7 +3356,7 @@ rb_id2name(id)
return rb_id2name(id);
}
}
- return find_ok;
+ return ok.name;
}
static int
@@ -3095,3 +3378,84 @@ rb_const_check(class, module)
{
st_foreach(module->iv_tbl, const_check, class);
}
+
+void
+local_var_append(id)
+ ID id;
+{
+ struct local_vars tmp;
+ struct local_vars *save = lvtbl;
+
+ if (the_scope->local_tbl) {
+ tmp.cnt = the_scope->local_tbl[0];
+ tmp.tbl = the_scope->local_tbl;
+ lvtbl->dlev = 0;
+ }
+ lvtbl = &tmp;
+ local_cnt(id);
+ lvtbl = save;
+}
+
+static VALUE
+special_local_get(c)
+ char c;
+{
+ int cnt, max;
+
+ if (!the_scope->local_vars) return Qnil;
+ for (cnt=1, max=the_scope->local_tbl[0]+1; cnt<max ;cnt++) {
+ if (the_scope->local_tbl[cnt] == c) {
+ return the_scope->local_vars[cnt-1];
+ }
+ }
+ return Qnil;
+}
+
+static void
+special_local_set(c, val)
+ char c;
+ VALUE val;
+{
+ int cnt, max;
+
+ if (the_scope->local_tbl) {
+ for (cnt=1, max=the_scope->local_tbl[0]+1; cnt<max ;cnt++) {
+ if (the_scope->local_tbl[cnt] == c) {
+ the_scope->local_vars[cnt-1] = val;
+ return;
+ }
+ }
+ }
+ top_local_init();
+ cnt = local_cnt(c);
+ top_local_setup();
+ the_scope->local_vars[cnt] = val;
+}
+
+VALUE
+backref_get()
+{
+ return special_local_get('~');
+}
+
+void
+backref_set(val)
+ VALUE val;
+{
+ special_local_set('~', val);
+}
+
+VALUE
+lastline_get()
+{
+ VALUE v = special_local_get('_');
+ if (v == 1) return Qnil; /* $_ undefined */
+ return v;
+}
+
+void
+lastline_set(val)
+ VALUE val;
+{
+ special_local_set('_', val);
+}
diff --git a/process.c b/process.c
index 116a93f965..29f61ddd42 100644
--- a/process.c
+++ b/process.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:47 $
created at: Tue Aug 10 14:30:50 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -25,7 +25,12 @@ struct timeval {
};
#endif
-#include <sys/resource.h>
+#ifdef HAVE_SYS_WAIT_H
+# include <sys/wait.h>
+#endif
+#ifdef HAVE_GETPRIORITY
+# include <sys/resource.h>
+#endif
#ifdef HAVE_VFORK_H
#include <vfork.h>
#endif
@@ -51,7 +56,7 @@ get_ppid()
#define HAVE_WAITPID
#endif
-static VALUE status;
+VALUE last_status = Qnil;
#if !defined(HAVE_WAITPID) && !defined(HAVE_WAIT4)
static st_table *pid_tbl;
@@ -59,55 +64,72 @@ static st_table *pid_tbl;
# define WAIT_CALL
#endif
-int
-rb_waitpid(pid, flags)
+static int
+rb_waitpid(pid, flags, st)
int pid;
int flags;
+ int *st;
{
- int result, st;
+ int result;
#ifdef HAVE_WAITPID
- result = waitpid(pid, &st, flags);
+ retry:
+ result = waitpid(pid, st, flags);
+ if (result < 0) {
+ if (errno == EINTR) goto retry;
+ return -1;
+ }
#else
#ifdef HAVE_WAIT4
- result = wait4(pid, &st, flags, NULL);
+ retry:
+ result = wait4(pid, st, flags, NULL);
+ if (result < 0) {
+ if (errno == EINTR) goto retry;
+ return -1;
+ }
#else
- if (pid_tbl && st_lookup(pid_tbl, pid, &st)) {
- status = INT2FIX(st);
+ if (pid_tbl && st_lookup(pid_tbl, pid, st)) {
+ last_status = INT2FIX(*st);
st_delete(pid_tbl, &pid, NULL);
return pid;
}
if (flags)
- Fail("Can't do waitpid with flags");
+ Fatal("Can't do waitpid with flags");
for (;;) {
- result = wait(&st);
- if (result < 0) return -1;
+ result = wait(st);
+ if (result < 0) {
+ if (errno != EINTR) continue;
+ return -1;
+ }
if (result == pid) {
break;
}
if (!pid_tbl)
- pid_tbl = st_init_table(ST_NUMCMP, ST_NUMHASH);
+ pid_tbl = st_init_numtable();
st_insert(pid_tbl, pid, st);
}
#endif
#endif
- status = INT2FIX(st);
+ last_status = INT2FIX(*st);
return result;
}
#ifndef WAIT_CALL
-static int wait_pid;
-static int wait_status;
+struct wait_data {
+ int pid;
+ int status;
+}
-static wait_each(key, value)
+static wait_each(key, value, data)
int key, value;
+ struct wait_data *data;
{
- if (wait_status != -1) return ST_STOP;
+ if (data->status != -1) return ST_STOP;
- wait_pid = key;
- wait_status = value;
+ data->pid = key;
+ data->status = value;
return ST_DELETE;
}
#endif
@@ -116,21 +138,22 @@ static VALUE
f_wait()
{
int pid, state;
-
#ifndef WAIT_CALL
- wait_status = -1;
- st_foreach(pid_tbl, wait_each, NULL);
- if (wait_status != -1) {
- status = wait_status;
- return wait_pid;
+ struct wait_data data;
+
+ data.status = -1;
+ st_foreach(pid_tbl, wait_each, &data);
+ if (data.status != -1) {
+ status = data.status;
+ return data.pid;
}
#endif
if ((pid = wait(&state)) < 0) {
if (errno == ECHILD) return Qnil;
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
}
- status = INT2FIX(state);
+ last_status = INT2FIX(state);
return INT2FIX(pid);
}
@@ -138,18 +161,88 @@ static VALUE
f_waitpid(obj, vpid, vflags)
VALUE obj, vpid, vflags;
{
- int pid, flags;
+ int pid, flags, status;
- if (vflags == Qnil) flags = 0;
+ if (NIL_P(vflags)) flags = 0;
else flags = FIX2UINT(vflags);
- if ((pid = rb_waitpid(FIX2UINT(vpid), flags)) < 0)
- rb_sys_fail(Qnil);
+ if ((pid = rb_waitpid(FIX2UINT(vpid), flags, &status)) < 0)
+ rb_sys_fail(0);
return INT2FIX(pid);
}
char *strtok();
+#if defined(THREAD) && defined(HAVE_SETITIMER)
+static void
+before_exec()
+{
+ {
+ struct itimerval tval;
+
+ tval.it_interval.tv_sec = 0;
+ tval.it_interval.tv_usec = 0;
+ tval.it_value = tval.it_interval;
+ setitimer(ITIMER_VIRTUAL, &tval, NULL);
+ }
+}
+
+static void
+after_exec()
+{
+ {
+ struct itimerval tval;
+
+ tval.it_interval.tv_sec = 1;
+ tval.it_interval.tv_usec = 0;
+ tval.it_value = tval.it_interval;
+ setitimer(ITIMER_VIRTUAL, &tval, NULL);
+ }
+}
+#else
+#define before_exec()
+#define after_exec()
+#endif
+
+extern char *dln_find_exe();
+
+static int
+proc_exec_v(argv)
+ char **argv;
+{
+ char *prog;
+
+ prog = dln_find_exe(argv[0], 0);
+ if (!prog) {
+ errno = ENOENT;
+ return -1;
+ }
+ before_exec();
+ execv(prog, argv);
+ after_exec();
+ return -1;
+}
+
+static int
+proc_exec_n(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ char **args;
+ int i;
+
+ args = ALLOCA_N(char*, argc+1);
+ for (i=0; i<argc; i++) {
+ Check_Type(argv[i], T_STRING);
+ args[i] = RSTRING(argv[i])->ptr;
+ }
+ args[i] = 0;
+ if (args[0]) {
+ return proc_exec_v(args);
+ }
+ return -1;
+}
+
int
rb_proc_exec(str)
char *str;
@@ -159,7 +252,13 @@ rb_proc_exec(str)
for (s=str; *s; s++) {
if (*s != ' ' && !isalpha(*s) && strchr("*?{}[]<>()~&|\\$;'`\"\n",*s)) {
+ before_exec();
+#if defined(MSDOS)
+ system(str);
+#else
execl("/bin/sh", "sh", "-c", str, (char *)NULL);
+#endif
+ after_exec();
return -1;
}
}
@@ -173,19 +272,25 @@ rb_proc_exec(str)
*a = NULL;
}
if (argv[0]) {
- execvp(argv[0], argv);
+ return proc_exec_v(argv);
}
+ errno = ENOENT;
return -1;
}
static VALUE
-f_exec(obj, str)
- VALUE obj;
- struct RString *str;
+f_exec(argc, argv)
+ int argc;
+ VALUE *argv;
{
- Check_Type(str, T_STRING);
- rb_proc_exec(str->ptr);
- rb_sys_fail(str->ptr);
+ if (argc == 1) {
+ Check_Type(argv[0], T_STRING);
+ rb_proc_exec(RSTRING(argv[0])->ptr);
+ }
+ else {
+ proc_exec_n(argc, argv);
+ }
+ rb_sys_fail(RSTRING(argv[0])->ptr);
}
static VALUE
@@ -224,7 +329,6 @@ f_exit_bang(obj, status)
_exit(code);
/* not reached */
- return Qnil;
}
void
@@ -232,12 +336,13 @@ rb_syswait(pid)
int pid;
{
RETSIGTYPE (*hfunc)(), (*ifunc)(), (*qfunc)();
+ int status;
hfunc = signal(SIGHUP, SIG_IGN);
ifunc = signal(SIGINT, SIG_IGN);
qfunc = signal(SIGQUIT, SIG_IGN);
- if (rb_waitpid(pid, 0) < 0) rb_sys_fail("wait");
+ if (rb_waitpid(pid, 0, &status) < 0) rb_sys_fail("wait");
signal(SIGHUP, hfunc);
signal(SIGINT, ifunc);
@@ -245,33 +350,58 @@ rb_syswait(pid)
}
static VALUE
-f_system(obj, str)
- VALUE obj;
- struct RString *str;
+f_system(argc, argv)
+ int argc;
+ VALUE *argv;
{
#ifdef NT
+ VALUE cmd;
+ int state;
+
+ cmd = ary_join(ary_new4(argc, argv), str_new2(" "));
+
+ state = do_spawn(RSTRING(cmd)->ptr);
+ last_status = INT2FIX(state);
+
+ if (state == 0) return TRUE;
+ return FALSE;
+#else
+#if defined(DJGPP)
+ VALUE cmd;
int state;
- Check_Type(str, T_STRING);
- state = do_spawn(str->ptr);
- status = INT2FIX(state);
+ cmd = ary_join(ary_new4(argc, argv), str_new2(" "));
+
+ state = system(RSTRING(cmd)->ptr);
+ last_status = INT2FIX(state);
if (state == 0) return TRUE;
return FALSE;
#else
+ int i;
int pid;
- Check_Type(str, T_STRING);
-
fflush(stdin); /* is it really needed? */
fflush(stdout);
fflush(stderr);
- if (*str->ptr == '\0') return INT2FIX(0);
+ if (argc == 0) {
+ last_status = INT2FIX(0);
+ return INT2FIX(0);
+ }
+
+ for (i=0; i<argc; i++) {
+ Check_Type(argv[i], T_STRING);
+ }
retry:
switch (pid = vfork()) {
case 0:
- rb_proc_exec(str->ptr);
+ if (argc == 1) {
+ rb_proc_exec(RSTRING(argv[0])->ptr);
+ }
+ else {
+ proc_exec_n(argc, argv);
+ }
_exit(127);
break; /* not reached */
@@ -280,62 +410,99 @@ f_system(obj, str)
sleep(5);
goto retry;
}
- rb_sys_fail(str->ptr);
+ rb_sys_fail(0);
break;
default:
rb_syswait(pid);
}
- if (status == INT2FIX(0)) return TRUE;
+ if (last_status == INT2FIX(0)) return TRUE;
return FALSE;
#endif
+#endif
}
+struct timeval time_timeval();
+
VALUE
f_sleep(argc, argv)
int argc;
VALUE *argv;
{
int beg, end;
+ int n;
beg = time(0);
+#ifdef THREAD
if (argc == 0) {
+ thread_sleep();
+ }
+ else if (argc == 1) {
+ thread_wait_for(time_timeval(argv[0]));
+ }
+#else
+ if (argc == 0) {
+ TRAP_BEG;
sleep((32767<<16)+32767);
+ TRAP_END;
}
else if (argc == 1) {
+ struct timeval tv;
+
+ tv = time_timeval(argv[0]);
TRAP_BEG;
- sleep(NUM2INT(argv[0]));
+ sleep(tv.tv_sec);
TRAP_END;
+ if (n<0) rb_sys_fail(0);
}
+#endif
else {
- Fail("wrong # of arguments");
+ ArgError("wrong # of arguments");
}
end = time(0) - beg;
- return int2inum(end);
+ return INT2FIX(end);
}
-#ifndef NT
+#if !defined(NT) && !defined(DJGPP)
+#ifdef _POSIX_SOURCE
+static VALUE
+proc_getpgrp()
+{
+ int pgrp;
+
+ pgrp = getpgrp();
+ if (pgrp < 0) rb_sys_fail(0);
+ return INT2FIX(pgrp);
+}
+
+static VALUE
+proc_setpgrp(obj)
+ VALUE obj;
+{
+ int pgrp;
+
+ if (setpgrp() < 0) rb_sys_fail(0);
+ return Qnil;
+}
+
+#else
+
static VALUE
-proc_getpgrp(argc, argv, obj)
+proc_getpgrp(argc, argv)
int argc;
VALUE *argv;
- VALUE obj;
{
VALUE vpid;
- int pid, pgrp;
+ int pgrp, pid;
rb_scan_args(argc, argv, "01", &vpid);
- if (vpid == Qnil) {
- pid = 0;
- }
- else {
- pid = NUM2INT(vpid);
- }
-
+ if (NIL_P(vpid)) pid = 0;
+ else pid = NUM2INT(vpid);
pgrp = getpgrp(pid);
+ if (pgrp < 0) rb_sys_fail(0);
return INT2FIX(pgrp);
}
@@ -347,11 +514,25 @@ proc_setpgrp(obj, pid, pgrp)
ipid = NUM2INT(pid);
ipgrp = NUM2INT(pgrp);
+ if (setpgrp(ipid, ipgrp) < 0) rb_sys_fail(0);
+ return Qnil;
+}
+#endif
- if (getpgrp(ipid, ipgrp) == -1) rb_sys_fail(Qnil);
+#ifdef HAVE_SETPGID
+static VALUE
+proc_setpgid(obj, pid, pgrp)
+ VALUE obj, pid, pgrp;
+{
+ int ipid, ipgrp;
- return INT2FIX(0);
+ ipid = NUM2INT(pid);
+ ipgrp = NUM2INT(pgrp);
+
+ if (setpgid(ipid, ipgrp) == -1) rb_sys_fail(0);
+ return Qnil;
}
+#endif
static VALUE
proc_getpriority(obj, which, who)
@@ -364,10 +545,10 @@ proc_getpriority(obj, which, who)
iwho = NUM2INT(who);
prio = getpriority(iwhich, iwho);
- if (prio == -1) rb_sys_fail(Qnil);
+ if (prio == -1) rb_sys_fail(0);
return INT2FIX(prio);
#else
- Fail("The getpriority() function is unimplemented on this machine");
+ rb_notimplement();
#endif
}
@@ -383,10 +564,10 @@ proc_setpriority(obj, which, who, prio)
iprio = NUM2INT(prio);
if (setpriority(iwhich, iwho, iprio) == -1)
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
return INT2FIX(0);
#else
- Fail("The setpriority() function is unimplemented on this machine");
+ rb_notimplement();
#endif
}
#endif
@@ -416,7 +597,7 @@ proc_setuid(obj, id)
if (geteuid() == uid)
setuid(uid);
else
- Fail("getruid not implemented");
+ rb_notimplement();
}
#endif
#endif
@@ -448,7 +629,7 @@ proc_setgid(obj, id)
if (getegid() == gid)
setgid(gid);
else
- Fail("getrgid not implemented");
+ rb_notimplement();
}
#endif
#endif
@@ -468,16 +649,16 @@ proc_seteuid(obj, euid)
VALUE obj, euid;
{
#ifdef HAVE_SETEUID
- if (seteuid(NUM2INT(euid)) == -1) rb_sys_fail(Qnil);
+ if (seteuid(NUM2INT(euid)) == -1) rb_sys_fail(0);
#else
#ifdef HAVE_SETREUID
- if (setreuid(-1, NUM2INT(euid)) == -1) rb_sys_fail(Qnil);
+ if (setreuid(-1, NUM2INT(euid)) == -1) rb_sys_fail(0);
#else
euid = NUM2INT(euid);
if (euid == getuid())
setuid(euid);
else
- Fail("seteuid() not implemented");
+ rb_notimplement();
#endif
#endif
return euid;
@@ -496,16 +677,16 @@ proc_setegid(obj, egid)
VALUE obj, egid;
{
#ifdef HAVE_SETEGID
- if (setegid(NUM2INT(egid)) == -1) rb_sys_fail(Qnil);
+ if (setegid(NUM2INT(egid)) == -1) rb_sys_fail(0);
#else
#ifdef HAVE_SETREGID
- if (setregid(-1, NUM2INT(egid)) == -1) rb_sys_fail(Qnil);
+ if (setregid(-1, NUM2INT(egid)) == -1) rb_sys_fail(0);
#else
egid = NUM2INT(egid);
if (egid == getgid())
setgid(egid);
else
- Fail("setegid() not implemented");
+ rb_notimplement();
#endif
#endif
return egid;
@@ -520,41 +701,60 @@ Init_process()
{
extern VALUE cKernel;
- rb_define_virtual_variable("$$", get_pid, Qnil);
- rb_define_readonly_variable("$?", &status);
+ rb_define_virtual_variable("$$", get_pid, 0);
+ rb_define_readonly_variable("$?", &last_status);
#ifndef NT
- rb_define_private_method(cKernel, "exec", f_exec, 1);
+ rb_define_private_method(cKernel, "exec", f_exec, -1);
rb_define_private_method(cKernel, "fork", f_fork, 0);
rb_define_private_method(cKernel, "exit!", f_exit_bang, 1);
- rb_define_private_method(cKernel, "wait", f_wait, 0);
- rb_define_private_method(cKernel, "waitpid", f_waitpid, 2);
-#endif
- rb_define_private_method(cKernel, "system", f_system, 1);
+ rb_define_private_method(cKernel, "system", f_system, -1);
rb_define_private_method(cKernel, "sleep", f_sleep, -1);
mProcess = rb_define_module("Process");
+#ifdef WNOHANG
+ rb_define_const(mProcess, "WNOHANG", INT2FIX(WNOHANG));
+#else
+ rb_define_const(mProcess, "WNOHANG", INT2FIX(0));
+#endif
+#ifdef WUNTRACED
+ rb_define_const(mProcess, "WUNTRACED", INT2FIX(WUNTRACED));
+#else
+ rb_define_const(mProcess, "WUNTRACED", INT2FIX(0));
+#endif
+#endif
+
#ifndef NT
rb_define_singleton_method(mProcess, "fork", f_fork, 0);
rb_define_singleton_method(mProcess, "exit!", f_exit_bang, 1);
- rb_define_singleton_method(mProcess, "wait", f_wait, 0);
- rb_define_singleton_method(mProcess, "waitpid", f_waitpid, 2);
- rb_define_singleton_method(mProcess, "kill", f_kill, -1);
#endif
+ rb_define_module_function(mProcess, "kill", f_kill, -1);
+ rb_define_module_function(mProcess, "wait", f_wait, 0);
+ rb_define_module_function(mProcess, "waitpid", f_waitpid, 2);
rb_define_module_function(mProcess, "pid", get_pid, 0);
rb_define_module_function(mProcess, "ppid", get_ppid, 0);
-#ifndef NT
+#if !defined(NT) && !defined(DJGPP)
+#ifdef _POSIX_SOURCE
+ rb_define_module_function(mProcess, "getpgrp", proc_getpgrp, 0);
+ rb_define_module_function(mProcess, "setpgrp", proc_setpgrp, 0);
+#else
rb_define_module_function(mProcess, "getpgrp", proc_getpgrp, -1);
rb_define_module_function(mProcess, "setpgrp", proc_setpgrp, 2);
+#endif
+#ifdef HAVE_SETPGID
+ rb_define_module_function(mProcess, "setpgid", proc_setpgid, 2);
+#endif
+#ifdef HAVE_GETPRIORITY
rb_define_module_function(mProcess, "getpriority", proc_getpriority, 2);
rb_define_module_function(mProcess, "setpriority", proc_setpriority, 3);
rb_define_const(mProcess, "PRIO_PROCESS", INT2FIX(PRIO_PROCESS));
rb_define_const(mProcess, "PRIO_PGRP", INT2FIX(PRIO_PGRP));
rb_define_const(mProcess, "PRIO_USER", INT2FIX(PRIO_USER));
+#endif
rb_define_module_function(mProcess, "uid", proc_getuid, 0);
rb_define_module_function(mProcess, "uid=", proc_setuid, 1);
diff --git a/random.c b/random.c
index f7bc59569b..ebe5a35dee 100644
--- a/random.c
+++ b/random.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:48 $
created at: Fri Dec 24 16:39:21 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -54,19 +54,35 @@ f_srand(argc, argv, obj)
}
static VALUE
-f_rand(obj, max)
- VALUE obj, max;
+f_rand(obj, vmax)
+ VALUE obj, vmax;
{
- int val;
+ int val, max;
#ifdef HAVE_RANDOM
if (first == 1) {
initstate(1, state, sizeof state);
first = 0;
}
- val = random() % NUM2INT(max);
+#endif
+
+ switch (TYPE(vmax)) {
+ case T_BIGNUM:
+ return big_rand(vmax);
+
+ case T_FLOAT:
+ if (RFLOAT(vmax)->value > LONG_MAX || RFLOAT(vmax)->value < LONG_MIN)
+ return big_rand(dbl2big(RFLOAT(vmax)->value));
+ break;
+ }
+
+ max = NUM2INT(vmax);
+ if (max == 0) ArgError("rand(0)");
+
+#ifdef HAVE_RANDOM
+ val = random() % max;
#else
- val = rand() % NUM2INT(max);
+ val = rand() % max;
#endif
if (val < 0) val = -val;
diff --git a/range.c b/range.c
index 147c28ae7c..b7d2f3b75e 100644
--- a/range.c
+++ b/range.c
@@ -6,7 +6,7 @@
$Date: 1994/12/06 09:30:12 $
created at: Thu Aug 19 17:46:47 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -14,55 +14,58 @@
VALUE mComparable;
static VALUE cRange;
+extern VALUE cNumeric;
static ID upto;
static VALUE
-range_s_new(class, start, end)
- VALUE class, start, end;
+range_s_new(class, first, last)
+ VALUE class, first, last;
{
VALUE obj;
- if (!(FIXNUM_P(start) && FIXNUM_P(end))
- && (TYPE(start) != TYPE(end)
- || CLASS_OF(start) != CLASS_OF(end)
- || !rb_responds_to(start, upto))) {
- Fail("bad value for range");
+ if (!(FIXNUM_P(first) && FIXNUM_P(last))
+ && (TYPE(first) != TYPE(last)
+ || CLASS_OF(first) != CLASS_OF(last)
+ || !rb_respond_to(first, upto))
+ && !(obj_is_kind_of(first, cNumeric)
+ && obj_is_kind_of(last, cNumeric))) {
+ ArgError("bad value for range");
}
obj = obj_alloc(class);
- rb_iv_set(obj, "start", start);
- rb_iv_set(obj, "end", end);
+ rb_iv_set(obj, "first", first);
+ rb_iv_set(obj, "last", last);
return obj;
}
VALUE
-range_new(start, end)
- VALUE start, end;
+range_new(first, last)
+ VALUE first, last;
{
- return range_s_new(cRange, start, end);
+ return range_s_new(cRange, first, last);
}
static VALUE
range_match(rng, obj)
VALUE rng, obj;
{
- VALUE beg, end;
+ VALUE first, last;
- beg = rb_iv_get(rng, "start");
- end = rb_iv_get(rng, "end");
+ first = rb_iv_get(rng, "first");
+ last = rb_iv_get(rng, "last");
- if (FIXNUM_P(beg) && FIXNUM_P(obj)) {
- if (FIX2INT(beg) <= FIX2INT(obj) && FIX2INT(obj) <= FIX2INT(end)) {
+ if (FIXNUM_P(first) && FIXNUM_P(obj)) {
+ if (FIX2INT(first) <= FIX2INT(obj) && FIX2INT(obj) <= FIX2INT(last)) {
return TRUE;
}
return FALSE;
}
else {
- if (rb_funcall(beg, rb_intern("<="), 1, obj) &&
- rb_funcall(end, rb_intern(">="), 1, obj)) {
+ if (rb_funcall(first, rb_intern("<="), 1, obj) &&
+ rb_funcall(last, rb_intern(">="), 1, obj)) {
return TRUE;
}
return FALSE;
@@ -70,23 +73,15 @@ range_match(rng, obj)
}
struct upto_data {
- VALUE beg;
- VALUE end;
+ VALUE first;
+ VALUE last;
};
static VALUE
range_upto(data)
struct upto_data *data;
{
- return rb_funcall(data->beg, upto, 1, data->end);
-}
-
-static VALUE
-range_upto_yield(v)
- VALUE v;
-{
- rb_yield(v);
- return Qnil;
+ return rb_funcall(data->first, upto, 1, data->last);
}
static VALUE
@@ -95,73 +90,105 @@ range_each(obj)
{
VALUE b, e;
- b = rb_iv_get(obj, "start");
- e = rb_iv_get(obj, "end");
+ b = rb_iv_get(obj, "first");
+ e = rb_iv_get(obj, "last");
if (FIXNUM_P(b)) { /* fixnum is a special case(for performance) */
num_upto(b, e);
}
- else if (TYPE(b) == T_STRING) {
- str_upto(b, e);
- }
else {
struct upto_data data;
- data.beg = b;
- data.end = e;
+ data.first = b;
+ data.last = e;
- rb_iterate(range_upto, &data, range_upto_yield, Qnil);
+ rb_iterate(range_upto, &data, rb_yield, 0);
}
return Qnil;
}
static VALUE
-range_start(obj)
+range_first(obj)
VALUE obj;
{
VALUE b;
- b = rb_iv_get(obj, "start");
+ b = rb_iv_get(obj, "first");
return b;
}
static VALUE
-range_end(obj)
+range_last(obj)
VALUE obj;
{
VALUE e;
- e = rb_iv_get(obj, "end");
+ e = rb_iv_get(obj, "last");
return e;
}
-static VALUE
-range_to_s(obj)
- VALUE obj;
-{
- VALUE args[4];
-
- args[0] = str_new2("%d..%d");
- args[1] = rb_iv_get(obj, "start");
- args[2] = rb_iv_get(obj, "end");
- return f_sprintf(3, args);
-}
-
VALUE
range_beg_end(range, begp, endp)
VALUE range;
int *begp, *endp;
{
- int beg, end;
+ VALUE first, last;
if (!obj_is_kind_of(range, cRange)) return FALSE;
- beg = rb_iv_get(range, "start"); *begp = NUM2INT(beg);
- end = rb_iv_get(range, "end"); *endp = NUM2INT(end);
+ first = rb_iv_get(range, "first"); *begp = NUM2INT(first);
+ last = rb_iv_get(range, "last"); *endp = NUM2INT(last);
return TRUE;
}
+static VALUE
+range_to_s(range)
+ VALUE range;
+{
+ VALUE str, str2;
+
+ str = obj_as_string(rb_iv_get(range, "first"));
+ str2 = obj_as_string(rb_iv_get(range, "last"));
+ str_cat(str, "..", 2);
+ str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
+
+ return str;
+}
+
+static VALUE
+range_inspect(range)
+ VALUE range;
+{
+ VALUE str, str2;
+
+ str = rb_inspect(rb_iv_get(range, "first"));
+ str2 = rb_inspect(rb_iv_get(range, "last"));
+ str_cat(str, "..", 2);
+ str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
+
+ return str;
+}
+
+static VALUE
+range_length(rng)
+ VALUE rng;
+{
+ VALUE first, last;
+ VALUE size;
+
+ first = rb_iv_get(rng, "first");
+ last = rb_iv_get(rng, "last");
+
+ if (!obj_is_kind_of(first, cNumeric)) {
+ return enum_length(rng);
+ }
+ size = rb_funcall(last, '-', 1, first);
+ size = rb_funcall(size, '+', 1, INT2FIX(1));
+
+ return size;
+}
+
extern VALUE mEnumerable;
void
@@ -170,11 +197,15 @@ Init_Range()
cRange = rb_define_class("Range", cObject);
rb_include_module(cRange, mEnumerable);
rb_define_singleton_method(cRange, "new", range_s_new, 2);
- rb_define_method(cRange, "=~", range_match, 1);
+ rb_define_method(cRange, "===", range_match, 1);
rb_define_method(cRange, "each", range_each, 0);
- rb_define_method(cRange, "start", range_start, 0);
- rb_define_method(cRange, "end", range_end, 0);
+ rb_define_method(cRange, "first", range_first, 0);
+ rb_define_method(cRange, "last", range_last, 0);
rb_define_method(cRange, "to_s", range_to_s, 0);
+ rb_define_method(cRange, "inspect", range_inspect, 0);
+
+ rb_define_method(cRange, "length", range_length, 0);
+ rb_define_method(cRange, "size", range_length, 0);
upto = rb_intern("upto");
}
diff --git a/re.c b/re.c
index f6dde5a4eb..bd6c2fb9b8 100644
--- a/re.c
+++ b/re.c
@@ -6,13 +6,15 @@
$Date: 1995/01/10 10:42:49 $
created at: Mon Aug 9 18:24:49 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
#include "ruby.h"
#include "re.h"
+static VALUE eRegxpError;
+
#define BEG(no) regs->beg[no]
#define END(no) regs->end[no]
@@ -104,6 +106,73 @@ static int reg_kcode =
# endif
#endif
+extern int rb_in_eval;
+
+static VALUE
+reg_desc(s, len, re)
+ char *s;
+ int len;
+ VALUE re;
+{
+ VALUE str = str_new2("/");
+ char *p, *pend;
+ int slash = 0;
+
+ p = s; pend = p + len;
+ while (p<pend) {
+ if (*p == '/') {
+ slash = 1;
+ break;
+ }
+ p++;
+ }
+ if (!slash) {
+ str_cat(str, s, len);
+ }
+ else {
+ p = s;
+ while (p<pend) {
+ if (*p == '/') {
+ char c = '\\';
+ str_cat(str, &c, 1);
+ str_cat(str, p, 1);
+ }
+ else {
+ str_cat(str, p, 1);
+ }
+ p++;
+ }
+ }
+ str_cat(str, "/", 1);
+ if (re && FL_TEST(re, REG_IGNORECASE)) {
+ str_cat(str, "i", 1);
+ }
+ return str;
+}
+
+static VALUE
+reg_inspect(re)
+ struct RRegexp *re;
+{
+ return reg_desc(re->str, re->len, re);
+}
+
+static void
+reg_raise(s, len, err, compile, re)
+ char *s;
+ int len;
+ char *err;
+ int compile;
+ VALUE re;
+{
+ VALUE desc = reg_desc(s, len, re);
+
+ if (!compile)
+ Raise(eRegxpError, "%s: %s", err, RSTRING(desc)->ptr);
+ else
+ Error("%s: %s", err, RSTRING(desc)->ptr);
+}
+
static Regexp*
make_regexp(s, len)
char *s;
@@ -125,17 +194,52 @@ make_regexp(s, len)
rp->allocated = 16;
rp->fastmap = ALLOC_N(char, 256);
- if ((err = re_compile_pattern(s, (size_t)len, rp)) != NULL)
- Fail("%s: /%s/", err, s);
+ if ((err = re_compile_pattern(s, (size_t)len, rp)) != NULL) {
+ reg_raise(s, len, err, !rb_in_eval, 0);
+ }
return rp;
}
+extern VALUE cData;
+static VALUE cMatch;
+
+static VALUE
+match_to_a(match)
+ struct RMatch *match;
+{
+ struct re_registers *regs = match->regs;
+ VALUE ary = ary_new(regs->num_regs);
+ int i;
+
+ for (i=0; i<regs->num_regs; i++) {
+ if (regs->beg[0] == -1) ary_push(ary, Qnil);
+ else ary_push(ary, str_new(match->ptr+regs->beg[i],
+ regs->end[i]-regs->beg[i]));
+ }
+ return ary;
+}
+
+static VALUE
+match_to_s(match)
+ struct RMatch *match;
+{
+ int beg, len;
+
+ if (match->regs->allocated == 0) return Qnil;
+
+ beg = match->regs->beg[0];
+ if (beg == -1) return Qnil;
+
+ len = match->regs->end[0] - beg;
+ return str_new(match->ptr+beg, len);
+}
+
static VALUE
match_alloc()
{
NEWOBJ(match, struct RMatch);
- OBJSETUP(match, cData, T_MATCH);
+ OBJSETUP(match, cMatch, T_MATCH);
match->ptr = 0;
match->len = 0;
@@ -155,10 +259,12 @@ reg_search(reg, str, start, regs)
struct re_registers *regs;
{
int result;
- int casefold = ignorecase;
+ int casefold = RTEST(ignorecase);
VALUE match = 0;
struct re_registers *regs0 = 0;
+ if (start > str->len) return -1;
+
/* case-flag set for the object */
if (FL_TEST(reg, REG_IGNORECASE)) {
casefold = TRUE;
@@ -174,16 +280,11 @@ reg_search(reg, str, start, regs)
reg->ptr->fastmap_accurate = 0;
}
- if (start > str->len) return -1;
-
- if (regs == (struct re_registers *)-1) {
+ if (regs == (struct re_registers*)-1) {
regs = 0;
}
- else if (match = backref_get()) {
- if (match == 1) {
- match = match_alloc();
- backref_set(match);
- }
+ else {
+ match = match_alloc();
regs0 = RMATCH(match)->regs;
}
@@ -192,8 +293,9 @@ reg_search(reg, str, start, regs)
if ((RBASIC(reg)->flags & KCODE_MASK) != reg_kcode) {
char *err;
- if ((err = re_compile_pattern(reg->str, reg->len, reg->ptr)) != NULL)
- Fail("%s: /%s/", err, reg->str);
+ if ((err = re_compile_pattern(reg->str, reg->len, reg->ptr)) != NULL) {
+ reg_raise(reg->str, reg->len, err, reg);
+ }
RBASIC(reg)->flags = RBASIC(reg)->flags & ~KCODE_MASK;
RBASIC(reg)->flags |= reg_kcode;
}
@@ -201,11 +303,18 @@ reg_search(reg, str, start, regs)
result = re_search(reg->ptr, str->ptr, str->len,
start, str->len - start, regs0);
- if (match && result >= 0) {
+ if (start == -2) {
+ reg_raise(reg->str, reg->len, "Stack overfow in regexp matcher", reg);
+ }
+ if (result < 0) {
+ backref_set(Qnil);
+ }
+ else if (match) {
RMATCH(match)->len = str->len;
REALLOC_N(RMATCH(match)->ptr, char, str->len+1);
memcpy(RMATCH(match)->ptr, str->ptr, str->len);
RMATCH(match)->ptr[str->len] = '\0';
+ backref_set(match);
}
if (regs && regs0 && regs0 != regs) re_copy_registers(regs, regs0);
@@ -217,7 +326,7 @@ reg_nth_defined(nth, match)
int nth;
struct RMatch *match;
{
- if (!match) return FALSE;
+ if (NIL_P(match)) return Qnil;
if (nth >= match->regs->num_regs) {
return FALSE;
}
@@ -232,7 +341,7 @@ reg_nth_match(nth, match)
{
int start, end, len;
- if (!match) return Qnil;
+ if (NIL_P(match)) return Qnil;
if (nth >= match->regs->num_regs) {
return Qnil;
}
@@ -254,7 +363,7 @@ VALUE
reg_match_pre(match)
struct RMatch *match;
{
- if (!match) return Qnil;
+ if (NIL_P(match)) return Qnil;
if (match->BEG(0) == -1) return Qnil;
return str_new(match->ptr, match->BEG(0));
}
@@ -263,7 +372,7 @@ VALUE
reg_match_post(match)
struct RMatch *match;
{
- if (!match) return Qnil;
+ if (NIL_P(match)) return Qnil;
if (match->BEG(0) == -1) return Qnil;
return str_new(match->ptr+match->END(0),
match->len-match->END(0));
@@ -275,7 +384,7 @@ reg_match_last(match)
{
int i;
- if (!match) return Qnil;
+ if (NIL_P(match)) return Qnil;
if (match->BEG(0) == -1) return Qnil;
for (i=match->regs->num_regs-1; match->BEG(i) == -1 && i > 0; i--)
@@ -293,13 +402,6 @@ Regexp *rp;
free(rp);
}
-void
-reg_error(s)
-const char *s;
-{
- Fail(s);
-}
-
VALUE cRegexp;
static VALUE
@@ -331,19 +433,22 @@ reg_new(s, len, ci)
return reg_new_1(cRegexp, s, len, ci);
}
-static VALUE reg_cache, ign_cache;
+int ign_cache;
+static VALUE reg_cache;
VALUE
reg_regcomp(str)
struct RString *str;
{
+ int ignc = RTEST(ignorecase);
+
if (reg_cache && RREGEXP(reg_cache)->len == str->len
- && ign_cache == ignorecase
+ && ign_cache == ignc
&& memcmp(RREGEXP(reg_cache)->str, str->ptr, str->len) == 0)
return reg_cache;
- ign_cache = ignorecase;
- return reg_cache = reg_new(str->ptr, str->len, ignorecase);
+ ign_cache = ignc;
+ return reg_cache = reg_new(str->ptr, str->len, ignc);
}
VALUE
@@ -356,7 +461,7 @@ reg_match(re, str)
if (TYPE(str) != T_STRING) return FALSE;
start = reg_search(re, str, 0, 0);
if (start < 0) {
- return Qnil;
+ return FALSE;
}
return INT2FIX(start);
}
@@ -365,15 +470,15 @@ VALUE
reg_match2(re)
struct RRegexp *re;
{
- extern VALUE rb_lastline;
int start;
+ VALUE line = lastline_get();
- if (TYPE(rb_lastline) != T_STRING)
- Fail("$_ is not a string");
+ if (TYPE(line) != T_STRING)
+ return FALSE;
- start = reg_search(re, rb_lastline, 0, 0);
- if (start == -1) {
- return Qnil;
+ start = reg_search(re, line, 0, 0);
+ if (start < 0) {
+ return FALSE;
}
return INT2FIX(start);
}
@@ -384,11 +489,11 @@ reg_s_new(argc, argv, self)
VALUE *argv;
VALUE self;
{
- VALUE src, reg;
+ VALUE src;
int ci = 0;
if (argc == 0 || argc > 2) {
- Fail("wrong # of argument");
+ ArgError("wrong # of argument");
}
if (argc == 2 && argv[1]) {
ci = 1;
@@ -397,10 +502,12 @@ reg_s_new(argc, argv, self)
src = argv[0];
switch (TYPE(src)) {
case T_STRING:
- reg = reg_new_1(self, RREGEXP(src)->ptr, RREGEXP(src)->len, ci);
+ return reg_new_1(self, RSTRING(src)->ptr, RSTRING(src)->len, ci);
+ break;
case T_REGEXP:
- reg = reg_new_1(self, RREGEXP(src)->str, RREGEXP(src)->len, ci);
+ return reg_new_1(self, RREGEXP(src)->str, RREGEXP(src)->len, ci);
+ break;
default:
Check_Type(src, T_STRING);
@@ -472,7 +579,7 @@ reg_regsub(str, src, regs)
no = -1;
if (no >= 0) {
- if (val == Qnil) {
+ if (NIL_P(val)) {
val = str_new(p, ss-p);
}
else {
@@ -490,7 +597,7 @@ reg_regsub(str, src, regs)
}
}
- if (val == Qnil) return (VALUE)str;
+ if (NIL_P(val)) return (VALUE)str;
if (p < e) {
str_cat(val, p, e-p);
}
@@ -501,20 +608,6 @@ reg_regsub(str, src, regs)
}
static VALUE
-reg_to_s(re)
- struct RRegexp *re;
-{
- VALUE str = str_new2("/");
-
- str_cat(str, re->str, re->len);
- str_cat(str, "/", 1);
- if (FL_TEST(re, REG_IGNORECASE)) {
- str_cat(str, "i", 1);
- }
- return str;
-}
-
-static VALUE
kcode_getter()
{
switch (reg_kcode) {
@@ -569,26 +662,7 @@ kcode_setter(val)
static VALUE
match_getter()
{
- VALUE match = backref_get();
-
- if (match && match != 1) {
- NEWOBJ(m, struct RMatch);
- OBJSETUP(m, cData, T_MATCH);
-
- m->len = RMATCH(match)->len;
- if (RMATCH(match)->ptr) {
- m->ptr = ALLOC_N(char, m->len+1);
- memcpy(m->ptr, RMATCH(match)->ptr, m->len);
- m->ptr[m->len] = '\0';
- }
- else {
- m->ptr = 0;
- }
- m->regs = ALLOC(struct re_registers);
- re_copy_registers(m->regs, RMATCH(match)->regs);
- return (VALUE)m;
- }
- return Qnil;
+ return backref_get();
}
static void
@@ -598,11 +672,16 @@ match_setter(val)
backref_set(val);
}
+VALUE krn_to_s();
+
void
Init_Regexp()
{
+ extern VALUE eException;
+
+ eRegxpError = rb_define_class("RegxpError", eException);
+
re_set_syntax(RE_NO_BK_PARENS | RE_NO_BK_VBAR
- | RE_AWK_CLASS_HACK
| RE_INTERVALS
| RE_NO_BK_BRACES
| RE_BACKSLASH_ESCAPE_IN_LISTS
@@ -623,8 +702,14 @@ Init_Regexp()
rb_define_method(cRegexp, "clone", reg_clone, 0);
rb_define_method(cRegexp, "=~", reg_match, 1);
+ rb_define_method(cRegexp, "===", reg_match, 1);
rb_define_method(cRegexp, "~", reg_match2, 0);
- rb_define_method(cRegexp, "to_s", reg_to_s, 0);
+ rb_define_method(cRegexp, "inspect", reg_inspect, 0);
rb_global_variable(&reg_cache);
+
+ cMatch = rb_define_class("MatchingData", cData);
+ rb_define_method(cMatch, "to_a", match_to_a, 0);
+ rb_define_method(cMatch, "to_s", match_to_s, 0);
+ rb_define_method(cMatch, "inspect", krn_to_s, 0);
}
diff --git a/re.h b/re.h
index babbe413e5..ebbe0673f5 100644
--- a/re.h
+++ b/re.h
@@ -7,7 +7,7 @@
$Date: 1994/08/12 04:47:52 $
created at: Thu Sep 30 14:18:32 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
diff --git a/regex.c b/regex.c
index 4b4ff8a193..c6bbb3027f 100644
--- a/regex.c
+++ b/regex.c
@@ -62,6 +62,10 @@ char *alloca();
#endif
#endif /* __GNUC__ */
+#ifdef _AIX
+#pragma alloca
+#endif
+
#define RE_ALLOCATE alloca
#define FREE_VARIABLES() alloca(0)
@@ -144,6 +148,8 @@ init_syntax_once()
for (c = '0'; c <= '9'; c++)
re_syntax_table[c] = Sword;
+ re_syntax_table['_'] = Sword;
+
/* Add specific syntax for ISO Latin-1. */
for (c = 0300; c <= 0377; c++)
re_syntax_table[c] = Sword;
@@ -238,7 +244,7 @@ enum regexpcode
#define NFAILURES 80
#endif
-#ifdef CHAR_UNSIGNED
+#if defined(CHAR_UNSIGNED) || defined(__CHAR_UNSIGNED__)
#define SIGN_EXTEND_CHAR(c) ((c)>(char)127?(c)-256:(c)) /* for IBM RT */
#endif
#ifndef SIGN_EXTEND_CHAR
@@ -795,7 +801,7 @@ re_compile_pattern(pattern, size, bufp)
while (1)
{
int size;
- unsigned last = -1;
+ unsigned last = (unsigned)-1;
if ((size = EXTRACT_UNSIGNED(&b[(1 << BYTEWIDTH) / BYTEWIDTH]))) {
/* Ensure the space is enough to hold another interval
@@ -830,8 +836,8 @@ re_compile_pattern(pattern, size, bufp)
PATFETCH(c);
switch (c) {
case 'w':
- for (c = 0; c < 256; c++)
- if (isalnum(c))
+ for (c = 0; c < (1 << BYTEWIDTH); c++)
+ if (SYNTAX(c) == Sword)
SET_LIST_BIT(c);
last = -1;
continue;
@@ -839,8 +845,8 @@ re_compile_pattern(pattern, size, bufp)
case 'W':
if (re_syntax_options & RE_MBCTYPE_MASK)
goto invalid_char;
- for (c = 0; c < 256; c++)
- if (!isalnum(c))
+ for (c = 0; c < (1 << BYTEWIDTH); c++)
+ if (SYNTAX(c) != Sword)
SET_LIST_BIT(c);
last = -1;
continue;
@@ -1072,7 +1078,9 @@ re_compile_pattern(pattern, size, bufp)
|| *laststart == charset
|| *laststart == charset_not
|| *laststart == start_memory
- || (*laststart == exactn && laststart[1] == 1)
+ || (*laststart == exactn
+ && (laststart[1] == 1
+ || laststart[1] == 2 && ismbchar(laststart[2])))
|| (! (re_syntax_options & RE_NO_BK_REFS)
&& *laststart == duplicate)))
{
@@ -1277,6 +1285,7 @@ re_compile_pattern(pattern, size, bufp)
c1 = 0;
GET_UNSIGNED_NUMBER(c1);
+ PATUNFETCH;
if (c1 >= regnum) {
if (c1 < RE_NREGS)
@@ -1722,27 +1731,27 @@ re_compile_fastmap(bufp)
-/* Using the compiled pattern in PBUFP->buffer, first tries to match
+/* Using the compiled pattern in BUFP->buffer, first tries to match
STRING, starting first at index STARTPOS, then at STARTPOS + 1, and
so on. RANGE is the number of places to try before giving up. If
RANGE is negative, it searches backwards, i.e., the starting
positions tried are STARTPOS, STARTPOS - 1, etc. STRING is of SIZE.
In REGS, return the indices of STRING that matched the entire
- PBUFP->buffer and its contained subexpressions.
+ BUFP->buffer and its contained subexpressions.
The value returned is the position in the strings at which the match
was found, or -1 if no match was found, or -2 if error (such as
failure stack overflow). */
int
-re_search(pbufp, string, size, startpos, range, regs)
- struct re_pattern_buffer *pbufp;
+re_search(bufp, string, size, startpos, range, regs)
+ struct re_pattern_buffer *bufp;
char *string;
int size, startpos, range;
struct re_registers *regs;
{
- register char *fastmap = pbufp->fastmap;
- register unsigned char *translate = (unsigned char *) pbufp->translate;
+ register char *fastmap = bufp->fastmap;
+ register unsigned char *translate = (unsigned char *) bufp->translate;
int val;
/* Check for out-of-range starting position. */
@@ -1750,8 +1759,8 @@ re_search(pbufp, string, size, startpos, range, regs)
return -1;
/* Update the fastmap now if not correct already. */
- if (fastmap && !pbufp->fastmap_accurate) {
- re_compile_fastmap (pbufp);
+ if (fastmap && !bufp->fastmap_accurate) {
+ re_compile_fastmap (bufp);
}
while (1)
@@ -1762,7 +1771,7 @@ re_search(pbufp, string, size, startpos, range, regs)
test it at each starting point so that we take the first null
string we get. */
- if (fastmap && startpos < size && pbufp->can_be_null != 1)
+ if (fastmap && startpos < size && bufp->can_be_null != 1)
{
if (range > 0) /* Searching forwards. */
{
@@ -1781,7 +1790,7 @@ re_search(pbufp, string, size, startpos, range, regs)
p++;
range--;
}
- else
+ else
if (fastmap[translate ? translate[c] : c])
break;
range--;
@@ -1799,11 +1808,12 @@ re_search(pbufp, string, size, startpos, range, regs)
}
}
- if (range >= 0 && startpos == size
- && fastmap && pbufp->can_be_null == 0)
- return -1;
+ if (range >= 0 && startpos == size && fastmap) {
+ if (bufp->can_be_null == 0 || (bufp->can_be_null == 2 && size > 0))
+ return -1;
+ }
- val = re_match(pbufp, string, size, startpos, regs);
+ val = re_match(bufp, string, size, startpos, regs);
if (val >= 0)
return startpos;
if (val == -2)
@@ -2006,12 +2016,12 @@ init_regs(regs, num_regs)
}
}
-/* Match the pattern described by PBUFP against STRING, which is of
+/* Match the pattern described by BUFP against STRING, which is of
SIZE. Start the match at index POS in STRING. In REGS, return the
- indices of STRING that matched the entire PBUFP->buffer and its
+ indices of STRING that matched the entire BUFP->buffer and its
contained subexpressions.
- If pbufp->fastmap is nonzero, then it had better be up to date.
+ If bufp->fastmap is nonzero, then it had better be up to date.
The reason that the data to match are specified as two components
which are to be regarded as concatenated is so this function can be
@@ -2022,24 +2032,24 @@ init_regs(regs, num_regs)
length of the substring which was matched. */
int
-re_match(pbufp, string_arg, size, pos, regs)
- struct re_pattern_buffer *pbufp;
+re_match(bufp, string_arg, size, pos, regs)
+ struct re_pattern_buffer *bufp;
char *string_arg;
int size, pos;
struct re_registers *regs;
{
- register unsigned char *p = (unsigned char *) pbufp->buffer;
+ register unsigned char *p = (unsigned char *) bufp->buffer;
/* Pointer to beyond end of buffer. */
- register unsigned char *pend = p + pbufp->used;
+ register unsigned char *pend = p + bufp->used;
- unsigned num_regs = pbufp->re_nsub + 1;
+ unsigned num_regs = bufp->re_nsub;
unsigned char *string = (unsigned char *) string_arg;
register unsigned char *d, *dend;
register int mcnt; /* Multipurpose. */
- unsigned char *translate = (unsigned char *) pbufp->translate;
+ unsigned char *translate = (unsigned char *) bufp->translate;
unsigned is_a_jump_n = 0;
/* Failure point stack. Each place that can handle a failure further
@@ -2133,7 +2143,7 @@ re_match(pbufp, string_arg, size, pos, regs)
#ifdef DEBUG_REGEX
fprintf(stderr,
"regex loop(%d): matching 0x%02d\n",
- p - (unsigned char *) pbufp->buffer,
+ p - (unsigned char *) bufp->buffer,
*p);
#endif
is_a_jump_n = 0;
@@ -2666,21 +2676,25 @@ re_copy_registers(regs1, regs2)
if (regs1->allocated == 0) {
regs1->beg = TMALLOC(regs2->num_regs, int);
regs1->end = TMALLOC(regs2->num_regs, int);
+ regs1->allocated = regs2->num_regs;
}
else if (regs1->allocated < regs2->num_regs) {
TREALLOC(regs1->beg, regs2->num_regs, int);
TREALLOC(regs1->end, regs2->num_regs, int);
+ regs1->allocated = regs2->num_regs;
}
for (i=0; i<regs2->num_regs; i++) {
regs1->beg[i] = regs2->beg[i];
regs1->end[i] = regs2->end[i];
}
+ regs1->num_regs = regs2->num_regs;
}
void
re_free_registers(regs)
struct re_registers *regs;
{
+ if (regs->allocated == 0) return;
if (regs->beg) free(regs->beg);
if (regs->end) free(regs->end);
}
diff --git a/regex.h b/regex.h
index 971c4e5c74..7b31b87b62 100644
--- a/regex.h
+++ b/regex.h
@@ -17,7 +17,7 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* Multi-byte extension added May, 1993 by t^2 (Takahiro Tanimoto)
Last change: May 21, 1993 by t^2 */
-
+/* modifis for Ruby by matz@caelum.co.jp */
#ifndef __REGEXP_LIBRARY
#define __REGEXP_LIBRARY
diff --git a/ruby.c b/ruby.c
index 9d437f8895..8e4ab30148 100644
--- a/ruby.c
+++ b/ruby.c
@@ -6,38 +6,39 @@
$Date: 1995/01/10 10:42:51 $
created at: Tue Aug 10 12:47:31 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
#include "ruby.h"
#include "re.h"
+#include "dln.h"
#include <stdio.h>
-#include <fcntl.h>
#include <sys/types.h>
-#include <sys/stat.h>
-#include "dln.h"
+#include <fcntl.h>
#ifdef HAVE_STRING_H
# include <string.h>
#else
char *strchr();
+char *strrchr();
char *strstr();
#endif
static int version, copyright;
-int debug = 0;
-int verbose = 0;
+int debug = FALSE;
+int verbose = FALSE;
static int sflag = FALSE;
-char *inplace = 0;
+char *inplace = FALSE;
char *strdup();
extern int yydebug;
extern int nerrs;
-int xflag = FALSE;
+static int xflag = FALSE;
+extern VALUE RS, RS_default, ORS, FS;
static void load_stdin();
static void load_file();
@@ -49,10 +50,18 @@ static int do_split = FALSE;
static char *script;
#ifndef RUBY_LIB
-#define RUBY_LIB ".:/usr/local/lib/ruby"
+#if defined(MSDOS)
+#define RUBY_LIB "/usr/local/lib/ruby;."
+#else
+#define RUBY_LIB "/usr/local/lib/ruby:."
+#endif
#endif
+#if defined(MSDOS)
+#define RUBY_LIB_SEP ';'
+#else
#define RUBY_LIB_SEP ':'
+#endif
extern VALUE rb_load_path;
VALUE Frequire();
@@ -62,21 +71,24 @@ addpath(path)
char *path;
{
char *p, *s;
+ VALUE ary;
if (path == 0) return;
+ ary = ary_new();
p = s = path;
while (*p) {
while (*p == RUBY_LIB_SEP) p++;
- if (s = strchr(p, RUBY_LIB_SEP)) {
- ary_push(rb_load_path, str_new(p, (int)(s-p)));
+ if (s = strrchr(p, RUBY_LIB_SEP)) {
+ ary_push(ary, str_new(p, (int)(s-p)));
p = s + 1;
}
else {
- ary_push(rb_load_path, str_new2(p));
+ ary_push(ary, str_new2(p));
break;
}
}
+ rb_load_path = ary_plus(ary, rb_load_path);
}
static void
@@ -89,13 +101,11 @@ proc_options(argcp, argvp)
int script_given, do_search;
char *s;
- extern VALUE RS, ORS, FS;
-
if (argc == 0) return;
version = FALSE;
- script_given = FALSE;
do_search = FALSE;
+ script_given = 0;
for (argc--,argv++; argc > 0; argc--,argv++) {
if (argv[0][0] != '-' || !argv[0][1]) break;
@@ -127,8 +137,10 @@ proc_options(argcp, argvp)
goto reswitch;
case 'v':
- verbose = TRUE;
show_version();
+ verbose = 2;
+ case 'w':
+ verbose |= 1;
s++;
goto reswitch;
@@ -157,13 +169,12 @@ proc_options(argcp, argvp)
script_given++;
if (script == 0) script = "-e";
if (argv[1]) {
- lex_setsrc("-e", argv[1], strlen(argv[1]));
+ compile_string("-e", argv[1], strlen(argv[1]));
argc--,argv++;
}
else {
- lex_setsrc("-e", "", 0);
+ compile_string("-e", "", 0);
}
- yyparse();
break;
case 'r':
@@ -211,9 +222,9 @@ proc_options(argcp, argvp)
case 'I':
if (*++s)
- ary_push(rb_load_path, str_new2(s));
+ addpath(s);
else if (argv[1]) {
- ary_push(rb_load_path, str_new2(argv[1]));
+ addpath(argv[1]);
argc--,argv++;
}
break;
@@ -250,7 +261,7 @@ proc_options(argcp, argvp)
else if (strcmp("version", s) == 0)
version = 1;
else if (strcmp("verbose", s) == 0)
- verbose = 1;
+ verbose = 2;
else if (strcmp("yydebug", s) == 0)
yydebug = 1;
else {
@@ -277,22 +288,29 @@ proc_options(argcp, argvp)
show_copyright();
}
- if (script_given == 0) {
+ if (script_given == FALSE) {
if (argc == 0) { /* no more args */
- if (verbose) exit(0);
+ if (verbose == 3) exit(0);
script = "-";
load_stdin();
}
else {
script = argv[0];
- if (do_search) {
- script = dln_find_file(script, getenv("PATH"));
- if (!script) script = argv[0];
+ if (script[0] == '\0') {
+ script = "-";
+ load_stdin();
+ }
+ else {
+ if (do_search) {
+ script = dln_find_file(script, getenv("PATH"));
+ if (!script) script = argv[0];
+ }
+ load_file(script, 1);
}
- load_file(script, 1);
- argc--,argv++;
+ argc--; argv++;
}
}
+ if (verbose) verbose = TRUE;
xflag = FALSE;
*argvp = argv;
@@ -321,93 +339,85 @@ proc_options(argcp, argvp)
}
+static VALUE
+open_to_load(fname)
+ char *fname;
+{
+}
+
static void
-readin(fd, fname, script)
- int fd;
+load_file(fname, script)
char *fname;
int script;
{
- struct stat st;
- char *ptr, *p, *pend;
+ extern VALUE rb_stdin;
+ VALUE f;
+ int line_start = 1;
- if (fstat(fd, &st) < 0) rb_sys_fail(fname);
- if (!S_ISREG(st.st_mode))
- Fail("script is not a regular file - %s", fname);
-
- p = ptr = ALLOC_N(char, st.st_size+1);
- if (read(fd, ptr, st.st_size) != st.st_size) {
- free(ptr);
- rb_sys_fail(fname);
+ if (strcmp(fname, "-") == 0) {
+ f = rb_stdin;
+ }
+ else {
+ f = file_open(fname, "r");
}
- pend = p + st.st_size;
- *pend = '\0';
if (script) {
+ VALUE c;
+ VALUE line;
+ VALUE rs = RS;
+
+ RS = RS_default;
if (xflag) {
xflag = FALSE;
- while (p < pend) {
- if (p[0] == '#' && p[1] == '!') {
- char *s = p;
- while (s < pend && *s != '\n') s++;
- if (*s == '\n') {
- *s = '\0';
- if (strstr(p, "ruby")) {
- *s = '\n';
- goto start_read;
- }
+ while (!NIL_P(line = io_gets(f))) {
+ line_start++;
+ if (RSTRING(line)->len > 2
+ || RSTRING(line)->ptr[0] != '#'
+ || RSTRING(line)->ptr[1] != '!') {
+ if (strstr(RSTRING(line)->ptr, "ruby")) {
+ goto start_read;
}
- p = s + 1;
- }
- else {
- while (p < pend && *p++ != '\n')
- ;
- if (p >= pend) break;
}
}
- free(ptr);
- Fail("No Ruby script found in input");
+ RS = rs;
+ LoadError("No Ruby script found in input");
}
- start_read:
- if (p[0] == '#' && p[1] == '!') {
- char *s = p, *q;
+ c = io_getc(f);
+ if (c == INT2FIX('#')) {
+ line = io_gets(f);
+ line_start++;
+
+ if (RSTRING(line)->len > 2
+ || RSTRING(line)->ptr[0] != '#'
+ || RSTRING(line)->ptr[1] != '!') {
- while (s < pend && *s != '\n') s++;
- if (*s == '\n') {
- *s = '\0';
- if (q = strstr(p, "ruby -")) {
+ char *p;
+
+ start_read:
+ if (p = strstr(RSTRING(line)->ptr, "ruby -")) {
int argc; char *argv[2]; char **argvp = argv;
- argc = 2; argv[0] = Qnil; argv[1] = q + 5;
+ char *s;
+
+ s = RSTRING(line)->ptr;
+ while (isspace(*s++))
+ ;
+ *s = '\0';
+ RSTRING(line)->ptr[RSTRING(line)->len-1] = '\0';
+ if (RSTRING(line)->ptr[RSTRING(line)->len-2] == '\r')
+ RSTRING(line)->ptr[RSTRING(line)->len-2] = '\0';
+ argc = 2; argv[0] = 0; argv[1] = p + 5;
proc_options(&argc, &argvp);
- p = s + 1;
- }
- else {
- *s = '\n';
}
}
}
+ else if (!NIL_P(c)) {
+ io_ungetc(f, c);
+ }
+ RS = rs;
}
- lex_setsrc(fname, p, pend - p);
- yyparse();
- free(ptr);
-}
-
-static void
-load_file(fname, script)
- char *fname;
- int script;
-{
- int fd;
-
- if (fname[0] == '\0') {
- load_stdin();
- return;
- }
-
- fd = open(fname, O_RDONLY, 0);
- if (fd < 0) rb_sys_fail(fname);
- readin(fd, fname, script);
- close(fd);
+ compile_file(fname, f, line_start);
+ if (f != rb_stdin) io_close(f);
}
void
@@ -420,21 +430,7 @@ rb_load_file(fname)
static void
load_stdin()
{
- char buf[32];
- FILE *f;
- char c;
- int fd;
-
- sprintf(buf, "/tmp/ruby-f%d", getpid());
- f = fopen(buf, "w");
- fd = open(buf, O_RDONLY, 0);
- if (fd < 0) rb_sys_fail(buf);
- unlink(buf);
- while ((c = getchar()) != EOF) {
- putc(c, f);
- }
- fclose(f);
- readin(fd, "-");
+ load_file("-", 1);
}
VALUE Progname;
@@ -500,16 +496,28 @@ ruby_options(argc, argv, envp)
origargc = argc; origargv = argv; origenvp = envp;
- rb_define_variable("$@", &errat);
errat = str_new2(argv[0]);
rb_define_variable("$VERBOSE", &verbose);
rb_define_variable("$DEBUG", &debug);
+ addpath(getenv("RUBYLIB"));
+ addpath(RUBY_LIB);
+#ifdef RUBY_ARCHLIB
+ addpath(RUBY_ARCHLIB);
+#endif
#if defined(USE_DLN_A_OUT)
dln_argv0 = argv[0];
#endif
+ rb_define_hooked_variable("$0", &Progname, 0, set_arg0);
+
+ Argv = ary_new2(argc);
+ rb_define_readonly_variable("$*", &Argv);
+ rb_define_global_const("ARGV", Argv);
+
proc_options(&argc, &argv);
+ ruby_script(script);
+
if (do_check && nerrs == 0) {
printf("Syntax OK\n");
exit(0);
@@ -518,18 +526,9 @@ ruby_options(argc, argv, envp)
yyappend_print();
}
if (do_loop) {
- yywhole_loop(do_line, do_split);
+ yywhile_loop(do_line, do_split);
}
- rb_define_hooked_variable("$0", &Progname, 0, set_arg0);
- ruby_script(script);
-
- addpath(getenv("RUBYLIB"));
- addpath(RUBY_LIB);
-
- rb_define_readonly_variable("$ARGV", &Argv);
- rb_define_readonly_variable("$*", &Argv);
- Argv = ary_new2(argc);
for (i=0; i < argc; i++) {
ary_push(Argv, str_new2(argv[i]));
}
diff --git a/ruby.h b/ruby.h
index 5ea5a237af..13c96e1a73 100644
--- a/ruby.h
+++ b/ruby.h
@@ -6,7 +6,7 @@
$Date: 1995/01/12 08:54:52 $
created at: Thu Jun 10 14:26:32 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
*************************************************/
@@ -26,12 +26,19 @@
# else
# define const
# endif
+# define _(args)
+#else
+# define _(args) args
#endif
#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
#include <alloca.h>
#endif
+#ifdef _AIX
+#pragma alloca
+#endif
+
typedef unsigned int UINT;
typedef UINT VALUE;
typedef UINT ID;
@@ -66,6 +73,7 @@ typedef unsigned short USHORT;
#define FIXNUM_FLAG 0x01
#define INT2FIX(i) (VALUE)(((int)(i))<<1 | FIXNUM_FLAG)
VALUE int2inum();
+#define INT2NUM(v) int2inum(v)
#if (-1==(((-1)<<1)&FIXNUM_FLAG)>>1)
# define RSHIFT(x,y) ((x)>>y)
@@ -80,19 +88,20 @@ VALUE int2inum();
#define NEGFIXABLE(f) ((f) >= FIXNUM_MIN)
#define FIXABLE(f) (POSFIXABLE(f) && NEGFIXABLE(f))
-#define NIL_P(p) ((p) == Qnil)
-
+/* special contants - i.e. non-zero and non-fixnum constants */
+#define FALSE 0
#undef TRUE
-extern VALUE TRUE;
-#define FALSE Qnil
+#define TRUE 2
+#define Qnil 4
+
+int rb_test_false_or_nil();
+# define RTEST(v) rb_test_false_or_nil(v)
+#define NIL_P(v) ((VALUE)(v) == Qnil)
extern VALUE cObject;
-extern VALUE cNil;
-extern VALUE cFixnum;
-extern VALUE cData;
-#define CLASS_OF(obj) (FIXNUM_P(obj)?cFixnum: NIL_P(obj)?cNil:\
- RBASIC(obj)->class)
+VALUE rb_class_of();
+#define CLASS_OF(v) rb_class_of(v)
#define T_NIL 0x00
#define T_OBJECT 0x01
@@ -107,9 +116,12 @@ extern VALUE cData;
#define T_HASH 0x0a
#define T_STRUCT 0x0b
#define T_BIGNUM 0x0c
+#define T_FILE 0x0d
-#define T_DATA 0x10
-#define T_MATCH 0x11
+#define T_TRUE 0x20
+#define T_FALSE 0x21
+#define T_DATA 0x22
+#define T_MATCH 0x23
#define T_VARMAP 0xfd
#define T_SCOPE 0xfe
@@ -118,8 +130,11 @@ extern VALUE cData;
#define T_MASK 0xff
#define BUILTIN_TYPE(x) (((struct RBasic*)(x))->flags & T_MASK)
-#define TYPE(x) (FIXNUM_P(x)?T_FIXNUM:NIL_P(x)?T_NIL:BUILTIN_TYPE(x))
-#define Check_Type(x,t) {if (TYPE(x)!=(t)) WrongType(x,t);}
+
+int rb_type();
+#define TYPE(x) rb_type(x)
+
+void Check_Type();
#define Need_Fixnum(x) {if (!FIXNUM_P(x)) (x) = num2fix(x);}
#define NUM2INT(x) (FIXNUM_P(x)?FIX2INT(x):num2int(x))
VALUE num2fix();
@@ -180,6 +195,11 @@ struct RHash {
struct st_table *tbl;
};
+struct RFile {
+ struct RBasic basic;
+ struct OpenFile *fptr;
+};
+
struct RData {
struct RBasic basic;
void (*dmark)();
@@ -189,23 +209,16 @@ struct RData {
#define DATA_PTR(dta) (RDATA(dta)->data)
-VALUE data_new();
-VALUE rb_ivar_get();
-VALUE rb_ivar_set();
-
-#define Get_Data_Struct(obj, iv, type, sval) {\
- VALUE _data_;\
- _data_ = rb_ivar_get(obj, iv);\
- Check_Type(_data_, T_DATA);\
- sval = (type*)DATA_PTR(_data_);\
-}
+VALUE data_object_alloc();
+#define Make_Data_Struct(class,type,mark,free,sval) (\
+ sval = ALLOC(type),\
+ memset(sval, 0, sizeof(type)),\
+ data_object_alloc(class,sval,mark,free)\
+)
-#define Make_Data_Struct(obj, iv, type, mark, free, sval) {\
- VALUE _new_;\
- sval = ALLOC(type);\
- _new_ = data_new(sval,mark,free);\
- memset(sval, 0, sizeof(type));\
- rb_ivar_set(obj, iv, _new_);\
+#define Get_Data_Struct(obj,type,sval) {\
+ Check_Type(obj, T_DATA); \
+ sval = (type*)DATA_PTR(obj);\
}
struct RStruct {
@@ -233,28 +246,27 @@ struct RBignum {
#define RDATA(obj) (R_CAST(RData)(obj))
#define RSTRUCT(obj) (R_CAST(RStruct)(obj))
#define RBIGNUM(obj) (R_CAST(RBignum)(obj))
+#define RFILE(obj) (R_CAST(RFile)(obj))
-#define FL_SINGLE (1<<8)
-#define FL_MARK (1<<9)
+#define FL_SINGLETON (1<<8)
+#define FL_MARK (1<<9)
-#define FL_USER0 (1<<10)
-#define FL_USER1 (1<<11)
-#define FL_USER2 (1<<12)
-#define FL_USER3 (1<<13)
-#define FL_USER4 (1<<14)
-#define FL_USER5 (1<<15)
-#define FL_USER6 (1<<16)
-#define FL_USER7 (1<<17)
+#define FL_USER0 (1<<10)
+#define FL_USER1 (1<<11)
+#define FL_USER2 (1<<12)
+#define FL_USER3 (1<<13)
+#define FL_USER4 (1<<14)
+#define FL_USER5 (1<<15)
+#define FL_USER6 (1<<16)
-#define FL_UMASK (0xff<<10)
+#define FL_UMASK (0x7f<<10)
-#define FL_ABLE(x) (!(FIXNUM_P(x)||NIL_P(x)))
+int rb_special_const_p();
+#define FL_ABLE(x) (!(FIXNUM_P(x)||rb_special_const_p(x)))
#define FL_TEST(x,f) (FL_ABLE(x)?(RBASIC(x)->flags&(f)):0)
#define FL_SET(x,f) if (FL_ABLE(x)) {RBASIC(x)->flags |= (f);}
#define FL_UNSET(x,f) if(FL_ABLE(x)){RBASIC(x)->flags &= ~(f);}
-
-extern VALUE Qself;
-#define Qnil 0
+#define FL_REVERSE(x,f) if(FL_ABLE(x)){RBASIC(x)->flags ^= f;}
#define ALLOC_N(type,n) (type*)xmalloc(sizeof(type)*(n))
#define ALLOC(type) (type*)xmalloc(sizeof(type))
@@ -277,6 +289,7 @@ void rb_extend_object();
void rb_define_variable();
void rb_define_const();
+void rb_define_global_const();
void rb_define_method();
void rb_define_singleton_method();
@@ -289,26 +302,30 @@ char *rb_id2name();
ID rb_to_id();
char *rb_class2name();
-VALUE rb_method_boundp();
+int rb_method_boundp();
VALUE rb_eval_string();
VALUE rb_funcall();
VALUE rb_funcall2();
int rb_scan_args();
+VALUE rb_ivar_get();
+VALUE rb_ivar_set();
+
VALUE rb_iv_get();
VALUE rb_iv_set();
void rb_const_set();
VALUE rb_yield();
-VALUE iterator_p();
+int iterator_p();
-VALUE rb_equal();
+int rb_equal();
extern int verbose, debug;
#ifdef __GNUC__
typedef void voidfn ();
+volatile voidfn Raise;
volatile voidfn Fail;
volatile voidfn Fatal;
volatile voidfn Bug;
@@ -316,8 +333,11 @@ volatile voidfn WrongType;
volatile voidfn rb_sys_fail;
volatile voidfn rb_break;
volatile voidfn rb_exit;
-volatile voidfn rb_fail;
+volatile voidfn rb_fatal;
+volatile voidfn rb_raise;
+volatile voidfn rb_notimplement;
#else
+void Raise();
void Fail();
void Fatal();
void Bug();
@@ -325,9 +345,12 @@ void WrongType();
void rb_sys_fail();
void rb_break();
void rb_exit();
-void rb_fail();
+void rb_fatal();
+void rb_raise();
+void rb_notimplement();
#endif
+void Error();
void Warning();
#if defined(EXTLIB) && defined(USE_DLN_A_OUT)
diff --git a/ruby.texi b/ruby.texi
deleted file mode 100644
index 50ffb63a16..0000000000
--- a/ruby.texi
+++ /dev/null
@@ -1,5044 +0,0 @@
-\input texinfo @c -*-texinfo-*- created at: Tue Jun 20 16:58:39 JST 1995
-@setfilename ruby.info
-@settitle Ruby Reference Manual
-
-@titlepage
-@title Ruby Reference Manual
-@subtitle The Object-Oriented Scripting Language
-@author Yukihiro Matsumoto
-@author matz@@caelum.co.jp
-@end titlepage
-
-@node Top, ¤Ï¤¸¤á¤Ë, (dir), (dir)
-
-Ruby Reference Manual
-
-@menu
-* ¤Ï¤¸¤á¤Ë::
-* ¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó::
-* ruby¤Îʸˡ::
-* ÁȤ߹þ¤ß´Ø¿ô::
-* ÁȤ߹þ¤ßÊÑ¿ô¤ÈÄê¿ô::
-* ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë::
-* C¸À¸ì¤È¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹::
-* ¼Õ¼­::
-* ʸˡ::
-* Variables Index::
-* Concept Index::
-* Function Index::
-@end menu
-
-@node ¤Ï¤¸¤á¤Ë, ¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó, Top, Top
-@comment node-name, next, previous, up
-@chapter ¤Ï¤¸¤á¤Ë
-
-Ruby¤Ï, ¼ê·Ú¤Ê¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¥×¥í¥°¥é¥ß¥ó¥°¤ò¼Â¸½¤¹¤ë¤¿¤á¤Î¼ï¡¹¤Îµ¡Ç½
-¤ò»ý¤Ä¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¥¹¥¯¥ê¥×¥È¸À¸ì¤Ç¤¢¤ë¡¥ËܳÊŪ¤Ê¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¸À
-¸ì¤Ç¤¢¤ëSmalltalk, Eiffel¤äC++¤Ê¤É¤Ç¤ÏÂ礲¤µ¤Ë»×¤ï¤ì¤ë¤è¤¦¤ÊÎΰè¤Ç¤Î¥ª
-¥Ö¥¸¥§¥¯¥È»Ø¸þ¥×¥í¥°¥é¥ß¥ó¥°¤ò»Ù±ç¤¹¤ë¤³¤È¤òÌÜŪ¤È¤¹¤ë¡¥¤½¤ÎÀ߷פδðËÜ
-¸¶Â§¤Ï, °Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë.
-
-@itemize @bullet
-@item
-
-µ¡Ç½À­
-
-ñ½ã¤ÇÎã³°¤Î¾¯¤Ê¤¤Ê¸Ë¡¤Ç¡¤¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¥×¥í¥°¥é¥ß¥ó¥°¤È¥¹¥¯¥ê¥×¥È¥×
-¥í¥°¥é¥ß¥ó¥°¤Î¤¿¤á¤ËɬÍפʵ¡Ç½¤ò½½Ê¬¤ËÈ÷¤¨¤ë.
-
-@item
-
-³ÈÄ¥À­
-
-ɬÍפ˱þ¤¸¤ÆÍưפ˵¡Ç½¤ò³ÈÄ¥¤Ç¤­¤ë¡¥¥¯¥é¥¹¤ò¼«Í³¤ËÄɲäǤ­¤ë¤³¤È¤ÏÌÞÏÀ,
-C¥×¥í¥°¥é¥à¤Î¥ê¥ó¥¯¤Ë¤è¤Ã¤Æ¥¤¥ó¥¿¥×¥ê¥¿¤Ë¤¢¤é¤æ¤ëµ¡Ç½¤òÄɲäǤ­¤ë¡¥ ¤µ
-¤é¤Ë¥×¥é¥Ã¥È¥Õ¥©¡¼¥à¤Ë¤è¤Ã¤Æ¤Ï, ưŪ¤Ë¥ª¥Ö¥¸¥§¥¯¥È¥³¡¼¥É¤ò¥ê¥ó¥¯¤¹¤ëµ¡
-ǽ¤âÄ󶡤¹¤ë.
-
-@item
-
-°ì´ÓÀ­
-
-¾¯¿ô¤Î¸¶Â§¤¬Á´ÂΤËŬÍѤµ¤ì¤ë¤è¤¦¤Ê°ì´ÓÀ­¤Î¤¢¤ë¸À¸ì»ÅÍͤò»ý¤Ä¡¥¤³¤ì¤Ë
-¤è¤Ã¤Æ¡Ö¥Ñ¥º¥ë¤Î³Ú¤·¤µ¡×¤Ï¸º¾¯¤·¤¿¤«¤âÃΤì¤Ê¤¤¡¥¤¿¤À¤·,°ì´ÓÀ­¤Î¤¿¤á»È
-¤¤¤ä¤¹¤µ¤òµ¾À·¤Ë¤¹¤ë¤³¤È¤Ï¤Ê¤¤.
-@end itemize
-
-Ruby¤Ï¡Ö¼ê·Ú¡×¤Ç¤Ï¤¢¤ë¤¬ËܳÊŪ¤Ê¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þµ¡Ç½¤ò»ý¤Ä¤Î¤Ç¡¤perl,
-tcl, python¤Ê¤É¥¹¥¯¥ê¥×¥È¸À¸ì¤Ë¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þµ¡Ç½¤òÄɲä·¤¿¤è¤¦¤Ê½è
-Íý·Ï¤è¤ê¤â¼«Á³¤Ë¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¤Ç¤­¤ë¡¥¹¹¤Ë¥¬¡¼¥Ù¡¼¥¸¥³¥ì¥¯¥¿¤äÎã³°½è
-Íýµ¡Ç½¤Ï¤è¤ê²÷Ŭ¤Ê¥×¥í¥°¥é¥ß¥ó¥°¤ò»Ù±ç¤¹¤ë¡¥
-
-Ruby¤Ï¥Æ¥­¥¹¥È½èÍý´Ø·¸¤Îµ¡Ç½¤òË­ÉÙ¤Ë(perl¤ÈƱ¤¸¤¯¤é¤¤)»ý¤Á¡¤OS¤òľÀÜÁà
-ºî¤¹¤ë¤è¤¦¤Ê½èÍý¤âµ­½Ò¤Ç¤­¤ë¡¥¤Þ¤¿, ½ã¿è¤Ê¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þ¸À¸ì¤Ç¤¢¤ê¤Ê
-¤¬¤é, ɬÍפǤ¢¤ì¤Ð¼ê³¤­·¿¥×¥í¥°¥é¥ß¥ó¥°¤â²Äǽ¤Ç¤¢¤ë.
-
-Ruby¤Ïsh¤äperl¤òÃΤäƤ¤¤ë¿Í¤Ë¤È¤Ã¤Æ¤Î¾ï¼±¤Ë¤Ç¤­¤ë¸Â¤ê½¾¤Ã¤¿¤Î¤Ç,¤½¤ì
-¤é¤Î¸À¸ì¤ËÀºÄ̤·¤Æ¤¤¤ë¿Í¤Ë¤È¤Ã¤Æ¤Ï½¬ÆÀ¤¬(¿ʬ)ÍưפÀ¤í¤¦¡¥¥×¥í¥°¥é¥Þ¤¬
-Ruby¤Î¥ª¥Ö¥¸¥§¥¯¥È»Ø¸þµ¡Ç½¤Ë¤Ä¤¤¤Æ³Ø¤Ù¤Ð¡¤¤è¤ê¶¯ÎϤʤ³¤È¤â¤Ç¤­¤ë¤è¤¦¤Ë
-¤Ê¤ë¤À¤í¤¦¡¥
-
-@node ¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó, ruby¤Îʸˡ, ¤Ï¤¸¤á¤Ë, Top
-@comment node-name, next, previous, up
-@chapter ¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó
-
-ruby¥¤¥ó¥¿¥×¥ê¥¿¤Ï°Ê²¼¤Î°ú¿ô¤ò¼õ¤±ÉÕ¤±¤ë.
-
-@table @samp
-
-@item -0¿ô»ú
-
-ÆþÎϥ쥳¡¼¥É¥»¥Ñ¥ì¡¼¥¿(@code{$/})¤Î8¿Ê¿ô¤Ç»ØÄꤹ¤ë¡¥
-
-¿ô»ú¤ò»ØÄꤷ¤Ê¤¤¾ì¹ç¤Ï¥Ì¥ë¥­¥ã¥é¥¯¥¿¤¬¥»¥Ñ¥ì¡¼¥¿¤Ë¤Ê¤ë¡£¿ô¤Î¸å¤Ë¾¤Î¥¹
-¥¤¥Ã¥Á¤¬¤¢¤Ã¤Æ¤â¤è¤¤¡£
-
--00¤Ç, ¥Ñ¥é¥°¥é¥Õ¥â¡¼¥É, -0777¤Ç(¤½¤Î¥³¡¼¥É¤ò»ý¤Äʸ»ú¤Ï¸ºß¤·¤Ê¤¤¤Î¤Ç)
-Á´¥Õ¥¡¥¤¥ë¤ò°ìÅÙ¤ËÆɤ߹þ¤à¥â¡¼¥É¤ËÀßÄê¤Ç¤­¤ë.
-
-@item -a
-@cindex{¥ª¡¼¥È¥¹¥×¥ê¥Ã¥È¥â¡¼¥É}
-
-@code{-n}¤ä@code{-p}¤È¤È¤â¤ËÍѤ¤¤Æ, ¥ª¡¼¥È¥¹¥×¥ê¥Ã¥È¥â¡¼¥É¤òON¤Ë¤¹¤ë¡¥
-¥ª¡¼¥È¥¹¥×¥ê¥Ã¥È¥â¡¼¥É¤Ç¤Ï³Æ¥ë¡¼¥×¤ÎÀèƬ¤Ç,
-
-@example
-$F = $_.split
-@end example
-
-¤¬¼Â¹Ô¤µ¤ì¤ë¡¥@code{-n}¤«@code{-p}¥ª¥×¥·¥ç¥ó¤¬Æ±»þ¤Ë»ØÄꤵ¤ì¤Ê¤¤¸Â¤ê,
-¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï°ÕÌ£¤ò»ý¤¿¤Ê¤¤.
-
-@item -c
-
-¥¹¥¯¥ê¥×¥È¤ÎÆâÉô·Á¼°¤Ø¤Î¥³¥ó¥Ñ¥¤¥ë¤Î¤ß¤ò¹Ô¤¤, ¼Â¹Ô¤·¤Ê¤¤¡¥¥³¥ó¥Ñ¥¤¥ë½ª
-λ¸å, ʸˡ¥¨¥é¡¼¤¬Ìµ¤±¤ì¤Ð, @samp{"Syntax OK"}¤È½ÐÎϤ¹¤ë.
-
-@item -K c
-
-ruby¤Î½èÍý¤¹¤ë´Á»ú¥³¡¼¥É¤ò»ØÄꤹ¤ë¡¥ ruby¤Ï»ØÄꤵ¤ì¤¿Ê¸»ú¤¬ @code{E}¤Þ
-¤¿¤Ï@code{e}¤Î¾ì¹ç¤Ïʸ»úÎó¤ä¥¢¥¯¥»¥¹¤¹¤ë¥Õ¥¡¥¤¥ë¤ÎÆâÍƤΥ³¡¼¥É¤¬EUC¤Ç
-¤¢¤ë¤È²¾Äꤹ¤ë¡¥Æ±ÍͤË@code{S}¤Þ¤¿¤Ï@code{s}¤Î¾ì¹ç¤ÏSJIS¤È¤·¤Æ½èÍý¤¹¤ë¡¥
-@code{N}¤Ï´Á»ú¤ò½èÍý¤·¤Ê¤¤¡¥¥Ç¥Õ¥©¥ë¥È¤ÏEUC.
-
-@example
-ruby -CE -e 'print "¥Æ¥¹¥È"'
-ruby -Cs -e 'print "¥Æ¥¹¥È"'
-ruby -Cn -e 'print "¥Æ¥¹¥È"'
-@end example
-
-¤³¤Î¥ª¥×¥·¥ç¥ó¤Ï¾­Íèʸ»ú¥³¡¼¥É¤Î¼«Æ°È½Ê̵¡Ç½¤¬Äɲ䵤줿¾ì¹çÅù¤Ë¤ÏÊѹ¹
-¤µ¤ì¤ë.
-
-@item -d
-@itemx --debug
-
-¥Ç¥Ð¥Ã¥°¥â¡¼¥É¤òon¤Ë¤¹¤ë¡¥¤³¤Î¥Õ¥é¥°¤¬¥»¥Ã¥È¤µ¤ì¤ë¤È¥·¥¹¥Æ¥àÊÑ¿ô
-@code{$DEBUG}¤¬¥»¥Ã¥È¤µ¤ì¤ë.
-
-@item -e @var{script}
-
-¥³¥Þ¥ó¥É¥é¥¤¥ó¤«¤é¥¹¥¯¥ê¥×¥È¤ò»ØÄꤹ¤ë¡¥-e¥ª¥×¥·¥ç¥ó¤òÉÕ¤±¤¿»þ¤Ë¤Ï°ú¿ô
-¤«¤é¥¹¥¯¥ê¥×¥È¥Õ¥¡¥¤¥ë̾¤ò¼è¤é¤Ê¤¤.
-
-@item -F @var{ʸ»úÎó}
-
-ÆþÎÏ¥Õ¥£¡¼¥ë¥É¥»¥Ñ¥ì¡¼¥¿(@code{$;})¤ÎÃͤòʸ»úÎó¤Ë¥»¥Ã¥È¤¹¤ë¡¥awk¤ÎƱ̾
-¤Î¥ª¥×¥·¥ç¥ó¤ÈƱ¤¸Æ¯¤­¤ò¤¹¤ë.
-
-@item -i @var{extension}
-
-°ú¿ô¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤ÎÆâÍƤòÃÖ¤­´¹¤¨¤ë(in-place edit)¤³¤È¤ò»ØÄꤹ
-¤ë¡¥¸µ¤Î¥Õ¥¡¥¤¥ë¤Ï³ÈÄ¥»Ò¤ò¤Ä¤±¤¿·Á¤ÇÊݸ¤µ¤ì¤ë.
-
-Îã:
-
-@example
-% echo matz > /tmp/junk
-% cat /tmp/junk
-matz
-% ruby -p -i.bak -e '$_.upcase' /tmp/junk
-% cat /tmp/junk
-MATZ
-% cat /tmp/junk.bak
-matz
-@end example
-
-³ÈÄ¥»Ò¤¬¤Ê¤±¤ì¤Ð¡¤¥Ð¥Ã¥¯¥¢¥Ã¥×¤Ï¤µ¤ì¤º¡¤Êѹ¹¤µ¤ì¤¿¥Õ¥¡¥¤¥ë¤À¤±¤¬»Ä¤ë¡¥
-
-@item -I @var{directory}
-
-¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¤¹¤ë¥Ñ¥¹¤ò»ØÄê(ÄɲÃ)¤¹¤ë¡¥»ØÄꤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Ïruby
-¤ÎÇÛÎóÊÑ¿ô@code{$:}¤ËÄɲ䵤ì¤ë.
-
-@item -l
-
-@code{$\}¤ò@code{$/}¤ÈƱ¤¸ÃͤËÀßÄꤷ, @code{print}¤Ç¤Î½ÐÎÏ»þ¤Ë²þ¹Ô¤òÉÕ
-²Ã¤¹¤ë¡¥¤Þ¤¿, @samp{-n}¤Þ¤¿¤Ï@samp{-p}¤È¤È¤â¤ËÍѤ¤¤é¤ì¤ë¤È, ÆþÎϤµ¤ì¤¿
-³Æ¹Ô¤ÎºÇ¸å¤Îʸ»ú¤ò@code{chop!}¤¹¤ë.
-
-@item -n
-
-¤³¤Î¥Õ¥é¥°¤¬¥»¥Ã¥È¤µ¤ì¤ë¤È¥×¥í¥°¥é¥àÁ´ÂΤ¬
-
-@example
-while gets
- @dots{}
-end
-@end example
-
-¤Ç°Ï¤Þ¤ì¤Æ¤¤¤ë¤è¤¦¤ËÆ°ºî¤¹¤ë.
-@item -p
-
-@code{-n}¥Õ¥é¥°¤ÈƱ¤¸¤À¤¬, ³Æ¥ë¡¼¥×¤ÎºÇ¸å¤ËÊÑ¿ô@code{$_}¤ÎÃͤò½ÐÎϤ¹¤ë.
-
-Îã:
-
-@example
-% echo matz | ruby -p -e '$_.tr! "a-z", "A-Z"'
-MATZ
-@end example
-
-@item -r ¥Õ¥¡¥¤¥ë̾
-
-¥¹¥¯¥ê¥×¥È¼Â¹ÔÁ°¤Ë¥Õ¥¡¥¤¥ë̾¤Ç»ØÄꤵ¤ì¤ë¥Õ¥¡¥¤¥ë¤ò@code{require}¤¹¤ë¡¥
-@samp{-n}¥ª¥×¥·¥ç¥ó¡¤@samp{-p}¥ª¥×¥·¥ç¥ó¤È¤È¤â¤Ë»È¤¦»þ¤ËÆäËÍ­¸ú¤Ç¤¢¤ë¡¥
-
-@xref{ÁȤ߹þ¤ß´Ø¿ô}
-
-@item -s
-
-¥¹¥¯¥ê¥×¥È̾¤Ë³¤¯, @code{-}¤Ç»Ï¤Þ¤ë°ú¿ô¤ò²ò¼á¤·¤Æ, Ʊ̾¤ÎÂç°èÊÑ¿ô¤ËÃÍ
-¤òÀßÄꤹ¤ë¡¥@code{--}¤Ê¤ë°ú¿ô°Ê¹ß¤Ï²ò¼á¤ò¹Ô¤Ê¤ï¤Ê¤¤¡¥³ºÅö¤¹¤ë°ú¿ô¤Ï
-@code{$ARGV}¤«¤é¼è¤ê½ü¤«¤ì¤ë.
-
-Îã:
-@example
-#! /usr/local/bin/ruby -s
-# -xyz¥ª¥×¥·¥ç¥ó¤¬Í¿¤¨¤é¤ì¤ë¤È"true"¤òɽ¼¨¤¹¤ë.
-print "true\n" if $xyz
-@end example
-
-@item -S
-
-¥¹¥¯¥ê¥×¥È̾¤¬@code{/}¤Ç»Ï¤Þ¤Ã¤Æ¤¤¤Ê¤¤¾ì¹ç, ´Ä¶­ÊÑ¿ô@code{PATH}¤ÎÃͤò
-»È¤Ã¤Æ¥¹¥¯¥ê¥×¥È¤òõ¤¹¡¥ ¤³¤ì¤Ï¡¢@samp{#!} ¤ò¥µ¥Ý¡¼¥È¤·¤Æ¤¤¤Ê¤¤¥Þ¥·¥ó
-¤Ç¡¢@samp{#!} ¤Ë¤è¤ë¼Â¹Ô¤ò¥¨¥ß¥å¥ì¡¼¥È¤¹¤ë¤¿¤á¤Ë¡¢°Ê²¼¤Î¤è¤¦¤Ë¤·¤Æ»È¤¦
-¤³¤È¤¬¤Ç¤­¤ë:
-
-Îã:
-@example
-#! /usr/local/bin/ruby
-# This line makes the next one a comment in ruby \
- exec /usr/local/bin/ruby -S $0 $*
-@end example
-
-¥·¥¹¥Æ¥à¤ÏºÇ½é¤Î¹Ô¤ò̵»ë¤·¡¤¥¹¥¯¥ê¥×¥È¤ò@code{/bin/sh}¤ËÅϤ¹¡¥
-@code{/bin/sh}¤Ïruby¥¹¥¯¥ê¥×¥È¤ò¥·¥§¥ë¥¹¥¯¥ê¥×¥È¤È¤·¤Æ¼Â¹Ô¤·¤è¤¦¤È¤¹¤ë¡¥
-¥·¥§¥ë¤Ï2¹ÔÌܤÀ¤±¤ò¥³¥á¥ó¥È¤Ç¤¢¤ë¤È²ò¼á¤·¡¤3¹ÔÌܤòÄ̾ï¤Î¥·¥§¥ë¥³¥Þ¥ó¥É
-¤È¤·¤Æ¼Â¹Ô¤·¡¤ruby¥¤¥ó¥¿¥×¥ê¥¿¤òµ¯Æ°¤¹¤ë¡¥
-
-¥·¥¹¥Æ¥à¤Ë¤è¤Ã¤Æ¤Ï@code{$0}¤Ïɬ¤º¤·¤â¥Õ¥ë¥Ñ¥¹¤ò´Þ¤Þ¤Ê¤¤¤Î¤Ç¡¤@code{-S}
-¤òÍѤ¤¤Æruby¤ËɬÍפ˱þ¤¸¤Æ¥¹¥¯¥ê¥×¥È¤òõ¤¹¤è¤¦¤Ë»Ø¼¨¤¹¤ë¡¥ruby¤¬¥¹¥¯¥ê
-¥×¥È¤ò¸«¤Ä¤±¤ë¤È¡¢¤³¤ì¤é¤Î¹Ô¤Î²òÀϤò»Ï¤á¤ë¤¬¡¤ruby¤Ï2¹ÔÌܤιÔËö¤Ë¤¢¤ë
-¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Ë¤è¤ê¡¤2¹ÔÌܤΥ³¥á¥ó¥È¤¬3¹ÔÌܤޤǷѳ¤¹¤ë¤È¤ß¤Ê¤·¤Æ¡¤
-3¹ÔÌܤò̵»ë¤¹¤ë¡¥
-
-¥Õ¥¡¥¤¥ë̾¤Ë´Þ¤Þ¤ì¤ë¥¹¥Ú¡¼¥¹¤Ê¤É¤òÀµ¤·¤¯°·¤¦¤Ë¤Ï¡¤@code{$*}¤è¤ê¤â
-@code{$@{1+"$@@"@}}¤Î¤Û¤¦¤¬¤è¤¤¤À¤í¤¦¤¬¡¤csh¤¬²ò¼á¤¹¤ë¾ì¹ç¤Ë¤ÏÆ°ºî¤·¤Ê
-¤¤¡¥@cindex{OS¤¬#!¤ò²ò¼á¤·¤Ê¤¤¾ì¹ç¤ÎÂкö}
-
-@item -v
-@itemx --verbose
-
-¾éĹ¥â¡¼¥É¡¥µ¯Æ°»þ¤Ë¥Ð¡¼¥¸¥ç¥óÈÖ¹æ¤Îɽ¼¨¤ò¹Ô¤¤, ¥·¥¹¥Æ¥àÊÑ¿ô
-@code{$VERBOSE}¤ò¥»¥Ã¥È¤¹¤ë¡¥¤³¤ÎÊÑ¿ô¤¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë»þ, ¤¤¤¯¤Ä¤«¤Î
-¥á¥½¥Ã¥É¤Ï¼Â¹Ô»þ¤Ë¾éĹ¤Ê¥á¥Ã¥»¡¼¥¸¤ò½ÐÎϤ¹¤ë¡¥@samp{-v}¥ª¥×¥·¥ç¥ó¤¬»Ø
-Äꤵ¤ì¤Æ, ¤½¤ì°Ê³°¤Î°ú¿ô¤¬¤Ê¤¤»þ¤Ë¤Ï¥Ð¡¼¥¸¥ç¥ó¤òɽ¼¨¤·¤¿¸å, ¼Â¹Ô¤ò½ªÎ»
-¤¹¤ë(ɸ½àÆþÎϤ«¤é¤Î¥¹¥¯¥ê¥×¥È¤òÂÔ¤¿¤Ê¤¤).
-
-@item --version
-
-ruby¤Î¥Ð¡¼¥¸¥ç¥ó¤òɽ¼¨¤¹¤ë.
-
-ɽ¼¨Îã:
-
-@example
-ruby - version 0.87 (95/09/23)
-@end example
-
-@item -x[directory]
-
-¥á¥Ã¥»¡¼¥¸Ãæ¤Î¥¹¥¯¥ê¥×¥È¤ò¼è¤ê½Ð¤·¤Æ¼Â¹Ô¤¹¤ë¡¥¥¹¥¯¥ê¥×¥È¤òÆɤ߹þ¤à»þ¤Ë¡¤
-@code{#!}¤Ç»Ï¤Þ¤ê, @code{ruby}¤È¤¤¤¦Ê¸»úÎó¤ò´Þ¤à¹Ô¤Þ¤Ç¤òÆɤßÈô¤Ð¤¹¡¥¥¹
-¥¯¥ê¥×¥È¤Î½ª¤ê¤Ï@samp{EOF}(¥Õ¥¡¥¤¥ë¤Î½ª¤ê), @samp{^D}(¥³¥ó¥È¥í¡¼¥ëD),
-@samp{^Z}(¥³¥ó¥È¥í¡¼¥ëZ)¤Þ¤¿¤ÏͽÌó¸ì@code{__END__}¤Ç»ØÄꤹ¤ë.
-
-¥Ç¥£¥ì¥¯¥È¥ê̾¤ò»ØÄꤹ¤ë¤È¡¤¥¹¥¯¥ê¥×¥È¼Â¹ÔÁ°¤Ë»ØÄꤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Ë
-°Ü¤ë.
-
-@item -X directory
-
-¥¹¥¯¥ê¥×¥È¼Â¹ÔÁ°¤Ë»ØÄꤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤Ë°Ü¤ë.
-
-@item -y
-@itemx --yydebug
-
-¥³¥ó¥Ñ¥¤¥é¥Ç¥Ð¥Ã¥°¥â¡¼¥É¡¥¥¹¥¯¥ê¥×¥È¤òÆâÉôɽ¸½¤Ë¥³¥ó¥Ñ¥¤¥ë¤¹¤ë»þ¤Î¹½Ê¸
-²òÀϤβáÄø¤òɽ¼¨¤¹¤ë¡¥¤³¤Îɽ¼¨¤ÏÈó¾ï¤Ë¾éĹ¤Ê¤Î¤Ç, ¥³¥ó¥Ñ¥¤¥é¤½¤Î¤â¤Î¤ò
-¥Ç¥Ð¥Ã¥°¤¹¤ë¿Í°Ê³°¤Ïɽ¼¨¤µ¤»¤Ê¤¤Êý¤¬Îɤ¤¤È»×¤¦.
-@end table
-
-@node ruby¤Îʸˡ, ÁȤ߹þ¤ß´Ø¿ô, ¥³¥Þ¥ó¥É¥é¥¤¥ó¥ª¥×¥·¥ç¥ó, Top
-@comment node-name, next, previous, up
-@chapter ruby¤Îʸˡ
-
-@menu
-* Lexical structure::
-* ¥×¥í¥°¥é¥à::
-* ¼°::
-@end menu
-
-@node Lexical structure, ¥×¥í¥°¥é¥à, ruby¤Îʸˡ, ruby¤Îʸˡ
-@comment node-name, next, previous, up
-@section Lexical structure
-
-¸½ºß¤Îruby¤Î¼ÂÁõ¤Ï¥­¥ã¥é¥¯¥¿¥»¥Ã¥È¤È¤·¤ÆASCII¤òÍѤ¤¤ë¡¥ruby¤ÏÂçʸ»ú¤È
-¾®Ê¸»ú¤ò¶èÊ̤¹¤ë¡¥¼±Ê̻ҤÎÅÓÃæ¤Ç¤Ê¤±¤ì¤ÐǤ°Õ¤Î¤È¤³¤í¤Ë¶õÇòʸ»ú¤ò¤ª¤¯¤³
-¤È¤¬½ÐÍè¤ë¡¥¶õÇòʸ»ú¤Ï¥¹¥Ú¡¼¥¹(space)¡¤¥¿¥Ö(tab)¡¤¿âľ¥¿¥Ö(vertical
-tab)¡¤ CR(carriage return)¡¤²þÊÇ(form feed)¤Ç¤¢¤ë¡¥²þ¹Ô(newline)¤ÏÌÀ¤é
-¤«¤Ë¼°¤¬·Ñ³¤¹¤ë¾ì¹ç¤Ë¤Ï¶õÇòʸ»ú¤È¤·¤Æ¡¤¤½¤ì°Ê³°¤Ç¤Ïʸ¤Î¶èÀÚ¤ê¤È¤·¤Æ²ò
-¼á¤µ¤ì¤ë¡¥
-
-¼±Ê̻ҤϱÑʸ»ú(@samp{"_"}¤ò´Þ¤à)¤«¤é»Ï¤Þ¤ê¡¤±Ñ¿ô»ú¤¬Â³¤¤¤¿¤â¤Î¤Ç¤¢¤ë¡¥
-ruby¤Î¼±Ê̻ҤÎŤµ¤ËÀ©¸Â¤Ï¤Ê¤¤¡¥¸½ºß¤Î¼ÂÁõ¤Ï¼±Ê̻ҤȤ·¤Æ¥Þ¥ë¥Á¥Ð¥¤¥È¥³¡¼
-¥É(EUC,SJIS)¤âÄ̤¹¤¬´«¤á¤é¤ì¤Ê¤¤¡¥
-
-¼±Ê̻ҤÎÎã
-
-@example
-foobar
-ruby_is_simple
-@end example
-
-@menu
-* ¥³¥á¥ó¥È::
-* ͽÌó¸ì::
-* ¶èÀÚ¤êʸ»ú::
-@end menu
-
-@node ¥³¥á¥ó¥È, ͽÌó¸ì, Lexical structure, Lexical structure
-@comment node-name, next, previous, up
-@subsection ¥³¥á¥ó¥È
-
-Îã
-
-@example
-# this is a comment line
-@end example
-
-¥¹¥¯¥ê¥×¥È¸À¸ì¤Î½¬´·¤Ë¤Ê¤é¤¤¡¤Ê¸»úÎóÃæ¤äʸ»úɽ¸½(@code{?#})°Ê³°¤Î
-@code{#}¤«¤é¹ÔËö¤Þ¤Ç¤Ï¥³¥á¥ó¥È¤È¸«¤Ê¤¹¡¥¥³¥á¥ó¥È¹ÔËö¤Î¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å
-¤Ï¼¡¤Î¹Ô¤Ø¤Î¥³¥á¥ó¥È¤Î·Ñ³¤ò°ÕÌ£¤¹¤ë¡¥
-
-@node ͽÌó¸ì, ¶èÀÚ¤êʸ»ú, ¥³¥á¥ó¥È, Lexical structure
-@comment node-name, next, previous, up
-@subsection ͽÌó¸ì
-
-ͽÌó¸ì¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë
-
-@display
-alias def for redo undef
-and defined? if rescue when
-begin else in retry while
-break elsif module return yield
-case end nil self __END__
-class ensure not super __FILE__
-continue fail or then __LINE__
-@end display
-
-ͽÌó¸ì¤Ï¥¯¥é¥¹Ì¾¡¤¥á¥½¥Ã¥É̾¡¤ÊÑ¿ô̾¤Ê¤É¤ËÍѤ¤¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡¥¤¿¤À¤·¡¤
-@samp{$}, @samp{@@}¤¬ÀèƬ¤Ë¤Ä¤¤¤¿¤â¤Î¤ÏͽÌó¸ì¤È¸«¤Ê¤µ¤ì¤Ê¤¤¤Î¤Ç¡¤¥°¥í¡¼
-¥Ð¥ëÊÑ¿ô¡¤¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤Ë¤Ä¤¤¤Æ¤ÏÌäÂê¤Ê¤¤¡¥
-
-@node ¶èÀÚ¤êʸ»ú, , ͽÌó¸ì, Lexical structure
-@comment node-name, next, previous, up
-@subsection ¶èÀÚ¤êʸ»ú
-
-ʸ»úÎó¤Ê¤É¤Î¥ê¥Æ¥é¥ë¤ÎÆâÉô°Ê³°¤Î¾ì½ê¤Î¶õÇòʸ»ú(¥¿¥Ö¤È¥¹¥Ú¡¼¥¹)¤ª¤è¤Ó²þ
-¹Ô(@samp{\n})¤¬¶èÀڤ국¹æ¤È¤Ê¤ë¡¥¹¹¤Ë²þ¹Ô¤Ï
-
-@example
-a +
-b
-@end example
-
-¤Î¤è¤¦¤Ë¹Ô¤¬¼°¤ÎÅÓÃæ¤Ç½ª¤ê¡¤¼¡¤Î¹Ô¤Ë³¤¯¤³¤È¤¬ÌÀÇò¤Ê(ºÇ¸å¤ÎÈó¶õÇòʸ»ú
-¤¬±é»»»Ò¤¢¤ë¤¤¤Ï@code{,}¤Ç¤¢¤ë)¾ì¹ç¤ò½ü¤­¡¤¼°¤Î¶èÀÚ¤ê¤È¤·¤Æǧ¼±¤µ¤ì¤ë¡¥
-
-@node ¥×¥í¥°¥é¥à, ¼°, Lexical structure, ruby¤Îʸˡ
-@comment node-name, next, previous, up
-@section ¥×¥í¥°¥é¥à
-
-Îã
-
-@example
-print "hello world!\n"
-@end example
-
-¥×¥í¥°¥é¥à¤Ï¼°¤òʤ٤¿¤â¤Î¤Ç¤¢¤ë¡¥¼°¤È¼°¤Î´Ö¤Ï¥»¥ß¥³¥í¥ó(@code{;})¤Þ¤¿
-¤Ï²þ¹Ô¤Ç¶èÀÚ¤é¤ì¤ë¡¥
-
-@node ¼°, , ¥×¥í¥°¥é¥à, ruby¤Îʸˡ
-@comment node-name, next, previous, up
-@section ¼°
-
-Îã
-
-@example
-TRUE
-(1+2)*3
-foo()
-if test then ok else ng end
-@end example
-
-Ruby¤Ç¤Ï@code{nil}¤¬µ¶¡¤¤½¤ì°Ê³°¤¬¿¿¤Èɾ²Á¤µ¤ì¤ë¡¥C¤äPerl¤Ê¤É¤È¤Ï°Û¤Ê
-¤ê¡¤0¤ä@code{""}(¶õʸ»úÎó)¤Ïµ¶¤È¤Ïɾ²Á¤µ¤ì¤Ê¤¤¤Î¤Çµ¤¤ò¤Ä¤±¤ë¤³¤È¡¥
-
-¼°¤Ï³ç¸Ì¤Ë¤è¤Ã¤Æ¥°¥ë¡¼¥Ô¥ó¥°¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥
-
-@menu
-* ʸ»úÎó¼°::
-* ¥³¥Þ¥ó¥É½ÐÎÏ::
-* Àµµ¬É½¸½¼°::
-* ÊÑ¿ôŸ³«::
-* ¿ôÃÍ¥ê¥Æ¥é¥ë::
-* ÊÑ¿ô¤ÈÄê¿ô::
-* ¥°¥í¡¼¥Ð¥ëÊÑ¿ô::
-* ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô::
-* ¥¯¥é¥¹Äê¿ô::
-* ¥í¡¼¥«¥ëÊÑ¿ô::
-* µ¿»÷ÊÑ¿ô::
-* ÇÛÎó¼°::
-* Ï¢ÁÛÇÛÎó¼°::
-* ¥á¥½¥Ã¥É¸Æ½Ð¼°::
-* SUPER::
-* ÂåÆþ::
-* ±é»»»Ò¼°::
-* À©¸æ¹½Â¤::
-* ¥¯¥é¥¹ÄêµÁ::
-* ¥â¥¸¥å¡¼¥ëÄêµÁ::
-* ¥á¥½¥Ã¥ÉÄêµÁ::
-* Æðۥ᥽¥Ã¥ÉÄêµÁ::
-* ALIAS::
-* UNDEF::
-* DEFINED?::
-@end menu
-
-@node ʸ»úÎó¼°, ¥³¥Þ¥ó¥É½ÐÎÏ, ¼°, ¼°
-@comment node-name, next, previous, up
-@subsection ʸ»úÎó¼°
-@cindex ʸ»úÎó¼°
-
-Îã
-
-@example
-"this is a string expression\n"
-'ʸ»úÎó¼°'
-@end example
-
-¥À¥Ö¥ë¥¯¥©¡¼¥È(@code{"})¤Ç³ç¤é¤ì¤¿Ê¸»úÎó¤ÎÃæ¤Ï¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥å¤Ë³¤¯Ê¸
-»ú¤¬°Ê²¼¤Î¤è¤¦¤Ë²ò¼á¤µ¤ì¤ë¡¥
-
-¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥åµ­Ë¡
-
-@table @samp
-@item \t
-¥¿¥Ö(0x09)
-@item \n
-²þ¹Ôʸ»ú(0x0a)
-@item \r
-Éüµ¢Ê¸»ú(0x0d)
-@item \f
-²þ¥Ú¡¼¥¸Ê¸»ú(0x0c)
-@item \b
-¥Ð¥Ã¥¯¥¹¥Ú¡¼¥¹(0x08)
-@item \a
-¥Ù¥ë(0x07)
-@item \e
-¥¨¥¹¥±¡¼¥×(0x1b)
-@item \nnn
-8¿Ê¿ôɽµ­(n¤Ï0-7)
-@item \xnn
-16¿Ê¿ôɽµ­(n¤Ï0-9,a-f)
-@item \cx
-¥³¥ó¥È¥í¡¼¥ëʸ»ú(x¤ÏASCIIʸ»ú)
-@item \x
-ʸ»úx¤½¤Î¤â¤Î
-@end table
-
-¤Þ¤¿¡¤@code{#}¤Ë¤è¤ëÊÑ¿ôŸ³«¤â¹Ô¤ï¤ì¤ë¡¥
-
-@xref{ÊÑ¿ôŸ³«}
-
-°ìÊý¡¤¥·¥ó¥°¥ë¥¯¥©¡¼¥È(@code{'})¤Ç³ç¤é¤ì¤¿Ê¸»úÎó¤Ï¡¤@code{\\}(¥Ð¥Ã¥¯¥¹
-¥é¥Ã¥·¥å¤½¤Î¤â¤Î)¤È@code{\'}(¥·¥ó¥°¥ë¥¯¥©¡¼¥È)¤ò½ü¤¤¤Æ¡¤Ê¸»úÎó¤ÎÃæ¿È¤Î
-²ò¼á¤ò¹Ô¤ï¤Ê¤¤¡¥
-
-ʸ»úÎó¼°¤ÏËè²ó¿·¤·¤¤Ê¸»úÎ󥪥֥¸¥§¥¯¥È¤òÀ¸À®¤¹¤ë¤Î¤Ç¡¤Ê¸»úÎó¤ÎÆâÍƤòÊÑ
-¹¹¤·¤Æ¤â¡¤¤â¤È¤â¤È¤Îʸ»úÎó¤ÏÊѤï¤é¤Ê¤¤¡¥
-
-@node ¥³¥Þ¥ó¥É½ÐÎÏ, Àµµ¬É½¸½¼°, ʸ»úÎó¼°, ¼°
-@comment node-name, next, previous, up
-@subsection ¥³¥Þ¥ó¥É½ÐÎÏ
-@cindex ¥³¥Þ¥ó¥É½ÐÎÏ
-
-Îã
-
-@example
-`date`
-@end example
-
-Ruby¤Ç¤Ïsh¤Î¤è¤¦¤Ë¥³¥Þ¥ó¥É¤Î¼Â¹Ô·ë²Ì¤òʸ»úÎó¥ê¥Æ¥é¥ë¤Î¤è¤¦¤Ë»È¤¦¤³¤È¤¬
-¤Ç¤­¤ë¡¥@code{``}¤Ç°Ï¤Þ¤ì¤¿Ê¸»úÎó¤Ï¡¤¥À¥Ö¥ë¥¯¥©¡¼¥È¤Ç°Ï¤Þ¤ì¤¿Ê¸»úÎó¤È
-ƱÍͤ˥Х寥¹¥é¥Ã¥·¥åµ­Ë¡¤Î²ò¼á¤ÈÊÑ¿ôŸ³«¤¬¹Ô¤Ê¤ï¤ì¤¿¸å¡¤¥³¥Þ¥ó¥É¤È¤·
-¤Æ¼Â¹Ô¤µ¤ì¡¤¤½¤Î¼Â¹Ô·ë²Ì¤¬Ê¸»úÎó¤È¤·¤ÆÍ¿¤¨¤é¤ì¤ë¡¥¥³¥Þ¥ó¥É¤Ïɾ²Á¤µ¤ì¤ë
-¤¿¤Ó¤Ë¼Â¹Ô¤µ¤ì¤ë¡¥
-
-@node Àµµ¬É½¸½¼°, ÊÑ¿ôŸ³«, ¥³¥Þ¥ó¥É½ÐÎÏ, ¼°
-@comment node-name, next, previous, up
-@subsection Àµµ¬É½¸½¼°
-@cindex Àµµ¬É½¸½¼°
-
-Îã
-
-@example
-/^ruby the OOPL/
-/ruby/i
-@end example
-
-@code{/}¤Ç°Ï¤Þ¤ì¤¿Ê¸»úÎó¤ÏÀµµ¬É½¸½¤òɽ¤¹¡¥½ª¤ê¤Î@code{/}¤Î¸å¤í¤Ëʸ»ú
-@code{i}¤¬Í¿¤¨¤é¤ì¤¿¾ì¹ç¤Ë¤Ï¡¤¤½¤ÎÀµµ¬É½¸½¤Ï¥Þ¥Ã¥Á»þ¤ËÂçʸ»ú¾®Ê¸»ú¤Î¶è
-Ê̤ò¤·¤Ê¤¤¡¥
-
-@table @code
-@item ^
-¹ÔƬ
-@item $
-¹ÔËö
-@item .
-Ǥ°Õ¤Î1ʸ»ú
-@item \w
-±Ñ¿ô»ú¡¥[0-9A-Za-z_]¤ÈƱ¤¸
-@item \W
-Èó±Ñ¿ô»ú
-@item \s
-¶õÇòʸ»ú¡¥[ \t\n\r\f]¤ÈƱ¤¸
-@item \S
-Èó¶õÇòʸ»ú
-@item \d
-¿ô»ú¡¥[0-9] ¤ÈƱ¤¸
-@item \D
-Èó¿ô»ú
-@item \b
-¸ì¶­³¦Ê¸»ú(ʸ»ú¥¯¥é¥¹³°)
-@item \B
-Èó¸ì¶­³¦Ê¸»ú
-@item \b
-¸åÂà(0x08)(ʸ»ú¥¯¥é¥¹Æâ)
-@item [ ]
-ʸ»ú¥¯¥é¥¹»ØÄê
-@item *
-ľÁ°¤Îɽ¸½¤Î0²ó°Ê¾å¤Î·«¤êÊÖ¤·
-@item +
-ľÁ°¤Îɽ¸½¤Î1²ó°Ê¾å¤Î·«¤êÊÖ¤·
-@item {m,n}
-m²ó¤«¤én²ó¤Î·«¤êÊÖ¤·
-@item ?
-0¤Þ¤¿¤Ï1²ó
-@item |
-ÁªÂò
-@item ( )
-Àµµ¬É½¸½¤ò¤Þ¤È¤á¤ë
-@end table
-
-¤½¤Î¾¤Ëʸ»úÎó¤ÈƱ¤¸¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥åµ­Ë¡¤äÊÑ¿ôŸ³«¤âÍ­¸ú¤Ç¤¢¤ë¡¥
-
-@node ÊÑ¿ôŸ³«, ¿ôÃÍ¥ê¥Æ¥é¥ë, Àµµ¬É½¸½¼°, ¼°
-@comment node-name, next, previous, up
-@subsection ÊÑ¿ôŸ³«
-@cindex ÊÑ¿ôŸ³«
-
-Îã
-
-@example
-"my name is #@{$ruby@}"
-@end example
-
-¥À¥Ö¥ë¥¯¥©¡¼¥È(@code{"})¤Ç°Ï¤Þ¤ì¤¿Ê¸»úÎó¼°¡¤¥³¥Þ¥ó¥Éʸ»úÎó¡¤Àµµ¬É½¸½¡¤
-¤ª¤è¤Ó¥ï¥¤¥ë¥É¥«¡¼¥É¼°¤ÎÃæ¤Ç¤Ï@code{#{ÊÑ¿ô̾}}¤È¤¤¤¦·Á¼°¤ÇÊÑ¿ô¤ÎÆâÍƤò
-Ÿ³«¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥ÊÑ¿ô¤¬ÊÑ¿ôµ­¹æ(@code{$},@code{@@})¤Ç»Ï¤Þ¤ë¾ì¹ç¤Ë
-¤Ï@code{#ÊÑ¿ô̾}¤È¤¤¤¦·Á¼°¤Ç¤âŸ³«¤Ç¤­¤ë¡¥Ê¸»ú@code{#}¤Ë³¤¯Ê¸»ú¤¬
-@code{@{},@code{$},@code{@@}¤Ç¤Ê¤±¤ì¤Ð¡¤¤½¤Î¤Þ¤Þʸ»ú@code{#}¤È¤·¤Æ²ò¼á
-¤µ¤ì¤ë¡¥
-
-@node ¿ôÃÍ¥ê¥Æ¥é¥ë, ÊÑ¿ô¤ÈÄê¿ô, ÊÑ¿ôŸ³«, ¼°
-@comment node-name, next, previous, up
-@subsection ¿ôÃÍ¥ê¥Æ¥é¥ë
-
-@table @samp
-@item 123
-À°¿ô
-@item -123
-À°¿ô(Éä¹ç¤Ä¤­¿ô)
-@item 1_234
-À°¿ô(10¿Ê¿ô¤Ï@code{_}¤ò´Þ¤à¤³¤È¤¬¤Ç¤­¤ë)
-@item 123.45
-ÉâÆ°¾®¿ôÅÀ¿ô
-@item 1.2e-3
-ÉâÆ°¾®¿ôÅÀ¿ô
-@item 0xffff
-16¿ÊÀ°¿ô
-@item 0377
-8¿ÊÀ°¿ô
-@item ?a
-ʸ»ú@code{a}¤Î¥³¡¼¥É(97)
-@item ?\C-a
-¥³¥ó¥È¥í¡¼¥ëa¤Î¥³¡¼¥É(1)
-@item ?\M-a
-¥á¥¿a¤Î¥³¡¼¥É(225)
-@item ?\M-\C-a
-¥á¥¿-¥³¥ó¥È¥í¡¼¥ëa¤Î¥³¡¼¥É(129)
-@item :¥·¥ó¥Ü¥ë
-¼±ÊÌ»Ò/ÊÑ¿ô̾/±é»»»Ò¤È°ìÂаìÂбþ¤¹¤ëÀ°¿ô¡¥send¤Ê¤É¤Ç¥á¥½¥Ã¥É¤ò»ØÄꤹ¤ë
-»þ¤Ê¤É¤Ë»È¤¦¡¥
-@end table
-
-?ɽ¸½¤Ç¤ÏÁ´¤Æ¤Î¥Ð¥Ã¥¯¥¹¥é¥Ã¥·¥åµ­Ë¡¤¬Í­¸ú¤Ç¤¢¤ë¡¥
-
-@node ÊÑ¿ô¤ÈÄê¿ô, ÇÛÎó¼°, ¿ôÃÍ¥ê¥Æ¥é¥ë, ¼°
-@comment node-name, next, previous, up
-@subsection ÊÑ¿ô¤ÈÄê¿ô
-
-Ruby¤ÎÊÑ¿ô¤Ï¥¹¥³¡¼¥×(Í­¸úÈÏ°Ï)¤È¼÷Ì¿(Í­¸ú´ü¸Â)¤Ë¤è¤Ã¤Æ4¼ïÎà¤ËʬÎव¤ì¡¤
-¤½¤Î¼ïÎà¤ÏÊÑ¿ô̾¤ÎºÇ½é¤Î°ìʸ»ú¤Ç·èÄꤵ¤ì¤ë¡¥Ä̾ï¤ÎÊÑ¿ô¤Î2ʸ»úÌܰʹߤÏ
-±Ñ¿ô»þ¤Þ¤¿¤Ï@code{_}¤Ç¤¢¤ë¤¬¡¤¥·¥¹¥Æ¥àÊÑ¿ô¤Î°ìÉô¤Ï¡Ö@code{$}+1ʸ»ú¤Îµ­
-¹æ¡×¤È¤¤¤¦ÊÑ¿ô¤¬¤¢¤ë¡¥ÊÑ¿ô̾¤ÎŤµ¤Ë´Ø¤·¤ÆÆÃÊ̤ÊÀ©¸Â¤Ï¤Ê¤¤¡¥
-
-@menu
-* ¥°¥í¡¼¥Ð¥ëÊÑ¿ô::
-* ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô::
-* ¥¯¥é¥¹Äê¿ô::
-* ¥í¡¼¥«¥ëÊÑ¿ô::
-* µ¿»÷ÊÑ¿ô::
-@end menu
-
-@node ¥°¥í¡¼¥Ð¥ëÊÑ¿ô, ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô, ÊÑ¿ô¤ÈÄê¿ô, ÊÑ¿ô¤ÈÄê¿ô
-@comment node-name, next, previous, up
-@subsection ¥°¥í¡¼¥Ð¥ëÊÑ¿ô
-
-Îã
-
-@example
-$foobar
-$/
-@end example
-
-@code{$}¤Ç»Ï¤Þ¤ëÊÑ¿ô¤Î¥¹¥³¡¼¥×¤Ï¥°¥í¡¼¥Ð¥ë¤Ç¤¢¤ê¡¤¥×¥í¥°¥é¥à¤Î¤É¤³¤«¤é
-¤Ç¤â»²¾È¤Ç¤­¤ë¡¥¤½¤Î¼÷Ì¿¤Ï¥×¥í¥°¥é¥à¤Î¼÷Ì¿¤ÈÅù¤·¤¤¡¥¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤Ë¤Ï
-Àë¸À¤ÏɬÍפʤ¤¡¥½é´ü²½¤µ¤ì¤Æ¤¤¤Ê¤¤¥°¥í¡¼¥Ð¥ëÊÑ¿ô¤ò»²¾È¤·¤¿»þ¤ÎÃͤÏ
-@code{nil}¤Ç¤¢¤ë¡¥
-
-@node ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô, ¥¯¥é¥¹Äê¿ô, ¥°¥í¡¼¥Ð¥ëÊÑ¿ô, ÊÑ¿ô¤ÈÄê¿ô
-@comment node-name, next, previous, up
-@subsection ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô
-
-Îã
-
-@example
-@@foobar
-@end example
-
-@code{@@}¤Ç»Ï¤Þ¤ëÊÑ¿ô¤Ï¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤Ç¤¢¤ê¡¤¤½¤Î¥¯¥é¥¹¤Þ¤¿¤Ï¥µ¥Ö¥¯
-¥é¥¹¤Î¥á¥½¥Ã¥É¤«¤é»²¾È¤Ç¤­¤ë¡¥¥¹¥³¡¼¥×¤Ï¥á¥½¥Ã¥ÉÆâ¤Ç¤¢¤ê¡¤¤½¤Î¼÷Ì¿¤Ï¥ª
-¥Ö¥¸¥§¥¯¥È¤Î¼÷Ì¿¤ËÅù¤·¤¤¡¥¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤Ë¤âÀë¸À¤ÏɬÍפʤ¤¡¥½é´ü²½¤µ
-¤ì¤Æ¤¤¤Ê¤¤¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô¤ò»²¾È¤·¤¿»þ¤ÎÃͤÏ@code{nil}¤Ç¤¢¤ë¡¥
-
-@node ¥¯¥é¥¹Äê¿ô, ¥í¡¼¥«¥ëÊÑ¿ô, ¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô, ÊÑ¿ô¤ÈÄê¿ô
-@comment node-name, next, previous, up
-@subsection ¥¯¥é¥¹Äê¿ô
-
-Îã
-
-@example
-FOOBAR
-@end example
-
-Âçʸ»ú¤Ç»Ï¤Þ¤ë¼±Ê̻ҤÏÄê¿ô¤Ø¤Î¥¢¥¯¥»¥¹¤Ç¤¢¤ê¡¤ºÇ½é¤ËÄêµÁ¤µ¤ì¤¿¥¯¥é¥¹¤È
-Á´¤Æ¤Î¥µ¥Ö¥¯¥é¥¹¤Î¥¹¥³¡¼¥×Æâ¤Ç»²¾È¤Ç¤­¤ë¡¥Äê¿ô¤ÎÄêµÁ¤ÏÂåÆþ¤«¡¤Äê¿ô¤òÄê
-µÁ¤·¤Æ¤¤¤ë¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¹Ô¤Ê¤ï¤ì¤ë¡¥Äê¿ô¤Ø¤Î
-ÂåÆþ¤Ï¥È¥Ã¥×¥ì¥Ù¥ë¡¤¤¹¤Ê¤ï¤Á¥á¥½¥Ã¥É¤¬ÄêµÁ¤Ç¤­¤ë¥ì¥Ù¥ë¤Ç¤Î¤ß²Äǽ¤Ç¤¢¤ë¡¥
-Äê¿ô¤Ï¥¯¥é¥¹´Ö¤ÇÃͤ¬¶¦Í­¤µ¤ì¡¤°ìÅÙÂåÆþ¤¹¤ë¤ÈÃͤòÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤Ê¤¤
-(ÂåÆþ¤ÏÎã³°¤òȯÀ¸¤µ¤»¤ë)¡¥¥¯¥é¥¹Äê¿ô¤Î¼÷Ì¿¤Ï¥¯¥é¥¹¤Î¼÷Ì¿¤ÈÅù¤·¤¤¡¥½é´ü
-²½¤µ¤ì¤Æ¤¤¤Ê¤¤¥¯¥é¥¹Äê¿ô¤ò»²¾È¤·¤¿»þ¤ÎÃͤÏ@code{nil}¤Ç¤¢¤ë¡¥
-
-¥¯¥é¥¹ÄêµÁ¤Ï¼«Æ°Åª¤ËÄê¿ô¤òÄêµÁ¤¹¤ë¤Î¤Ç¡¤¥¯¥é¥¹Ì¾¤ÏÄê¿ô¤Ç¤¢¤ë¡¥
-
-¤¢¤ë¥¯¥é¥¹¤Þ¤¿¤Ï¥â¥¸¥å¡¼¥ë¤Ë°¤¹¤ëÄê¿ô¤ò³°Éô¤«¤é»²¾È¤¹¤ë¤¿¤á¤Ë¤Ï
-@code{::}±é»»»Ò¤òÍѤ¤¤ë¡¥
-
-Îã
-@example
-Foo::Bar
-@end example
-
-@code{::}±é»»»Ò¤òÍѤ¤¤¿ÂåÆþ¤Ï¤Ç¤­¤Ê¤¤¡¥
-
-@node ¥í¡¼¥«¥ëÊÑ¿ô, µ¿»÷ÊÑ¿ô, ¥¯¥é¥¹Äê¿ô, ÊÑ¿ô¤ÈÄê¿ô
-@comment node-name, next, previous, up
-@subsection ¥í¡¼¥«¥ëÊÑ¿ô
-
-Îã
-
-@example
-foobar
-@end example
-
-¾®Ê¸»ú¤Þ¤¿¤Ï@code{_}¤Ç»Ï¤Þ¤ë¼±ÊÌ»Ò¤Ï¥í¡¼¥«¥ëÊÑ¿ô¤Þ¤¿¤Ï¥á¥½¥Ã¥É¸Æ½Ð¤·¤Ç
-¤¢¤ë¡¥¥í¡¼¥«¥ëÊÑ¿ô¥¹¥³¡¼¥×¤Ë¤ª¤±¤ë¾®Ê¸»ú¤Ç»Ï¤Þ¤ë¼±Ê̻Ҥؤκǽé¤ÎÂåÆþ¤Ï
-¤½¤Î¥¹¥³¡¼¥×¤Ë°¤¹¤ë¥í¡¼¥«¥ëÊÑ¿ô¤ÎÀë¸À¤Ë¤Ê¤ë¡¥Àë¸À¤µ¤ì¤Æ¤¤¤Ê¤¤¼±Ê̻ҤÎ
-»²¾È¤Ï°ú¿ô¤Î̵¤¤¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¤È¤ß¤Ê¤µ¤ì¤ë¡¥
-
-¥í¡¼¥«¥ëÊÑ¿ô¤Î¥¹¥³¡¼¥×¤Ï¡¤¤½¤ÎÊÑ¿ô¤¬Àë¸À¤µ¤ì¤¿¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¡¤¥á¥½¥Ã
-¥ÉÄêµÁ¡¤¤Þ¤¿¤Ï¥¯¥é¥¹/¥â¥¸¥å¡¼¥ëÄêµÁ¥Ö¥í¥Ã¥¯¤Î½ª¤ê¤Þ¤Ç¤Ç¤¢¤ë¡¥¼÷Ì¿¤â¤½
-¤Î¥Ö¥í¥Ã¥¯¤Î½ª¤ê¤Þ¤Ç(¥È¥Ã¥×¥ì¥Ù¥ë¤Î¥í¡¼¥«¥ëÊÑ¿ô¤Ï¥×¥í¥°¥é¥à¤Î½ªÎ»¤Þ¤Ç)
-¤Ç¤¢¤ë¤¬¡¤Îã³°¤È¤·¤Æ¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤¬¼ê³¤­¥ª¥Ö¥¸¥§¥¯¥È²½¤µ¤ì¤¿¾ì¹ç
-¤Ï¡¤¤½¤Î¥ª¥Ö¥¸¥§¥¯¥È¤¬¾ÃÌǤ¹¤ë¤Þ¤Ç¸ºß¤¹¤ë¡¥Æ±¤¸¥¹¥³¡¼¥×¤ò»²¾È¤¹¤ë¼ê³
-¤­¥ª¥Ö¥¸¥§¥¯¥È´Ö¤Ç¤Ï¥í¡¼¥«¥ëÊÑ¿ô¤Ï¶¦Í­¤µ¤ì¤ë¡¥
-
-@node µ¿»÷ÊÑ¿ô, ÊÑ¿ô¤ÈÄê¿ô, ¥í¡¼¥«¥ëÊÑ¿ô, ÊÑ¿ô¤ÈÄê¿ô
-@comment node-name, next, previous, up
-@subsection µ¿»÷ÊÑ¿ô
-
-Ä̾ï¤ÎÊÑ¿ô°Ê³°¤Ëµ¿»÷ÊÑ¿ô¤È¸Æ¤Ð¤ì¤ëÆüì¤ÊÊÑ¿ô¤¬4¤Ä¤¢¤ë¡¥
-
-@table @code
-@item self
-¸½ºß¤Î¥á¥½¥Ã¥É¤Î¼Â¹Ô¼çÂÎ
-@item nil
-Nil¥¯¥é¥¹¤ÎÍ£°ì¤Î¥¤¥ó¥¹¥¿¥ó¥¹(µ¶¤òɽ¤¹)
-@item __FILE__
-¥¹¥¯¥ê¥×¥È¤Î¥Õ¥¡¥¤¥ë̾(ʸ»úÎó)
-@item __LINE__
-¸½ºß¤Î¹ÔÈÖ¹æ(À°¿ô)
-@end table
-
-¤³¤ì¤é¤Îµ¿»÷ÊÑ¿ô¤ÏÂåÆþ¤Ë¤è¤Ã¤Æ¤½¤ÎÃͤòÊѹ¹¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡¥¤³¤ì¤é¤Î
-ÊÑ¿ô¤Ø¤ÎÂåÆþ¤ÏÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥
-
-@node ÇÛÎó¼°, Ï¢ÁÛÇÛÎó¼°, ÊÑ¿ô¤ÈÄê¿ô, ¼°
-@comment node-name, next, previous, up
-@subsection ÇÛÎó¼°
-
-Îã
-
-@example
-[1, 2, 3]
-@end example
-
-ÇÛÎó¤ÏArray¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤¢¤ë¡¥ÇÛÎó¤òÀ¸À®¤¹¤ë¼°¤Ï°Ê²¼¤Î·Á¼°¤Ç
-¤¢¤ë¡¥
-
-@example
-@code{[} ¼°,@dots{}@code{]}
-@end example
-
-¤½¤ì¤¾¤ì¤Î¼°¤òɾ²Á¤·¤¿·ë²Ì¤ò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥Í×ÁÇ¿ô¤¬0¤Î¶õÇÛÎó¤òÀ¸À®¤¹
-¤ë¤¿¤á¤Ë¤Ï¶õ¤ÎÇÛÎó¼°
-
-@example
-@code{[} @code{]}
-@end example
-
-¤òÍѤ¤¤ë¡¥
-
-@node Ï¢ÁÛÇÛÎó¼°, ¥á¥½¥Ã¥É¸Æ½Ð¼°, ÇÛÎó¼°, ¼°
-@comment node-name, next, previous, up
-@subsection Ï¢ÁÛÇÛÎó¼°
-
-Îã
-
-@example
-@{1=>2, 2=>4, 3=>6@}
-@end example
-
-Ï¢ÁÛÇÛÎó¤È¤ÏǤ°Õ¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ò¥­¡¼(ź»ú)¤È¤·¤Æ»ý¤ÄÇÛÎó¤Ç¤¢¤ë¡¥Ruby¤Î
-Ï¢ÁÛÇÛÎó¤ÏHash(Ï¢ÁÛÇÛÎó)¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤¢¤ë¡¥¾ÜºÙ¤Ï¥¯¥é¥¹
-@code{Hash}¤Î¹à¤ò»²¾È¤µ¤ì¤¿¤¤¡¥@xref{Hash}
-
-Ï¢ÁÛÇÛÎó¤òÀ¸À®¤¹¤ëÏ¢ÁÛÇÛÎ󼰤ϰʲ¼¤Î·Á¼°¤Ç¤¢¤ë¡¥
-
-@example
-@code{@{} ¼° @code{=>} ¼°@dots{}@code{@}}
-@end example
-
-¤½¤ì¤¾¤ì¤Î¼°¤òɾ²Á¤·¤¿·ë²Ì¤ò¥­¡¼¤ÈÃͤȤ¹¤ëÏ¢ÁÛÇÛÎ󥪥֥¸¥§¥¯¥È¤òÊÖ¤¹¡¥
-Í×ÁÇ¿ô¤¬0¤ÎÏ¢ÁÛÇÛÎó¤òÀ¸À®¤¹¤ë¤¿¤á¤Ë¤Ï¶õ¤ÎÏ¢ÁÛÇÛÎó¼°
-
-@example
-@code{@{} @code{@}}
-@end example
-
-¤òÍѤ¤¤ë¡¥Í×ÁǤ¬1¤Ä°Ê¾å¤¢¤ë¾ì¹ç¡¤Û£Ëæ¤Ç¤Ê¤±¤ì¤Ð@code{@{}, @code{@}}¤Ï
-¾Êά¤Ç¤­¤ë¡¥
-
-@node ¥á¥½¥Ã¥É¸Æ½Ð¼°, SUPER, Ï¢ÁÛÇÛÎó¼°, ¼°
-@comment node-name, next, previous, up
-@subsection ¥á¥½¥Ã¥É¸Æ½Ð¼°
-
-Îã
-
-@example
-foo.bar()
-foo.bar
-bar()
-print "hello world\n"
-print
-@end example
-
-¥ª¥Ö¥¸¥§¥¯¥È¤Ë¥á¥Ã¥»¡¼¥¸¤òÁ÷¤ë´ðËÜŪ¤Ê¹½Ê¸¤¬¥á¥Ã¥»¡¼¥¸¼°¤Ç¤¢¤ê¡¤¤½¤Î´ð
-ËÜ·Á¼°¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
-
-@display
-¼°1 `.' ¥á¥½¥Ã¥É̾ [`(' °ú¿ô@dots{}[`*' °ú¿ô] `)']
-@end display
-
-¼°1¤òɾ²Á¤·¤ÆÆÀ¤é¤ì¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Î¡¤¼±Ê̻ҤǻØÄꤵ¤ì¤ë¥á¥½¥Ã¥É¤ò¸Æ¤Ó
-½Ð¤¹¡¥
-
-¥á¥½¥Ã¥É̾¤Ë¤ÏÄ̾ï¤Î¼±Ê̻Ҥξ¡¤¼±Ê̻ҤË@code{?}¤Þ¤¿¤Ï@code{!}¤Î³¤¤¤¿
-¤â¤Î¤¬µö¤µ¤ì¤ë¡¥´·½¬¤È¤·¤Æ¡¤½Ò¸ì(¿¿µ¶ÃͤòÊÖ¤¹¥á¥½¥Ã¥É)¤Ë¤Ï@code{?}¤ò¡¤
-Ʊ̾¤Î¥á¥½¥Ã¥É¤ËÈæ¤Ù¤Æ¤è¤êÇ˲õŪ¤ÊºîÍѤò¤â¤Ä¥á¥½¥Ã¥É(Îã:@code{tr}¤È
-@code{tr!})¤Ë¤Ï@code{!}¤ò¤Ä¤±¤ë¡¥
-
-¥á¥Ã¥»¡¼¥¸¼°¤Ç¡¤¥ì¥·¡¼¥Ð¤¬@code{self}¤Î¾ì¹ç¡¤¥ì¥·¡¼¥Ð¤ò¾Êά¤·¤ÆÄ̾ï¤Î
-¥×¥í¥°¥é¥ß¥ó¥°¸À¸ì¤Ë¤ª¤±¤ë´Ø¿ô¤Î¤è¤¦¤Ê·Á¼°¤Ç¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹¤³¤È¤¬¤Ç
-¤­¤ë¡¥
-
-@display
-¥á¥½¥Ã¥É̾ `(' °ú¿ô@dots{}[`*' °ú¿ô]`)'
-@end display
-
-¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¤Î°ú¿ô¤Î¼þ¤ê¤Î³ç¸Ì¤ò¾Êά¤Ç¤­¤ë¤¬¡¤Âè°ì°ú¿ô¤È¤Ê¤ë¼°¤¬°Ê
-²¼¤Îʸ»ú¤Þ¤¿¤ÏͽÌó¸ì¤Ç»Ï¤Þ¤ë¾ì¹ç¤Ï¡¤²ò¼á¤ËÛ£ËæÀ­¤¬À¸¤¸¤ë¡¥
-
-@example
-(, [, @{, /, +, -, if, while, *
-@end example
-
-ruby¤ÏÂè1°ú¿ô¤Î¤è¤¦¤Ë¸«¤¨¤ëÉôʬ¤ò¡¤¿Í´Ö¤Ë¤È¤Ã¤Æ¼«Á³¤À¤È»×¤ï¤ì¤ë¤è¤¦¤Ë
-±é»»»Ò¤ÎÁ°¸å¤Î¶õÇò¤ò¸«¤Ê¤¬¤é¡¤¼ã´³Ê£»¨¤Ê¥ë¡¼¥ë¤Ç²ò¼á¤¹¤ë¡¥Í½ÁÛÄ̤ê¤Î·ë
-²Ì¤¬ÆÀ¤é¤ì¤Ê¤«¤Ã¤¿¤ê¡¤¤É¤Î¤è¤¦¤Ëɾ²Á¤µ¤ì¤ë¤«Ê¬¤«¤é¤Ê¤¤¾ì¹ç¤Ï¾Êά¤»¤º¤Ë
-³ç¸Ì¤ò¤Ä¤±¤ë»ö¡¥
-
-Îã
-
-@example
-foo bar+baz # ¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·foo(bar+baz)
-foo(1+2)*5 # ¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·(foo(1+2)) * 5
-foo (1+2)*5 # ¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·foo((1+2) * 5)
-foo 1 # ¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·foo(1)
-foo -1 # ¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·foo(-1)
-foo - 1 # ¥í¡¼¥«¥ëÊÑ¿ôfoo - 1
-@end example
-
-¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¤Ç¤Ï°ú¿ô¤¬1¤Ä¤â¤Ê¤¤»þ¤Ë¤â³ç¸Ì¤ò¾Êά¤Ç¤­¤ë¡¥¤¿¤À¤·¡¤¥ì
-¥·¡¼¥Ð¤ò»ØÄꤷ¤Ê¤¤¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¤Î¾ì¹ç¤Ï¥í¡¼¥«¥ëÊÑ¿ô¤Î»²¾È¤È²ò¼á¤µ¤ì
-¤¦¤ë¡¥
-
-¥á¥½¥Ã¥É̾¤È¤·¤Æ¤ÏǤ°Õ¤Î¼±Ê̻ҤòÍѤ¤¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥ºÇ½é¤Îʸ»ú¤ÏÂçʸ»ú
-¤Ç¤â¾®Ê¸»ú¤Ç¤â¹½¤ï¤Ê¤¤¡¥ÊÑ¿ô̾¤È¤Ï¼±Ê̻ҤÎ̾Á°¶õ´Ö¤¬°ã¤¦¤Î¤Ç½ÅÊ£¤·¤Æ¤â
-¹½¤ï¤Ê¤¤¡¥
-
-¥¯¥é¥¹Module¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥á¥½¥Ã¥É(@code{public},@code{private})¤Ç¥á
-¥½¥Ã¥É¤Î¸Æ¤Ó½Ð¤·Êý¤òÀ©¸æ¤¹¤ë¤³¤È¤¬½ÐÍè¤ë¡¥@code{private}¤Ç»ØÄꤵ¤ì¤¿À©
-¸Â¤µ¤ì¤¿¥á¥½¥Ã¥É¤Ï´Ø¿ô·Á¼°¤Ç¤·¤«¸Æ¤Ó½Ð¤¹¤³¤È¤¬½ÐÍè¤Ê¤¤¡¥
-
-@node SUPER, ÂåÆþ ,¥á¥½¥Ã¥É¸Æ½Ð¼°, Ï¢ÁÛÇÛÎó¼°, ¼°
-@comment node-name, next, previous, up
-@subsection SUPER
-
-Îã
-
-@example
-super
-super(1,2,3)
-@end example
-
-¥á¥Ã¥»¡¼¥¸¼°¤ÎÆüì¤Ê¥±¡¼¥¹¤È¤·¤Æ¥¹¡¼¥Ñ¡¼¥¯¥é¥¹¤Î¥á¥½¥Ã¥É¤Î¸Æ¤Ó½Ð¤·¤¬¤¢
-¤ë¡¥¤³¤Î·Á¼°¤Ï¥á¥½¥Ã¥É¤òºÆÄêµÁ¤·¤¿»þ¤Ë¥¹¡¼¥Ñ¡¼¥¯¥é¥¹¤ÎÄêµÁ¤òÍøÍѤ¹¤ë¤¿
-¤á¤Ë»È¤¦¡¥
-
-@display
-super
-@end display
-
-
-¸½ºß¤Î¥á¥½¥Ã¥É¤ËÍ¿¤¨¤é¤ì¤¿°ú¿ô¤Î¤Þ¤Þ¥¹¡¼¥Ñ¥¯¥é¥¹¤ÎƱ̾¤Î¥á¥½¥Ã¥É¤ò¸Æ¤Ó
-½Ð¤¹¡¥°ú¿ô¤È¤·¤ÆÍ¿¤¨¤é¤ì¤¿ÊÑ¿ô¤ÎÃͤòÊѹ¹¤·¤Æ¤â¡¤ÅϤµ¤ì¤ë¤Î¤Ï¸µ¤Î°ú¿ô¤Î
-ÃͤǤ¢¤ë¡¥
-
-@display
-super`(' °ú¿ô@dots{}`)'
-@end display
-
-°ú¿ô¤È¤È¤â¤Ë¥¹¡¼¥Ñ¡¼¥¯¥é¥¹¤ÎƱ̾¤Î¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹¡¥°ìÈֺǸå¤Î°ú¿ô¤¬
-@code{*}¤Ë³¤¯¾ì¹ç¤ÏÄ̾ï¤Î¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¤ÈƱÍͤËŸ³«¤·¤ÆÅϤµ¤ì¤ë¡¥
-
-@node ÂåÆþ, ±é»»»Ò¼°, SUPER, ¼°
-@comment node-name, next, previous, up
-@subsection ÂåÆþ
-
-Îã
-
-@example
-foo = bar
-foo[0] = bar
-foo.bar = baz
-@end example
-
-ÂåÆþ¼°¤ÏÊÑ¿ô¤Ê¤É¤ËÃͤòÀßÄꤹ¤ë¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¡¥ÂåÆþ¼°¤Ï±é»»»Ò·Á¼°¤ò¤È¤Ã
-¤Æ¤¤¤ë¤¬¡¤¥á¥½¥Ã¥É¤Ç¤Ï¤Ê¤¤¤Î¤ÇºÆÄêµÁ¤¹¤ë¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡¥º¸Êդˤʤ뤳¤È
-¤¬½ÐÍè¤ë¤Î¤Ï°Ê²¼¤Î3¼ïÎà¤Î¼°¤Ç¤¢¤ë¡¥
-
-ÊÑ¿ô(`$'¼±ÊÌ»Ò | `@@'¼±ÊÌ»Ò | ¼±ÊÌ»Ò)
-
-@display
-ÊÑ¿ô `=' ¼°
-@end display
-
-ÊÑ¿ô¤Ø¤ÎÂåÆþ¤Ï±¦Êդμ°¤òɾ²Á¤·¤ÆÆÀ¤é¤ì¤¿Ãͤòº¸ÊդǻØÄꤵ¤ì¤¿ÊÑ¿ô¤ËÂåÆþ
-¤¹¤ë¡¥
-
-ÇÛÎó»²¾È(¼°[¼°@dots{}])
-
-@display
-¼°1`[' ¼°2@dots{}`]' `=' ¼°n
-@end display
-
-ÇÛÎ󻲾ȼ°¤Ø¤ÎÂåÆþ¤Ï¡¤¼°1¤òɾ²Á¤·¤ÆÆÀ¤é¤ì¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Ë¡¤¼°2¤«¤é¼°n
-¤Þ¤Ç¤ò°ú¿ô¤È¤·¤Æ¡¤@code{[]=} ¤È¤¤¤¦¥á¥½¥Ã¥É¤ò¸Æ¤Ó½Ð¤¹¡¥
-
-°À­»²¾È(¼°`.'¼±ÊÌ»Ò)
-
-@display
-¼°1 `.' ¼±ÊÌ»Ò `=' ¼°2
-@end display
-
-°À­»²¾È(°ú¿ô¤Ê¤·¤Î¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·)¤Ø¤ÎÂåÆþ¤Ï¡¤¼°1¤òɾ²Á¤·¤ÆÆÀ¤é¤ì¤ë
-¥ª¥Ö¥¸¥§¥¯¥È(¥ì¥·¡¼¥Ð¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Ï@code{self})¤ËÂФ·¤Æ¡¤
-@code{¼±ÊÌ»Ò=}¤È¤¤¤¦¥á¥½¥Ã¥É¤ò¡¤¼°2¤ò°ú¿ô¤È¤·¤Æ¸Æ¤Ó½Ð¤¹¡¥
-
-@menu
-* ¼«¸ÊÂåÆþ::
-* ¿½ÅÂåÆþ::
-@end menu
-
-@node ¼«¸ÊÂåÆþ, ¿½ÅÂåÆþ, ÂåÆþ, ÂåÆþ
-@comment node-name, next, previous, up
-@subsubsection ¼«¸ÊÂåÆþ
-
-Îã
-
-@example
-foo += 12
-@end example
-
-¼°¤ÎÃͤ½¤Î¤â¤Î¤Ë±é»»¤ò²Ã¤¨¤ë¤¿¤á¤Ë¼«¸ÊÂåÆþ·Á¼°¤¬¤¢¤ë¡¥
-
-@display
-¼°1 op= ¼°2 # ¼°1¤ÏÂåÆþ²Äǽ¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¥
-@end display
-
-¤³¤Î·Á¼°¤ÏÆâÉôŪ¤Ë@code{¼°1 = ¼°1 op ¼°2}¤ÈƱÍͤËɾ²Á¤µ¤ì¤ë¡¥¤¿¤À¤·¡¤
-¼°1¤Ï1²ó¤·¤«É¾²Á¤µ¤ì¤Ê¤¤¤Î¤Ç¡¤¼°1¤ËÉûºîÍѤ¬¤¢¤ë¾ì¹ç¤Ï¡¤
-@code{¼°1 = ¼°1 op ¼°2}¤È¤ÏÆ°ºî¤¬°Û¤Ê¤ë·ë²Ì¤È¤Ê¤ë¡¥
-op¤È¤·¤Æ»È¤¨¤ë±é»»»Ò¤Ï
-
-@display
- +, -, *, /, %, **, &, |, ^, <<, >>
-@end display
-
-¤Î11¼ïÎà¤Ç¤¢¤ë¡¥±é»»»Ò¤È@code{=}¤Î´Ö¤Ë¥¹¥Ú¡¼¥¹¤ò¶õ¤±¤Æ¤Ï¤¤¤±¤Ê¤¤¡¥
-
-@node ¿½ÅÂåÆþ, , ¼«¸ÊÂåÆþ, ÂåÆþ
-@comment node-name, next, previous, up
-@subsubsection ¿½ÅÂåÆþ
-
-Îã
-
-@example
-foo, bar, baz = 1, 2, 3
-foo, = list()
-foo, *rest = list2()
-@end example
-
-Ʊ»þ¤ËÊ£¿ô¤ÎÊÑ¿ô¤ËÂåÆþ¤ò¹Ô¤Ê¤¦¤³¤È¤¬¤Ç¤­¤ë¡¥¤½¤Î·Á¼°¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
-
-@display
- º¸ÊÕ `,' [º¸ÊÕ `,'@dots{}] [`*' º¸ÊÕ]= ¼° [, ¼°@dots{}]
-@end display
-
-º¸ÊդˤÏÂåÆþ¼°¤Î3¼ïÎà¤Î¼°¤¬Íè¤ë¡¥±¦Êդμ°¤¬°ì¤Ä¤·¤«¤Ê¤¤¾ì¹ç¤Ï¡¤¤½¤ÎÃÍ
-¤òÇÛÎó¤È¤·¤Æ(ɬÍפʤé¤Ð@code{to_a}¥á¥½¥Ã¥É¤ÇÇÛÎó¤ËÊÑ´¹¤·¤Æ)¡¤Í×ÁǤò¤½
-¤ì¤¾¤ìº¸ÊÕ¤ËÂåÆþ¤¹¤ë¡¥¤½¤ì°Ê³°¤Î¾ì¹ç¤Ë¤Ï¡¤¤½¤ì¤¾¤ì¤Î¼°¤ÎÃͤ¬º¸ÊÕ¤ËÂåÆþ
-¤µ¤ì¤ë¡¥º¸Êդοô¤È±¦ÊÕ¤ÎÍ×ÁǤοô¤¬¹ç¤ï¤Ê¤¤»þ¤Ë¤Ï­¤ê¤Ê¤¤ÊÑ¿ô¤Ë¤Ï
-@code{nil}¤¬ÂåÆþ¤µ¤ì¡¤Í¾¤Ã¤¿Í×ÁǤÏ̵»ë¤µ¤ì¤ë¡¥Â¿½ÅÂåÆþ¤ÎºÇ¸å¤ÎÍ×ÁǤÎÁ°
-¤Ë@code{*}¤¬¤¢¤ë¾ì¹ç¡¤»Ä¤ê¤ÎÁ´¤Æ°ú¿ô¤¬ÇÛÎó¤È¤·¤ÆÂåÆþ¤µ¤ì¤ë¡¥
-
-Îã
-
-@example
-foo, bar = [1, 2] # foo = 1; bar = 2
-foo, bar = 1, 2 # foo = 1; bar = 2
-foo, bar = 1 # foo = 1; bar = nil
-
-foo, bar, baz = 1, 2 # foo = 1; bar = 2; baz = nil
-foo, bar = 1, 2, 3 # foo = 1; bar = 2
-foo,*bar = 1, 2, 3 # foo = 1; bar = [2, 3]
-@end example
-
-¿½ÅÂåÆþ¤ÎÃͤÏ(ÇÛÎó¤ËÊÑ´¹¤µ¤ì¤¿)±¦ÊդǤ¢¤ë¡¥
-
-@node ±é»»»Ò¼°, À©¸æ¹½Â¤, ÂåÆþ, ¼°
-@comment node-name, next, previous, up
-@subsection ±é»»»Ò¼°
-
-Îã
-
-@example
-1+2*3/4
-@end example
-
-¥×¥í¥°¥é¥ß¥ó¥°¤ÎÍøÊؤΤ¿¤á¤Ë°ìÉô¤Î¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¤ÈÀ©¸æ¹½Â¤¤Ï±é»»»Ò·Á
-¼°¤ò¤È¤ë¡¥Ruby¤Ë¤Ï°Ê²¼¤Ë¤¢¤²¤ë±é»»»Ò¤¬¤¢¤ë¡¥¾å¤Î¤â¤Î¤Û¤É·ë¹ç½ç°Ì¤¬¶¯¤¯¡¤
-Ʊ¤¸Îó¤Î±é»»»Ò¤Î·ë¹ç½ç°Ì¤ÏƱ¤¸¤Ç¤¢¤ë¡¥
-@cindex{·ë¹çµ¬Â§}
-
-@display
- ¶¯ ::
- [](ÇÛÎó»²¾È), []=(ÇÛÎóÂåÆþ)
- **
- -(unary) +(unary) ! ~
- * / %
- + -
- << >>
- &
- | ^
- > >= < <=
- <=> == != =~ !~
- &&
- ||
- .. ...
- =(ÂåÆþ) ¼«¸ÊÂåÆþ(+=, -=@dots{})
- and or
- not
- ¼å if½¤¾þ»Ò while½¤¾þ»Ò
-@end display
-
-¤Û¤È¤ó¤É¤Î±é»»¼°¤Ë¤Ï¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¤È¤·¤Æ²ò¼á¤µ¤ì¤ë(¥¯¥é¥¹Ëè¤ËºÆÄêµÁ
-¤Ç¤­¤ë)¤¬¡¤°ìÉôºÆÄêµÁ¤Ç¤­¤Ê¤¤Æüì¤Ê¤â¤Î¤¬¤¢¤ë¡¥ºÆÄêµÁ¤Ç¤­¤Ê¤¤Æüì±é»»
-»Ò¤Ï
-
-@display
- =, .., ..., !, not, &&, and, |, or, if½¤¾þ»Ò, while½¤¾þ»Ò
-@end display
-
-¤Î³Æ±é»»»Ò¤È¡¤¤³¤ì¤é¤È¤ÎÁȤ߹ç¤ï¤»¤Ë¤Ê¤ë !=, !~ ¤ª¤è¤Ó¼«¸ÊÂåÆþ±é»»»Ò¤Ç
-¤¢¤ë¡¥
-
-¾å¤Ç¤¢¤²¤¿Æüì±é»»»Ò°Ê³°¤Î±é»»»Ò·Á¼°¤Ï°Ê²¼¤Î¤è¤¦¤Ê¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¤È¸«
-¤Ê¤µ¤ì¤ë¡¥
-
-ñ¹à±é»»»Ò(+, -, ~)
-
-@display
-¼°1. ±é»»»Ò ()
-@end display
-
-ÇÛÎó(Ï¢ÁÛÇÛÎó¤ò´Þ¤à)¤ÎÍ×ÁǤλ²¾È(¼°1 `[' ¼°2@dots{}`]')
-
-@display
-¼°1. `[]' (¼°2@dots{})
-@end display
-
-ÇÛÎóÍ×ÁǤÎÂåÆþ( ¼°1 `[' ¼°2@dots{}`]' `=' ¼°n)
-
-@display
-¼°1. `[]=' (¼°2@dots{}, ¼°n)
-@end display
-
-¤½¤ì°Ê³°¤Î2¹à±é»»»Ò(¼°1 ±é»»»Ò ¼°2)
-
-@display
-¼°1. ±é»»»Ò (¼°2)
-@end display
-
-¤³¤ì¤Ï¤¢¤¯¤Þ¤Ç¤â¤½¤¦¤¤¤¦·Á¼°¤Î¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¤È¤·¤Æ²ò¼á¤µ¤ì¤ë¤È¤¤¤¦¤À
-¤±¤Ç¡¤ruby¥×¥í¥°¥é¥à¤Ç¤³¤¦¤¤¤¦µ­½Ò¤¬µö¤µ¤ì¤ë¤È¤¤¤¦¤ï¤±¤Ç¤Ï¤Ê¤¤¡¥
-
-@node À©¸æ¹½Â¤, ¥¯¥é¥¹ÄêµÁ, ±é»»»Ò¼°, ¼°
-@comment node-name, next, previous, up
-@subsection À©¸æ¹½Â¤
-
-Ruby¤Ç¤Ï(C¤Ê¤É¤È¤Ï°Û¤Ê¤ê)À©¸æ¹½Â¤¤Ï¼°¤Ç¤¢¤ê¡¤²¿¤é¤«¤ÎÃͤò»ý¤Ä¡¥¤³¤ÎÅÀ¤Ç
-lisp¤Ê¤É¤Ë»÷¤Æ¤¤¤ë¤È¤¤¤¨¤ë¡¥Ruby¤ÏC¸À¸ì¤äPerl¤«¤é°ú¤­·Ñ¤¤¤ÀÀ©¸æ¹½Â¤¤ò»ý
-¤Ä¤¬¡¤ÆÃħŪ¤ÊÀ©¸æ¹½Â¤¤È¤·¤Æ¥¤¥Æ¥ì¡¼¥¿¤ò»ý¤Ä¡¥¥¤¥Æ¥ì¡¼¥¿¤Ï·«¤êÊÖ¤·¤ò»Ï¤á
-¤È¤¹¤ëÀ©¸æ¤ò¥æ¡¼¥¶¤¬ÄêµÁ¤¹¤ë»ö¤¬½ÐÍè¤ë¤â¤Î¤Ç¤¢¤ë.
-@xref{¥¤¥Æ¥ì¡¼¥¿(·«¤êÊÖ¤·»Ò)}
-
-@menu
-* IF::
-* IF½¤¾þ»Ò::
-* CASE::
-* AND::
-* OR::
-* ÈÏ°Ï»ØÄê¼°::
-* NOT::
-* WHILE::
-* WHILE½¤¾þ»Ò::
-* ¥¤¥Æ¥ì¡¼¥¿(·«¤êÊÖ¤·»Ò)::
-* FOR::
-* YIELD::
-* FAIL::
-* BEGIN::
-* RETRY::
-* RETURN::
-* BREAK::
-* CONTINUE::
-* REDO::
-@end menu
-
-@node IF, IF½¤¾þ»Ò, À©¸æ¹½Â¤, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection IF
-
-Îã
-
-@example
-if age >= 12 then print "adult fee\n" else print "child fee\n" end
-gender = if foo.gender == "male" then "male" else "female" end
-@end example
-
-¹½Ê¸
-
-@display
-if ¼°1 [then]
- ¼°@dots{}
-[elsif ¼°2 [then]
- ¼°@dots{}]@dots{}
-[else
- ¼°@dots{}]
-end
-@end display
-
-¾ò·ïȽÃǼ°¡¥Ruby¤Î@code{if}¼°¤Ï@code{else if}¤Ç¤â@code{elif}¤Ç¤â¤Ê¤¯
-@code{elsif}¤Ç@code{if}¤ÎϢ³¤ò¹Ô¤Ê¤¦¤³¤È¤ËÃí°Õ¤¹¤ë¤³¤È¡¥¾ò·ï¤¬À®Î©¤·
-¤Æ¼Â¹Ô¤·¤¿¼°¤ÎÃͤòÊÖ¤¹¡¥¼Â¹Ô¤·¤Ê¤«¤Ã¤¿¾ì¹ç¤ÎÃͤÏ@code{nil}¡¥
-
-@code{if}¤Î¾ò·ïȽÃÇÉô¤Î¼°¤Ç¤Ïʸ»úÎó¤ÈÀµµ¬É½¸½¥ê¥Æ¥é¥ë¤Ï¼°
-@example
-$_=~ ¥ê¥Æ¥é¥ë
-@end example
-¤Î¾Êά¤Ç¤¢¤ë¤È¤ß¤Ê¤µ¤ì¤ë¡¥
-
-@node IF½¤¾þ»Ò, CASE, IF, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection IF½¤¾þ»Ò
-
-Îã
-
-@example
-print "debug\n" if $debug
-@end example
-
-¹½Ê¸
-
-@display
-¼° if ¼°
-@end display
-
-¾ò·ï½¤¾þ»Ò(@code{if})¤Î¼°¤ÏÀè¹Ô¤¹¤ë¼°¤ËÀè¤À¤Ã¤Æɾ²Á¤µ¤ì¤ë¡¥Æ°ºî¤âÂбþ
-¤¹¤ë@code{if}¼°¤ÈƱÍͤǤ¢¤ë¡¥@code{if}½¤¾þ»Ò¤Î¤Ä¤¤¤¿¼°¤ÎÃͤϾò·ï¤¬À®Î©
-¤·¤¿¾ì¹ç¤Ë¤Ï¼°¤ÎÃÍ¡¤ÉÔÀ®Î©¤Î¾ì¹ç¤Ë¤Ï@code{nil}¤Ç¤¢¤ë¡¥
-
-@node CASE, AND, IF½¤¾þ»Ò, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection CASE
-
-Îã
-
-@example
-case $age
-when 0 .. 2
- "baby"
-when 3 .. 6
- "little child"
-when 7 .. 12
- "child"
-when 12 .. 18
- "youth"
-else
- "adult"
-end
-@end example
-
-¹½Ê¸
-
-@display
-case ¼°0
-[when ¼°1 [, ¼°2]@dots{}[then]
- ¼°@dots{}]@dots{}
-[else
- ¼°@dots{}]
-end
-@end display
-
-¾ò·ïʬ´ô¡¤C¤Î@code{switch}¤è¤ê¤âPascal¤Î@code{case}¤Ë»÷¤Æ¤¤¤ë¡¥
-@code{break}¤Çæ½Ð¤¹¤ë¤³¤È¤â¸å¤í¤Î¼°¤Ë·Ñ³¤¹¤ë¤³¤È¤â¤Ê¤¤¤Î¤ÇÃí°Õ¡¥
-
-¾ò·ï¤Î°ìÃפÏ@code{¼°n =~ ¼°0}¤Ç¹Ô¤Ê¤ï¤ì¤ë¡¥¤Ä¤Þ¤ê¡¤
-
-@example
-case expr0
-when expr1, expr2
- stmt1
-when expr3, expr4
- stmt2
-else
- stmt3
-end
-@end example
-
-¤Ï°Ê²¼¤Î@code{if}¼°¤È¤Û¤ÜÅù²Á¤Ç¤¢¤ë¡¥
-
-@example
-_tmp = expr0
-if expr1 =~ _tmp || expr2 =~ _tmp
- stmt1
-elsif expr3 =~ _tmp || expr4 =~ _tmp
- stmt2
-else
- stmt3
-end
-@end example
-
-@node AND, OR, CASE, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection AND
-
-Îã
-
-@example
-test && set
-test and set
-@end example
-
-¹½Ê¸
-
-@display
-¼°1 `&&' ¼°2
-¼°1 `and' ¼°2
-@end display
-
-¼°1¤òɾ²Á¤·¡¤¤½¤ÎÃͤ¬¿¿(@code{nil}°Ê³°)¤Ç¤¢¤ì¤Ð¡¤¼°2¤òɾ²Á¤¹¤ë¡¥
-@code{and}¤ÏÍ¥Àè½ç°Ì¤¬Ä㤤ÊÌ̾¤Ç¤¢¤ë¡¥
-
-@code{and}¤ÎξÊդμ°¤Ç¤Ïʸ»úÎó¤ÈÀµµ¬É½¸½¥ê¥Æ¥é¥ë¤Ï¼°
-@code{$_ =~ ¥ê¥Æ¥é¥ë} ¤Î¾Êά¤Ç¤¢¤ë¤È¤ß¤Ê¤µ¤ì¤ë¡¥
-
-@node OR, ÈÏ°Ï»ØÄê¼°, AND, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection OR
-
-Îã
-
-@example
-demo || die
-demo or die
-@end example
-
-¹½Ê¸
-
-@display
-¼°1 `||' ¼°2
-¼°1 'or ¼°2
-@end display
-
-¼°1¤òɾ²Á¤·¡¤¤½¤ÎÃͤ¬µ¶¤Ç¤¢¤ì¤Ð¡¤¼°2¤òɾ²Á¤¹¤ë¡¥@code{or}¤ÏÍ¥Àè½ç°Ì¤¬
-Ä㤤ÊÌ̾¤Ç¤¢¤ë¡¥
-
-@code{or}¤ÎξÊդμ°¤Ç¤Ïʸ»úÎó¤ÈÀµµ¬É½¸½¥ê¥Æ¥é¥ë¤Ï¼°
-@code{$_ =~ ¥ê¥Æ¥é¥ë}¤Î¾Êά
-¤Ç¤¢¤ë¤È¤ß¤Ê¤µ¤ì¤ë¡¥
-
-@node ÈÏ°Ï»ØÄê¼°, NOT, OR, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection ÈÏ°Ï»ØÄê¼°
-
-Îã
-
-@example
-1 .. 20
-/first/ ... /second/
-@end example
-
-¹½Ê¸
-
-@display
-¼°1 `..' ¼°2
-¼°1 `...' ¼°2
-@end display
-
-¾ò·ï¼°°Ê³°¤Î¾ì½ê¤Ç¤Ï¼°1¤«¤é¼°2¤Þ¤Ç¤ÎÈÏ°Ï¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡¥
-
-¾ò·ï¼°¤È¤·¤ÆÈÏ°Ï»ØÄê¼°¤¬ÍѤ¤¤é¤ì¤¿¾ì¹ç¤Ï¡¤¼°1¤¬¿¿¤Ë¤Ê¤ë¤Þ¤Ç¤Ïµ¶¤òÊÖ¤·¡¤
-¤½¤Î¸å¤Ï¼°2¤¬¿¿¤òÊÖ¤¹¤Þ¤Ç¤Ï¿¿¤òÊÖ¤¹¡¥¼°2¤¬¿¿¤Ë¤Ê¤ì¤Ð¾õÂ֤ϵ¶¤ËÌá¤ë¡¥
-@code{..}¤Ï¼°1¤¬¿¿¤Ë¤Ê¤Ã¤¿»þ¤Ë¼°2¤òɾ²Á¤·(awk¤Î¤è¤¦¤Ë)¡¤@code{...}¤Ï¼¡
-¤Îɾ²Á¤Þ¤Ç¼°2¤òɾ²Á¤·¤Ê¤¤(sed¤Î¤è¤¦¤Ë)¡¥
-
-¾ò·ï¼°¤ÇÈÏ°Ï»ØÄê¼°¤ÎξÊդȤʤ뼰¤Ç¤Ï¡¤Ê¸»úÎó¤ÈÀµµ¬É½¸½¥ê¥Æ¥é¥ë¤Ï¼°
-@code{$_ =~ ¥ê¥Æ¥é¥ë}¤Î¾Êά¡¤À°¿ôÄê¿ô¤Ï@code{$. == Äê¿ô}¤Î¾Êά¤È²ò¼á¤µ
-¤ì¤ë¡¥
-
-@node NOT, WHILE, ÈÏ°Ï»ØÄê¼°, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection NOT
-
-Îã
-
-@example
-! me
-not me
-i != you
-@end example
-
-¹½Ê¸
-
-@display
-`!' ¼°
-not ¼°
-@end display
-
-¼°¤¬¿¿¤Ç¤¢¤ì¤Ðµ¶¡¤µ¶¤Ç¤¢¤ì¤Ð¿¿¤òÊÖ¤¹¡¥
-
-@code{!}¼°¤Ç¤Ïʸ»úÎó¤ÈÀµµ¬É½¸½¥ê¥Æ¥é¥ë¤Ï¼°@code{$_ =~ ¥ê¥Æ¥é¥ë}¤Î¾Êά
-¤Ç¤¢¤ë¤È¤ß¤Ê¤µ¤ì¤ë¡¥
-
-@display
-¼°1 `!=' ¼°2
-@end display
-
-@code{!(¼°1 == ¼°2)}¤Î¾Êά·Á
-
-@display
-¼°1 `!~' ¼°2
-@end display
-
-@code{!(¼°1 ~= ¼°2)}¤Î¾Êά·Á
-
-@node WHILE, WHILE½¤¾þ»Ò, NOT, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection WHILE
-
-Îã
-
-@example
-while sunshine()
- work()
-end
-@end example
-
-¹½Ê¸
-
-@display
-while ¼°
- @dots{}
-end
-@end display
-
-¼°¤òɾ²Á¤·¤¿Ãͤ¬¿¿¤Î´Ö¡¤ËÜÂΤò·«¤êÊÖ¤·¼Â¹Ô¤¹¤ë¡¥@code{while}¼°¤ÎÃͤÏ
-@code{nil}¤Ç¤¢¤ë¡¥
-
-while¤Î¾ò·ïȽÃÇÉô¤Î¼°¤Ç¤Ïʸ»úÎó¤ÈÀµµ¬É½¸½¥ê¥Æ¥é¥ë¤Ï¼°
-@code{$_ =~ ¥ê¥Æ¥é¥ë} ¤Î¾Êά¤Ç¤¢¤ë¤È¤ß¤Ê¤µ¤ì¤ë¡¥
-
-@node WHILE½¤¾þ»Ò, ¥¤¥Æ¥ì¡¼¥¿(·«¤êÊÖ¤·»Ò), WHILE, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection WHILE½¤¾þ»Ò
-
-Îã
-
-@example
-sleep while idle
-@end example
-
-¹½Ê¸
-
-@display
-ñ½ã¼° while ¼°
-@end display
-
-º¸¤Î¼°¤òɾ²Á¤·¤¿Ãͤ¬¿¿¤Î´Ö¡¤±¦¤Îñ½ã¼°¤ò·«¤êÊÖ¤·¼Â¹Ô¤¹¤ë¡¥±¦¤Îñ½ã¼°¤¬
-@code{begin}¼°¤Ç¤¢¤ë¾ì¹ç¤Ï¤Þ¤º@code{begin}¼°¤òɾ²Á¤·¤Æ¤«¤é¾ò·ï¼°¤òɾ²Á
-¤¹¤ë(ºÇÄã°ìÅÙ¤Ïbegin¼°¤ò¼Â¹Ô¤¹¤ë)¡¥@code{while}½¤¾þ»Ò¤Î¤Ä¤¤¤¿¼°¤ÎÃͤÏ
-@code{nil}¤Ç¤¢¤ë¡¥
-
-@node ¥¤¥Æ¥ì¡¼¥¿(·«¤êÊÖ¤·»Ò), FOR, WHILE½¤¾þ»Ò, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection ¥¤¥Æ¥ì¡¼¥¿(·«¤êÊÖ¤·»Ò)
-
-Îã
-
-@example
-[1,2,3].each@{|i| print i*2, "\n"@}
-@end example
-
-¥¤¥Æ¥ì¡¼¥¿¤È¤ÏÀ©¸æ¹½Â¤(Æä˥롼¥×)¤ÎÃê¾Ý²½¤Î¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¥á¥½¥Ã¥É¤Î
-°ì¼ï¤Ç¤¢¤ë¡¥¥³¡¼¥É¤ÎÃÇÊÒ(¥Ö¥í¥Ã¥¯¤È¸Æ¤Ð¤ì¤ë)¤ò»ØÄꤷ¤Æ¥¤¥Æ¥ì¡¼¥¿¤ò¸Æ¤Ó
-½Ð¤¹¤È¡¤¥¤¥Æ¥ì¡¼¥¿¤ÏŬÅö¤ÊÃͤò¥»¥Ã¥È¤·¤Æ¥Ö¥í¥Ã¥¯¤òɾ²Á¤¹¤ë(¤ª¤½¤é¤¯¤Ï
-Ê£¿ô²ó)¡¥¥¤¥Æ¥ì¡¼¥¿¤«¤é¤Î¥Ö¥í¥Ã¥¯¤Î¸Æ¤Ó½Ð¤·¤Ï@code{yield}¼°¤òÍѤ¤¤ë(¸å
-½Ò)¡¥
-
-¥¤¥Æ¥ì¡¼¥¿¤Î¸Æ¤Ó½Ð¤·¤Ï°Ê²¼¤Î¹½Ê¸¤Ç¹Ô¤Ê¤ï¤ì¤ë¡¥
-
-@display
-¼° `@{' [`|' º¸ÊÕ¼°@dots{}`|'] ¼°@dots{}`@}'
-@end display
-
-¡Ö¼°¡×¤ò¥Ö¥í¥Ã¥¯¤È¤·¤ÆÀßÄꤷ¡¤¡Ö¼°¡×¤Î¥á¥½¥Ã¥É¤ò¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æɾ²Á¤¹
-¤ë¡¥¡Ö¼°¡×¤Î¥È¥Ã¥×¥ì¥Ù¥ë¤Î¥á¥½¥Ã¥É¤À¤±¤¬¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ó½Ð¤µ¤ì¡¤
-¥ì¥·¡¼¥Ð¤òɽ¤¹¼°¤ä¡¤°ú¿ô¤Î¼°¤Ï¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¤Ï¸Æ¤Ó½Ð¤µ¤ì¤Ê¤¤¡¥¡Ö¼°¡×
-¤¬Ê£¿ô¤Î¼°¤ò´Þ¤à»þ¡¤³Æ¡¹¤¬¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ½ç¤Ë¸Æ¤Ð¤ì¤ë¡¥
-
-¥¤¥Æ¥ì¡¼¥¿Æâ¤Ç@code{yield}¼°¤¬¼Â¹Ô¤µ¤ì¤ë¤È¡¤¤½¤³¤Ç»ØÄꤵ¤ì¤¿Ãͤ¬º¸ÊÕ¼°
-¤Ç»ØÄꤵ¤ì¤¿ÊÑ¿ô¤ËÂåÆþ¤µ¤ì¡¤¥Ö¥í¥Ã¥¯¤¬¼Â¹Ô¤µ¤ì¤ë¡¥¥Ö¥í¥Ã¥¯¤Î¼Â¹Ô¤¬½ªÎ»
-¤¹¤ë¤È¤½¤ÎÃÍ¤Ï @code{yield}¼°¤ÎÃͤȤ·¤ÆÊÖ¤µ¤ì¤ë¡¥¤¢¤ë¥á¥½¥Ã¥É¤¬¥¤¥Æ¥ì¡¼
-¥¿¤È¤·¤Æ¸Æ¤Ó½Ð¤µ¤ì¤¿¤«¤É¤¦¤«¤Ï¥á¥½¥Ã¥É@code{iterator?}¤ÎÌá¤êÃͤÇÃΤ뤳
-¤È¤¬¤Ç¤­¤ë¡¥Ãæ¤Ë¤Ï@code{Enumerable:grep}¥á¥½¥Ã¥É¤Î¤è¤¦¤Ë¥¤¥Æ¥ì¡¼¥¿¤È¤·
-¤Æ¸Æ¤Ð¤ì¤¿»þ¤ÈÉáÄ̤Υ᥽¥Ã¥É¤È¤·¤Æ¸Æ¤Ð¤ì¤¿»þ¤È¤ÇÆ°ºî¤¬°Û¤Ê¤ë¥á¥½¥Ã¥É¤â
-¤¢¤ë¡¥
-
-@node FOR, YIELD, ¥¤¥Æ¥ì¡¼¥¿(·«¤êÊÖ¤·»Ò), À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection FOR
-
-Îã
-
-@example
-for i in [1, 2, 3]
- print i*2, "\n"
-end
-@end example
-
-¥ª¥Ö¥¸¥§¥¯¥È¤Î³ÆÍ×ÁǤËÂФ·¤ÆÁàºî¤ò¹Ô¤Ê¤¦¤¿¤á¤Î·Á¼°¤âÄ󶡤µ¤ì¤Æ¤¤¤ë¡¥·Á
-¼°¤Ï°Ê²¼¤ÎÄ̤ꡥ
-
-@display
-for º¸ÊÕ¼°@dots{} in ¼°
- ¼°
-end
-@end display
-
-¼°¤Î³ÆÍ×ÁǤËÂФ·¼°¤ò¼Â¹Ô¤¹¤ë¡¥¤³¤ì¤Ï°Ê²¼¤Î¼°¤È¤Û¤ÜÅù²Á¤Ç¤¢¤ë¡¥¡Ö¤Û¤Ü¡×
-¤È¤¤¤¦¤Î¤Ï¡¤¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤Ï¿·¤·¤¤¥í¡¼¥«¥ëÊÑ¿ô¤ÎÍ­¸úÈϰϤòƳÆþ¤¹¤ë
-¤Î¤ËÂФ·¡¤@code{for}ʸ¤Ï¥í¡¼¥«¥ëÊÑ¿ô¤Î¥¹¥³¡¼¥×¤Ë±Æ¶Á¤òµÚ¤Ü¤µ¤Ê¤¤ÅÀ¤¬°Û
-¤Ê¤ë¤«¤é¤Ç¤¢¤ë
-
-@display
-(¼°).each `@{' `|' º¸ÊÕ¼°@dots{}`|' ¼° `@}'
-@end display
-
-¤è¤Ã¤Æ¼°¤ÎÃͤΥª¥Ö¥¸¥§¥¯¥È¤¬¥á¥½¥Ã¥É@code{each}¤ò»ý¤¿¤Ê¤¤¾ì¹ç¡¤
-@code{for}¤ò¼Â¹Ô¤¹¤ë¤ÈÎã³°¤¬È¯À¸¤¹¤ë¡¥
-
-@node YIELD, FAIL, FOR, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection YIELD
-
-Îã
-
-@example
-yield data
-@end example
-
-¹½Ê¸
-
-@display
-yield `(' [¼° [`,' ¼°@dots{}]])
-@end display
-
-¥¤¥Æ¥ì¡¼¥¿¤ÎÃæ¤Ç¥Ö¥í¥Ã¥¯¤Î¸Æ¤Ó½Ð¤·¤ò¹Ô¤Ê¤¦¡¥@code{yield}¤ò¼Â¹Ô¤·¤¿¥á¥½¥Ã
-¥É¤¬¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ó½Ð¤µ¤ì¤Æ¤¤¤Ê¤¤»þ¤Ë¤ÏÎã³°¤¬È¯À¸¤¹¤ë¡¥
-@code{yield} ¤ÎÃͤϥ֥í¥Ã¥¯¤ÎÌá¤êÃͤǤ¢¤ë¡¥
-
-@code{yield}¤Î°ú¿ô¤Î³ç¸Ì¤ÏÛ£Ëæ¤Ç¤Ê¤¤¸Â¤ê¾Êά¤Ç¤­¤ë¡¥
-
-@node FAIL, BEGIN, YIELD, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection FAIL
-
-Îã
-
-@example
-fail
-fail "you lose"
-@end example
-
-¹½Ê¸
-
-@display
-fail `(' [¥á¥Ã¥»¡¼¥¸] `)'
-@end display
-
-Îã³°¤òȯÀ¸¤µ¤»¤ë¡¥¥á¥Ã¥»¡¼¥¸¤¬Í¿¤¨¤é¤ì¤¿¾ì¹ç¤Ë¤ÏȯÀ¸¤·¤¿¥½¡¼¥¹¥Õ¥¡¥¤¥ë
-̾¡¤¹ÔÈÖ¹æ¤ò¥·¥¹¥Æ¥àÊÑ¿ô@code{$@@}¤Ë¡¤¥á¥Ã¥»¡¼¥¸¤ò@code{$!}¤Ë¥»¥Ã¥È¤¹¤ë¡¥
-
-@code{fail}¤Î°ú¿ô¤Î³ç¸Ì¤Ï¾Êά¤Ç¤­¤ë¡¥
-
-@node BEGIN, RETRY, FAIL, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection BEGIN
-
-Îã
-
-@example
-begin
- do_something()
-rescue
- recover()
-ensure
- must_to_do()
-end
-@end example
-
-Ê£¿ô¤Î¼°¤ò¤Þ¤È¤á¤ë¤¿¤á¤ÈÎã³°½êÍý¤Î¤¿¤á¤Ë@code{begin}¼°¤¬¤¢¤ë¡¥
-@code{begin}¼°¤Î·Á¼°¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
-
-@display
-begin
- ¼°@dots{}
-[rescue
- ¼°@dots{}]
-[ensure
- ¼°@dots{}]
-end
-@end display
-
-@code{begin}¼°¤ÎÃͤϰìÈֺǸå¤Ëɾ²Á¤µ¤ì¤¿¼°¤ÎÃͤǤ¢¤ë¡¥@code{begin}¼°¤Î
-½èÍýÃæ¤ËȯÀ¸¤·¤¿»þ¤ËÎã³°¤Ï@code{rescue}Àá¤ÇÊá³Í¤¹¤ë¤³¤È¤¬½ÐÍè¤ë¡¥¤³¤Î
-¾ì¹ç¤ÎÃÍ@code{begin}¼°¤ÎÃͤϤÏ@code{rescue}Éô¤ÇºÇ¸å¤Ëɾ²Á¤·¤¿¼°¤ÎÃͤÇ
-¤¢¤ë¡¥¹¹¤Ë@code{ensure}À᤬¸ºß¤¹¤ë»þ¤Ï@code{begin}¼°¤ò½ªÎ»¤¹¤ëÁ°¤Ëɬ
-¤º(Àµ¾ï½ªÎ»»þ¤À¤±¤Ç¤Ê¤¯¡¤Îã³°, @code{return}, @code{break},
-@code{continue}, @code{redo}¤Ê¤É¤Ë¤è¤ëæ½Ð¤Ç¤â)@code{ensure}Àá¤Î¼°¤òɾ
-²Á¤¹¤ë¡¥
-
-@node RETRY, RETURN, BEGIN, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection RETRY
-
-Îã
-
-@example
-retry
-@end example
-
-¹½Ê¸
-
-@display
-retry
-@end display
-
-ºÆ¼Â¹Ô¡¥@code{begin}¼°¤Î@code{rescue}Àá¤Ç»È¤ï¤ì¤¿¾ì¹ç¡¤@code{begin}¼°
-¤ò»Ï¤á¤«¤é¤â¤¦°ìÅټ¹Ԥ¹¤ë¡¥Îã³°½èÍý¤ò¹Ô¤Ê¤Ã¤Æ¤«¤éºÆ»î¹Ô¤¹¤ë¤Î¤Ë»È¤¦¡¥
-
-@example
-begin
- ²¿¤é¤«¤Î½èÍý(Îã³°¤¬È¯À¸¤¹¤ë)
-rescue
- Îã³°½èÍý
- retry # Îã³°¤ËÂбþ¤·¤ÆºÆ¼Â¹Ô
-end
-@end example
-
-¥¤¥Æ¥ì¡¼¥¿¡¤¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤Þ¤¿¤Ïforʸ¤ÎÃæ¤Ç»È¤ï¤ì¤¿¾ì¹ç¤Ë¤Ï¡¤¤½¤Î
-¥¤¥Æ¥ì¡¼¥¿¤Îɾ²Á¼«ÂΤòºÇ½é¤«¤é¼Â¹Ô¤¹¤ë¡¥¥¤¥Æ¥ì¡¼¥¿¤Î°ú¿ô¤âºÆɾ²Á¤µ¤ì¤ë¡¥
-
-@example
-for i in 1..5
- retry if some_condition # i == 1 ¤«¤é¤ä¤êľ¤·
-end
-@end example
-
-@example
-# ¥æ¡¼¥¶ÄêµÁ¤Îuntil loop
-def until(cond)
- yield
- retry if not cond
-end
-@end example
-
-@code{rescue}Àá¤ä¥¤¥Æ¥ì¡¼¥¿°Ê³°¤Çretry¤¬ÍѤ¤¤é¤ì¤¿¾ì¹çÎã³°¤¬È¯À¸¤¹¤ë¡¥
-
-@node RETURN, BREAK, RETRY, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection RETURN
-
-Îã
-
-@example
-return
-return 12
-return 1,2,3
-@end example
-
-¹½Ê¸
-
-@display
-return [¼°[`,' ¼°@dots{}]]
-@end display
-
-¼°¤ÎÃͤòÌá¤êÃͤȤ·¤Æ¥á¥½¥Ã¥É¤Î¼Â¹Ô¤ò½ªÎ»¤¹¤ë¡¥¼°¤¬2¤Ä°Ê¾åÍ¿¤¨¤é¤ì¤¿»þ
-¤Ë¤Ï¡¤¤½¤ì¤é¤òÍ×ÁǤȤ¹¤ëÇÛÎó¤ò¥á¥½¥Ã¥É¤ÎÌá¤êÃͤȤ¹¤ë¡¥¼°¤¬°ì¤Ä¤â¤Ê¤¤¾ì
-¹ç¤Ë¤Ï @code{nil} ¤¬Ìá¤êÃͤȤʤ롥
-
-@node BREAK, CONTINUE, RETURN, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection BREAK
-
-Îã
-
-@example
-break
-@end example
-
-¹½Ê¸
-
-@display
-break
-@end display
-
-@code{break} ¤Ï¥ë¡¼¥×¤òæ½Ð¤¹¤ë¡¥C¤È°ã¤¤¡¤@code{break}¤Ï¤â¤Ã¤È¤âÆ⦤Î
-¥ë¡¼¥×¤òæ½Ð¤¹¤ëºîÍѤÀ¤±¤ò»ý¤Á¡¤@code{case} ¤òÈ´¤±¤ëºîÍѤϻý¤¿¤Ê¤¤¡¥
-
-@node CONTINUE, REDO, BREAK, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection CONTINUE
-
-Îã
-
-@example
-continue
-@end example
-
-¹½Ê¸
-
-@display
-continue
-@end display
-
-@code{continue}¤Ï¤â¤Ã¤È¤âÆ⦤Υ롼¥×¤Î¼¡¤Î·«¤êÊÖ¤·¤ò»Ï¤á¤ë¡¥
-
-@node REDO, À©¸æ¹½Â¤, CONTINUE, À©¸æ¹½Â¤
-@comment node-name, next, previous, up
-@subsubsection REDO
-
-Îã
-
-@example
-redo
-@end example
-
-¹½Ê¸
-
-@display
-redo
-@end display
-
-@findex redo
-@code{redo}¤Ï¥ë¡¼¥×¾ò·ï¤Î¥Á¥§¥Ã¥¯¤ò¹Ô¤Ê¤ï¤º¡¤¸½ºß¤Î·«¤êÊÖ¤·¤ò¤ä¤êľ¤¹¡¥
-
-@node ¥¯¥é¥¹ÄêµÁ, ¥â¥¸¥å¡¼¥ëÄêµÁ, À©¸æ¹½Â¤, ¼°
-@comment node-name, next, previous, up
-@subsection ¥¯¥é¥¹ÄêµÁ
-@cindex ¥¯¥é¥¹¤òÄêµÁ¤¹¤ë
-
-Îã
-
-@example
-class Foo:Super
- def test
- :
- end
- :
-end
-@end example
-
-¹½Ê¸
-
-@display
-class ¥¯¥é¥¹Ì¾ [`:' ¥¹¡¼¥Ñ¡¼¥¯¥é¥¹Ì¾ ]
- ÄêµÁ¼ÂÂÎ
-end
-@end display
-
-@findex class
-¥¯¥é¥¹Ì¾¤ÏÂçʸ»ú¤Ç»Ï¤Þ¤ë¼±Ê̻ҤǤ¢¤ë¡¥
-
-@node ¥â¥¸¥å¡¼¥ëÄêµÁ, ¥á¥½¥Ã¥ÉÄêµÁ, ¥¯¥é¥¹ÄêµÁ, ¼°
-@comment node-name, next, previous, up
-@subsection ¥â¥¸¥å¡¼¥ëÄêµÁ
-@cindex ¥â¥¸¥å¡¼¥ë¤òÄêµÁ¤¹¤ë
-
-Îã
-
-@example
-module Foo
- def test
- :
- end
- :
-end
-@end example
-
-¹½Ê¸
-
-@display
-module ¥¯¥é¥¹Ì¾
- ÄêµÁ¼ÂÂÎ
-end
-@end display
-
-@findex module
-¥â¥¸¥å¡¼¥ë̾¤ÏÂçʸ»ú¤Ç»Ï¤Þ¤ë¼±Ê̻ҤǤ¢¤ë¡¥
-
-@node ¥á¥½¥Ã¥ÉÄêµÁ, Æðۥ᥽¥Ã¥ÉÄêµÁ, ¥â¥¸¥å¡¼¥ëÄêµÁ, ¼°
-@comment node-name, next, previous, up
-@subsection ¥á¥½¥Ã¥ÉÄêµÁ
-@cindex ¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë
-
-Îã
-
-@example
-def fact(n)
- if n == 1 then
- 1
- else
- n * fact(n-1)
- end
-end
-@end example
-
-¹½Ê¸
-
-@display
-def ¥á¥½¥Ã¥É̾ [`(' [°ú¿ô [= ¥Ç¥Õ¥©¥ë¥È]]@dots{}[`,' `*' °ú¿ô ]`)']
- ÄêµÁ¼ÂÂÎ
-end
-@end display
-@findex def
-
-°ú¿ô¤Ë¥Ç¥Õ¥©¥ë¥È¼°¤¬Í¿¤¨¤é¤ì¤¿¾ì¹ç¡¤¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·»þ¤Ë°ú¿ô¤¬Í¿¤¨¤é¤ì
-¤Ê¤«¤Ã¤¿¾ì¹ç¤Ë¤Ï¥Ç¥Õ¥©¥ë¥È¼°¤òɾ²Á¤·¤¿·ë²Ì¤Ç½é´ü²½¤µ¤ì¤ë(¥Ç¥Õ¥©¥ë¥È¼°
-¤Îɾ²Á¤Ï¸Æ¤Ó½Ð¤·»þ¤Ë¹Ô¤ï¤ì¤ë)¡¥°ìÈֺǸå¤Î°ú¿ô¤¬@code{*}¤Ë³¤¯(ñ°ì¤Î)
-¼°¤Ç¤¢¤ë¾ì¹ç¡¤¤½¤Î¼°¤òɾ²Á¤·¤¿·ë²Ì(ÇÛÎó¤Ç¤Ê¤±¤ì¤ÐÊÑ´¹¤µ¤ì¤ë)¤òŸ³«¤·¤Æ¡¤
-°ú¿ô¤È¤·¤ÆÄɲ乤롥
-
-Ä̾ï¥á¥½¥Ã¥ÉÄêµÁ¤Ï¥Í¥¹¥È¤Ç¤­¤Ê¤¤¤Î¤Ç¡¤¥á¥½¥Ã¥ÉÄêµÁ¼°Ãæ¤Ç¤Ï¥á¥½¥Ã¥ÉÄêµÁ
-¼°¤òºÆ¤Ó¸Æ¤Ó½Ð¤»¤Ê¤¤¡¥
-
-¥á¥½¥Ã¥É̾¤Ï¼±Ê̻Ҥޤ¿¤Ïʸ»úÎó¤Ç¤¢¤ë¡¥±é»»»Ò¤ÎºÆÄêµÁ¤ò¤¹¤ë»þ¤Ë¤Ïʸ»úÎó
-¤Ç»ØÄꤹ¤ë¡¥²¾°ú¿ôʤӤκǸå¤Ë@code{*}¤¬¤¢¤ë¾ì¹ç¡¤²¾°ú¿ô¤è¤ê¿¤¯Í¿¤¨¤é
-¤ì¤¿¼Â°ú¿ô¤Ï¡¤ºÇ¸å¤Î°ú¿ô¤ËÇÛÎó¤È¤·¤ÆÍ¿¤¨¤é¤ì¤ë(­¤ê¤Ê¤¤»þ¤Ë¤Ï¥¨¥é¡¼)¡¥
-
-¥á¥½¥Ã¥É¤Ë¤Ï¸Æ¤Ó½Ð¤·À©¸Â¤ò²Ã¤¨¤ë¤³¤È¤¬¤Ç¤­¡¤À©¸Â¤ò²Ã¤¨¤é¤ì¤¿¥á¥½¥Ã¥É¤Ï¡¤
-´Ø¿ô·Á¼°¤Ç¤·¤«¸Æ¤Ó½Ð¤»¤Ê¤¤(private¥á¥½¥Ã¥É)¡¥
-
-¿·µ¬¤Ë¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¾ì¹ç¡¤¥¯¥é¥¹ÄêµÁ¼°¤Î³°¤Ë¤¢¤ëdef¼°¤Ï¥Ç¥Õ¥©¥ë¥È
-¤Ç¤Ïprivate¥á¥½¥Ã¥É¤òÄêµÁ¤·¡¤¥¯¥é¥¹ÄêµÁ¼°¤ÎÃæ¤Ë¤¢¤ëdef¼°¤Ïpublic¥á¥½¥Ã
-¥É¤òÄêµÁ¤¹¤ë¡¥¥¹¡¼¥Ñ¡¼¥¯¥é¥¹¤Î¥á¥½¥Ã¥É¤òºÆÄêµÁ¤¹¤ë¾ì¹ç¤Ë¤ÏÄêµÁ¤µ¤ì¤ë¥á
-¥½¥Ã¥É¤Î²Ä»ëÀ­¤Ï¥¹¡¼¥Ñ¡¼¥¯¥é¥¹¤Î¥á¥½¥Ã¥É¤Î¤â¤Î¤ò¼õ¤±·Ñ¤°¡¥
-
-¥á¥½¥Ã¥É¤Î²Ä»ëÀ­¤òÊѹ¹¤¹¤ë¾ì¹ç¤Ë¤Ï@code{Module}¥¯¥é¥¹¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë
-@code{public}, @code{private}¤Î³Æ¥á¥½¥Ã¥É¤òÍѤ¤¤ë¡¥
-
-@node Æðۥ᥽¥Ã¥ÉÄêµÁ, ALIAS, ¥á¥½¥Ã¥ÉÄêµÁ, ¼°
-@comment node-name, next, previous, up
-@subsection Æðۥ᥽¥Ã¥ÉÄêµÁ
-
-Îã
-
-@example
-def foo.test()
- print "this is foo\n"
-end
-@end example
-
-¹½Ê¸
-
-@display
-def ¼° `.' ¥á¥½¥Ã¥É̾ [`(' [°ú¿ô [= ¥Ç¥Õ¥©¥ë¥È]]@dots{}[`,' `*' °ú¿ô ]`)']
- ÄêµÁ¼ÂÂÎ
-end
-@end display
-
-Æðۥ᥽¥Ã¥É¤È¤Ï¤¢¤ëÆÃÄê¤Î¥ª¥Ö¥¸¥§¥¯¥È¤Ë¸ÇÍ­¤Î¥á¥½¥Ã¥É¤Ç¤¢¤ë¡¥
-
-¤³¤Î·Á¼°¤Ï¼°¤ÎÃͤǤ¢¤ë¥ª¥Ö¥¸¥§¥¯¥È¤ËÆðۥ᥽¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥¼°¤ÎÃͤÏ
-(¥Ó¥ë¥È¥¤¥ó¥¯¥é¥¹¤Ç¤Ê¤¤)Ä̾索¥Ö¥¸¥§¥¯¥È¤«¡¤¥¯¥é¥¹¤Þ¤¿¤Ï¥â¥¸¥å¡¼¥ë¤Ç¤¢
-¤ëɬÍפ¬¤¢¤ë¡¥Ä̾ï¥á¥½¥Ã¥ÉÄêµÁ¤È¤Ï°Û¤Ê¤ê¡¤Æðۥ᥽¥Ã¥É¤Ï¥á¥½¥Ã¥ÉËÜÂÎÆâ
-¤Ç¤â¥Í¥¹¥È¤·¤ÆÄêµÁ¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥
-
-Æðۥ᥽¥Ã¥É¤ÏÄ̾ï¤Ï·Ñ¾µ¤·¤Ê¤¤¤¬¡¤Îã³°¤È¤·¤Æ¥¯¥é¥¹¤ÎÆðۥ᥽¥Ã¥É¤Ï¤½¤Î
-¥µ¥Ö¥¯¥é¥¹¤Ë¤â·Ñ¾µ¤µ¤ì¤ë¡¥¸À¤¤Âؤ¨¤ì¤Ð¥¯¥é¥¹¤ÎÆðۥ᥽¥Ã¥É¤Ï¾¤Î¥ª¥Ö¥¸¥§
-¥¯¥È»Ø¸þ¥·¥¹¥Æ¥à¤Ë¤ª¤±¤ë¥¯¥é¥¹¥á¥½¥Ã¥É¤ÎƯ¤­¤ò¤¹¤ë¡¥
-
-Ãí°Õ: ¥¤¥ó¥¯¥ë¡¼¥É¤·¤¿¥â¥¸¥å¡¼¥ë¤ÎÆðۥ᥽¥Ã¥É¤Ï·Ñ¾µ¤·¤Ê¤¤¡¥
-
-@node ALIAS, UNDEF, Æðۥ᥽¥Ã¥É, ¼°
-@comment node-name, next, previous, up
-@subsection ALIAS
-@cindex ¥á¥½¥Ã¥É¤ËÊÌ̾¤ò¤Ä¤±¤ë
-
-Îã
-
-@example
-alias foo bar
-@end example
-
-¹½Ê¸
-
-@display
-alias ¥á¥½¥Ã¥É̾1 ¥á¥½¥Ã¥É̾2
-@end display
-
-@findex alias
-@code{alias}ʸ¤Ç¥á¥½¥Ã¥É¤ËÊÌ̾¤ò¤Ä¤±¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥ÊÌ̾¤òÉÕ¤±¤é¤ì¤¿¥á
-¥½¥Ã¥É¤Ï¡¤¤½¤Î»þÅÀ¤Ç¤Î¥á¥½¥Ã¥ÉÄêµÁ¤ò°ú¤­·Ñ¤®¡¤¸µ¤Î¥á¥½¥Ã¥É¤¬ºÆÄêµÁ¤µ¤ì
-¤Æ¤â¡¤ºÆÄêµÁÁ°¤Î¸Å¤¤¥á¥½¥Ã¥É¤¬¸Æ¤Ó½Ð¤µ¤ì¤¿¤Î¤ÈÁ´¤¯Æ±¤¸Æ¯¤­¤ò¤¹¤ë¡¥
-
-@node UNDEF, DEFINED?, ALIAS, ¼°
-@comment node-name, next, previous, up
-@subsection UNDEF
-@cindex ¥á¥½¥Ã¥É¤ÎÄêµÁ¤ò¼è¤ê¾Ã¤¹
-
-Îã
-
-@example
-undef bar
-@end example
-
-¹½Ê¸
-
-@display
-undef ¥á¥½¥Ã¥É̾
-@end display
-
-@findex undef
-¥á¥½¥Ã¥É¤ÎÄêµÁ¤ò¼è¤ê¾Ã¤¹¤¿¤á¤Ë¤Ïundef¤òÍѤ¤¤ë¡¥
-
-def¤Ë¤è¤ëÊÌ̾ÄêµÁ¤È@code{undef}¤Ë¤è¤ëÄêµÁ¼è¤ê¾Ã¤·¤Ë¤è¤Ã¤Æ¥¯¥é¥¹¤Î¥¤¥ó
-¥¿¥Õ¥§¡¼¥¹¤ò¥¹¡¼¥Ñ¡¼¥¯¥é¥¹¤ÈÆÈΩ¤ËÊѹ¹¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥¤¿¤À¤·¡¤¥á¥½¥Ã
-¥É¤¬self¤Ë¥á¥Ã¥»¡¼¥¸¤òÁ÷¤Ã¤Æ¤¤¤ë¾ì¹ç¤â¤¢¤ë¤Î¤Ç¡¤¤è¤¯Ãí°Õ¤·¤Ê¤¤¤È´û¸¤Î
-¥á¥½¥Ã¥É¤¬Æ°ºî¤·¤Ê¤¯¤Ê¤ë²ÄǽÀ­¤¬¤¢¤ë¡¥
-
-@node DEFINED?, , UNDEF, ¼°
-@comment node-name, next, previous, up
-@subsection DEFINED?
-@cindex ¥á¥½¥Ã¥É¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«
-@cindex ÊÑ¿ô¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«
-@cindex Äê¿ô¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤«¤É¤¦¤«
-
-Îã
-
-@example
-defined? print
-defined? File.print
-defined?(foobar)
-defined?($foobar)
-defined?(@@foobar)
-defined?(Foobar)
-@end example
-
-¹½Ê¸
-
-@display
-defined? ¼°
-@end display
-
-@findex defined?
-¼°¤¬¥á¥½¥Ã¥É¸Æ¤Ó½Ð¤·¤Î¾ì¹ç¡¤¤½¤Î¥á¥½¥Ã¥É¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë»þ¤Ë¿¿¤òÊÖ¤¹¡¥
-¼°¤¬ÊÑ¿ô¤äÄê¿ô¤Î»²¾È¤Ç¤¢¤ë¾ì¹ç¤Ï¡¤¤½¤ì¤é¤ÎÊÑ¿ô¤äÄê¿ô¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë»þ
-¤Ë¿¿¤òÊÖ¤¹¡¥¤½¤ì°Ê³°¤Î¼°¤Î¾ì¹ç¤Ï¼°¤òɾ²Á¤·¤Æ¡¤Îã³°¤¬È¯À¸¤·¤Ê¤±¤ì¤Ð¿¿¤ò
-ÊÖ¤¹¡¥
-
-@node ÁȤ߹þ¤ß´Ø¿ô, ÁȤ߹þ¤ßÊÑ¿ô¤ÈÄê¿ô, ruby¤Îʸˡ, Top
-@comment node-name, next, previous, up
-@chapter ÁȤ߹þ¤ß´Ø¿ô
-
-Ruby¤Ë¤Ï¸·Ì©¤Ê°ÕÌ£¤Ç¤Ï´Ø¿ô¤Ï¤Ê¤¤¤¬@code{Kernel}¥¯¥é¥¹¤Î´Ø¿ô¥á¥½¥Ã¥É¤Ï
-(Á´¤Æ¤ÎÄ̾說¥é¥¹¤«¤é´Ø¿ô·Á¼°¤Ç¸Æ¤Ó½Ð¤»¤ë¤Î¤Ç)¡¤´Ø¿ôŪ¤ËÍѤ¤¤é¤ì¤ë¡¥´Ø
-¿ôŪ¤ËÍѤ¤¤é¤ì¤ë¥á¥½¥Ã¥É¤ò°Ê²¼¤Ë¤¢¤²¤ë¡¥¤³¤ì¤é¤Î¥á¥½¥Ã¥É¤òºÆÄêµÁ¤¹¤ëºÝ
-¤Ë¤Ï¸ß´¹À­¤ò¹Í¤¨¤Æ¹Ô¤Ê¤¦¤Ù¤­¤Ç¤¢¤ë¡¥
-
-@ftable @code
-@item autoload(@var{module}, @var{file})
-
-@var{module}¤ËºÇ½é¤Ë¥¢¥¯¥»¥¹¤·¤¿»þ¤Ë@var{file}¤ò@code{require}¤¹¤ë¤è¤¦
-¤ËÀßÄꤹ¤ë¡¥@var{module}¤Ïʸ»úÎó¤Þ¤¿¤Ï¥·¥ó¥Ü¥ë¤Ç»ØÄꤹ¤ë¡¥
-
-@item caller([@var{level}])
-
-@var{level}Ãʾå¤Î¸Æ½Ð¤·¸µ¤Î¾ðÊó¤ò@code{$@@}¤Î·Á¼°¤ÇÆÀ¤ë¡¥¥È¥Ã¥×¥ì¥Ù¥ë
-¤Ç¤Ï@code{nil}¤òÊÖ¤¹¡¥caller¤ÎÌá¤êÃͤò@code{$@@}¤ËÂåÆþ¤¹¤ë¤³¤È¤ÇÎã³°¤Î
-ȯÀ¸°ÌÃÖ¤òÀßÄê¤Ç¤­¤ë¡¥¤Þ¤¿¡¤°Ê²¼¤Î¤è¤¦¤Ê¥³¡¼¥É¤Ç¸Æ½Ð¤·´Ø·¸¤Î¥Ð¥Ã¥¯¥È¥ì¡¼
-¥¹¤òɽ¼¨¤Ç¤­¤ë¡¥
-
-@example
-n = 0
-while c = caller(n)
- print c, "\n"
-end
-@end example
-
-@item eof
-@itemx eof?
-
-¥³¥Þ¥ó¥É¥é¥¤¥ó¤«¤é¤ÎÆþÎϤ¬@code{EOF}¤ËÅþ㤷¤Æ¤¤¤ë¾ì¹ç¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item eval(@var{expr})
-
-@var{expr}¤È¤·¤ÆÍ¿¤¨¤é¤ì¤¿Ê¸»úÎó¤òruby¥×¥í¥°¥é¥à¤È¤·¤Æ²ò¼á¡¤¼Â¹Ô¤¹¤ë¡¥
-
-@item exec(@var{command})
-
-¥×¥í¥°¥é¥à¤Î¼Â¹Ô¤ò½ªÎ»¤¹¤ë¡¥@var{status}¤È¤·¤ÆÀ°¿ô¤¬Í¿¤¨¤é¤ì¤¿¾ì¹ç¡¤¤½
-¤ÎÃͤòruby¥³¥Þ¥ó¥É¤Î½ªÎ»¥¹¥Æ¡¼¥¿¥¹¤È¤¹¤ë¡¥¥Ç¥Õ¥©¥ë¥È¤Ï0¡¥
-
-@item exit!(@var{status})
-
-¥×¥í¥°¥é¥à¤Î¼Â¹Ô¤ò½ªÎ»¤¹¤ë¡¥À°¿ô@var{status}¤ò½ªÎ»¥¹¥Æ¡¼¥¿¥¹¤È¤¹¤ë¡¥
-@code{exit}¤È¤Ï°ã¤Ã¤Æ¡¤Îã³°½èÍý¤Ê¤É¤Ï°ìÀڹԤʤï¤Ê¤¤¡¥@code{fork}¤Î¸å¡¤
-»Ò¥×¥í¥»¥¹¤ò½ªÎ»¤µ¤»¤ë»þ¤Ê¤É¤ËÍѤ¤¤ë¡¥
-
-@item fork
-
-@samp{fork}¥·¥¹¥Æ¥à¥³¡¼¥ë¤ò¼Â¹Ô¤·¡¤»Ò¥×¥í¥»¥¹¤òÀ¸À®¤¹¤ë¡¥¾ÜºÙ¤Ï
-@samp{fork(2)}¤ò»²¾È¤Î¤³¤È¡¥¿Æ¥×¥í¥»¥¹Â¦¤Ç¤Ï»Ò¥×¥í¥»¥¹¤Î¥×¥í¥»¥¹id¤òÊÖ
-¤·¡¤»Ò¥×¥í¥»¥¹Â¦¤Ç¤Ï@code{nil}¤òÊÖ¤¹¡¥²¿¤é¤«¤Î¸¶°ø¤Ç»Ò¥×¥í¥»¥¹¤ÎÀ¸À®¤Ë
-¼ºÇÔ¤·¤¿»þ¤Ë¤ÏÎã³°¤¬È¯À¸¤¹¤ë¡¥¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ð¤ì¤¿»þ¤Ï¡¤À¸À®¤·¤¿»Ò
-¥×¥í¥»¥¹¤ÇÍ¿¤¨¤é¤ì¤¿¥Ö¥í¥Ã¥¯¤òɾ²Á¤·¡¤¥Ö¥í¥Ã¥¯¤Îɾ²Á¤¬½ªÎ»¤·¤¿»þÅÀ¤Ç»Ò
-¥×¥í¥»¥¹¤ÏÀµ¾ï½ªÎ»¤¹¤ë¡¥
-
-@item format(@var{format}@dots{})
-
-¥Õ¥©¡¼¥Þ¥Ã¥È¤È¤·¤ÆÍ¿¤¨¤é¤ì¤¿Ê¸»úÎó¤òC¸À¸ì¤Î@samp{sprintf}¤ÈƱ¤¸¤è¤¦¤Ë
-²ò¼á¤·¡¤°ú¿ô¤òŸ³«¤·¤¿Ê¸»úÎó¤òÊÖ¤¹¡¥¥á¥½¥Ã¥É@code{sprintf}¤ÎÊÌ̾¡¥
-
-Ruby¤Ë¤ª¤±¤ë@samp{format}»ØÄê»Ò¤Î³ÈÄ¥¤Ë¤Ä¤¤¤Æ¤Ï@code{sprintf}¤Î¹à¤ò»²
-¾È¤Î¤³¤È¡¥
-
-@item getc
-
-ɸ½àÆþÎϤ«¤é°ìʸ»ú¼è¤ê½Ð¤¹¡¥Ìá¤êÃͤÏÆɤ߹þ¤ó¤Àʸ»ú¤Îʸ»ú¥³¡¼¥É(ASCII)
-¤òɽ¤¹@code{Fixnum}¤Ç¤¢¤ë¡¥
-
-@item gets
-
-°ú¿ô¤È¤·¤ÆÍ¿¤¨¤é¤ì¤¿¥Õ¥¡¥¤¥ë(¤Ê¤±¤ì¤Ðɸ½àÆþÎÏ)¤Ç¹½À®¤µ¤ì¤ë²¾ÁÛ
-Ū¤Ê¥Õ¥¡¥¤¥ë(¥·¥¹¥Æ¥àÊÑ¿ô@code{$<}¤Ç¥¢¥¯¥»¥¹¤Ç¤­¤ë)¤«¤é°ì¹ÔÆɤ߹þ¤ó
-¤Ç¡¤Æɤ߹þ¤ß¤ËÀ®¸ù¤·¤¿»þ¤Ë¤Ï¤½¤Îʸ»úÎó¤òÊÖ¤¹¡¥¥Õ¥¡¥¤¥ë¤Î½ª¤ê¤Ë
-Åþ㤷¤¿»þ¤Ë¤Ï@code{nil}¤òÊÖ¤¹¡¥¹Ô¤Î¶èÀÚ¤ê¤Ï¥·¥¹¥Æ¥àÊÑ¿ô@code{$/}¤Ë¤è¤Ã¤Æ
-Êѹ¹¤Ç¤­¤ë¡¥Æɤ߹þ¤ó¤Àʸ»úÎó¤Ï¥·¥¹¥Æ¥àÊÑ¿ô@code{$_}¤Ë¤â¥»¥Ã¥È¤µ¤ì¤ë¡¥
-
-@item gsub(@var{pattern}[, @var{replace}])
-@itemx gsub!(@var{pattern}[, @var{replace}])
-
-¥·¥¹¥Æ¥àÊÑ¿ô@code{$_}¤Î»Ø¤¹Ê¸»úÎóÆâ¤Ç @var{pattern}¤Ë¥Þ¥Ã¥Á¤¹¤ëÉôʬ¤ò
-Á´¤Æ@var{replace}¤ËÃÖ¤­´¹¤¨¤ë¡¥@code{String}¥¯¥é¥¹¤Î@code{gsub}¥á¥½¥Ã
-¥É¤Î²òÀâ¤ò»²¾È¤Î¤³¤È¡¥°ú¿ô@var{replace}¤¬¾Êά¤µ¤ì¤¿»þ¤Ë¤Ï¥¤¥Æ¥ì¡¼¥¿¤È
-¤·¤ÆÆ°ºî¤·¡¤¥Ö¥í¥Ã¥¯¤òɾ²Á¤·¤¿·ë²Ì¤ÇÃÖ´¹¤¹¤ë¡¥@code{gsub}¥á¥½¥Ã¥É¤Ï
-@code{$_}¤ÎÃͤò¥³¥Ô¡¼¤·¤Æ¡¤¥³¥Ô¡¼¤ÎÊý¤ò¹¹¿·¤·¡¤@code{$_}¤ËÂåÆþ¤¹¤ë¡¥
-
-@code{gsub!}¤Ï@code{$_}¤Î»Ø¤·¤Æ¤¤¤ëʸ»úÎ󤽤Τâ¤Î¤ò½ñ¤­´¹¤¨¤ë¡¥
-
-@item iterator?
-
-¥á¥½¥Ã¥É¤¬¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ó½Ð¤µ¤ì¤¿»þ¤Ë¤Ï¿¿¡¤¤½¤¦¤Ç¤Ê¤¤»þ¤Ëµ¶¤òÊÖ¤¹
-½Ò¸ì¡¥
-
-@item kill(@var{signal}, @var{pid}@dots{})
-
-@var{pid}¤Ç»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤Ë¥·¥°¥Ê¥ë¤òÁ÷¤ë¡¥@var{signal}¤Ï¥·¥°¥Ê¥ë
-Èֹ椫̾Á°¤Ç»ØÄꤹ¤ë¡¥Éé¤ÎÃͤò»ý¤Ä¥·¥°¥Ê¥ë(¤¢¤ë¤¤¤Ï¥·¥°¥Ê¥ë̾¤ÎÁ°¤Ë
-@code{-})¤òÍ¿¤¨¤ë¤È¥×¥í¥»¥¹¤Ç¤Ï¤Ê¤¯¥×¥í¥»¥¹¥°¥ë¡¼¥×¤Ë¥·¥°¥Ê¥ë¤òÁ÷¤ë¡¥
-
-@item load(@var{file})
-
-@var{file}¤ò¥í¡¼¥É¤¹¤ë¡¥@var{file}¤ò¥í¡¼¥É¤¹¤ë¥Ñ¥¹¤Ï¥·¥¹¥Æ¥àÊÑ¿ô
-@code{$:}¤Ç·èÄꤵ¤ì¤ë¡¥
-
-@item loop
-
-̵¸Â¥ë¡¼¥×¤¹¤ë¥¤¥Æ¥ì¡¼¥¿¡¥(ÃæÃǤµ¤ì¤Ê¤¤¸Â¤ê)±Êµ×¤Ë¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤ò
-ɾ²Á¤·Â³¤±¤ë¡¥
-
-@item open(@var{file}[, @var{mode}])
-
-@var{file}¤ò¥ª¡¼¥×¥ó¤·¤Æ¡¤@code{File}¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡¥¥Õ¥¡¥¤¥ë̾¤Ï
-¥ª¡¼¥×¥ó¤¹¤ë¥Õ¥¡¥¤¥ë¤ò¼¨¤¹¡¥¥Õ¥¡¥¤¥ë̾¤¬@code{|}¤Ç»Ï¤Þ¤ë»þ¤Ë¤Ï³¤¯Ê¸»ú
-Îó¤ò¥³¥Þ¥ó¥É¤È¤·¤Æµ¯Æ°¤·¡¤¥Ñ¥¤¥×¥é¥¤¥ó¤òÀ¸À®¤¹¤ë¡¥
-
-¥³¥Þ¥ó¥É̾¤¬@samp{"-"}¤Ç¤¢¤ë»þ¡¤@code{open}¤Ïruby¤Î»Ò¥×¥í¥»¥¹¤òÀ¸À®¤·¡¤
-¤½¤Î»Ò¥×¥í¥»¥¹¤È¤Î¥Ñ¥¤¥×¤òÊÖ¤¹¡¥
-
-@var{mode}¤Ï¥Õ¥¡¥¤¥ë¤Î¥¢¥¯¥»¥¹¥â¡¼¥É¤ò»ØÄꤹ¤ë¡¥¤³¤ì¤Ï°Ê²¼¤Î¤¦¤Á¤Î¤¤¤º
-¤ì¤«¤Îʸ»úÎó¤Ç¤¢¤ë¡¥
-
-@table @samp
-@item r
-Æɤ߹þ¤ßÀìÍÑ¡¥@code{open}¤¹¤ë¥Õ¥¡¥¤¥ë¤Ï¤¢¤é¤«¤¸¤á¸ºß¤·¤Æ¤¤¤ëɬÍפ¬¤¢
-¤ë¡¥
-
-@item r+
-Æɤ߽ñ¤­Î¾ÍÑ¡¥@code{open}¤¹¤ë¥Õ¥¡¥¤¥ë¤Ï¤¢¤é¤«¤¸¤á¸ºß¤·¤Æ¤¤¤ëɬÍפ¬¤¢
-¤ë¡¥
-
-@item w
-½ñ¤­¹þ¤ßÀìÍÑ¡¥¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Æ¤¤¤¿¾ì¹ç¡¤Ä¹¤µ¤ò0¤Ë¤¹¤ë¡¥Â¸ºß¤·¤Æ¤¤¤Ê
-¤±¤ì¤Ð¿·¤¿¤Ë¥Õ¥¡¥¤¥ë¤òºîÀ®¤¹¤ë¡¥
-
-@item w+
-Æɤ߽ñ¤­Î¾ÍÑ¡¥Æɤ߹þ¤ß¤¬¹Ô¤Ê¤¨¤ë¤³¤È°Ê³°¤Ï@samp{"w"}¤ÈƱ¤¸Æ¯¤­¤ò¤¹¤ë¡¥
-
-@item a
-Äɲýñ¤­¹þ¤ßÀìÍÑ¡¥¥Õ¥¡¥¤¥ë¤Ï¤¢¤é¤«¤¸¤á¸ºß¤·¤Æ¤¤¤ëɬÍפ¬¤¢¤ë¡¥½ñ¤­¹þ¤ß
-¤Ï¥Õ¥¡¥¤¥ë¤ÎºÇ¸å¤ËÄɲ䵤ì¤ë¡¥
-
-@item a+
-Æɤ߽ñ¤­Î¾ÍÑ¡¥¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¤Æ¤¤¤Ê¤±¤ì¤Ð¿·¤¿¤ËºîÀ®¤¹¤ë¡¥¥¢¥¯¥»¥¹°ÌÃÖ
-¤Ï¥Õ¥¡¥¤¥ë¤ÎºÇ¸å¤Ë½é´ü²½¤µ¤ì¤ë¡¥
-@end table
-
-¥â¡¼¥É¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¤Î¥Ç¥Õ¥©¥ë¥È¤Ï@samp{"r"}¤Ç¤¢¤ë¡¥
-
-@item print(@var{arg}1@dots{})
-
-°ú¿ô¤ò½ç¤Ë½ÐÎϤ¹¤ë¡¥°ú¿ô¤¬Í¿¤¨¤é¤ì¤Ê¤¤»þ¤Ë¤Ï@code{$_}¤ÎÃͤò½ÐÎϤ¹¤ë¡¥
-ʸ»úÎó°Ê³°¤Î¥ª¥Ö¥¸¥§¥¯¥È¤¬°ú¿ô¤È¤·¤ÆÍ¿¤¨¤é¤ì¤¿¾ì¹ç¤Ë¤Ï¡¤Åö³º¥ª¥Ö¥¸¥§¥¯
-¥È¤Î@code{to_s}¥á¥½¥Ã¥É¤Ë¤è¤Ã¤Æʸ»úÎó¤ËÊÑ´¹¤·¤Æ¤«¤é½ÐÎϤµ¤ì¤ë¡¥¥·¥¹¥Æ
-¥àÊÑ¿ô@code{$;}(½ÐÎÏ¥Õ¥£¡¼¥ë¥É¥»¥Ñ¥ì¡¼¥¿)¤Ë@code{nil}¤Ç¤Ê¤¤Ãͤ¬¥»¥Ã¥È
-¤µ¤ì¤Æ¤¤¤ë»þ¤Ë¤Ï¡¤³Æ°ú¿ô¤Î´Ö¤Ë¤½¤Îʸ»úÎó¤ò½ÐÎϤ¹¤ë¡¥¥·¥¹¥Æ¥àÊÑ¿ô
-@code{$\}(½ÐÎÏ¥Õ¥£¡¼¥ë¥É¥»¥Ñ¥ì¡¼¥¿)¤Ë@code{nil}¤Ç¤Ê¤¤Ãͤ¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë»þ
-¤Ë¤Ï¡¤ºÇ¸å¤Ë¤½¤ì¤ò½ÐÎϤ¹¤ë¡¥
-
-@item printf([@var{port}, ]@var{format}, @var{arg}@dots{})
-
-C¸À¸ì¤Îprintf¤ÈƱ¤¸¤è¤¦¤Ë@var{format}¤Ë½¾¤¤°ú¿ô¤òʸ»úÎó¤ËÊÑ´¹¤·¡¤½ÐÎÏ
-¤¹¤ë¡¥Âè1°ú¿ô¤¬IO¤Î¥µ¥Ö¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤¢¤Ã¤¿¾ì¹ç¤Ï¤½¤Î¥ª¥Ö¥¸¥§
-¥¯¥È¤ËÂФ·¤Æ½ÐÎϤò¹Ô¤Ê¤¦¡¥¥Ç¥Õ¥©¥ë¥È¤Ï@code{$stdout}¤Ë½ÐÎϤ¹¤ë¡¥
-
-Ruby¤Ë¤ª¤±¤ëformat»ØÄê»Ò¤Î³ÈÄ¥¤Ë¤Ä¤¤¤Æ¤Ïsprintf¤Î¹à¤ò»²¾È¤Î¤³¤È¡¥
-
-@item proc
-@itemx lambda
-
-Í¿¤¨¤é¤ì¤¿¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤ò¼ê³¤­¥ª¥Ö¥¸¥§¥¯¥È(¥¯¥é¥¹@code{Proc}¤Î¥¤
-¥ó¥¹¥¿¥ó¥¹)¤È¤·¤ÆÊÖ¤¹¡¥
-
-@item rand(@var{max})
-
-0¤«¤é@var{max}¤ò±Û¤¨¤Ê¤¤ÈϰϤÎÀ°¿ô¤ÎÍð¿ô¤òȯÀ¸¤¹¤ë¡¥Ìá¤êÃͤÏ
-@code{Fixnum}¡¥
-
-@item require(@var{feature})
-
-@var{feature}¤Ç»ØÄꤵ¤ì¤ëfile¤ò¥í¡¼¥É¤¹¤ë¡¥@var{feature}¤Ï¥í¡¼¥É¤¹¤ë¥Õ¥¡
-¥¤¥ë¤ò»ØÄꤹ¤ëʸ»úÎó¤Ç¡¤³ÈÄ¥»Ò@code{.rb}¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë»þ¤Ïruby¥¹¥¯¥ê
-¥×¥È¡¤³ÈÄ¥»Ò@code{.o}¤¬»ØÄꤵ¤ì¤Æ¤¤¤ë»þ¤Ï¡¤¥Ð¥¤¥Ê¥ê¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É
-¤¹¤ë¡¥¤¿¤À¤·¡¤¤¤¤¯¤Ä¤«¤Î¥¢¡¼¥­¥Æ¥¯¥Á¥ã¤Ç¤Ï¥Ð¥¤¥Ê¥ê¥â¥¸¥å¡¼¥ë¤Î¥í¡¼¥É¤Ï
-Ä󶡤µ¤ì¤Ê¤¤¡¥¥Ð¥¤¥Ê¥ê¥â¥¸¥å¡¼¥ë¤Î¼ÂºÝ¤Î¥Õ¥¡¥¤¥ë¤Î³ÈÄ¥»Ò¤Ï¥¢¡¼¥­¥Æ¥¯¥Á¥ã
-Ëè¤Ë°Û¤Ê¤ë¤¬¡¤@var{feature}̾¤Î³ÈÄ¥»Ò¤Ï¤¤¤Ä¤â@code{.o}¤òÍѤ¤¤ë¡¥
-
-³ÈÄ¥»Ò¤¬»ØÄꤵ¤ì¤Ê¤¤¾ì¹ç¤Ï¡¤¤Þ¤º@code{.rb}¡¤¼¡¤Ë@code{.o}¤òÊä¤Ã¤Æ¡¤¥Õ¥¡
-¥¤¥ë¤ò¸¡º÷¤¹¤ë¡¥
-
-require¤Ï¼ÂºÝ¤Ë¥í¡¼¥É¤·¤¿»þ¤Ë¤Ï @code{TRUE}¡¤´û¤Ë¥í¡¼¥É¤µ¤ì¤Æ¤¤¤ë»þ¤Ë
-¤Ï@code{FALSE}¤òÊÖ¤¹¡¥¤Þ¤¿¥í¡¼¥É¤·¤¿@var{feature}¤Î̾Á°¤ò(³ÈÄ¥»Ò¤â´Þ¤á
-¤Æ)¡¤ÊÑ¿ô@code{$"}¤ËÄɲ乤롥
-
-@item select(@var{reads}[, @var{writes}[, @var{execpts}[, @var{timeout}]]])
-
-@samp{select(2)}¤ò¼Â¹Ô¤¹¤ë¡¥@var{reads}/@var{writes}/@var{execpts}¤Ë¤Ï
-IO(¤Þ¤¿¤Ï¤½¤Î¥µ¥Ö¥¯¥é¥¹)¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤ÎÇÛÎó¤òÍ¿¤¨¤ë¡¥@var{timeout}¤Ï
-Fixnum/Float/Time¤Î¤¤¤º¤ì¤«¤Ç»ØÄꤹ¤ë¡¥Ìá¤êÃͤÏ@var{timeout}¤¬À®Î©¤·¤¿
-¾ì¹ç¤Ë¤Ï@code{nil}¡¤¤½¤¦¤Ç¤Ê¤¤¤È¤­¤Ï3Í×ÁǤÎÇÛÎó¤òÊÖ¤·¡¤¤½¤Î³ÆÍ×ÁǤ¬Æþ
-ÎÏ/½ÐÎÏ/Îã³°ÂÔ¤Á¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ÎÇÛÎó¤Ç¤¢¤ë(»ØÄꤷ¤¿ÇÛÎó¤Î¥µ¥Ö¥»¥Ã¥È¡¥
-ÂÔ¤Á¥ª¥Ö¥¸¥§¥¯¥È¤ÎÇÛÎó¤ò»ØÄꤷ¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï@code{nil})¡¥¥·¥¹¥Æ¥à¥³¡¼
-¥ë¼Â¹ÔÃæ¤Ë³ä¹þ¤ß¤¬µ¯¤³¤Ã¤¿¾ì¹ç¤Ë¤Ï³ÆÇÛÎó¤Ï¶õ¤Ë¤Ê¤ë¡¥
-
-@item sleep([@var{sec}])
-
-@var{sec}ÉäÀ¤±¥×¥í¥°¥é¥à¤Î¼Â¹Ô¤òÄä»ß¤¹¤ë¡¥@var{sec}¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¡¤
-¥×¥í¥»¥¹¤Ë@code{SIGALRM}¤¬Á÷¤é¤ì¤Ê¤¤¸Â¤ê¡¤±Êµ×¤Ë¥¹¥ê¡¼¥×¤¹¤ë¡¥¼ÂºÝ¤Ë¥¹
-¥ê¡¼¥×¤·¤¿Éÿô¤òÊÖ¤¹¡¥
-
-@item sprintf(@var{format}@dots{})
-
-@var{format}ʸ»úÎó¤òC¸À¸ì¤Î@samp{sprintf}¤ÈƱ¤¸¤è¤¦¤Ë²ò¼á¤·¡¤°ú¿ô¤òŸ
-³«¤·¤¿Ê¸»úÎó¤òÊÖ¤¹¡¥¥á¥½¥Ã¥É@code{format}¤ÎÊÌ̾¡¥
-
-@var{format}»ØÄê»Ò¤ÏC¸À¸ì¤Î@samp{sprintf}()¤¬¼õ¤±ÉÕ¤±¤ë¤â¤Î(¤¿¤À¤·¡¤
-Ruby¤Ë¤Ï unsigned¤¬¤Ê¤¤¤Î¤Ç¡¤%u¤Ï½ü¤¯)¤Ë²Ã¤¨¤Æ, %b, %B, %O, %X¤ò»È¤¦¤³
-¤È¤¬¤Ç¤­¤ë¡¥%b¤Ï¿ôÃͤÎ2¿Êɽ¼¨¡¤%B, %O, %X¤Ï¤½¤ì¤¾¤ì2¿Ê¡¤8¿Ê¡¤16¿Ê¿ô¤Î
-ɽ¼¨¤ò¹Ô¤Ê¤¦¤¬¡¤Éé¤Î¿ô¤Î½èÍý¤ÎºÝ¤Ë2¤ÎÊä¿ôɽ¸½¤Ç¤Ï¤Ê¤¯¡¤¤½¤ÎÀäÂÐÃÍɽµ­
-¤ÎÀèƬ¤Ë@code{-}¤ò¤Ä¤±¤¿¤â¤Î¤òɽ¼¨¤¹¤ë¡¥
-
-@item srand([@var{seed}])
-
-Íð¿ô¤Î@var{seed}¤òÀßÄꤷ¡¤¸Å¤¤½é´üÃͤòÊÖ¤¹¡¥½é´üÃͤ¬¾Êά¤µ¤ì¤¿»þ¤Ë¤Ï
-@samp{time(3)}¤ÎÊÖ¤¹Ãͤò¥Ç¥Õ¥©¥ë¥È¤È¤¹¤ë¡¥
-
-@item sub(@var{pattern}[, @var{replace}])
-@itemx sub!(@var{pattern}[, @var{replace}])
-
-¥·¥¹¥Æ¥àÊÑ¿ô@code{$_}¤Î»Ø¤¹Ê¸»úÎó¤ÇºÇ½é¤Ë@var{pattern}¤Ë¥Þ¥Ã¥Á¤¹¤ëÉôʬ
-¤ò@var{replace}¤ËÃÖ¤­´¹¤¨¤ë¡¥°ú¿ô@var{replace} ¤¬¾Êά¤µ¤ì¤¿»þ¤Ë¤Ï¥¤¥Æ
-¥ì¡¼¥¿¤È¤·¤ÆÆ°ºî¤·¡¤¥Ö¥í¥Ã¥¯¤òɾ²Á¤·¤¿·ë²Ì¤ÇÃÖ´¹¤¹¤ë¡¥sub¥á¥½¥Ã¥É¤Ï
-@code{$_}¤ÎÃͤò¥³¥Ô¡¼¤·¤Æ¡¤¥³¥Ô¡¼¤ÎÊý¤ò¹¹¿·¤·¡¤@code{$_}¤ËÂåÆþ¤¹¤ë¡¥¤½
-¤Î¾¤Î¾ÜºÙ¤Ë´Ø¤·¤Æ¤Ï@code{String}¥¯¥é¥¹¤Î@code{sub}¥á¥½¥Ã¥É¤Î²òÀâ¤ò»²
-¾È¤Î¤³¤È¡¥
-
-@code{sub!}¤Ï@code{$_}¤Î»Ø¤·¤Æ¤¤¤ëʸ»úÎ󤽤Τâ¤Î¤ò½ñ¤­´¹¤¨¤ë¡¥
-
-@item syscall(@var{num}, @var{arg}@dots{})
-
-@var{num}¤Ç»ØÄꤵ¤ì¤¿ÈÖ¹æ¤Î¥·¥¹¥Æ¥à¥³¡¼¥ë¤ò¼Â¹Ô¤¹¤ë¡¥Âè2°ú¿ô°Ê¹ß¤ò¥·¥¹
-¥Æ¥à¥³¡¼¥ë¤Î°ú¿ô¤È¤·¤ÆÅϤ¹¡¥°ú¿ô¤Ïʸ»úÎó¤Þ¤¿¤ÏÀ°¿ô¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¥
-
-@item system(@var{command})
-
-@var{command}¤ò¼Â¹Ô¤·¡¤À®¸ù¤·¤¿»þ(¥µ¥Ö¥×¥í¥»¥¹¤¬status 0¤Ç½ªÎ»¤·¤¿»þ)
-¤Ë¤Ï¿¿¤ò¡¤¼ºÇÔ¤·¤¿»þ¤Ë¤Ïµ¶¤òÊÖ¤¹¡¥½ªÎ»¥¹¥Æ¡¼¥¿¥¹¤ÏÊÑ¿ô@code{$?} ¤Ç»²
-¾È¤Ç¤­¤ë¡¥
-
-@item test(@var{cmd}, @var{file} [, @var{file}])
-
-¥Õ¥¡¥¤¥ë¥Æ¥¹¥È¤ò¹Ô¤¦¡¥@var{cmd}¤Ï°Ê²¼¤Ë¼¨¤¹Ê¸»ú¥ê¥Æ¥é¥ë¤Ç¤¢¤ë¡¥¥Õ¥¡¥¤
-¥ë̾¤È¤·¤Æ@code{"&"}¤ò»ØÄꤹ¤ë¤È¡¤Ä¾Á°¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î@samp{stat(2)}¤Î·ë
-²Ì¤òºÆÍøÍѤ¹¤ë¡¥
-
-
-1¤Ä¤Î°ú¿ô¤ò¼è¤ë¤â¤Î
-
-@display
-?r ¥Õ¥¡¥¤¥ë¤ò¼Â¸ú uid ¤ÇÆɤळ¤È¤¬¤Ç¤­¤ë
-?w ¥Õ¥¡¥¤¥ë¤Ë¼Â¸ú uid ¤Ç½ñ¤¯¤³¤È¤¬¤Ç¤­¤ë
-?x ¥Õ¥¡¥¤¥ë¤ò¼Â¸ú uid ¤Ç¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë
-?o ¥Õ¥¡¥¤¥ë¤Î½êÍ­¼Ô¤¬¼Â¸ú uid ¤Ç¤¢¤ë
-
-?R ¥Õ¥¡¥¤¥ë¤ò¼Â uid ¤ÇÆɤळ¤È¤¬¤Ç¤­¤ë
-?W ¥Õ¥¡¥¤¥ë¤Ë¼Â uid ¤Ç½ñ¤¯¤³¤È¤¬¤Ç¤­¤ë
-?X ¥Õ¥¡¥¤¥ë¤ò¼Â uid ¤Ç¼Â¹Ô¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë
-?O ¥Õ¥¡¥¤¥ë¤Î½êÍ­¼Ô¤¬¼Â uid ¤Ç¤¢¤ë
-
-?e ¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë
-
-?z ¥Õ¥¡¥¤¥ë¥µ¥¤¥º¤¬ 0 ¤Ç¤¢¤ë
-?s ¥Õ¥¡¥¤¥ë¥µ¥¤¥º¤¬ 0 ¤Ç¤Ê¤¤(¥Õ¥¡¥¤¥ë¥µ¥¤¥º¤òÊÖ¤¹)
-
-?f ¥Õ¥¡¥¤¥ë¤Ï¥×¥ì¡¼¥ó¥Õ¥¡¥¤¥ë¤Ç¤¢¤ë
-?d ¥Õ¥¡¥¤¥ë¤Ï¥Ç¥£¥ì¥¯¥È¥ê¤Ç¤¢¤ë
-?l ¥Õ¥¡¥¤¥ë¤Ï¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤Ç¤¢¤ë
-?p ¥Õ¥¡¥¤¥ë¤Ï̾Á°¤Ä¤­¥Ñ¥¤¥×(FIFO)¤Ç¤¢¤ë
-?S ¥Õ¥¡¥¤¥ë¤Ï¥½¥±¥Ã¥È¤Ç¤¢¤ë
-?b ¥Õ¥¡¥¤¥ë¤Ï¥Ö¥í¥Ã¥¯Æüì¥Õ¥¡¥¤¥ë¤Ç¤¢¤ë
-?c ¥Õ¥¡¥¤¥ë¤Ï¥­¥ã¥é¥¯¥¿¡¼Æüì¥Õ¥¡¥¤¥ë¤Ç¤¢¤ë
-
-?u ¥Õ¥¡¥¤¥ë¤Ë setuid ¥Ó¥Ã¥È¤¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë
-?g ¥Õ¥¡¥¤¥ë¤Ë setgid ¥Ó¥Ã¥È¤¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë
-?k ¥Õ¥¡¥¤¥ë¤Ë sticky ¥Ó¥Ã¥È¤¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë
-
-?M ¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤ò³«»Ï¤·¤¿»þÅÀ¤Ç¤Î¥Õ¥¡¥¤¥ë¤Î¸Å¤µ
-?A ¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤ò³«»Ï¤·¤¿»þÅÀ¤Ç¤Î¥Õ¥¡¥¤¥ë¤Î¥¢¥¯¥»¥¹»þ´Ö
-?C ¥¹¥¯¥ê¥×¥È¤Î¼Â¹Ô¤ò³«»Ï¤·¤¿»þÅÀ¤Ç¤Î¥Õ¥¡¥¤¥ë¤Î inode Êѹ¹»þ´Ö
-@end display
-
-2¤Ä¤Î°ú¿ô¤ò¼è¤ë¤â¤Î
-
-@display
-?= ¥Õ¥¡¥¤¥ë1¤È¥Õ¥¡¥¤¥ë2¤Î¥¿¥¤¥à¥¹¥¿¥ó¥×¤¬Åù¤·¤¤
-?> ¥Õ¥¡¥¤¥ë1¤ÎÊý¤¬¥Õ¥¡¥¤¥ë2¤è¤ê¹¹¿·»þ´Ö¤¬¿·¤·¤¤
-?< ¥Õ¥¡¥¤¥ë1¤ÎÊý¤¬¥Õ¥¡¥¤¥ë2¤è¤ê¹¹¿·»þ´Ö¤¬¸Å¤¤
-?- ¥Õ¥¡¥¤¥ë1¤¬¥Õ¥¡¥¤¥ë2¤Ë¥Ï¡¼¥É¥ê¥ó¥¯¤µ¤ì¤Æ¤¤¤ë
-@end display
-
-@item trace_var(@var{var}, @var{command})
-
-@var{var}¤Ç»ØÄꤵ¤ì¤¿Âç°èÊÑ¿ô¤ÎÃͤ¬Êѹ¹¤µ¤ì¤¿»þ¤Ëɾ²Á¤µ¤ì¤ë
-@var{command}¤ò»ØÄꤹ¤ë¡¥@var{command}¤Ïʸ»úÎ󡤤ޤ¿¤Ï¥Ö¥í¥Ã¥¯¤Ç»ØÄꤹ
-¤ë¡¥trace¤ò²ò½ü¤¹¤ë¤¿¤á¤Ë¤Ï@code{untrace_var}¤òÍѤ¤¤ë¡¥
-
-@item trap(@var{signal}, @var{command})
-@itemx trap(@var{signal}) @{@dots{}@}
-
-@var{signal}¤Î³ä¤ê¹þ¤ß¤¬¤«¤«¤Ã¤¿»þ¤Ë@var{command}¤ò¼Â¹Ô¤¹¤ë¡¥
-@var{signal}¤Ï¥·¥°¥Ê¥ë̾¤«¥·¥°¥Ê¥ë¤ÎÈֹ桥@var{command}¤Ïʸ»úÎ󡤤ޤ¿
-¤Ï¥Ö¥í¥Ã¥¯¤Ç»ØÄꤹ¤ë¡¥command¤È¤·¤Æ@samp{"SIG_IGN"}¤Þ¤¿¤Ï
-@samp{"IGNORE"}¤ò»ØÄꤷ¤¿»þ¤Ë¤Ï¤½¤Î¥·¥°¥Ê¥ë¤ò̵»ë¤¹¤ë(²Äǽ¤Ê¤é¤Ð)¡¥
-@samp{"SIG_DFL"}¤Þ¤¿¤Ï@samp{"DEFAULT"}¤ò»ØÄꤷ¤¿»þ¤Ï¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤ò
-¹Ô¤Ê¤¦¡¥@samp{"EXIT"}¤ò»ØÄꤷ¤¿»þ¤Ï¥·¥°¥Ê¥ë¤ò¼õ¤±¼è¤ë¤È(½ªÎ»½èÍý¤ò¹Ô¤Ã
-¤¿¸å)¡¤exit status 1¤Ç½ªÎ»¤¹¤ë¡¥
-
-@item untrace_var(@var{var})
-
-@var{var}¤ËÂФ¹¤ëÁ´¤Æ¤Îtrace¤ò²ò½ü¤¹¤ë¡¥trace¤È¤·¤Æ»ØÄꤵ¤ì¤Æ¤¤¤ë¥ª¥Ö
-¥¸¥§¥¯¥È¤òÇÛÎó¤Ë¤¤¤ì¤ÆÊÖ¤¹¡¥
-
-@item wait
-
-»Ò¥×¥í¥»¥¹¤¬½ªÎ»¤¹¤ë¤Î¤òÂÔ¤Á¡¤½ªÎ»¤·¤¿»Ò¥×¥í¥»¥¹¤Îpid¤òÊÖ¤¹¡¥»Ò¥×¥í¥»
-¥¹¤¬°ì¤Ä¤â¤Ê¤±¤ì¤Ð@code{nil}¤òÊÖ¤¹¡¥
-
-@item waitpid(@var{pid}, @var{flags})
-
-@var{pid}¤Ç»ØÄꤵ¤ì¤ëÆÃÄê¤Î»Ò¥×¥í¥»¥¹¤Î½ªÎ»¤òÂÔ¤Á¡¤¤½¤Î¥×¥í¥»¥¹¤¬½ªÎ»
-¤·¤¿»þ¤Ë¿¿¤òÊÖ¤¹¡¥»Ò¥×¥í¥»¥¹¤¬Â¸ºß¤·¤Ê¤¤¤«¡¤¥Î¥ó¥Ö¥í¥Ã¥­¥ó¥°¥â¡¼¥É¤Ç»Ò
-¥×¥í¥»¥¹¤¬¤Þ¤À½ªÎ»¤·¤Æ¤¤¤Ê¤¤»þ¤Ë¤Ï@code{nil}¤òÊÖ¤¹¡¥@samp{waitpid(2)}¤«
-@samp{wait4(2)}¤Î¼ÂÁõ¤µ¤ì¤Æ¤¤¤Ê¤¤¥Þ¥·¥ó¤Ç¤Ï@var{flags}¤Ï¤¤¤Ä¤â@code{nil}¤Þ¤¿
-¤Ï0¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¥
-@end ftable
-
-@node ÁȤ߹þ¤ßÊÑ¿ô¤ÈÄê¿ô, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë, ÁȤ߹þ¤ß´Ø¿ô, Top
-@comment node-name, next, previous, up
-@chapter ÁȤ߹þ¤ßÊÑ¿ô¤ÈÄê¿ô
-@cindex{Áȹþ¤ßÊÑ¿ô}
-
-@table @samp
-
-@item $!
-¥¨¥é¡¼¥á¥Ã¥»¡¼¥¸¡¥fail¤ÇÀßÄꤹ¤ë¡¥
-
-@item $@@
-¥¨¥é¡¼¤¬È¯À¸¤·¤¿»þÅÀ¤Î¥Õ¥¡¥¤¥ë̾¤È¹ÔÈֹ椬
-@example
-"¥Õ¥¡¥¤¥ë:¹ÔÈÖ¹æ[:¥á¥½¥Ã¥É̾(¤¢¤ì¤Ð)]"
-@end display
-¤Î·Á¼°¤Ç³ÊǼ¤µ¤ì¤ë¡¥
-
-@item $&
-ºÇ¸å¤ËÀ®¸ù¤·¤¿¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á
-
-@item $`
-ºÇ¸å¤Î¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤Ç¥Þ¥Ã¥Á¤·¤¿Ê¸»úÎó¤ÎÁ°¤Îʸ»úÎó
-
-@item $'
-ºÇ¸å¤Î¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤Ç¥Þ¥Ã¥Á¤·¤¿Ê¸»úÎó¤Î¸å¤Ë³¤¯Ê¸»úÎó
-
-@item $+
-ºÇ¸å¤Î¸¡º÷¥Ñ¥¿¡¼¥ó¤Ç¥Þ¥Ã¥Á¤·¤¿ºÇ¸å¤Î³ç¸Ì
-
-@item $1@dots{}$9
-ºÇ¸å¤ËÀ®¸ù¤·¤¿¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤ÇnÈÖÌܤγç¸Ì¤Ë¥Þ¥Ã¥Á¤·¤¿Ãͤ¬³ÊǼ¤µ¤ì¤ë¡¥
-³ºÅö¤¹¤ë³ç¸Ì¤¬¤Ê¤±¤ì¤Ð@code{nil}¤¬Æþ¤Ã¤Æ¤¤¤ë¡¥
-
-@item $~
-ºÇ¸å¤Î¥Þ¥Ã¥Á¤Ë´Ø¤¹¤ë¾ðÊ󡥤³¤ì¤ò¥»¥Ã¥È¤¹¤ë¤È@code{$&}¤ä
-@samp{$1@dots{}$9}¤ÎÃͤ¬ÊѲ½¤¹¤ë¡¥
-
-@item $=
-¤³¤ÎÊÑ¿ô¤ÎÃͤ¬@code{nil}¤Ç¤Ê¤¤»þ¡¤¥Ñ¥¿¡¼¥ó¥Þ¥Ã¥Á¤äʸ»úÎó¤ÎÈæ³Ó¤Ç¥¢¥ë¥Õ¥¡¥Ù¥Ã
-¥È¤ÎÂçʸ»ú¾®Ê¸»ú¤ò¶èÊ̤·¤Ê¤¤¡¥¥Ç¥Õ¥©¥ë¥È¤Ï@code{nil}(¶èÊ̤¹¤ë)¡¥
-
-@item $/
-ÆþÎϥ쥳¡¼¥É¥»¥Ñ¥ì¡¼¥¿¡¥¥Õ¥¡¥¤¥ë¤äʸ»úÎó¤ËÂФ·¤Æ@code{each}¤ò¹Ô¤Ê¤¦»þ
-¤Îʬ³äʸ»ú¤ò»ØÄꤹ¤ë¡¥$/¤Ë¶õʸ»úÎó(@code{""})¤ò»ØÄꤹ¤ë¤ÈÃÊÍîñ°Ì¤ÇÆþ
-ÎϤò¹Ô¤Ê¤¤¡¤@code{nil}¤ò»ØÄꤹ¤ë¤ÈÁ´ÂΤò°ìÅÙ¤ËÆɤ߹þ¤à¡¥@code{$/}¤Ë¤Ï
-Àµµ¬É½¸½¤Ï»È¤¨¤Ê¤¤¡¥¥Ç¥Õ¥©¥ë¥È¤Ï@samp{"\n"}¡¥
-
-@item $\
-½ÐÎϥ쥳¡¼¥É¥»¥Ñ¥ì¡¼¥¿¡¥¤³¤ÎÊÑ¿ô¤Ëʸ»úÎó¤ò»ØÄꤹ¤ë¤È@code{write}¤ä
-@code{print}¤ÎÅ٤˺Ǹå¤Ë¤³¤Îʸ»úÎó¤òÉղ䷤ƽÐÎϤ¹¤ë¡¥¥Ç¥Õ¥©¥ë¥È¤Ï
-@code{nil} (¤Ê¤Ë¤âÄɲ䷤ʤ¤)¡¥
-
-@item $,
-@code{Array:join}¤Î¥Ç¥Õ¥©¥ë¥È¤Î¶èÀÚ¤êʸ»úÎó¡¥@code{print}¤Î³Æ°ú¿ô¤Î´Ö
-¤Ë½ÐÎϤµ¤ì¤ëʸ»úÎó¡¥
-
-@item $;
-@code{String:split}¤Î¥Ç¥Õ¥©¥ë¥È¤Î¶èÀÚ¤êʸ»ú¡¥
-
-@item $.
-ºÇ¸å¤ËÆɤó¤ÀÆþÎÏ¥Õ¥¡¥¤¥ë¤Î¹ÔÈֹ桥
-
-@item $<
-°ú¿ô(¤Ê¤±¤ì¤Ðɸ½àÆþÎÏ)¤Ç¹½À®¤µ¤ì¤ë²¾ÁÛ¥Õ¥¡¥¤¥ë¡¥¤Ä¤Þ¤ê@code{gets}¤Ï
-@code{$<.gets}¤ÈƱ¤¸°ÕÌ£¤Ç¤¢¤ë¡¥@code{$<.file}¤Ç¸½ºßÆɤ߹þ¤ßÃæ¤Î¥Õ¥¡¥¤
-¥ë¥ª¥Ö¥¸¥§¥¯¥È¤¬¡¤@code{$<.filename}¤Ç¤½¤Î¥Õ¥¡¥¤¥ë̾¤¬ÆÀ¤é¤ì¤ë¡¥(³Ð¤¨
-Êý: @code{<}¤Ï¥·¥§¥ë¤ÎÆþÎϸµ»ØÄê)
-
-@item $>
-@code{print}¤ä@code{printf}¤Î¥Ç¥Õ¥©¥ë¥È¤Î½ÐÎÏÀè¡¥½é´üÃͤÏ
-@code{$stdout}¡¥@samp{-i}¥ª¥×¥·¥ç¥ó¤ò»ØÄꤷ¤¿¾ì¹ç¤Ë¤ÏÆɤ߹þ¤ß¸µ¤ÈƱ¤¸
-̾Á°¤Î¥Õ¥¡¥¤¥ë¡¥(³Ð¤¨Êý: @code{>}¤Ï¥·¥§¥ë¤Î½ÐÎÏÀè»ØÄê)
-
-@item $_
-ºÇ¸å¤Ë@code{gets}¤Ê¤É¤ÇÆɤ߹þ¤ó¤Àʸ»úÎó¡¥
-
-@item $0
-ruby¥¹¥¯¥ê¥×¥È¤Î̾Á°¡¥¤³¤ÎÊÑ¿ô¤ËÂåÆþ¤¹¤ë¤È@samp{ps(1)}¤Î½ÐÎϤ¬ÊѲ½¤¹¤ë¡¥
-
-@item $*
-ruby¥¹¥¯¥ê¥×¥È¤ËÍ¿¤¨¤é¤ì¤¿°ú¿ô¡¥ruby¼«¿È¤ËÂФ¹¤ë°ú¿ô¤Ï¼è¤ê½ü¤«¤ì¤Æ¤¤¤ë¡¥
-
-@item $$
-¸½ºß¼Â¹ÔÃæ¤Îruby¥×¥í¥»¥¹¤Îpid¡¥
-
-@item $?
-ºÇ¸å¤Ë¼Â¹Ô¤·¤¿»Ò¥×¥í¥»¥¹¤Îstatus¡¥
-
-@item $:
-¥Õ¥¡¥¤¥ë¤ò¥í¡¼¥É¤¹¤ë»þ¤Ë¸¡º÷¤¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¤Ø¤Î¥Ñ¥¹¤ò´Þ¤àÇÛÎó¡¥µ¯Æ°»þ
-¤Ë¤Ï¥Ç¥Õ¥©¥ë¥ÈÃÍ(¥³¥ó¥Ñ¥¤¥ë»þ¤Ë»ØÄꤹ¤ë)¤Ë²Ã¤¨¤Æ¡¤´Ä¶­ÊÑ¿ô
-@var{RUBYLIB}¤ÎÃͤÈrubyµ¯Æ°»þ¤Î@samp{-I}¥ª¥×¥·¥ç¥ó¤Ç»ØÄꤵ¤ì¤¿Ãͤ¬ÄɲÃ
-¤µ¤ì¤ë¡¥(³Ð¤¨Êý: ¥³¥í¥ó¤Ï´Ä¶­ÊÑ¿ô@var{PATH}¤Î¶èÀÚ¤êʸ»ú¤Ç¤¢¤ë)
-
-@item $"
-@code{require}¤Ç¥í¡¼¥É¤µ¤ì¤¿¥Õ¥¡¥¤¥ë̾¤ò´Þ¤àÇÛÎó¡¥@code{require}¤ÇƱ¤¸
-¥Õ¥¡¥¤¥ë¤ò2²ó¥í¡¼¥É¤·¤Ê¤¤¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¡¥(³Ð¤¨Êý: prevent files to
-be doubly quoted(loaded))
-
-@item $ARGF
-@code{$<}¤ÎÊÌ̾¡¥
-
-@item $ARGV
-@code{$*}¤ÎÊÌ̾¡¥
-
-@item $DEBUG
-@code{-d}¥Õ¥é¥°¤Î¾õÂÖ(¿¿µ¶ÃÍ)¡¥
-
-@item $FILENAME
-²¾ÁÛ¥Õ¥¡¥¤¥ë@code{$<}¤Ç¸½ºßÆɤ߹þ¤ßÃæ¤Î(¥á¥½¥Ã¥Égets¤¬º£Æɤó¤Ç¤¤¤ë)¥Õ¥¡
-¥¤¥ë̾¡¥@code{$<.filename}¤ÈƱ¤¸¡¥
-
-@item $KCODE
-¸½ºß½èÍýÂоݤȤ·¤Æ¤¤¤ë´Á»ú¥³¡¼¥É¤òɽ¤¹Ê¸»úÎó¡¥@samp{"EUC"}¡¤
-@samp{"SJIS"}¤Þ¤¿¤Ï@samp{"NONE"}¡¥¤³¤ÎÊÑ¿ô¤ÎÃͤòÊѹ¹¤¹¤ë¤ÈÀµµ¬É½¸½¤Î¥Þ¥Ã
-¥Á¤ÎľÁ°¤ËÀµµ¬É½¸½¤ÎºÆ¥³¥ó¥Ñ¥¤¥ë¤¬¹Ô¤ï¤ì¤ë¡¥
-
-@item $LOAD_PATH
-@code{$:}¤ÎÊÌ̾¡¥
-
-@item $stdin
-ɸ½àÆþÎÏ
-
-@item $stdout
-ɸ½à½ÐÎÏ
-
-@item $stderr
-ɸ½à¥¨¥é¡¼½ÐÎÏ
-
-@item $VERBOSE
-@code{-v}¥Õ¥é¥°¤Î¾õÂÖ(¿¿µ¶ÃÍ)
-
-@item TRUE
-@itemx FALSE
-¤½¤ì¤¾¤ì¿¿µ¶Ãͤòɽ¤¹(@code{TRUE}¤ÎÃͤÏt¡¤@code{FALSE}¤ÎÃͤÏ@code{nil})¡¥
-¾ò·ïȽÃǤÏ@code{nil}¤òµ¶¡¤¤½¤ì°Ê³°¤ÎÁ´¤Æ¤ÎÃͤò¿¿¤È¤·¤ÆȽÃǤ¹¤ë¤¿¤á¡¤
-@code{TRUE}¤ÎÃͤÏÂåɽŪ¤Ê¿¿¤ÎÃͤȤ¤¤¦°Ê¾å¤Î°ÕÌ£¤ò»ý¤¿¤Ê¤¤¡¥¤è¤Ã¤Æ¡¤¤¢
-¤ë¥á¥½¥Ã¥É¤ÎÊÖÃͤ¬¿¿¤Ç¤¢¤ë¤È¤¤¤¦¤³¤È¤È¡¤¤½¤ì¤¬@code{TRUE}¤òÊÖ¤¹¤È¤¤¤¦
-¤³¤È¤Ï¸·Ì©¤Ë¤ÏƱ¤¸¤Ç¤Ï¤Ê¤¤(½Ò¸ìŪ¤ËÍѤ¤¤é¤ì¤ë¥á¥½¥Ã¥É¤ÏÂçÄñ¿¿¤ÎÃͤȤ·
-¤Æ@code{TRUE}¤òÊÖ¤¹¤è¤¦¤Ë¤Ï¤Ê¤Ã¤Æ¤¤¤ë¤¬)¡¥¤Ä¤Þ¤ê
-
-@example
-if some.method() then @dots{} else @dots{} end
-@end example
-
-¤È
-
-@example
-if some.method() == TRUE then @dots{} else @dots{} end
-@end example
-
-¤Ï´°Á´¤Ë¤ÏƱµÁ¤Ç¤Ï¤Ê¤¤¡¥@code{FALSE}¤Ë´Ø¤·¤Æ¤Ï¡¤¤³¤Î¤è¤¦¤ÊÌäÂê¤ÏÀ¸¤¸
-¤Ê¤¤¡¥
-
-@item STDIN
-ɸ½àÆþÎÏ($stdin¤Î½é´üÃÍ)
-@item STDOUT
-ɸ½à½ÐÎÏ($stdout¤Î½é´üÃÍ)
-@item STDERR
-ɸ½à¥¨¥é¡¼½ÐÎÏ($stderr¤Î½é´üÃÍ)
-
-@item ENV
-´Ä¶­ÊÑ¿ô¤Ë¥¢¥¯¥»¥¹¤¹¤ëÏ¢ÁÛÇÛÎó¡¥Ê¸»úÎó¤ò¥­¡¼¤È¤·¤ÆÍ¿¤¨¤ë¤ÈÂбþ¤¹¤ë´Ä¶­
-ÊÑ¿ô¤ÎÃͤ¬ÆÀ¤é¤ì¤ë¡¥´Ä¶­ÊÑ¿ô¤¬Â¸ºß¤·¤Ê¤¤¾ì¹ç¤Ï@code{nil}¤¬Ê֤롥
-
-@item VERSION
-ruby¤Î¥Ð¡¼¥¸¥ç¥ó¤ò¼¨¤¹Ê¸»úÎó
-@end table
-
-@node ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë, C¸À¸ì¤È¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹, ÁȤ߹þ¤ßÊÑ¿ô¤ÈÄê¿ô, Top
-@comment node-name, next, previous, up
-@chapter ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-
-@menu
-¥¯¥é¥¹
-* Array::
-* Bignum::
-* Class::
-* Dir::
-* File::
-* Fixnum::
-* Float::
-* Hash::
-* Integer::
-* IO::
-* Kernel::
-* Module::
-* Nil::
-* Numeric::
-* Object::
-* Proc::
-* Range::
-* Regexp::
-* String::
-* Struct::
-* Time::
-
-¥â¥¸¥å¡¼¥ë
-
-* Comparable::
-* Enumerable::
-* Etc::
-* FileTest::
-* GC::
-* Math::
-* Process::
-@end menu
-
-@node Array, Bignum, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Array
-
-¿ô»ú¤òź»ú¤È¤·¤¿ÇÛÎó¤Î¥¯¥é¥¹¤Ç¤¢¤ë¡¥À¸À®¤Ï°ìÈÌŪ¤Ë¤ÏÇÛÎó¼°``[@dots{}]''¤Ç
-¹Ô¤Ê¤ï¤ì¤ë¡¥
-
-SuperClass: Object
-
-Included Modules: Enumerable
-
-Methods:
-
-@ftable @code
-@item self[@var{nth}]
-@itemx self[@var{start}..@var{end}]
-@itemx self[@var{start}, @var{length}]
-
-ÇÛÎó¤ÎÍ×ÁǤ˥¢¥¯¥»¥¹¤¹¤ë¡¥ºÇ½é¤Î·Á¼°¤Ç¤ÏÇÛÎó¤Î@var{nth}ÈÖÌܤÎÍ×ÁǤòÊÖ
-¤·¡¤2ÈÖÌܤηÁ¼°¤Ç¤Ï@var{start}ÈÖÌܤÎÍ×ÁǤ«¤é@var{end}ÈÖÌܤÎÍ×ÁǤò´Þ¤à
-ÉôʬÇÛÎó¤òÊÖ¤¹¡¥3ÈÖÌܤηÁ¼°¤Ç¤Ï@var{start}ÈÖÌܤ«¤é@var{length}¸Ä¤ÎÍ×ÁÇ
-¤ò´Þ¤àÉôʬÇÛÎó¤òÊÖ¤¹¡¥
-
-@item self[@var{nth}] = @var{val}
-@itemx self[@var{start}..@var{end}] = @var{val}
-@itemx self[@var{start}, @var{length}] = @var{val}
-
-ÇÛÎó¤ÎÍ×ÁǤòÊѹ¹¤¹¤ë¡¥ºÇ½é¤Î·Á¼°¤Ç¤ÏÇÛÎó¤Î@var{nth}ÈÖÌܤÎÍ×ÁǤò
-@var{val}¤ËÊѹ¹¤¹¤ë¡¥2ÈÖÌܤηÁ¼°¤Ï@var{start}ÈÖÌܤÎÍ×ÁǤ«¤é@var{end}ÈÖ
-ÌܤÎÍ×ÁǤޤǤò@var{val}¤ËÊѹ¹¤¹¤ë¡¥3ÈÖÌܤηÁ¼°¤Ç¤Ï@var{start}ÈÖÌܤ«¤é
-@var{length}¸Ä¤ÎÍ×ÁǤò@var{val}¤ËÊѹ¹¤¹¤ë¡¥
-
-2ÈÖÌÜ¡¤3ÈÖÌܤηÁ¼°¤Ç¤Ï@var{val}¤ÏÇÛÎó¤Ç¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¥
-
-Îã
-
-@example
-ary = [1, 2, 3, 4, 5]
-ary[0..2] = [0, 0] # ÇÛÎó¤ÎÆâÍÆ¤Ï [0, 0, 4, 5]
-ary[1, 0] = [7] # ÇÛÎó¤ÎÆâÍÆ¤Ï [0, 7, 0, 6, 5]
-@end example
-
-@item self + @var{other}
-
-ÇÛÎó¤ÎÏ¢·ë¡¥@code{self}¤È@var{other}¤ÎξÊý¤ÎÇÛÎó¤ÎÆâÍƤò·Ò¤²¤¿¿·¤·¤¤ÇÛ
-Îó¤òÊÖ¤¹¡¥
-
-@item self * @var{times}
-
-ÇÛÎó¤Î·«¤êÊÖ¤·¡¥
-
-@item self - @var{other}
-
-½¸¹ç¤Îº¹±é»»¡¥@code{self}¤«¤é@var{other}¤ÎÍ×ÁǤò¼è¤ê½ü¤¤¤¿ÆâÍƤο·¤·¤¤
-ÇÛÎó¤òÊÖ¤¹¡¥½ÅÊ£¤¹¤ëÍ×ÁǤÏ1ÅÙ¤À¤±¸½¤ì¤ë¡¥
-
-@item self * @var{other}
-
-½¸¹ç¤ÎÀѱ黻¡¥Î¾Êý¤ÎÇÛÎó¤Ë´Þ¤Þ¤ì¤ëÍ×ÁǤ«¤é¤Ê¤ë¿·¤·¤¤ÇÛÎó¤òÊÖ¤¹¡¥
-½ÅÊ£¤¹¤ëÍ×ÁǤÏ1ÅÙ¤À¤±¸½¤ì¤ë¡¥
-
-@item self | @var{other}
-
-½¸¹ç¤Îϱ黻¡¥Î¾Êý¤ÎÇÛÎó¤Ë¤¤¤º¤ì¤«¤Ë´Þ¤Þ¤ì¤ëÍ×ÁǤòÁ´¤Æ´Þ¤à¿·¤·
-¤¤ÇÛÎó¤òÊÖ¤¹¡¥½ÅÊ£¤¹¤ëÍ×ÁǤÏ1ÅÙ¤À¤±¸½¤ì¤ë¡¥
-
-@item self << @var{obj}
-
-obj¤òÇÛÎó¤ÎËöÈø¤ËÄɲ乤롥@code{self}¤òÊÖ¤¹¤Î¤Ç@code{C++}Ū¤ËÏ¢º¿¤Ç¤­
-¤ë¡¥
-
-@item assoc(@var{key})
-
-Ï¢Áۥꥹ¥È(2Í×ÁǤÎÇÛÎó¤òÍ×ÁǤȤ¹¤ëÇÛÎó)¤ò¸¡º÷¤·¡¤Âè1Í×ÁǤ¬@var{key}¤È
-Åù¤·¤¤ (@code{==}¤ÇÈæ³Ó¤¹¤ë)ÇÛÎó¤òÊÖ¤¹¡¥
-
-@item clear
-
-ÇÛÎó¤ÎÂ礭¤µ¤ò0¤Ë¤¹¤ë¡¥
-
-@item delete(@var{val})
-
-@var{val}¤È°ìÃפ¹¤ëÍ×ÁǤòºï½ü¤¹¤ë¡¥
-
-@item delete_if @{@dots{}@}
-
-Í×ÁǤòºï½ü¤¹¤ë¥¤¥Æ¥ì¡¼¥¿¡¥¥Ö¥í¥Ã¥¯¤òɾ²Á¤·¤¿Ãͤ¬¿¿¤Î»þ¡¤Âбþ¤¹¤ëÍ×ÁǤò
-ÇÛÎ󤫤éºï½ü¤¹¤ë¡¥
-
-@item each @{@dots{}@}
-
-ÇÛÎó¤Î³ÆÍ×ÁǤò½ç¤ËÍ¿¤¨¤ë¥¤¥Æ¥ì¡¼¥¿¡¥
-
-@item fill(@var{val})
-@itemx fill(@var{val}, @var{start}[, @var{length}])
-@itemx fill(@var{val}, @var{start}..@var{end})
-
-ÇÛÎó(¤Î»ØÄꤵ¤ì¤¿Éôʬ)¤ÎÍ×ÁǤÎÃͤò@var{val}¤ËÀßÄꤹ¤ë¡¥2ÈÖ¤á¤Î·Á¼°¤Ç
-@var{length}¤¬¾Êά¤µ¤ì¤¿»þ¤ÏÇÛÎó¤Î½ª¤ê¤Þ¤Ç¤ÎŤµ¤ò¤È¤ë¡¥»ØÄꤵ¤ì¤¿Éôʬ
-ÇÛÎ󤬸µ¤ÎÇÛÎó¤ÎÈϰϤò±Û¤¨¤ë»þ¤Ï¼«Æ°Åª¤Ë³ÈÄ¥¤µ¤ì¤ë¡¥
-
-@item index(@var{val})
-
-@var{val}¤ÈÅù¤·¤¤ºÇ½é¤ÎÍ×ÁǤΥ¤¥ó¥Ç¥Ã¥¯¥¹¤òÊÖ¤¹¡¥³ºÅö¤¹¤ëÍ×ÁǤ¬Â¸ºß¤·
-¤Ê¤¤¾ì¹ç¤Ï@code{nil}¤òÊÖ¤¹¡¥
-
-@item indexes(@var{ary})
-@itemx indexes(@var{index_}1,@dots{}, @var{index_n})
-
-1ÈÖÌܤηÁ¼°¤Ç¤ÏÀ°¿ô¤ÎÇÛÎó¤ò°ú¿ô¤È¤·¤Æ¼õ¤±¤Æ¡¤¤½¤ÎÍ×ÁǤò¥¤¥ó¥Ç¥Ã¥¯¥¹¤È
-¤¹¤ëÍ×ÁǤò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥2ÈÖÌܤηÁ¼°¤Ç¤Ï³Æ°ú¿ô¤ÎÃͤò¥¤¥ó¥Ç¥Ã¥¯¥¹¤È¤¹
-¤ëÍ×ÁǤò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥
-
-@item join([@var{sep}])
-
-ÇÛÎó¤ÎÍ×ÁǤòÏ¢·ë¤·¤¿Ê¸»úÎó¤òÊÖ¤¹¡¥³ÆÍ×ÁǤÏʸ»úÎó¤ËÊÑ´¹¤µ¤ì¡¤´Ö¤Ë
-@var{sep}¤ò¶´¤ó¤ÇÏ¢·ë¤µ¤ì¤ë¡¥@var{sep}¤¬¾Êά¤µ¤ì¤¿»þ¤Ë¤Ï¥·¥¹¥Æ¥àÊÑ¿ô
-@code{$,}¤ÎÃͤ¬ÍѤ¤¤é¤ì¤ë¡¥
-
-@item length
-@itemx size
-
-ÇÛÎó¤ÎŤµ(Í×ÁÇ¿ô)¤òÊÖ¤¹¡¥
-
-@item pack(@var{template})
-
-ÇÛÎó¤ÎÆâÍƤò@var{template}ʸ»úÎó¤Ë¤·¤¿¤¬¤Ã¤Æ¡¤1¤Ä¤Îʸ»úÎó¤Ë¥Ñ¥Ã¥¯¤¹¤ë¡¥
-¥Ñ¥Ã¥¯¤·¤¿Ê¸»úÎó¤òÊÖ¤¹¡¥¥Æ¥ó¥×¥ì¡¼¥È¤Ï·¿»ØÄêʸ»úÎó¤È¤½¤ÎŤµ(¾Êά»þ¤Ï
-1)¤òʤ٤¿¤â¤Î¤Ç¤¢¤ë¡¥Ä¹¤µ¤È¤·¤Æ@code{*}¤¬»ØÄꤵ¤ì¤¿»þ¤Ï¡Ö»Ä¤ê¤Î¥Ç¡¼¥¿
-Á´¤Æ¡×¤ÎŤµ¤òɽ¤¹¡¥
-
-·¿»ØÄêʸ»ú¤Ï°Ê²¼¤Î¤â¤Î¤¬¤¢¤ë¡¥
-
-@display
-a ASCIIʸ»úÎó(nullʸ»ú¤òµÍ¤á¤ë)
-A ASCIIʸ»úÎó(¥¹¥Ú¡¼¥¹¤òµÍ¤á¤ë)
-b ¥Ó¥Ã¥È¥¹¥È¥ê¥ó¥°(²¼°Ì¥Ó¥Ã¥È¤«¤é¾å°Ì¥Ó¥Ã¥È)
-B ¥Ó¥Ã¥È¥¹¥È¥ê¥ó¥°(¾å°Ì¥Ó¥Ã¥È¤«¤é²¼°Ì¥Ó¥Ã¥È)
-h 16¿Êʸ»úÎó(²¼°Ì¥Ë¥Ö¥ë¤¬Àè)
-H 16¿Êʸ»úÎó(¾å°Ì¥Ë¥Ö¥ë¤¬Àè)
-c char
-C unsigned char
-s sort
-S unsigned sort
-i int
-I unsigned int
-l long
-L unsigned int
-n ¥Í¥Ã¥È¥ï¡¼¥¯¥Ð¥¤¥È¥ª¡¼¥À¡¼¤Îshort
-N ¥Í¥Ã¥È¥ï¡¼¥¯¥Ð¥¤¥È¥ª¡¼¥À¡¼¤Îlong
-f ñÀºÅÙÉâÆ°¾®¿ôÅÀ¿ô(µ¡¼ï°Í¸)
-d ÇÜÀºÅÙÉâÆ°¾®¿ôÅÀ¿ô(µ¡¼ï°Í¸)
-x ¥Ê¥ë¥Ð¥¤¥È
-X 1¥Ð¥¤¥È¸åÂà
-@@ ÀäÂаÌÃ֤ؤΰÜÆ°
-@end display
-
-@item pop
-
-ÇÛÎó¤ÎËöÈø¤ÎÍ×ÁǤò¼è¤ê½ü¤¤¤Æ¡¤¤½¤ì¤òÊÖ¤¹¡¥
-
-@item push(@var{obj})
-
-@var{obj}¤òÇÛÎó¤ÎËöÈø¤ËÄɲ乤롥
-
-@item rassoc(@var{value})
-
-Ï¢Áۥꥹ¥È(2Í×ÁǤÎÇÛÎó¤òÍ×ÁǤȤ¹¤ëÇÛÎó)¤ò¸¡º÷¤·¡¤Âè2Í×ÁǤ¬@var{value}
-¤ÈÅù¤·¤¤(@code{==}¤ÇÈæ³Ó¤¹¤ë)ÇÛÎó¤òÊÖ¤¹¡¥
-
-@item shift
-
-ÇÛÎó¤ÎÀèƬ¤ÎÍ×ÁǤò¼è¤ê½ü¤¤¤Æ¡¤¤½¤ì¤òÊÖ¤¹¡¥
-
-@item sort
-@itemx sort @{|@var{a}, @var{b}|@dots{}@}
-
-ÇÛÎó¤ÎÆâÍƤò¥½¡¼¥È¤¹¤ë¡¥¥¤¥Æ¥ì¡¼¥¿¤È¤·¤Æ¸Æ¤Ó½Ð¤µ¤ì¤¿¾ì¹ç¤Ï¥Ö¥í¥Ã¥¯¤òɾ
-²Á¤·¤¿ÃͤÇÍ×ÁǤÎÂç¾®¤ò·èÄꤹ¤ë¡¥Â礭¤¤»þ¤ËÀµ¡¤Åù¤·¤¤»þ¤Ë0¡¤¾®¤µ¤­»þ¤Ë
-Éé¡¥Ä̾ï¤Î¥á¥½¥Ã¥É¤È¤·¤Æ¸Æ¤Ó½Ð¤µ¤ì¤¿¾ì¹ç¤Ï³ÆÍ×ÁǤò@code{<=>}¤ÇÈæ³Ó¤¹¤ë¡¥
-
-@item to_a
-
-¼«Ê¬¼«¿È¤òÊÖ¤¹¡¥ÂоÎÀ­¤Î¤¿¤á¤ËÍÑ°Õ¤µ¤ì¤Æ¤¤¤ë¥á¥½¥Ã¥É¤Ç¤¢¤Þ¤êÌÌÇò¤¯¤Ê¤¤¡¥
-
-@item unshift(@var{obj})
-
-@var{obj}¤òÇÛÎó¤ÎÀèƬ¤ËÄɲ乤롥
-@end ftable
-
-Single Methods:
-
-@ftable @code
-@item Array[@var{item}@dots{}]
-
-°ú¿ô¤òÍ×ÁǤȤ¹¤ëÇÛÎó¤òÀ¸À®¤¹¤ë¡¥
-@end ftable
-
-@xref{Object}
-@xref{Enumerable}
-
-@node Bignum, Class, Array, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Bignum
-
-̵¸Â¿ÇÜĹÀ°¿ô¤Î¥¯¥é¥¹¡¥±é»»¤Î·ë²Ì¤¬¤³¤Î@code{Fixnum}¤ÎÈÏ°ÏÆâ¤Ç¤¢¤ë¾ì
-¹ç¤Ë¤Ï¼«Æ°Åª¤Ë¥¯¥é¥¹¤Ï@code{Fixnum}¤ËÊÑ´¹¤µ¤ì¤ë¡¥°ìÈÌŪ¤Ëruby¥×¥í¥°¥é
-¥à¤Ç¤Ï@code{Fixnum}¤È@code{Bignum}¤ÎÊÑ´¹¤Ï°ÅÌۤΤ¦¤Á¤Ë¹Ô¤ï¤ì¤ë¤Î¤Ç¡¤°Õ
-¼±¤¹¤ëɬÍפÏ̵¤¤¡¥@code{Float}¤È¤Îº®¹ç¤Ë´Ø¤·¤Æ¤Ï¡¤@code{Bignum}¤è¤ê
-@code{Float}¤ÎÊý¤¬genericity¤¬¹â¤¤¤Î¤Ë¤â´Ø¤ï¤é¤º¡¤@code{Bignum}¤ÎÊý¤¬¡¤
-Â礭¤ÊÃͤòɽ¸½¤Ç¤­¤ë¤Î¤Ç¡¤ÊÑ´¹»þ¤Ë·åÍî¤Á¤¬À¸¤¸¤ë²ÄǽÀ­¤¬¤¢¤ë¡¥
-
-SuperClass: Integer
-
-Methods:
-
-@ftable @code
-@item self + @var{other}
-@itemx self - @var{other}
-@itemx self * @var{other}
-@itemx self / @var{other}
-@itemx self % @var{other}
-@itemx self ** @var{other}
-
-»»½Ñ±é»»¡¥¤½¤ì¤¾¤ìÏ¡¤º¹¡¤ÀÑ¡¤¾¦¡¤¾ê;¡¤ÑѾè¤òÊÖ¤¹¡¥
-
-@item ~ self
-@itemx self | @var{other}
-@itemx self & @var{other}
-@itemx self ^ @var{other}
-
-¥Ó¥Ã¥È±é»»¡¥¤½¤ì¤¾¤ì¥Ó¥Ã¥Èȿž¡¤ÏÀÍýÏ¡¤ÏÀÍýÀÑ¡¤ÇÓ¾ŪÏÀÍýϤòÊÖ¤¹¡¥
-
-@item self << @var{bits}
-@itemx self >> @var{bits}
-
-¥·¥Õ¥È±é»»¡¥¤½¤ì¤¾¤ì@var{bits}¥Ó¥Ã¥È¤À¤±º¸±¦¤Ë¥Ó¥Ã¥È¥·¥Õ¥È¤ò¹Ô¤Ê¤¦¡¥
-
-@item divmod(@var{other})
-
-¾¦¤È¾ê;¤«¤é¤Ê¤ëÇÛÎó¤òÊÖ¤¹¡¥
-@end ftable
-
-@xref{Integer}
-
-@node Class, Comparable, Bignum, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Class
-
-¥¯¥é¥¹¤Î¥¯¥é¥¹¡¥¤è¤ê¸·Ì©¤ËÀâÌÀ¤¹¤ë¤È¥¯¥é¥¹¤ÏÆðۥ᥽¥Ã¥É¤ò·Ñ¾µ¤¹¤ë¤¿¤á
-¤Ë¡¤¤½¤ì¤¾¤ì¥á¥¿¥¯¥é¥¹¤È¸Æ¤Ð¤ì¤ë̾Á°¤Î¤Ê¤¤¥¯¥é¥¹¤ò¥¯¥é¥¹¤È¤·¤Æ»ý¤Á¡¤
-@code{Class}¤Ï¤½¤Î¥á¥¿¥¯¥é¥¹¤Î¥¯¥é¥¹¤Ç¤¢¤ë(ʬ¤«¤Ã¤¿¤«¤Ê?)¡¥¤¬¡¤¤³¤Î²ò
-À⤬Íý²ò¤Ç¤­¤Ê¤¯¤Æ¤â¡¤ruby¤ò»È¤¦¤³¤È¤Ë²¿¤Î»Ù¾ã¤â¤Ê¤¤¡¥¥¯¥é¥¹¤Ë¤ÏÆðۥá
-¥½¥Ã¥É¤òÄêµÁ¤Ç¤­¤ë»ö¤È¡¤¥¹¡¼¥Ñ¡¼¥¯¥é¥¹¤ÇÄêµÁ¤µ¤ì¤¿Æðۥ᥽¥Ã¥É¤Ï¤½¤Î¥µ
-¥Ö¥¯¥é¥¹¤Ç¤âÍ­¸ú¤Ç¤¢¤ë»ö¤òÃΤì¤Ð½½Ê¬¤Ç¤¢¤ë¡¥
-
-SuperClass: Module
-
-Private Methods:
-
-@ftable @code
-@item attr(@var{name}[, @var{public}])
-
-¤½¤Î¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤ËÂФ·¤Æ@var{name}¤Ç»ØÄꤵ¤ì¤ë°À­¤òÄêµÁ¤¹¤ë¡¥
-¾Ü¤·¤¯¤Ï@code{Module}¤Î@code{attr}¥á¥½¥Ã¥É¤Î¹à¤ò»²¾È¤Î¤³¤È¡¥
-@end ftable
-
-Methods:
-
-@ftable @code
-@item new(@dots{})
-
-¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤òÀ¸À®¤¹¤ë¡¥Â¿¤¯¤Î¾ì¹ç¤³¤Î¥á¥½¥Ã¥É¤Ï¥µ¥Ö¥¯¥é¥¹¤ÎÆÃ
-°Û¥á¥½¥Ã¥É¤Ë¤è¤Ã¤Æ¥ª¡¼¥Ð¡¼¥é¥¤¥É¤µ¤ì¡¤¥¯¥é¥¹¤Ë¤è¤Ã¤Æ°ú¿ô¤¬°Û¤Ê¤ë¡¥
-@end ftable
-
-@xref{Module}
-
-@node Comparable, Dir, Class, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Comparable
-
-Èæ³Ó±é»»¤òµö¤¹¥¯¥é¥¹¤Î¤¿¤á¤Î@code{Mixin}¡¥¤³¤Î¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É
-¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¤@code{<=>}±é»»»Ò¤òÄêµÁ¤¹¤ë¤À¤±¤Ç¾¤Î±é»»»Ò¤Ï¤½¤ÎÄêµÁ
-¤òÍøÍѤ·¤ÆÇÉÀ¸¤Ç¤­¤ë¡¥
-
-Methods:
-
-@ftable @code
-@item self == @var{other}
-
-@code{self}¤¬@var{other}¤ÈÅù¤·¤¤»þ¿¿¤òÊÖ¤¹¡¥
-
-@item self > other
-
-@code{self}¤¬@var{other}¤è¤êÂ礭¤¤»þ¿¿¤òÊÖ¤¹¡¥
-
-@item self >= @var{other}
-
-@code{self}¤¬@var{other}¤è¤êÂ礭¤¤¤«Åù¤·¤¤»þ¿¿¤òÊÖ¤¹¡¥
-
-@item self < @var{other}
-
-@code{self}¤¬@var{other}¤è¤ê¾®¤µ¤¤»þ¿¿¤òÊÖ¤¹¡¥
-
-@item self <= @var{other}
-
-@code{self}¤¬@var{other}¤è¤ê¾®¤µ¤¤¤«Åù¤·¤¤»þ¿¿¤òÊÖ¤¹¡¥
-
-@item between?(min, max)
-
-@code{self}¤¬@var{min}¤È@var{max}¤ÎÈÏ°ÏÆâ¤Ë¤¢¤ë»þ¿¿¤òÊÖ¤¹¡¥
-@end ftable
-
-@node Dir, Enumerable, Comparable, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Dir
-
-¥Ç¥£¥ì¥¯¥È¥êÆâ¤ÎÍ×ÁǤò½ç¤ËÊÖ¤¹¥Ç¥£¥ì¥¯¥È¥ê¥¹¥È¥ê¡¼¥àÁàºî¤Î¤¿¤á¤Î¥¯¥é¥¹¡¥
-
-SuperClass: Object
-
-Included Modules: Enumerable
-
-Methods:
-
-@ftable @code
-
-@item close
-
-¥Ç¥£¥ì¥¯¥È¥ê¥¹¥È¥ê¡¼¥à¤ò¥¯¥í¡¼¥º¤¹¤ë¡¥°Ê¸å¤ÎÁàºî¤ÏÎã³°¤òȯÀ¸¤µ¤»¤ë¡¥
-
-@item each @{|@var{item}|@dots{}@}
-
-¥Ç¥£¥ì¥¯¥È¥êÆâ¤Î³ÆÍ×ÁǤò½ç¤ËÍ¿¤¨¤ë¥¤¥Æ¥ì¡¼¥¿¡¥
-
-@item getwd
-@itemx pwd
-
-¥«¥ì¥ó¥È¥Ç¥£¥ì¥¯¥È¥ê¤òÊÖ¤¹¡¥
-
-@item rewind
-
-¥Ç¥£¥ì¥¯¥È¥ê¥¹¥È¥ê¡¼¥à¤òÀèƬ¤Ë¥ê¥»¥Ã¥È¤¹¤ë¡¥
-
-@item seek(@var{pos})
-
-¥Ç¥£¥ì¥¯¥È¥ê¥¹¥È¥ê¡¼¥à¤Î°ÌÃÖ¤ò@var{pos}¤ËÀßÄꤹ¤ë¡¥
-
-@item tell
-
-¥Ç¥£¥ì¥¯¥È¥ê¥¹¥È¥ê¡¼¥à¤Î¸½ºß¤Î°ÌÃÖ¤òÊÖ¤¹¡¥
-
-Single Methods:
-
-@item self[@var{pat}]
-@itemx glob(@var{pat})
-
-ʸ»úÎó@var{pat}¤ò@samp{sh}·Á¼°¤Î¥ï¥¤¥ë¥É¥«¡¼¥É¤È¤·¤ÆŸ³«¤·¤¿·ë²Ì¤òʸ»ú
-Îó¤ÎÇÛÎó¤È¤·¤ÆÊÖ¤¹¡¥½ñ¼°¤Ï°Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
-
-@ftable @samp
-@item *
-Ǥ°Õ¤Îʸ»úÎó(¶õʸ»úÎó¤ò´Þ¤à)¤È°ìÃ×
-@item ?
-Ǥ°Õ¤Î1ʸ»ú¤È°ìÃ×
-@item [ ]
-[]Æâ¤Î¤¤¤º¤ì¤«1ʸ»ú¤È°ìÃ×
-@item {@dots{}}
-{}Æâ¤Î(¥³¥ó¥Þ¤Ç¶èÀÚ¤é¤ì¤¿)¤¤¤º¤ì¤«¤Îʸ»úÎó¤È°ìÃ×
-@end ftable
-
-@item chdir(@var{path})
-
-¥«¥ì¥ó¥È¥Ç¥£¥ì¥¯¥È¥ê¤ò@var{path}¤ËÊѹ¹¤¹¤ë¡¥
-
-@item chroot(@var{path})
-
-¥×¥í¥»¥¹¤Î¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê¤òÊѹ¹¤¹¤ë¡¤Æ±Ì¾¤Î¥·¥¹¥Æ¥à¥³¡¼¥ë¤ÈƱ¤¸Æ¯¤­
-¤ò¤¹¤ë¡¥¤³¤ÎÁàºî¤Ï¼Â¸úuid¤¬¥¹¡¼¥Ñ¥æ¡¼¥¶¤Ç¤¢¤ë»þ¤À¤±¤ËÀ©¸Â¤µ¤ì¤Æ¤¤¤ë¡¥
-¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê¤ò¸µ¤ËÌ᤹(¥ë¡¼¥È¥Ç¥£¥ì¥¯¥È¥ê¤ò¾åÊý¤ËÊѹ¹¤¹¤ë)ÊýË¡¤Ï
-Ä󶡤µ¤ì¤Æ¤¤¤Ê¤¤¡¥
-
-@item mkdir(@var{path}[, @var{mode}])
-
-@var{mode}¤Ç»ØÄꤵ¤ì¤¿¥â¡¼¥É¤ò»ý¤Ä¥Ç¥£¥ì¥¯¥È¥ê@var{path}¤òºîÀ®¤¹¤ë¡¥¥â¡¼
-¥É¤Ï@code{umask}¤Ë¤è¤Ã¤Æ½¤Àµ¤µ¤ì¤ë¡¥@var{mode}¤Î¥Ç¥Õ¥©¥ë¥ÈÃͤÏ0777¡¥
-
-@item open(@var{path})
-
-@var{path}¤ËÂФ¹¤ë¥Ç¥£¥ì¥¯¥È¥ê¥¹¥È¥ê¡¼¥à¤ò¥ª¡¼¥×¥ó¤¹¤ë¡¥
-
-@item rmdir(@var{path})
-
-@var{path}¤Ç»ØÄꤵ¤ì¤¿¥Ç¥£¥ì¥¯¥È¥ê¤òºï½ü¤¹¤ë¡¥¥Ç¥£¥ì¥¯¥È¥ê¤Ï¶õ¤Ç¤¢¤ëɬ
-Íפ¬¤¢¤ë¡¥
-@end ftable
-
-@xref{Object}
-@xref{Enumerable}
-
-@node Enumerable, File, Dir, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Enumerable
-
-Í×ÁǤËÂФ¹¤ë·«¤êÊÖ¤·¤ò¹Ô¤Ê¤¦¥¯¥é¥¹¤Î¤¿¤á¤Î@code{Mixin}¡¥¤³¤Î¥â¥¸¥å¡¼¥ë
-¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¤¿¤á¤Ë¤Ï¡¤¥á¥½¥Ã¥É@code{each}¤òÄêµÁ¤¹¤ëɬÍפ¬¤¢¤ë¡¥
-
-Methods:
-
-@ftable @code
-
-@item collect @{|@var{item}|@dots{}@}
-
-³ÆÍ×ÁǤËÂФ·¤Æ¥Ö¥í¥Ã¥¯¤òɾ²Á¤·¤¿·ë²Ì¤òÁ´¤Æ´Þ¤àÇÛÎó¤òÊÖ¤¹
-
-@item find @{|@var{item}|@dots{}@}
-
-Í×ÁǤËÂФ·¤Æ¥Ö¥í¥Ã¥¯¤òɾ²Á¤·¤¿Ãͤ¬¿¿¤Ë¤Ê¤Ã¤¿ºÇ½é¤ÎÍ×ÁǤòÊÖ¤¹¡¥
-
-@item find_all @{|@var{item}|@dots{}@}
-
-³ÆÍ×ÁǤËÂФ·¤Æ¥Ö¥í¥Ã¥¯¤òɾ²Á¤·¤¿Ãͤ¬¿¿¤Ç¤¢¤Ã¤¿Í×ÁǤòÁ´¤Æ´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥
-
-@item grep(pattern)
-@itemx grep(pattern) @{|@var{item}|@dots{}@}
-
-@code{Í×ÁÇ =~ @var{pattern}}¤¬À®Î©¤¹¤ëÁ´¤Æ¤ÎÍ×ÁǤò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥¥¤¥Æ
-¥ì¡¼¥¿¤È¤·¤ÆÍѤ¤¤é¤ì¤¿»þ¤Ï¾åµ­¤Î¾ò·ï¤ÎÀ®Î©¤·¤¿Í×ÁǤËÂФ·¤Æ¥Ö¥í¥Ã¥¯¤ò¼Â
-¹Ô¤¹¤ë¡¥
-
-@item member?(@var{val})
-
-@var{val}¤È@code{==}¤Î´Ø·¸¤Ë¤¢¤ëÍ×ÁǤò»ý¤Ä»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item index(@var{val})
-
-@var{val}¤È@code{==}¤Î´Ø·¸¤Ë¤¢¤ë¥ª¥Ö¥¸¥§¥¯¥È¤¬²¿ÈÖÌܤ˸½¤ì¤¿¤«¤òÊÖ¤¹¡¥
-°ìÈֺǽé¤ÎÍ×ÁǤ¬0¤Ë¤Ê¤ë¡¥Í×ÁǤ¬Â¸ºß¤·¤Ê¤¤»þ¤Ë¤Ï@code{nil}¤òÊÖ¤¹¡¥½ç½ø
-¤Î¤Ê¤¤¥¯¥é¥¹¤ËÂФ·¤Æ¤Ï¤¢¤Þ¤ê°ÕÌ£¤¬¤Ê¤¤¡¥
-
-@item length
-
-Í×ÁǤοô¤òÊÖ¤¹¡¥
-
-@item min
-
-ºÇ¾®¤ÎÍ×ÁǤòÊÖ¤¹¡¥Á´¤Æ¤ÎÍ×ÁǤ¬¤ª¸ß¤¤¤Ë@code{<=>}¥á¥½¥Ã¥É¤ÇÈæ³Ó¤Ç¤­¤ë¤³
-¤È¤ò²¾Äꤷ¤Æ¤¤¤ë¡¥
-
-@item max
-
-ºÇÂç¤ÎÍ×ÁǤòÊÖ¤¹¡¥³ÆÍ×ÁǤ¬@code{<=>}¥á¥½¥Ã¥É¤ÇÈæ³Ó¤Ç¤­¤ë¤³¤È¤ò²¾Äꤷ¤Æ
-¤¤¤ë¡¥
-
-@item reverse
-
-Á´¤Æ¤ÎÍ×ÁǤòµÕ½ç¤Ëʤ٤¿ÇÛÎó¤òÊÖ¤¹¡¥
-
-@item sort
-@itemx sort @{|@var{a}, @var{b}|@dots{}@}
-
-Á´¤Æ¤ÎÍ×ÁǤò¥½¡¼¥È¤·¤¿ÇÛÎó¤òÊÖ¤¹¡¥
-@end ftable
-
-@node File, FileTest, Enumerable, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section File
-
-¥Õ¥¡¥¤¥ë¥¢¥¯¥»¥¹¤Î¤¿¤á¤Î¥¯¥é¥¹¡¥¥á¥½¥Ã¥É@code{open}¤ÇÀ¸À®¤µ¤ì¤ë¡¥¤Þ¤¿¡¤
-¤³¤Î¥¯¥é¥¹¤ÎÆðۥ᥽¥Ã¥É¤È¤·¤Æ@code{test}¤Î¥Õ¥¡¥¤¥ë¥Æ¥¹¥È±é»»»ÒÁêÅö¤Î
-¥á¥½¥Ã¥É¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë(@code{FileTest}¥â¥¸¥å¡¼¥ë¤Î¥á¥½¥Ã¥É·´)¡¥
-
-SuperClass: IO
-
-Methods:
-
-@ftable @code
-
-@item atime
-
-¥Õ¥¡¥¤¥ë¤ÎºÇ½ª¥¢¥¯¥»¥¹»þ¹ï¤òÊÖ¤¹¡¥
-
-@item ctime
-
-¥Õ¥¡¥¤¥ë¤ÎºÇ½ª¥¹¥Æ¡¼¥¿¥¹Êѹ¹»þ¹ï¤òÊÖ¤¹¡¥
-
-@item chmod(@var{mode})
-
-¥Õ¥¡¥¤¥ë¤Î¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤òÊѹ¹¤¹¤ë(cf @samp{chmod(2)})¡¥
-
-@item chown(@var{owner}, @var{group})
-
-¥Õ¥¡¥¤¥ë¤Î½êÍ­¼Ô¤È¥°¥ë¡¼¥×¤òÊѹ¹¤¹¤ë(cf @samp{chown(2)})¡¥@code{nil}¤«
-@code{-1}¤ò»ØÄꤹ¤ë¤³¤È¤Ë¤è¤Ã¤Æ½êÍ­¼Ô¤ä¥°¥ë¡¼¥×¤ò¸½ºß¤Î¤Þ¤ÞÊѤ¨¤Ê¤¤¤Ç
-¤ª¤¯¤³¤È¤¬¤Ç¤­¤ë¡¥
-
-@item eof
-@itemx eof?
-
-¥Õ¥¡¥¤¥ë¤Î½ªÃ¼¤ËÅþ㤷¤¿»þ¤Ë¿¿¤òÊÖ¤¹¡¥
-
-@item lstat
-
-¥Õ¥¡¥¤¥ë¤Ë´Ø¤¹¤ë@code{Stat}¹½Â¤ÂΤòÊÖ¤¹¡¥@code{lstat}¤Ï¥Õ¥¡¥¤¥ë¤¬¥·¥ó
-¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤Ç¤¢¤ì¤Ð¥ê¥ó¥¯¤½¤Î¤â¤Î¤Ë´Ø¤¹¤ë@code{Stat}¹½Â¤ÂΤòÊÖ¤¹¡¥
-¹½Â¤ÂΤÎÆâÍƤˤĤ¤¤Æ¤Ï@code{stat}¤ò»²¾È¤Î¤³¤È¡¥
-
-@item mtime
-
-¥Õ¥¡¥¤¥ë¤ÎºÇ½ª½¤Àµ»þ¹ï¤òÊÖ¤¹¡¥
-
-@item rewind
-
-¥Õ¥¡¥¤¥ë¤Î¥Õ¥¡¥¤¥ë¥Ý¥¤¥ó¥¿¤Î°ÌÃÖ¤òÀèƬ¤Ë°ÜÆ°¤¹¤ë¡¥
-
-@item path
-
-¥Õ¥¡¥¤¥ë¤Î¥Ñ¥¹Ì¾¤òÊÖ¤¹¡¥
-
-@item seek(@var{offset}, @var{ptrname})
-
-¥Õ¥¡¥¤¥ë¤Î¥Õ¥¡¥¤¥ë¥Ý¥¤¥ó¥¿¤Î°ÌÃÖ¤ò@var{offset}¤Ë°ÜÆ°¤¹¤ë¡¥
-@var{ptrname}¤Ï0¡¤1¡¤2¤Î¤¤¤º¤ì¤«¤Ç¤¢¤Ã¤Æ¡¤¤½¤ì¤¾¤ì¥Õ¥¡¥¤¥ë¤ÎÀèƬ¡¤¸½ºß
-°ÌÃÖ¡¤¥Õ¥¡¥¤¥ë¤Î½ªÃ¼¤«¤é¤ÎÁêÂФò¼¨¤¹¡¥
-
-@item stat
-
-¥Õ¥¡¥¤¥ë¤Ë´Ø¤¹¤ë@code{Stat}¹½Â¤ÂΤòÊÖ¤¹(@xref{Struct})¡¥
-
-@display
-struct stat
- dev # ¥Õ¥¡¥¤¥ë¤Î¸ºß¤¹¤ë¥Ç¥Ð¥¤¥¹
- ino # ¥Õ¥¡¥¤¥ë¤Îi-nodeÈÖ¹æ
- mode # ¥â¡¼¥É
- nlink # ¥Ï¡¼¥É¥ê¥ó¥¯¤Î¿ô
- uid # ½êÍ­¼Ô¤Î¥æ¡¼¥¶ID
- gid # ½êÍ­¼Ô¤Î¥°¥ë¡¼¥×ID
- rdev # ¥Ç¥Ð¥¤¥¹¤ÎID(¥¹¥Ú¥·¥ã¥ë¥Õ¥¡¥¤¥ë¤Î¤ß)
- size # ¥Õ¥¡¥¤¥ë¥µ¥¤¥º(byte¿ô)
- blksize # ¥Õ¥¡¥¤¥ë¥·¥¹¥Æ¥à¤Ë¤ª¤¤¤ÆŬÀڤʥ֥í¥Ã¥¯¥µ¥¤¥º
- blocks # ¥Ö¥í¥Ã¥¯¿ô
- atime # ºÇ½ª¥¢¥¯¥»¥¹»þ´Ö
- mtime # ºÇ½ª¹¹¿·»þ´Ö
- ctime # ºÇ½ª¾õÂÖÊѹ¹»þ´Ö
-end
-@end display
-
-¾ÜºÙ¤ÊÀâÌÀ¤Ï@samp{stat(2)}¤ò»²¾È¤Î¤³¤È¡¥¥·¥¹¥Æ¥à¾å¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë
-@code{Stat}¹½Â¤ÂΤ˳ºÅö¤¹¤ë¥á¥ó¥Ð¤¬¤Ê¤¤¾ì¹ç¤Ï0¤¬ÀßÄꤵ¤ì¤Æ¤¤¤ë¡¥
-
-@item tell
-
-¥Õ¥¡¥¤¥ë¤Î¸½ºß¤Î¥Õ¥¡¥¤¥ë¥Ý¥¤¥ó¥¿¤Î°ÌÃÖ¤òÊÖ¤¹¡¥
-
-@item truncate(@var{length})
-
-¥Õ¥¡¥¤¥ë¤òÀÚ¤ê¼Î¤Æ¤ÆºÇÂç@var{length}¥Ð¥¤¥È¤Ë¤¹¤ë¡¥¥Õ¥¡¥¤¥ë¤Ï
-@code{write}¥â¡¼¥É¤Ç¥ª¡¼¥×¥ó¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¥
-
-Single Methods:
-
-@item atime(@var{filename})
-
-@var{filename}¤ÎºÇ½ª¥¢¥¯¥»¥¹»þ¹ï¤òÊÖ¤¹¡¥
-
-@item basename(@var{filename}[, @var{suffix}])
-
-@var{filename}¤ÎºÇ¸å¤ÎÍ×ÁǤòÊÖ¤¹¡¥@var{suffix}¤¬Í¿¤¨¤é¤ì¤¿¾ì¹ç¤Ï¡¤¤½¤Î
-³ÈÄ¥»Ò¤â¼è¤ê½ü¤¯¡¥
-
-@example
-basename("ruby/ruby.c")
- @result{} "ruby.c"
-basename("ruby/ruby.c", ".c")
- @result{} "ruby"
-@end example
-
-@item ctime(@var{filename})
-
-@var{filename}¤ÎºÇ½ª¥¹¥Æ¡¼¥¿¥¹Êѹ¹»þ¹ï¤òÊÖ¤¹¡¥
-
-@item chmod(@var{mode}, @var{path}, @var{file}@dots{})
-
-¥Õ¥¡¥¤¥ë¤Î¥Ñ¡¼¥ß¥Ã¥·¥ç¥ó¤òÊѹ¹¤¹¤ë(cf @samp{chmod(2)})¡¥Êѹ¹¤·¤¿¥Õ¥¡¥¤
-¥ë¿ô¤òÊÖ¤¹¡¥
-
-@item chown(@var{owner}, @var{group}, @var{file}@dots{})
-
-¥Õ¥¡¥¤¥ë¤Î½êÍ­¼Ô¤È¥°¥ë¡¼¥×¤òÊѹ¹¤¹¤ë(cf @samp{chown(2)})¡¥@code{nil}¤«
-@code{-1}¤ò»ØÄꤹ¤ë¤³¤È¤Ë¤è¤Ã¤Æ½êÍ­¼Ô¤ä¥°¥ë¡¼¥×¤ò¸½ºß¤Î¤Þ¤ÞÊѤ¨¤Ê¤¤¤Ç
-¤ª¤¯¤³¤È¤¬¤Ç¤­¤ë¡¥Êѹ¹¤·¤¿¥Õ¥¡¥¤¥ë¿ô¤òÊÖ¤¹¡¥
-
-@item dirname(@var{fname})
-
-¥Õ¥¡¥¤¥ë̾¤ÎºÇ¸å¤ÎÍ×Áǰʳ°¤òÊÖ¤¹¡¥
-
-@item expand_path(@var{path})
-
-¥Õ¥¡¥¤¥ë̾¤òÀäÂХѥ¹¤ËŸ³«¤¹¤ë¡¥@samp{~}¤Ï¥Û¡¼¥à¥Ç¥£¥ì¥¯¥È¥ê¤ËŸ³«¤µ¤ì
-¤ë¡¥
-
-@example
-expand_file_name("..")
- @result{} "/home/matz/work"
-expand_file_name("~")
- @result{} "/home/matz"
-expand_file_name("~matz")
- @result{} "/home/matz"
-@end example
-
-@item link(@var{old}, @var{new})
-
-@var{old}¤Ø¤Î¥Ï¡¼¥É¥ê¥ó¥¯@var{new}¤òÀ¸À®¤¹¤ë¡¥@samp{link(2)}¤ÈƱ¤¸À©¸Â
-¤¬¤¢¤ë¡¥
-
-@item mtime(@var{filename})
-
-@var{filename}¤ÎºÇ½ª½¤Àµ»þ¹ï¤òÊÖ¤¹¡¥
-
-@item readlink(@var{path})
-
-¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯@var{path}¤ÎÆâÍƤòʸ»úÎó¤È¤·¤ÆÊÖ¤¹¡¥
-
-@item rename(@var{from}, @var{to})
-
-¥Õ¥¡¥¤¥ë̾@var{from}¤ò@var{to}¤ËÊѹ¹¤¹¤ë¡¥@samp{rename(2)}»²¾È¡¥´û¤Ë
-@var{to}¤È¤¤¤¦Ì¾Á°¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë»þ¤Ë¤Ï¤Þ¤º¤½¤Î¥Õ¥¡¥¤¥ë¤¬ºï½ü¤µ¤ì
-¤ë¡¥
-
-@item stat(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤Î@code{Stat}¹½Â¤ÂΤòÊÖ¤¹¡¥
-
-@item symlink(@var{old}, @var{new})
-
-@var{old}¤Ø¤Î¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯@var{new}¤òÀ¸À®¤¹¤ë¡¥
-
-@item truncate(@var{path}, @var{length})
-
-@var{path}¤Ç»ØÄꤵ¤ì¤¿¥Õ¥¡¥¤¥ë¤òÀÚ¤ê¼Î¤Æ¤ÆºÇÂç@var{length}¥Ð¥¤¥È¤Ë¤¹¤ë¡¥
-
-@item type(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤Î¥¿¥¤¥×¤òɽ¤¹Ê¸»úÎó¤òÊÖ¤¹¡¥Ê¸»úÎó¤Ï
-@code{"file"}¡¤@code{"directory"}¡¤@code{"characterSpecial"}¡¤
-@code{"blockSpecial"}¡¤@code{"fifo"}¡¤@code{"link"}¡¤@code{"socket"}¤Î
-¤¦¤Á¤Î¤¤¤º¤ì¤«°ì¤Ä¤Ç¤¢¤ë¡¥
-
-@item unlink(@var{file}@dots{})
-
-¥Õ¥¡¥¤¥ë¤òºï½ü¤¹¤ë¡¥¥Ç¥£¥ì¥¯¥È¥ê¤Îºï½ü¤Ë¤Ï@code{Dir.rmdir}¤ò»È¤¦¤³¤È¡¥
-
-@item utime(@var{atime}, @var{mtime}, @var{file}@dots{})
-
-¥Õ¥¡¥¤¥ë¤Î¥¢¥¯¥»¥¹»þ¹ï¤ò@var{atime}¤Ë¡¤½¤Àµ»þ¹ï¤ò@var{mtime}¤ËÀßÄꤹ¤ë¡¥
-@var{atime}¡¤@var{mtime}¤Ï¿ô¤Þ¤¿¤Ï@code{Time}¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤Ê
-¤±¤ì¤Ð¤Ê¤é¤Ê¤¤¡¥
-@end ftable
-
-¤³¤ì°Ê³°¤Ë@code{FileTest}¥â¥¸¥å¡¼¥ë¤Î¥á¥½¥Ã¥É¤âÆðۥ᥽¥Ã¥É¤È¤·¤Æ»ý¤Ä¡¥
-
-@xref{IO}
-
-@node FileTest, Fixnum, File, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section FileTest
-
-¥Õ¥¡¥¤¥ë¥Æ¥¹¥ÈÍѥ᥽¥Ã¥É¤ò½¸¤á¤¿¥â¥¸¥å¡¼¥ë¡¥¥¤¥ó¥¯¥ë¡¼¥É¤·¤ÆÍѤ¤¤ë¤³¤È
-¤â¤Ç¤­¤ë¡¥¤³¤Î¥â¥¸¥å¡¼¥ë¤Î¥á¥½¥Ã¥É¤Ë¥Õ¥¡¥¤¥ë̾¤È¤·¤Æ@code{"&"}¤ò»ØÄꤹ
-¤ë¤È¡¤Ä¾Á°¤Î¥Õ¥¡¥¤¥ë¤Ø¤Î@samp{stat(2)}¤Î·ë²Ì¤òºÆÍøÍѤ¹¤ë¡¥
-
-Methods:
-Single Methods:
-
-@ftable @code
-@item blockdev?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬¥Ö¥í¥Ã¥¯¥¹¥Ú¥·¥ã¥ë¥Õ¥¡¥¤¥ë¤Ç¤¢¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item chardev?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬¥­¥ã¥é¥¯¥¿¥¹¥Ú¥·¥ã¥ë¥Õ¥¡¥¤¥ë¤Ç¤¢¤ë»þ¡¤¿¿¤òÊÖ
-¤¹¡¥
-
-@item executable?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬¼Â¹Ô²Äǽ¤Î»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item executable_real?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬¼Âuid/gid¤Ç¼Â¹Ô²Äǽ¤Î»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item exists?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item grpowned?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤Îgid¤¬¼Â¸ú¥°¥ë¡¼¥×¤Îgid¤ÈƱ¤¸»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item directory?(@var{filename})
-
-@var{filename}¤¬¥Ç¥£¥ì¥¯¥È¥ê¤Î»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item file?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬Ä̾ï¥Õ¥¡¥¤¥ë¤Î»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item link?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤Ç¤¢¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item pipe?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬Ì¾Á°¤Ä¤­¥Ñ¥¤¥×(@code{FIFO})¤Ç¤¢¤ë»þ¡¤¿¿¤òÊÖ
-¤¹¡¥
-
-@item socket?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬¥½¥±¥Ã¥È¤Ç¤¢¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item owned?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤ò¼Â¸ú¥æ¡¼¥¶¤¬½êÍ­¤·¤Æ¤¤¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item readable?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤òÆɤߤȤê²Äǽ¤Î»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item readable_real?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤ò¼Âuid/gid¤ÇÆɤߤȤê²Äǽ¤Î»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item setuid?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤Îsetuid¥Ó¥Ã¥È¤¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item setgid?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤Îsetgid¥Ó¥Ã¥È¤¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item size(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤¹¤ë»þ¡¤¥Õ¥¡¥¤¥ë¤ÎÂ礭¤µ¤òÊÖ¤¹¡¥Â¸ºß¤·¤Ê
-¤¤»þ¤Ï@code{nil}¤òÊÖ¤¹¡¥
-
-@item sticky?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤Îsticky¥Ó¥Ã¥È¤¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item symlink?(@var{filename})
-
-@var{filename}¤¬¥·¥ó¥Ü¥ê¥Ã¥¯¥ê¥ó¥¯¤Ç¤¢¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item writable?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬¼Âuid/gid¤Ç½ñ¤­¹þ¤ß²Äǽ¤Î»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item writable_real?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬½ñ¤­¹þ¤ß²Äǽ¤Î»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item zero?(@var{filename})
-
-@var{filename}¤Î¥Õ¥¡¥¤¥ë¤¬Â¸ºß¤·¡¤Â礭¤µ¤¬0¤Ç¤¢¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-@end ftable
-
-@node Fixnum, Float, FileTest, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Fixnum
-
-31bit(¥Þ¥·¥ó¤Îlong¤ÎŤµ-1 bit)À°¿ô¤Î¥¯¥é¥¹¡¥builtin class¤Ç¤¢¤ë¡¥¤³¤Î
-¥¯¥é¥¹¤ÏpointerÆâ¤Î¨ÃͤǤ¢¤ë¤¿¤ácall by value¤Ç¸Æ¤Ó½Ð¤µ¤ì¤ëÅÀ¤¬ÆÃħŪ
-¤Ç¤¢¤ë(¾¤Î¥¯¥é¥¹¤Ïcall by reference)¡¥±é»»¤Î·ë²Ì¤¬31bit¤ò±Û¤¨¤ë¾ì¹ç¤Ë
-¤Ï¼«Æ°Åª¤Ë@code{Bignum}(̵¸Â¿ÇÜĹÀ°¿ô)¤Ë³ÈÄ¥¤µ¤ì¤ë¡¥
-
-¥¤¥Æ¥ì¡¼¥¿@code{upto}¡¤@code{downto}¡¤@code{step}¤Ï·«¤êÊÖ¤·¤Î¤¿¤á¤ËÍÑ
-¤¤¤é¤ì¡¤°ìÈ̤Ë@code{Range}¥¯¥é¥¹¤òÍѤ¤¤ë¤è¤ê¹â®¤Ç¤¢¤ë¡¥
-
-SuperClass: Integer
-
-Methods:
-
-@ftable @code
-@item self + @var{other}
-@itemx self - @var{other}
-@itemx self * @var{other}
-@itemx self / @var{other}
-@itemx self % @var{other}
-@itemx self ** @var{other}
-
-»»½Ñ±é»»¡¥¤½¤ì¤¾¤ìÏ¡¤º¹¡¤ÀÑ¡¤¾¦¡¤¾ê;¡¤ÑѾè¤òÊÖ¤¹¡¥
-
-@item ~ self
-@itemx self | @var{other}
-@itemx self & @var{other}
-@itemx self ^ @var{other}
-
-¥Ó¥Ã¥È±é»»¡¥¤½¤ì¤¾¤ì¥Ó¥Ã¥Èȿž¡¤ÏÀÍýÏ¡¤ÏÀÍýÀÑ¡¤ÇÓ¾ŪÏÀÍýϤòÊÖ¤¹¡¥
-
-@item self << @var{bits}
-@itemx self >> @var{bits}
-
-¥·¥Õ¥È±é»»¡¥¤½¤ì¤¾¤ì@var{bits}¥Ó¥Ã¥È¤À¤±º¸±¦¤Ë¥Ó¥Ã¥È¥·¥Õ¥È¤ò¹Ô¤Ê¤¦¡¥
-
-@item downto(@var{min}) @{@dots{}@}
-
-¥¤¥Æ¥ì¡¼¥¿¡¥@code{self}¤«¤é@var{min}¤Þ¤Ç²¼¸þ¤­¤Ë·«¤êÊÖ¤¹¡¥
-
-@item id2name
-
-À°¿ôÃͤòID¤À¤È¤ß¤Ê¤·¤Æ¡¤ÁêÅö¤¹¤ëʸ»úÎó¤òÊÖ¤¹¡¥ÁêÅö¤¹¤ëʸ»úÎó¤¬Â¸ºß¤·¤Ê
-¤¤¾ì¹ç¤Ï@code{nil}¤òÊÖ¤¹¡¥
-
-@item step(@var{max}, @var{step}) @{@dots{}@}
-
-¥¤¥Æ¥ì¡¼¥¿¡¥@code{self}¤«¤é@var{max}¤Þ¤Ç@var{step}¤º¤ÄÊѲ½¤·¤Ê¤¬¤é¡¤·«
-¤êÊÖ¤¹¡¥
-
-@item to_f
-
-@code{self}¤ò@code{Float}¤ËÊÑ´¹¤·¤¿¤â¤Î¤òÊÖ¤¹¡¥
-
-@item to_i
-
-@code{self}¤ò¤½¤Î¤Þ¤ÞÊÖ¤¹¡¥
-
-@item upto(@var{max}) @{@dots{}@}
-
-¥¤¥Æ¥ì¡¼¥¿¡¥@code{self}¤«¤é@var{max}¤Þ¤Ç·«¤êÊÖ¤¹¡¥
-@end ftable
-
-@xref{Integer}
-
-@node Float, GC, Fixnum, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Float
-
-ÉâÆ°¾®¿ôÅÀ¿ô¤Î¥¯¥é¥¹¡¥
-
-SuperClass: Numeric
-
-Methods:
-
-@ftable @code
-@item self + @var{other}
-@itemx self - @var{other}
-@itemx self * @var{other}
-@itemx self / @var{other}
-@itemx self % @var{other}
-@itemx self ** @var{other}
-
-»»½Ñ±é»»¡¥¤½¤ì¤¾¤ìÏ¡¤º¹¡¤ÀÑ¡¤¾¦¡¤¾ê;¡¤ÑѾè¤òÊÖ¤¹¡¥
-
-@item self == @var{other}
-@itemx self > @var{other}
-
-Èæ³Ó±é»»¡¥
-
-@item coerce(@var{num})
-
-@var{num}¤ò@code{Float}¤ËÊÑ´¹¤¹¤ë¡¥¤¿¤À¤·¸½»þÅÀ¤Ç@code{Float}¤¬Íý²ò¤Ç
-¤­¤ë¾¤Î¿ô¤Ï@code{Fixnum}¤È@code{Bignum}¤À¤±¤Ç¤¢¤ë¡¥
-
-@item to_f
-
-@code{self}¤ò¤½¤Î¤Þ¤ÞÊÖ¤¹¡¥
-
-@item to_i
-
-@code{self}¤òÀ°¿ô¤ËÊÑ´¹¤·¤¿·ë²Ì¤òÊÖ¤¹¡¥
-@end ftable
-
-Single Methods:
-
-@ftable @code
-@item new(@var{float})
-
-@var{float}¤ÈƱ¤¸Ãͤò»ý¤Ä¿·¤·¤¤@code{Float}¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡¥
-@end ftable
-
-@xref{Numeric}
-
-@node GC, Hash, Float, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section GC
-
-RubyÁȤ߹þ¤ß¤Îgarbage collector¤ÎÀ©¸æ¤ò¹Ô¤Ê¤¦¤¿¤á¤Î¥â¥¸¥å¡¼¥ë¡¥¤³¤Î¥â
-¥¸¥å¡¼¥ë¤Î¥á¥½¥Ã¥É¤ò¤òÍѤ¤¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¤°ì»þŪ¤ËGC¤ò»ß¤á¤¿¤ê¡¤GC¤Îµ¯
-¤­¤ë¥¿¥¤¥ß¥ó¥°¤òÀ©¸æ¤·¤¿¤ê¤Ç¤­¤ë¡¥
-
-Methods:
-
-@ftable @code
-@item garbage_collect
-
-GC¤ò³«»Ï¤¹¤ë¡¥@code{GC.start}¤ÈƱµÁ¡¥
-@end ftable
-
-Single Methods:
-
-@ftable @code
-@item disable
-
-GC¤ò¶Ø»ß¤¹¤ë¡¥
-
-@item enable
-
-GC¤òµö²Ä¤¹¤ë¡¥
-
-@item start
-
-GC¤ò³«»Ï¤¹¤ë¡¥
-@end ftable
-
-@node Hash, Integer, GC, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Hash
-
-Ï¢ÁÛÇÛÎ󤢤뤤¤Ï¥Ï¥Ã¥·¥åɽ¡¥Ç¤°Õ¤Î¥ª¥Ö¥¸¥§¥¯¥È¤òź»ú¤È¤Ç¤­¤ëÇÛÎó¤Î¥¯¥é
-¥¹¤Ç¤¢¤ë¡¥Ï¢ÁÛÇÛÎ󥪥֥¸¥§¥¯¥È¤ÎÀ¸À®¤Ï°ìÈÌŪ¤Ë¤ÏÏ¢ÁÛÇÛÎó¼°
-
-@display
-{a=>b,@dots{}}
-@end display
-
-¤Ç¹Ô¤Ê¤ï¤ì¤ë¡¥
-
-¥­¡¼¤È¤·¤ÆÍ¿¤¨¤¿¥ª¥Ö¥¸¥§¥¯¥È¤ÎÆâÍƤ¬ÊѲ½¤·¡¤¥á¥½¥Ã¥É@code{hash}¤ÎÊÖ¤¹
-Ãͤ¬ÊѤï¤ë¤È@code{Hash}¤ÏÀµ¾ï¤ËÆ°ºî¤·¤Ê¤¤(Ãͤ¬¼è¤ê½Ð¤»¤Ê¤¯¤Ê¤ë)¡¥ÆâÍÆ
-¤Ë¤è¤Ã¤Æ@code{hash}¤ÎÃͤ¬ÊѲ½¤¹¤ë¥¯¥é¥¹(¤¿¤È¤¨¤Ð@code{Array},
-@code{Hash}¤Ê¤É)¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ï¥­¡¼¤Ë¸þ¤«¤Ê¤¤¡¥¤¿¤À¤·¡¤ÆâÍƤ¬
-@code{hash}¤ÎÃͤ˱ƶÁ¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤Î¤¦¤Á¡¤Ê¸»úÎó¤À¤±¤ÏÆÃÊ̤˰·¤ï¤ì
-¤ë¡¥Ê¸»úÎó¤ò¥­¡¼¤È¤·¤ÆÍ¿¤¨¤ë¤È¡¤Ê¸»úÎó¤ò¥³¥Ô¡¼¤·¡¤¥³¥Ô¡¼¤ò¹¹¿·ÉԲĤËÀß
-Äꤷ¤¿¾å¤Ç¡¤¥­¡¼¤È¤·¤Æ»ÈÍѤ¹¤ë¡¥¤è¤Ã¤Æ¡¤¸µ¤Îʸ»úÎó¤ò¹¹¿·¤·¤Æ¤â¥­¡¼¤Îʸ
-»úÎó¤ÏÊѲ½¤·¤Ê¤¤¡¥@code{each}, @code{each_key}, @code{keys}¤Ê¤É¤Î¥á¥½¥Ã
-¥É¤¬¥­¡¼¤È¤·¤Æʸ»úÎó¤òÊÖ¤¹»þ¡¤¤½¤Îʸ»úÎó¤Ï¹¹¿·¤Ç¤­¤Ê¤¤(Îã³°¤¬È¯À¸¤¹¤ë)¡¥
-
-SuperClass: Object
-
-Included Modules: Enumerable
-
-Methods:
-
-@ftable @code
-@item self [@var{key}]
-
-@var{key}¤ò¥­¡¼¤È¤¹¤ëÃͤòÊÖ¤¹¡¥
-
-@item self [@var{key}]= @var{value}
-
-@var{key}¤ò¥­¡¼¤È¤·¤Æ¡¤@var{value}¤ò³ÊǼ¤¹¤ë¡¥@var{value}¤È¤·¤Æ
-@code{nil}¤ò»ØÄꤹ¤ë¤È¤½¤Î@var{key}¤ËÂФ¹¤ë¹àÌܤκï½ü¤È¤Ê¤ë¡¥¤Ä¤Þ¤ê¡¤
-@code{Hash}¤ÏÃͤȤ·¤Æ@code{nil}¤ò»ý¤Ä¤³¤È¤Ï¤Ç¤­¤Ê¤¤¡¥
-
-@item clear
-
-Ï¢ÁÛÇÛÎó¤ò¶õ¤Ë¤¹¤ë¡¥
-
-@item delete(@var{key})
-
-@var{key}¤ò¥­¡¼¤È¤¹¤ëÁȤòºï½ü¤¹¤ë¡¥
-
-@item delete_if @{|@var{item}|@dots{}@}
-
-Í×ÁǤòºï½ü¤¹¤ë¥¤¥Æ¥ì¡¼¥¿¡¥@code{[key,value]}¤È¤¤¤¦ÇÛÎó¤òÍ¿¤¨¤Æ¡¤¥Ö¥í¥Ã
-¥¯¤òɾ²Á¤·¤¿Ãͤ¬¿¿¤Î»þ¡¤³ºÅö¤¹¤ë¹àÌܤòºï½ü¤¹¤ë¡¥
-
-@item each @{|@var{key}, @var{value}|@dots{}@}
-@itemx each_pair @{|@var{key}, @var{value}|@dots{}@}
-
-@code{[key,value]}¤Ê¤ë2Í×ÁǤÎÇÛÎó¤òÍ¿¤¨¤ë¥¤¥Æ¥ì¡¼¥¿¡¥
-
-@item each_key @{|@var{key}|@dots{}@}
-
-Á´¤Æ¤Îkey¤ËÂФ·¤Æ·«¤êÊÖ¤¹¥¤¥Æ¥ì¡¼¥¿¡¥
-
-@item each_value @{|@var{value}|@dots{}@}
-
-Á´¤Æ¤Îvalue¤ËÂФ·¤Æ·«¤êÊÖ¤¹¥¤¥Æ¥ì¡¼¥¿¡¥
-
-@item has_key?(@var{key})
-
-@var{key}¤ò¥­¡¼¤È¤¹¤ëÁȤ¬Ï¢ÁÛÇÛÎóÃæ¤Ë¸ºß¤¹¤ë»þ¡¤¿¿¤òÊÖ¤¹
-
-@item has_value?(@var{value})
-
-@var{value}¤òÃͤȤ¹¤ëÁȤ¬Ï¢ÁÛÇÛÎóÃæ¤Ë¸ºß¤¹¤ë»þ¡¤¿¿¤òÊÖ¤¹
-
-@item indexes(@var{ary})
-@itemx indexes(@var{key_}1,@dots{}, @var{key_n})
-
-1ÈÖÌܤηÁ¼°¤Ç¤ÏÇÛÎó¤ò°ú¿ô¤È¤·¤Æ¼õ¤±¤Æ¡¤¤½¤ÎÍ×ÁǤò¥­¡¼¤È¤¹¤ëÍ×ÁǤò´Þ¤à
-ÇÛÎó¤òÊÖ¤¹¡¥2ÈÖÌܤηÁ¼°¤Ç¤Ï³Æ°ú¿ô¤ÎÃͤò¥­¡¼¤È¤¹¤ëÍ×ÁǤò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥
-
-@item keys
-
-Ï¢ÁÛÇÛÎóÃæ¤Ë¸ºß¤¹¤ë¥­¡¼Á´¤Æ¤ò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥
-@item length
-@itemx size
-
-Ï¢ÁÛÇÛÎóÃæ¤ÎÍ×ÁǤοô¤òÊÖ¤¹¡¥
-
-@item shift
-
-Ï¢ÁÛÇÛÎóÃæ¤ÎÍ×ÁǤò°ì¤Ä¼è¤ê½Ð¤·(ºï½ü¤·¤Æ)¡¤@code{[key,value]}¤Ê¤ë2Í×ÁÇ
-¤ÎÇÛÎó¤òÊÖ¤¹¡¥
-
-@item to_a
-
-Ï¢ÁÛÇÛÎóÃæ¤Î@code{key-value}2Í×ÁǤÎÇÛÎó¤òÍ×ÁǤȤ¹¤ëÇÛÎó¤òÊÖ¤¹¡¥
-
-@item values
-
-Ï¢ÁÛÇÛÎóÃæ¤Ë¸ºß¤¹¤ëÃÍÁ´¤Æ¤ò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥
-@end ftable
-
-Single Methods:
-
-@ftable @code
-@item Hash[@var{key}, @var{value}@dots{}]
-
-´ñ¿ôÈÖÌܤΰú¿ô¤ò@var{key}¡¤¶ö¿ôÈÖÌܤΰú¿ô¤ò@var{value}¤È¤¹¤ëÏ¢ÁÛÇÛÎó¤ò
-À¸À®¤¹¤ë¡¥
-
-@item new
-
-¿·¤·¤¤(¶õ¤Î)Ï¢ÁÛÇÛÎ󥪥֥¸¥§¥¯¥È¤òÊÖ¤¹¡¥
-@end ftable
-
-@xref{Object}
-@xref{Enumerable}
-
-@node Integer, IO, Hash, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Integer
-
-À°¿ô¥¯¥é¥¹¡¥¼ÂºÝ¤Ï¤½¤ÎÂ礭¤µ¤Ë¤è¤Ã¤Æ@code{Fixnum}¤È@code{Bignum}¤¤¤¦Æó
-¤Ä¤Î¥µ¥Ö¥¯¥é¥¹¤Ç¼Â¸½¤µ¤ì¤Æ¤¤¤ë¡¥@code{Integer}¤Ï¤½¤ì¤é¤Î¥¹¡¼¥Ñ¡¼¥¯¥é¥¹
-¤È¤Ê¤ëÃê¾Ý¥¯¥é¥¹¤Ç¤¢¤ë¡¥Ruby¤Ç¤Ï¤Û¤È¤ó¤É¤Î¾ì¹ç¡¤@code{Fixnum}¤È
-@code{Bignum}¤Î¶èÊ̤ÏɬÍפʤ¯¡¤Áê¸ß¤ÎÊÑ´¹¤Ï¼«Æ°Åª¤Ë¹Ô¤Ê¤ï¤ì¤ë¡¥À°¿ô¤ò
-¥Ó¥Ã¥ÈÎó¤À¤È¤ß¤Ê¤¹¾ì¹ç¤Ë¤Ï¡¤Ìµ¸Â¤ÎŤµ¤ò¤â¤Ä¥Ó¥Ã¥ÈÎó¤È¹Í¤¨¤Æ¹½¤ï¤Ê¤¤¡¥
-
-SuperClass: Numeric
-
-Methods:
-
-@ftable @code
-@item self[@var{idx}]
-
-À°¿ô¤Î@var{idx}¥Ó¥Ã¥ÈÌܤ¬¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤ì¤Ð1¡¤¥»¥Ã¥È¤µ¤ì¤Æ¤¤¤Ê¤±¤ì¤Ð0
-¤òÊÖ¤¹¡¥
-
-@item chr
-
-¤½¤Î¿ô¤ò¥³¡¼¥É¤È¤¹¤ëʸ»ú¤À¤±¤ò´Þ¤à1ʸ»ú¤Îʸ»úÎó¤òÊÖ¤¹¡¥°ìÈ̤ËŤµ1°Ê¾å
-¤Îʸ»úÎó¤Ë¤Ä¤¤¤Æ¡¤¼¡¤Î´Ø·¸¤¬¾ï¤ËÀ®Î©¤¹¤ë¡¥
-
-@example
-str[0].chr == str[0,1]
-@end example
-
-À°¿ô¤¬Ê¸»ú¤ÎÈÏ°ÏÆâ(0@dots{}255)¤Ë¤Ê¤±¤ì¤ÐÎã³°¤¬È¯À¸¤¹¤ë¡¥
-
-@item integer?
-
-¤¤¤Ä¤â¿¿¤òÊÖ¤¹¡¥
-@end ftable
-
-@xref{Numeric}
-
-@node IO, Kernel, Integer, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section IO
-
-Æþ½ÐÎϤΤ¿¤á¤Î´ðËÜ¥¯¥é¥¹¡¥
-
-SuperClass: Object
-
-Included Modules: Enumerable
-
-Methods:
-
-@ftable @code
-@item self << @var{object}
-
-@var{object}¤ò½ÐÎϤ¹¤ë¡¥@var{object}¤¬Ê¸»úÎó¤Ç¤Ê¤¤»þ¤Ë¤Ï¥á¥½¥Ã¥É
-@code{to_s}¤òÍѤ¤¤Æʸ»úÎó¤ËÊÑ´¹¤¹¤ë¡¥@code{self}¤òÌá¤êÃͤȤ¹¤ë¤Î¤Ç¡¤
-@code{C++}¤Î¤è¤¦¤Ê@code{<<}¤ÎÏ¢º¿¤ò»È¤¨¤ë¡¥
-
-Îã
-
-@example
-$stdout << 1 << " is a " << Fixnum << "\n"
-@end example
-
-@item close
-
-Æþ½ÐÎϥݡ¼¥È¤ò¥¯¥í¡¼¥º¤¹¤ë¡¥°Ê¸å¤Î¤³¤Î¥ª¥Ö¥¸¥§¥¯¥È¤ËÂФ¹¤ëÆþ½ÐÎÏÁàºî¤Ï
-¥¨¥é¡¼¤Ë¤Ê¤ë¡¥
-
-@item closed?
-
-¥Ý¡¼¥È¤¬¥¯¥í¡¼¥º¤µ¤ì¤Æ¤¤¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item each @{|@var{line}|@dots{}@}
-@item each_line @{|@var{line}|@dots{}@}
-
-°ì¹Ô¤º¤ÄÆɤ߹þ¤ó¤Ç¤¯¤ë¤¿¤á¤Î¥¤¥Æ¥ì¡¼¥¿¡¥¹Ô¤Î¶èÀÚ¤ê¤Ï¥·¥¹¥Æ¥àÊÑ¿ô
-@code{$/}¤Ë¤è¤Ã¤ÆÊѹ¹¤Ç¤­¤ë¡¥Æɤ߹þ¤ó¤Àʸ»úÎó¤Ï¥·¥¹¥Æ¥àÊÑ¿ô@code{$_}¤Ë
-¤â¥»¥Ã¥È¤µ¤ì¤ë¡¥
-
-@itemx each_byte @{|@var{ch}|@dots{}@}
-
-°ìʸ»ú¤º¤ÄÆɤ߹þ¤ó¤Ç¤¯¤ë¤¿¤á¤Î¥¤¥Æ¥ì¡¼¥¿¡¥Ê¸»ú¤Ïʸ»ú¥³¡¼¥É¤òɽ¤¹
-@code{Fixnum}¤Ç¤¢¤ë¡¥
-
-@item fileno
-@itemx to_i
-
-@code{IO}¥ª¥Ö¥¸¥§¥¯¥È¤¬»È¤Ã¤Æ¤¤¤ë¥Õ¥¡¥¤¥ë¥Ç¥£¥¹¥¯¥ê¥×¥¿(@code{Fixnum})
-¤òÊÖ¤¹¡¥
-
-@item flush
-
-¥Ð¥Ã¥Õ¥¡¤ò¥Õ¥é¥Ã¥·¥å¤¹¤ë¡¥
-
-@item getc
-
-°ì¹ÔÆɤ߹þ¤ó¤Ç¡¤Æɤ߹þ¤ß¤ËÀ®¸ù¤·¤¿»þ¤Ë¤Ï¤½¤Îʸ»úÎó¤òÊÖ¤¹¡¥¥Õ¥¡¥¤¥ë¤Î½ª
-¤ê¤ËÅþ㤷¤¿»þ¤Ë¤Ï@code{nil}¤òÊÖ¤¹¡¥¥«¡¼¥Í¥ë¥á¥½¥Ã¥É@code{getc}¤Ï
-@code{$stdin.getc}¤ÈƱ¤¸°ÕÌ£¤Ç¤¢¤ë¡¥
-
-@item gets
-
-°ì¹ÔÆɤ߹þ¤ó¤Ç¡¤Æɤ߹þ¤ß¤ËÀ®¸ù¤·¤¿»þ¤Ë¤Ï¤½¤Îʸ»úÎó¤òÊÖ¤¹¡¥¥Õ¥¡¥¤¥ë¤Î½ª
-¤ê¤ËÅþ㤷¤¿»þ¤Ë¤Ï@code{nil}¤òÊÖ¤¹¡¥
-
-@item isatty
-@itemx tty?
-
-Æþ½ÐÎϥݡ¼¥È¤¬tty¤Ç¤¢¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item print(@var{arg}@dots{})
-
-°ú¿ô¤ò½ç¤Ë½ÐÎϤ¹¤ë¡¥½ÐÎÏÀ褬@code{$>}¤Ç¤Ê¤¯¡¤¥ì¥·¡¼¥Ð¤Ç¤¢¤ë°Ê³°¤Ï
-@code{Kernel}¥¯¥é¥¹¤Î@code{print}¥á¥½¥Ã¥É¤ÈƱ¤¸Æ°ºî¤ò¤¹¤ë¡¥
-
-@item printf(@var{format}, @var{arg}@dots{})
-
-@code{C}¸À¸ì¤Î@code{printf()}¤ÈƱ¤¸@var{format}¤Ë½¾¤¤°ú¿ô¤òʸ»úÎó¤ËÊÑ
-´¹¤·¡¤¥ì¥·¡¼¥Ð¤Ë½ÐÎϤ¹¤ë¡¥
-
-@item puts(@var{obj})
-
-@var{obj}¤ò½ÐÎϤ¹¤ë¡¥@code{self << obj}¤ÈƱ¤¸°ÕÌ£¤Ç¤¢¤ë¡¥
-
-@item read([@var{length}])
-
-@var{length}¥Ð¥¤¥ÈÆɤ߹þ¤ó¤Ç¡¤¤½¤Îʸ»úÎó¤òÊÖ¤¹¡¥@var{length}¤¬¾Êά¤µ¤ì
-¤¿»þ¤Ë¤Ï¡¤@code{EOF}¤Þ¤Ç¤ÎÁ´¤Æ¤Î¥Ç¡¼¥¿¤òÆɤ߹þ¤à¡¥
-
-@item readlines
-
-¥Õ¥¡¥¤¥ë¤òÁ´¤ÆÆɤ߹þ¤ó¤Ç³Æ¹Ô¤òÍ×ÁǤȤ·¤Æ¤â¤ÄÇÛÎó¤òÊÖ¤¹¡¥
-
-@item sync
-
-¸½ºß¤Î½ÐÎÏƱ´ü¥â¡¼¥É¤ò¿¿µ¶ÃͤÇÊÖ¤¹¡¥Æ±´ü¥â¡¼¥É¤¬¿¿¤Î»þ¤Ï½ÐÎÏ´Ø¿ô¤Î¸Æ½Ð
-Ëè¤Ë¥Ð¥Ã¥Õ¥¡¤¬¥Õ¥é¥Ã¥·¥å¤µ¤ì¤ë¡¥
-
-@item sync= @var{newstate}
-
-½ÐÎÏƱ´ü¥â¡¼¥É¤òÀßÄꤹ¤ë¡¥
-
-@item sysread(@var{length})
-
-@samp{stdio}¤ò·Ðͳ¤»¤º¤Ë@samp{read(2)}¤òÍѤ¤¤ÆÆþÎϤò¹Ô¤Ê¤¦¡¥ÆþÎϤµ¤ì¤¿
-¥Ç¡¼¥¿¤ò´Þ¤àʸ»úÎó¤òÊÖ¤¹¡¥¥Õ¥¡¥¤¥ë¤Î½ª¤ê¤ËÅþ㤷¤¿»þ¤Ë¤Ï@code{nil}¤òÊÖ
-¤¹¡¥@samp{read(2)}¤ÎÀ­¼Á¤Ë¤è¤êɬ¤º@var{length}¥Ð¥¤¥È¤Îʸ»úÎó¤¬Æɤ߹þ¤Þ
-¤ì¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤¡¥@code{gets}¤ä@code{getc}¤Ê¤É@samp{stdio}¤ò·Ðͳ¤¹¤ë¥á
-¥½¥Ã¥É¤Èº®ÍѤ¹¤ë¤³¤È¤Ï¥Ð¥Ã¥Õ¥¡¥ê¥ó¥°¤ÎÉÔÀ°¹ç¤Ê¤É¤Ç»×¤ï¤ÌÆ°ºî¤ò¤¹¤ë¤³¤È
-¤¬¤¢¤ë¡¥
-
-@item syswrite(@var{str})
-
-@samp{stdio}¤ò·Ðͳ¤»¤º¤Ë¡¤@samp{write(2)}¤òÍѤ¤¤Æ½ÐÎϤò¹Ô¤Ê¤¦¡¥¤³¤Î¥á
-¥½¥Ã¥É¤Ï¥Ð¥Ã¥Õ¥¡¥ê¥ó¥°¤Ê¤É@samp{stdio}¤¬¤·¤Æ¤¯¤ì¤ë¤³¤È¤Ï°ìÀڹԤʤï¤Ê¤¤¡¥
-@code{syswrite}¤Ï¼ÂºÝ¤Ë½ñ¤­¹þ¤ó¤À¥Ð¥¤¥È¿ô¤òÊÖ¤¹¡¥@code{print}¤ä
-@code{printf}¤È@code{syswrite}¤òº®ÍѤ¹¤ë¤Î¤Ï¿ä¾©¤Ç¤­¤Ê¤¤¡¥
-
-@item write(@var{str})
-
-@var{str}¤ò½ÐÎϤ¹¤ë¡¥½ÐÎϤ·¤¿¥Ð¥¤¥È¿ô¤òÊÖ¤¹¡¥
-@end ftable
-
-@xref{Object}
-@xref{Enumerable}
-
-@node Kernel, Math, IO, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Kernel
-
-Á´¤Æ¤Î¥¯¥é¥¹¤Î´ðÄ쥯¥é¥¹¡¥RubyÁȤ߹þ¤ß¤ÎÁ´¤Æ¤Î´Ø¿ô¥á¥½¥Ã¥É¤Ï¤³¤Î¥¯¥é¥¹
-¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡¥´Ø¿ô¥á¥½¥Ã¥É¤Ë¤Ä¤¤¤Æ¤Ï¡Ö´Ø¿ô¡×¤Î¹àÌܤò»²¾È¤Î¤³¤È¡¥
-
-SuperClass: ¤Ê¤·
-
-Methods:
-
-@ftable @code
-@item self == @var{other}
-@itemx equal?(@var{other})
-
-¥ª¥Ö¥¸¥§¥¯¥È¤Î°ìÃ×ȽÄê¡¥¥ì¥·¡¼¥Ð¤È°ú¿ô¤Î°ú¿ô¤¬°ìÃפ¹¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-@code{Kernel}¥¯¥é¥¹¤ÎÄêµÁ¤Ç¤ÏÁÐÊý¤Î¥ª¥Ö¥¸¥§¥¯¥È¤¬Æ±°ì¤Î»þ¿¿¤òÊÖ¤¹¡¥
-@code{==}¥á¥½¥Ã¥É¤Ï³Æ¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ­¼Á¤Ë±þ¤¸¤ÆºÆÄêµÁ¤¹¤ëɬÍפ¬¤¢¤ë¡¥
-@code{==}¥á¥½¥Ã¥É¤òºÆÄêµÁ¤·¤¿»þ¤Ë¤Ï¡¤@code{hash}¥á¥½¥Ã¥É¤â¤½¤ì¤Ë¹ç¤ï¤»
-¤ÆºÆÄêµÁ¤¹¤ëɬÍפ¬¤¢¤ë¡¥
-
-equal?¥á¥½¥Ã¥É¤Ï@code{==}¥á¥½¥Ã¥É¤ÎÊÌ̾¤Ç¡¤@code{==}¤òºÆÄêµÁ¤·¤¿¸å¤Ç¤â
-¥ª¥Ö¥¸¥§¥¯¥È¤ÎƱ°ìÀ­È½Äê¤ò¹Ô¤Ê¤¦¤¿¤á¤ËÍѤ¤¤é¤ì¤ë¡¥¤è¤Ã¤Æ@code{equal?}
-¥á¥½¥Ã¥É¤Ï¥µ¥Ö¥¯¥é¥¹¤ÇºÆÄêµÁ¤¹¤ë¤Ù¤­¤Ç¤Ï¤Ê¤¤¡¥
-
-@item self =~ @var{other}
-
-¥Þ¥Ã¥Á¡¥¥Ç¥Õ¥©¥ë¥È¤ÎÆ°ºî¤Ï@code{==}¤ÈƱ¤¸¤Ç¤¢¤ë¡¥@code{=~}¤Ï
-@code{case}ʸ¤Ç¤ÎÈæ³Ó¤Ë¤âÍѤ¤¤é¤ì¤ë¡¥
-
-@item hash
-
-¥ª¥Ö¥¸¥§¥¯¥È¤Î¥Ï¥Ã¥·¥åÃÍ(@code{Fixnum})¤òÊÖ¤¹¡¥@code{Hash}¥¯¥é¥¹¤Ç¥­¡¼
-¤È¤Ê¤ë¥ª¥Ö¥¸¥§¥¯¥È¤ò³ÊǼ¤¹¤ë¤Î¤ËÍѤ¤¤é¤ì¤Æ¤¤¤ë.@code{A == B}¤¬À®Î©¤¹¤ë
-»þ¤Ïɬ¤º@code{A.hash == B.hash}¤¬À®Î©¤¹¤ëɬÍפ¬¤¢¤ë¤Î¤Ç¡¤@code{==}¤òºÆ
-ÄêµÁ¤·¤¿»þ¤Ë¤Ïɬ¤º¤³¤Á¤é¤â¤½¤ì¤Ë¹ç¤ï¤»¤ÆºÆÄêµÁ¤¹¤ë¤³¤È¡¥
-
-@item id
-
-³Æ¥ª¥Ö¥¸¥§¥¯¥È¤ËÂФ·¤Æ°ì°Õ¤Î@code{Fixnum}¤òÊÖ¤¹¡¥¤¬¡¤@code{Fixnum}¤Ï¼«
-ʬ¼«¿È¤òÊÖ¤¹¤Î¤Ç¡¤@code{id}¤¬°ìÃפ·¤Æ¤âƱ¤¸¥ª¥Ö¥¸¥§¥¯¥È¤Ç¤¢¤ë¤³¤È¤ÏÊÝ
-¾Ú¤µ¤ì¤Ê¤¤¡¥¤Ä¤Þ¤ê¡¤@code{obj1.id == obj2.id}¤¬À®Î©¤·¤Æ¤â¡¤¤É¤Á¤é¤«¤¬
-@code{Fixnum}¤Ç¤¢¤ì¤Ð¡¤@code{obj1}¤È@code{obj2}¤¬Æ±¤¸¤Ç¤¢¤ë¤È¤Ï¸Â¤é¤Ê
-¤¤¡¥¤¿¤À¤·¡¤Î¾Êý¤¬@code{Fixnum}¤Ç¤Ê¤¤¤³¤È¤¬ÊݾڤǤ­¤ì¤Ð¡¤2¤Ä¤Î¥ª¥Ö¥¸¥§
-¥¯¥È¤¬Æ±°ì¤Ç¤¢¤ë¤³¤È¤Ï³Î¼Â¤Ç¤¢¤ë¡¥
-
-@item inspect
-
-¥ª¥Ö¥¸¥§¥¯¥È¤ò¿Í´Ö¤¬Æɤá¤ë·Á¼°¤Îʸ»úÎó¤ËÊÑ´¹¤¹¤ë¡¥
-
-@item nil?
-
-¥ª¥Ö¥¸¥§¥¯¥È¤¬@code{nil}¤Ç¤¢¤ë¤«¤É¤¦¤«¡¥@code{Kernel}¥¯¥é¥¹¤ÎÄêµÁ¤Ç¤Ï
-¿¿¤òÊÖ¤¹¡¥@code{Nil}¥¯¥é¥¹¤Çµ¶¤òÊÖ¤¹¤è¤¦ºÆÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡¥
-
-
-@item type
-
-¥ª¥Ö¥¸¥§¥¯¥È¤ÎưŪ¤Ê·¿(¥¯¥é¥¹)¤òÊÖ¤¹¡¥
-
-@example
-obj.is_kind_of?(obj.type)
-@end example
-
-¤Ï¾ï¤ËÀ®Î©¤¹¤ë¡¥
-
-@item send(@var{symbol}[, @var{args}@dots{}])
-
-@var{symbol}¤Ç»ØÄꤵ¤ì¤ë¥á¥½¥Ã¥É¤ò@var{args}¤È¤È¤â¤Ë¸Æ¤Ó½Ð¤¹¡¥
-
-@end ftable
-
-@node Math, Module, Kernel, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Math
-
-ÉâÆ°¾®¿ôÅÀ±é»»¤ò¥µ¥Ý¡¼¥È¤¹¤ë¥¯¥é¥¹¡¥Math¥â¥¸¥å¡¼¥ë¤ÏƱ¤¸ÄêµÁ¤Î¥á¥½¥Ã¥É
-¤ÈÆðۥ᥽¥Ã¥É¤È¤ÎξÊý¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¤Î¤Ç¡¤Æðۥ᥽¥Ã¥É¤ò¸Æ¤Ó½Ð¤·¤Æ»È
-¤¦»È¤¤Êý¤È¡¤¥¯¥é¥¹¤Ë¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ»È¤¦»È¤¤Êý¤È¤ÎξÊý¤¬¤Ç¤­¤ë¡¥
-
-Îã
-
-@example
-pi = Math.atan2(1, 1) * 4;
-include Math
-pi2 = atan2(1, 1)
-@end example
-
-Methods:
-Single Methods:
-
-@ftable @code
-@item atan2(@var{x}, @var{y})
-
-¦Ð¡Á-¦Ð¤ÎÈϰϤÇ@var{x}/@var{y}¤Î¥¢¡¼¥¯¥¿¥ó¥¸¥§¥ó¥È¤òÊÖ¤¹¡¥
-
-@item cos(@var{x})
-@itemx sin(@var{x})
-@itemx tan(@var{x})
-
-¥é¥¸¥¢¥ó¤Çɽ¤µ¤ì¤¿@var{x}¤Î»°³Ñ´Ø¿ô¤ÎÃͤòÊÖ¤¹¡¥
-
-@item exp(@var{x})
-
-@var{x}¤Î»Ø¿ô´Ø¿ô¤ÎÃͤòÊÖ¤¹¡¥
-
-@item log(@var{x})
-
-@var{x}¤Î¼«Á³Âпô¤òÊÖ¤¹¡¥
-
-@item log10(@var{x})
-
-@var{x}¤Î¾ïÍÑÂпô¤òÊÖ¤¹¡¥
-
-@item sqrt(@var{x})
-
-@var{x}¤ÎÊ¿Êýº¬¤òÊÖ¤¹¡¥@var{x}¤ÎÃͤ¬Éé¤Ç¤¢¤ë»þ¤Ë¤ÏÎã³°¤¬È¯À¸¤¹¤ë¡¥
-
-@item cbrt(@var{x})
-
-@var{x}¤ÎΩÊýº¬¤òÊÖ¤¹¡¥
-@end ftable
-
-@node Module, Nil, Math, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Module
-
-¥â¥¸¥å¡¼¥ë¤Î¥¯¥é¥¹¡¥
-
-SuperClass: Object
-
-Private Methods:
-
-@ftable @code
-@item attr(@var{name}[, @var{public}])
-
-¤½¤Î¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤¿¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤ËÂФ·¤Æ@var{name}
-¤Ç»ØÄꤵ¤ì¤ë°À­¤òÉղä·¡¤Â°À­¤ËÂФ¹¤ë¥¢¥¯¥»¥¹¥á¥½¥Ã¥É¤òÄêµÁ¤¹¤ë¡¥
-@code{attr("attr")}¤Ï¥¯¥é¥¹ÄêµÁ¤Ë°Ê²¼¤Ë¼¨¤¹¥³¡¼¥É¤òÄɲ乤ë¤Î¤È¤Û¤ÜƱ
-µÁ¤Ç¤¢¤ë¡¥
-
-@example
-def attr; @@attr; end
-@end example
-
-¾Êά²Äǽ¤ÊÂè2°ú¿ô@var{public}¤¬Í¿¤¨¤é¤ì¤Æ¡¤¤«¤Ä¤½¤ÎÃͤ¬@code{nil}¤Ç¤Ê
-¤¤»þ¤Ë¤Ï¤½¤Î°À­¤Ë¤Ï°À­ÀßÄê¥á¥½¥Ã¥É¤âÍÑ°Õ¤µ¤ì¡¤³°Éô¤«¤éÂåÆþ²Äǽ¤Ë¤Ê¤ë¡¥
-
-@code{attr("attr", TRUE)}¤Ï¥¯¥é¥¹ÄêµÁ¤Ë°Ê²¼¤Î¥³¡¼¥É¤òÄɲ乤ë¤Î¤È¤Û¤Ü
-ƱµÁ¤Ç¤¢¤ë¡¥
-
-@example
-def attr; @@attr; end
-def attr=(val); @@attr = val; end
-@end example
-
-°À­¤ò¹½À®¤¹¤ë¥á¥½¥Ã¥É¤òºÆÄêµÁ¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¤¥¢¥¯¥»¥¹»þ¤ÎÆ°ºî¤òÊѹ¹
-¤Ç¤­¤ë¡¥Î㤨¤Ð
-
-@example
-attr("test", TRUE)
-def test=(val)
- print("test was ", @@test, "\n")
- print("and now is ", @@test = val, "\n")
-end
-@end example
-
-¤Î¤è¤¦¤ËÀßÄê»þ¤Ë°À­¤ÎÃͤòɽ¼¨¤¹¤ë¤è¤¦¤Ê¤³¤È¤¬²Äǽ¤Ç¤¢¤ë¡¥@var{attr}¤Ï
-¥¢¥¯¥»¥¹¥á¥½¥Ã¥É¤¬¤¹¤Ç¤ËÄêµÁ¤µ¤ì¤Æ¤¤¤ë¾ì¹ç¤Ï¡¤¥Ç¥Õ¥©¥ë¥È¤Î¥¢¥¯¥»¥¹¥á¥½¥Ã
-¥É¤òÄêµÁ¤·¤Ê¤¤¡¥
-@end ftable
-
-Methods:
-
-@ftable @code
-@item include(@var{module}@dots{})
-
-°ú¿ô¤Ç»ØÄꤷ¤¿¥â¥¸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤Æ¡¤¥á¥½¥Ã¥É¡¤Äê¿ô¤òÄɲ乤롥
-¥¯¥é¥¹¡¤¥â¥¸¥å¡¼¥ë¤ËÊ̤Υ⥸¥å¡¼¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¤³¤È¤Ë¤è¤Ã¤Æ¡¤¸ÂÄê
-¤µ¤ì¤¿Â¿½Å·Ñ¾µ(@code{Mixin})¤ò¼Â¸½¤Ç¤­¤ë¡¥
-
-@item module_function(@var{name}@dots{})
-
-@var{name}¤Ç»ØÄꤵ¤ì¤¿¥á¥½¥Ã¥É¤ò@samp{module function}¤Ë»ØÄꤹ¤ë¡¥
-@samp{Module function}¤È¤Ï¥â¥¸¥å¡¼¥ë¤ÎÆðۥ᥽¥Ã¥É¤Ç¤¢¤ê¡¤¤«¤Ä¤½¤Î¥â¥¸¥å¡¼
-¥ë¤ò¥¤¥ó¥¯¥ë¡¼¥É¤·¤¿¥¯¥é¥¹¤Îprivate¥á¥½¥Ã¥É¤Ë¤â¤Ê¤ë¤è¤¦¤Ê¥á¥½¥Ã¥É¤Î»ö
-¤Ç¤¢¤ë¡¥Î㤨¤Ð¡¤Math¥â¥¸¥å¡¼¥ë¤Î´Ø¿ô·²¤Ï@samp{module function}¤Ç¤¢¤ë¡¥
-
-@item private(@var{name}@dots{})
-
-@var{name}¤Ç»ØÄꤵ¤ì¤¿¥á¥½¥Ã¥É¤ò´Ø¿ô·Á¼°¤Ç¤À¤±¸Æ¤Ó½Ð¤·²Äǽ¤Ë¤¹¤ë¡¥¤¹¤Ç
-¤Ëprivate¥á¥½¥Ã¥É¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï²¿¤â¤·¤Ê¤¤¡¥
-
-@item public(@var{name}@dots{})
-
-@var{name}¤Ç»ØÄꤵ¤ì¤¿¥á¥½¥Ã¥É¤òÄ̾ï·Á¼°¤Ç¸Æ¤Ó½Ð¤·²Äǽ¤Ë¤¹¤ë¡¥¤¹¤Ç¤Ë
-public¥á¥½¥Ã¥É¤Ç¤¢¤ë¾ì¹ç¤Ë¤Ï²¿¤â¤·¤Ê¤¤¡¥
-
-@example
-def foo() 1 end
-foo
- @result{} 1
-self.foo
- @result{} 1
-
-def bar() 2 end
-private :bar
-bar
- @result{} 2
-self.bar
- @error{} method `bar' not available for "main"(Object)
-
-Module Baz
- def baz() 3 end
- module_function :baz
-end
-Baz.baz
- @result{} 3
-include Baz
-baz
- @result{} 3
-self.baz
- @error{} method `baz' not available for "main"(Object)
-@end example
-
-@item to_s
-
-¥â¥¸¥å¡¼¥ë¤Îʸ»úÎóɽ¸½¤Ç¤¢¤ë¥â¥¸¥å¡¼¥ë̾¤òÊÖ¤¹¡¥
-@end ftable
-
-@xref{Object}
-
-@node Nil, Numeric, Module, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Nil
-
-µ¶¤òɽ¤¹¥ª¥Ö¥¸¥§¥¯¥È@code{nil}¤Î¥¯¥é¥¹¡¥µ¶ÊÑ¿ô(¤ÎÃÍ)@code{nil}¤Ï
-@code{Nil}¥¯¥é¥¹¤ÎÍ£°ì¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤¢¤ë¡¥
-
-SuperClass: Kernel
-
-Methods:
-
-@ftable @code
-@item self + @var{other}
-
-@var{other}¤¬À°¿ô¡¤ÉâÆ°¾®¿ôÅÀ¿ô¡¤Ê¸»úÎó¡¤ÇÛÎó¤Ç¤¢¤ë»þ¡¤@var{other}¤òÊÖ
-¤¹¡¥
-
-@item nil?
-
-¾ï¤Ë¿¿¤òÊÖ¤¹¡¥
-@end ftable
-
-@xref{Kernel}
-
-@node Numeric, Object, Nil, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Numeric
-
-¿ô°ìÈ̤ÎÀ­¼Á¤òɽ¤¹Ãê¾Ý¥¯¥é¥¹¡¥
-
-SuperClass: Object
-
-Included Modules: Comparable
-
-Methods:
-
-@ftable @code
-@item + self
-
-¥ª¥Ö¥¸¥§¥¯¥È@code{self}¤½¤Î¤â¤Î¤òÊÖ¤¹
-
-@item - self
-
-@code{0 - self}¤ÎÃͤòÊÖ¤¹¡¥¥µ¥Ö¥¯¥é¥¹¤Ç¤è¤ê¸úΨŪ¤ËºÆÄêµÁ¤µ¤ì¤ë¤³¤È¤¬
-´üÂÔ¤µ¤ì¤ë¡¥
-
-@item abs
-
-ÀäÂÐÃͤòÊÖ¤¹¡¥
-
-@item divmod(@var{other})
-
-¾¦¤È¾ê;¤Î2Í×ÁǤÎÇÛÎó¤òÊÖ¤¹¡¥
-
-@item next
-
-¼¡¤Î¿ô¤òÊÖ¤¹¡¥¼¡¤Î¿ô¤È¤Ï¤½¤Î¿ô¤ò±Û¤¨¤ëºÇ¾®¤ÎÀ°¿ô¤Ç¤¢¤ë¡¥
-@end ftable
-
-@xref{Object}
-@xref{Comparable}
-
-@node Object, Proc, Numeric, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Object
-
-Á´¤Æ¤ÎÄ̾說¥é¥¹¤Î¥¹¡¼¥Ñ¥¯¥é¥¹¡¥Ä̾說¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Î°ìÈÌŪ¤Ê¿¶Éñ
-¤¤¤òÄêµÁ¤·¤Æ¤¤¤ë¡¥¤³¤Î¥¯¥é¥¹¤Î¥µ¥Ö¥¯¥é¥¹¤Ç¤Ê¤¤¥¯¥é¥¹¤Ï@code{Kernel}¤È
-@code{Nil}¤À¤±¤Ç¤¢¤ë¡¥
-
-SuperClass: Kernel
-
-Methods:
-
-@ftable @code
-@item extened(module@dots{})
-
-°ú¿ô¤Ç»ØÄꤷ¤¿¥â¥¸¥å¡¼¥ë¤ò@code{self}¤Ë¥¤¥ó¥¯¥ë¡¼¥É¤¹¤ë¡¥¥â¥¸¥å¡¼¥ë¤Ç
-ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥á¥½¥Ã¥É¤¬Æðۥ᥽¥Ã¥É¤È¤·¤ÆÄɲ䵤ì¤ë¡¥
-
-@item initialize(@dots{})
-
-@code{Class:new}¤«¤é¥ª¥Ö¥¸¥§¥¯¥È¤ÎÀ¸À®»þ¤Ë¼«Æ°Åª¤Ë¸Æ¤Ó½Ð¤µ¤ì¤ë¡¥¥Ç¥Õ¥©
-¥ë¥È¤ÎÄêµÁ¤Ï²¿¤â¤·¤Ê¤¤¡¥¥µ¥Ö¥¯¥é¥¹¤ÇɬÍפ˱þ¤¸¤ÆºÆÄêµÁ¤µ¤ì¤ë¤³¤È¤¬´üÂÔ
-¤µ¤ì¤Æ¤¤¤ë¡¥@code{Class:new}¤ËÍ¿¤¨¤é¤ì¤¿°ú¿ô¤¬¤½¤Î¤Þ¤ÞÅϤµ¤ì¤ë¡¥
-
-@item is_instance_of?(@var{class})
-
-¥ª¥Ö¥¸¥§¥¯¥È@code{self}¤¬¥¯¥é¥¹@var{class}¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤¢¤ë»þ¡¤¿¿¤ò
-ÊÖ¤¹¡¥@code{obj.is_instance_of?(c)}¤¬À®Î©¤¹¤ë»þ¡¤¤¤¤Ä¤â
-@code{obj.is_kind_of?(c)}¤âÀ®Î©¤¹¤ë¡¥
-
-@item is_kind_of?(@var{class})
-
-¥ª¥Ö¥¸¥§¥¯¥È@code{self}¤¬¥¯¥é¥¹@var{class}¤«¤½¤Î¥µ¥Ö¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó
-¥¹¤Ç¤¢¤ë»þ¡¤¿¿¤òÊÖ¤¹¡¥
-
-@item clone
-@item dup
-
-¥ª¥Ö¥¸¥§¥¯¥È¤ÎÊ£À½¤òºî¤ë¡¥¥¤¥ó¥¹¥¿¥ó¥¹¤¬Â¨ÃͤǤ¢¤ëFixnum¥¯¥é¥¹°Ê³°¤Î¥¯
-¥é¥¹¤Î¾ì¹ç¡¤@code{obj.equal?(obj.clone)}¤Ïµ¶¤Ç¤¢¤ë¤¬¡¤Â¿¤¯¤Î¾ì¹ç
-@code{obj == obj.clone}¤Ï¿¿¤Ç¤¢¤ë¡¥
-
-String¥¯¥é¥¹°Ê³°¤Ç¤Ï(Æä˺ÆÄêµÁ¤·¤Ê¤¤¸Â¤ê)dup¤Ïclone¤ÎÊÌ̾¤Ç¤¢¤ë¡¥
-
-@item to_s
-
-¥ª¥Ö¥¸¥§¥¯¥È¤Îʸ»úÎóɽ¸½¤òÊÖ¤¹¡¥¤³¤Î¥á¥½¥Ã¥É¤ÏÆâÉôŪ¤Ëprint¤äformat¥á
-¥½¥Ã¥É¤ÇÍѤ¤¤é¤ì¤Æ¤¤¤ë¡¥
-
-@item to_a
-
-¥ª¥Ö¥¸¥§¥¯¥È¤òÇÛÎó¤ËÊÑ´¹¤¹¤ë¡¥@code{Kernel}¥¯¥é¥¹¤ÇÄêµÁ¤µ¤ì¤Æ¤¤¤ë¥Ç¥Õ¥©
-¥ë¥È¤Ï¡¤¤½¤Î¥ª¥Ö¥¸¥§¥¯¥È¼«¿È¤ò´Þ¤à1Í×ÁǤÎÇÛÎó¤òÊÖ¤¹¡¥
-@end ftable
-
-@xref{Kernel}
-
-@node Proc, Process, Object, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Proc
-
-¥¤¥Æ¥ì¡¼¥¿¤ËÅϤµ¤ì¤¿¥¤¥Æ¥ì¡¼¥¿¥Ö¥í¥Ã¥¯¤ò¼ê³¤­¤È¤·¤Æ¥ª¥Ö¥¸¥§¥¯¥È²½¤·¤¿
-¤â¤Î¡¥¼Â¹Ô¤¹¤ë¥³¡¼¥É¤À¤±¤Ç¤Ê¤¯¥³¥ó¥Æ¥­¥¹¥È(¥í¡¼¥«¥ëÊÑ¿ô)¤Ê¤É¤âÊݸ¤¹¤ë¡¥
-¥Ö¥í¥Ã¥¯¥ª¥Ö¥¸¥§¥¯¥È¤Ï¡¤@code{call}¥á¥½¥Ã¥É¤Ë¤è¤Ã¤Æ¡¤À¸À®¤µ¤ì¤¿¤Î¤ÈƱ
-¤¸´Ä¶­¤Çɾ²Á¤¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥¤¿¤À¤·¡¤Âç°èæ½Ð(@code{return},
-@code{break}, @code{continue}, @code{redo}, @code{retry})¤Î´Ä¶­¤ÏÊݸ
-¤µ¤ì¤Ê¤¤¤Î¤Ç¡¤¥Ö¥í¥Ã¥¯¥ª¥Ö¥¸¥§¥¯¥È¤«¤é¤ÎÂç°èæ½Ð¤Î¼Â¹Ô¤ÏÎã³°¤òȯÀ¸¤µ¤»
-¤ë¤³¤È¤Ë¤Ê¤ë¡¥
-
-SuperClass: Object
-
-Methods:
-
-@ftable @code
-@item call(@var{arg}[,@dots{}])
-
-¥Ö¥í¥Ã¥¯¤ò¼Â¹Ô¤¹¤ë¡¥
-@end ftable
-
-Single Methods:
-
-@ftable @code
-@item new
-
-¿·¤·¤¤¥Ö¥í¥Ã¥¯¤òÀ¸À®¤¹¤ë¡¥@code{yield}¤ò¼Â¹Ô¤Ç¤­¤ë¾ì½ê¤Ç¤³¤Î¥á¥½¥Ã¥É¤¬
-¸Æ¤Ð¤ì¤ë¤È¡¤¤½¤Î»þÅÀ¤Ç¼Â¹Ô¤µ¤ì¤ë¤Ù¤­¥³¡¼¥É¤ò¥³¥ó¥Æ¥­¥¹¥È¤È¤È¤â¤ËÊñ¤ß¹þ
-¤ó¤À¥ª¥Ö¥¸¥§¥¯¥È(@code{Proc})¤òÀ¸À®¤¹¤ë¡¥
-@end ftable
-
-@xref{Object}
-
-@node Process, Range, Proc, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Process
-
-¥×¥í¥»¥¹¤Ë´Ø¤¹¤ëÁàºî¤ò¹Ô¤Ê¤¦¤¿¤á¤Î¥â¥¸¥å¡¼¥ë¡¥@code{Math}¥â¥¸¥å¡¼¥ë¤È
-ƱÍͤËÁ´¤Æ¤Î¥á¥½¥Ã¥É¤ÏÆðۥ᥽¥Ã¥É¤È¤·¤Æ¤âÄ̾ï¤Î¥á¥½¥Ã¥É¤È¤·¤Æ¤â»È¤¨¤ë¡¥
-@code{Process}¤Ï¥×¥í¥»¥¹¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¯¥é¥¹¤Ç¤Ï¤Ê¤¯¤Æ¡¤¥×¥í¥»¥¹Áàºî¤Î
-¥á¥½¥Ã¥É¤ò¤Þ¤È¤á¤¿¤â¤Î¤Ç¤¢¤ë¤³¤È¤ËÃí°Õ¤¹¤ë¤³¤È¡¥
-
-Methods:
-Single Methods:
-
-@ftable @code
-@item egid
-
-¥×¥í¥»¥¹¤Î¸½ºß¤Î¼Â¸úGID¤òÊÖ¤¹¡¥
-
-@item egid= @var{gid}
-
-¥×¥í¥»¥¹¤Î¸½ºß¤Î¼Â¸úGID¤ò@var{gid}¤Ë¥»¥Ã¥È¤¹¤ë¡¥
-
-@item euid
-
-¥×¥í¥»¥¹¤Î¸½ºß¤Î¼Â¸úUID¤òÊÖ¤¹¡¥
-
-@item euid= @var{uid}
-
-¥×¥í¥»¥¹¤Î¸½ºß¤Î¼Â¸úUID¤ò@var{uid}¤Ë¥»¥Ã¥È¤¹¤ë¡¥
-
-@item getpgrp([@var{pid}])
-
-@var{pid}¤Ç»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤¬¸½ºß½ê°¤·¤Æ¤¤¤ë¥×¥í¥»¥¹¥°¥ë¡¼¥×¤Îid¤ò
-ÊÖ¤¹¡¥@var{pid}¤ò¾Êά¤·¤¿»þ¤È@var{pid}¤Ë0¤òÍ¿¤¨¤¿»þ¤Ï¸½ºß¼Â¹Ô¤·¤Æ¤¤¤ë
-¥×¥í¥»¥¹¤òÂоݤˤ¹¤ë¡¥
-
-@item getpriority(@var{which}, @var{who})
-
-@var{which}¤È@var{who}¤Ç»ØÄꤵ¤ì¤ë¥×¥í¥»¥¹¡¤¥×¥í¥»¥¹¥°¥ë¡¼¥×¡¤¥æ¡¼¥¶¤Î
-¸½ºß¤ÎÍ¥Àè½ç°Ì¤òÊÖ¤¹¡¥¾ÜºÙ¤Ï@samp{getpriority(2)}¤ò»²¾È¡¥Process¥â¥¸¥å¡¼
-¥ë¤Ç¤Ïwhich¤È¤·¤Æ»ØÄê¤Ç¤­¤ëÄê¿ô@var{PRIO_PROCESS}¡¤@var{PRIO_PGRP}¡¤
-@var{PRIO_USER}¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤ë¡¥
-
-@item gid
-
-¥×¥í¥»¥¹¤Î¸½ºß¤Î¼ÂGID¤òÊÖ¤¹¡¥
-
-@item gid= @var{gid}
-
-¥×¥í¥»¥¹¤Î¸½ºß¤Î¼ÂGID¤ògid¤Ë¥»¥Ã¥È¤¹¤ë.
-
-@item pid
-
-¥×¥í¥»¥¹¤Î¥×¥í¥»¥¹ID¤òÊÖ¤¹¡¥¤³¤ì¤Ï¥·¥¹¥Æ¥àÊÑ¿ô@code{$$}¤ÎÃͤÈƱ¤¸¤Ç¤¢
-¤ë¡¥
-
-@item ppid
-
-¿Æ¥×¥í¥»¥¹¤Î¥×¥í¥»¥¹¤Î¥×¥í¥»¥¹ID¤òÊÖ¤¹¡¥UNIX¤Ç¤ÏľÀÜ¤Î¿Æ¥×¥í¥»¥¹¤¬½ªÎ»
-¤·¤¿¾ì¹ç¡¤¿Æ¥×¥í¥»¥¹¤Îpid¤Ï1(init¤Îpid)¤Ë¤Ê¤ë¡¥
-
-@item setpgrp(@var{pid}, @var{pgrp})
-
-@var{pid}¤Ç»ØÄꤵ¤ì¤¿¥×¥í¥»¥¹¤Î¥×¥í¥»¥¹¥°¥ë¡¼¥×¤ò@var{pgrp}¤Ë¤¹¤ë¡¥
-@var{pid}¤Ë0¤òÍ¿¤¨¤ë¤È¸½ºß¼Â¹ÔÃæ¤Î¥×¥í¥»¥¹¤òÂоݤˤ¹¤ë¡¥
-
-@item setpriority(@var{which}, @var{who}, @var{prio})
-
-@var{which}¤È@var{who}¤Ç»ØÄꤵ¤ì¤ë¥×¥í¥»¥¹¡¤¥×¥í¥»¥¹¥°¥ë¡¼¥×¡¤¥æ¡¼¥¶¤Î
-¸½ºß¤ÎÍ¥Àè½ç°Ì¤ò@var{prio}¤ËÀßÄꤹ¤ë¡¥¾ÜºÙ¤Ï@samp{setpriority(2)}¤ò»²
-¾È¤Î¤³¤È¡¥
-
-@item uid
-
-¥×¥í¥»¥¹¤Î¸½ºß¤Î¼ÂUID¤òÊÖ¤¹¡¥
-
-@item uid= @var{uid}
-
-¥×¥í¥»¥¹¤Î¸½ºß¤Î¼ÂUID¤ò@var{uid}¤Ë¥»¥Ã¥È¤¹¤ë.
-@end ftable
-
-@node Range, Regexp, Process, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Range
-
-ÈÏ°Ï¥ª¥Ö¥¸¥§¥¯¥È¤Î¥¯¥é¥¹¡¥ÈÏ°Ï¥ª¥Ö¥¸¥§¥¯¥È¤Ï@code{..}±é»»»Ò¤Ë¤è¤Ã¤ÆÀ¸
-À®¤µ¤ì¡¤°ìÈÌŪ¤Ë¤Ï°Ê²¼¤Î¤è¤¦¤Ê»È¤¤Êý¤ò¤¹¤ë
-
-@example
-for i in 1..5
- @dots{}
-end
-@end example
-
-¤·¤«¤·¡¤¤³¤Î¾ì¹ç¤Ï°Ê²¼¤ÎÊý¤¬Â®¤¤.
-
-@example
-1.upto(5) {
- @dots{}
-}
-@end example
-
-ÈÏ°Ï¥ª¥Ö¥¸¥§¥¯¥È¤òÀ¸À®¤¹¤ë@code{..}±é»»»Ò¤ÎξÊÕ¤Ï@code{Comparable}¤ò´Þ
-¤à¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤¢¤ì¤Ð²¿¤Ç¤â¹½¤ï¤Ê¤¤¡¥ÈϰϤϻÏÅÀ¤È½ªÅÀ¤ò´Þ¤à¤³
-¤È¤ËÃí°Õ¤¹¤ë¤³¤È.
-
-SuperClass: Object
-
-Included Modules: Enumerable
-
-Methods:
-
-@ftable @code
-@item self =~ @var{other}
-
-@code{self}¤¬@var{other}¤ÈƱ¤¸¥¯¥é¥¹¤ËÂФ¹¤ëÈÏ°Ï¥ª¥Ö¥¸¥§¥¯¥È¤Ç¡¤¤½¤ÎÈÏ
-°ÏÆâ¤Ë@var{other}¤¬¤¢¤ë»þ(@code{start <= @var{other} <= end})¡¤¿¿¤òÊÖ
-¤¹¡¥¤³¤ì¤Ï@code{case}¼°¤ÇÈÏ°Ï»ØÄꤹ¤ë»þ¤ËÊØÍø¤Ç¤¢¤ë¡¥Î㤨¤Ð
-
-@example
-case i
-when 1, 3..5
- @dots{}
-end case
-@end example
-
-¤Î¤è¤¦¤Ê¥³¡¼¥É¤ò½ñ¤¯¤³¤È¤¬¤Ç¤­¤ë¡¥
-
-@item each
-
-ÈÏ°ÏÆâ¤Ë¸ºß¤¹¤ë¥ª¥Ö¥¸¥§¥¯¥È¤òÍ¿¤¨¤ë¥¤¥Æ¥ì¡¼¥¿¡¥¼ç¤Ë@code{for}¼°¤Î¤¿¤á
-¤ËÍѤ¤¤é¤ì¤ë¡¥
-
-@item end
-
-ÈϰϤνªÅÀ¤òÊÖ¤¹
-
-@item start
-
-ÈϰϤλÏÅÀ¤òÊÖ¤¹¡¥
-@end ftable
-
-@xref{Object}
-@xref{Enumerable}
-
-@node Regexp, String, Range, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Regexp
-
-Àµµ¬É½¸½¤Î¥¯¥é¥¹¡¥Àµµ¬É½¸½¤Î¥ê¥Æ¥é¥ë¤Ï@code{/@dots{}/}¤È¤¤¤¦·Á¼°¤Çɽ¤¹
-¤¬¡¤Æ°Åª¤ËÀ¸À®¤¹¤ë¤¿¤á¤Ë¤Ï
-
-@example
-Regexp.new(ʸ»úÎó)
-@end example
-
-¤È¤¹¤ë¡¥¤¿¤À¤·¡¤String¥¯¥é¥¹¤Î@code{=~}¤ò»Ï¤á¤È¤·¤Æ¿¤¯¤Î¥á¥½¥Ã¥É¤ÏÀµ
-µ¬É½¸½¤ÎÂؤï¤ê¤Ëʸ»úÎó¤¬Í¿¤¨¤é¤ì¤¿»þ¤Ë¤ÏÆâÉôŪ¤ËÀµµ¬É½¸½¤òÀ¸À®¤¹¤ë¤Î¤Ç¡¤
-À¸À®¥³¥¹¥È¤òÀáÌó¤·¤¿¤¤¤È»×¤¦»þ¤ä¡¤Àµµ¬É½¸½¤ÎÂçʸ»ú¾®Ê¸»ú¤Î¶èÊ̤òÌÀ¼¨Åª
-¤Ë»ØÄꤷ¤¿¤¤»þ¤Ê¤É°Ê³°¤ÏÌÀ¼¨Åª¤ËÀ¸À®¤·¤¿¤¤¤È»×¤¦¤³¤È¤Ï¾¯¤Ê¤¤¤Ï¤º¤À¡¥
-
-SuperClass: Object
-
-Methods:
-
-@ftable @code
-@item self =~ @var{string}
-
-Àµµ¬É½¸½¤¬Ê¸»úÎó¤Ë¥Þ¥Ã¥Á¤·¤¿¾ì¹ç¡¤¥Þ¥Ã¥Á¤·¤¿°ÌÃÖ¤òÊÖ¤¹¡¥¥Þ¥Ã¥Á¤·¤Ê¤¤¾ì
-¹ç¤Ï@code{nil}¤òÊÖ¤¹¡¥
-
-@item ~ self
-
-@code{$_ =~ self}¤ÈƱµÁ¡¥
-@end ftable
-
-Single Methods:
-
-@ftable @code
-@item compile(@var{string}[, @var{casefold}])
-@itemx new(@var{string}[, @var{casefold}])
-
-ʸ»úÎó¤òÀµµ¬É½¸½¤ËÊÑ´¹¤·¤¿¥ª¥Ö¥¸¥§¥¯¥È¤òÊÖ¤¹¡¥¾Êά²Äǽ¤ÊÂè2°ú¿ô¤¬Í¿¤¨
-¤é¤ì¡¤¤½¤ÎÃͤ¬@code{nil}¤Ç¤Ê¤¤»þ¤Ë¤Ï¡¤À¸À®¤µ¤ì¤¿Àµµ¬É½¸½¥ª¥Ö¥¸¥§¥¯¥È¤Ï
-¥·¥¹¥Æ¥àÊÑ¿ô@code{$=}¤ÎÃͤ˴ؤï¤é¤º¡¤¥Þ¥Ã¥Á¤¹¤ë»þ¤ËÂçʸ»ú¾®Ê¸»ú¤Î°ã¤¤
-¤ò̵»ë¤¹¤ë¡¥
-
-@item quote(@var{str})
-
-ʸ»úÎó¤ÎÃæ¤ÎÀµµ¬É½¸½¤Ç°ÕÌ£¤ò»ý¤Äʸ»ú¤ò¥¨¥¹¥±¡¼¥×¤¹¤ë¡¥¿·¤·¤¤Ê¸»úÎó¤òÊÖ
-¤¹¡¥
-@end ftable
-
-@xref{Object}
-
-@node String, Struct, Regexp, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section String
-
-ʸ»úÎ󥯥饹¡¥Ruby¤Îʸ»úÎó¤Ï¥Ì¥ë¥¿¡¼¥ß¥Í¡¼¥È¤Ç¤Ï¤Ê¤¤¤Î¤Ç¡¤¥Ð¥¤¥Ê¥ê¥Ç¡¼
-¥¿¤â°·¤¨¤ë¡¥½¾¤Ã¤Æ¤É¤Á¤é¤«¤È¤¤¤¦¤Èñ¤Ê¤ëʸ»úÎó¤È¤¤¤¦¤è¤ê¥Ð¥¤¥ÈÎó¤Ç¤¢¤ë¡¥
-¤½¤Î»×Áۤ˴ð¤Å¤¤¤Æ¡¤Àµµ¬É½¸½¤Ë´Ø¤¹¤ë¥á¥½¥Ã¥É°Ê³°¤Ï2byte·Ï¤Îʸ»ú¤ò°Õ¼±
-¤·¤Æ¤¤¤Ê¤¤¡¥¤³¤ì¤Ïºî¼Ô¤Î¼êÈ´¤­¤Ç¤Ï¤Ê¤¯°Õ¿ÞŪ¤Ë¤½¤¦¤·¤Æ¤¤¤ë¤Î¤Ç¤¢¤ë(¿®
-¤¸¤Æ¤¯¤ì)¡¥
-
-String¥¯¥é¥¹¤Î¥á¥½¥Ã¥É¤Î¤¦¤Á@code{!}¤Ç½ª¤ë¤â¤Î¤Ï¥ì¥·¡¼¥Ð¤ò½ñ¤­´¹¤¨¤ë¡¥
-Ʊ¤¸Ì¾Á°¤Ç@code{!}¤Î̵¤¤¤â¤Î¤Ï¥ì¥·¡¼¥Ð¤Î¥³¥Ô¡¼¤òºî¤Ã¤Æ¤«¤é¡¤¤½¤Á¤é¤ò½ñ
-¤­´¹¤¨¤ë¡¥@code{!}¤Î¤¢¤ë¤â¤Î¤ÎÊý¤¬¹â®¤À¤¬¡¤Í½´ü¤»¤Ì·ë²Ì¤ò¾·¤­¤ä¤¹¤¤¤Î
-¤Ç¡¤Ìµ¤¤¤â¤Î¤ÎÊý¤¬°ÂÁ´¤Ç¤¢¤ë¡¥
-
-@example
-f = "string"
-print f, sub("str", "ski"), f
- @result{} string, skiing, string
-print f, sub!("str", "ski"), f
- @result{} skiing, skiing, skiing
-@end example
-
-SuperClass: Object
-
-Included Modules: Comparable, Enumerable
-
-Methods:
-
-@ftable @code
-@item self + @var{other}
-
-ʸ»úÎó¤ÎÏ¢·ë¡¥Ï¢·ë¤µ¤ì¤¿Ê¸»úÎó¤òÊÖ¤¹¡¥
-
-@item self * @var{times}
-
-ʸ»úÎó¤Î·«¤êÊÖ¤·¡¥Î㤨¤Ð@code{x" * 4 == "xxxx"}¤Ç¤¢¤ë¡¥
-
-@item self == @var{other}
-@item self > @var{other}
-
-ʸ»úÎó¤ÎÈæ³Ó¡¥¥·¥¹¥Æ¥àÊÑ¿ô@code{$=}¤¬@code{nil}¤Ç¤Ê¤¤»þ¤Ë¤ÏÂçʸ»ú¾®Ê¸
-»ú¤ò¶èÊ̤»¤º¤ËÈæ³Ó¤ò¹Ô¤Ê¤¦¡¥
-
-@item self =~ @var{other}
-
-ʸ»úÎó¤Î¥Þ¥Ã¥Á¡¥@var{other}¤ÏÀµµ¬É½¸½¤«Ê¸»úÎó¡¥@var{other}¤¬Ê¸»úÎó¤Î¾ì
-¹ç¤Ë¤ÏưŪ¤ËÀµµ¬É½¸½¤ËÊÑ´¹¤µ¤ì¤ë¡¥¥Þ¥Ã¥Á¤·¤¿¾ì¹ç¤Ï¥Þ¥Ã¥Á¤·¤¿°ÌÃÖ¡¤¤·¤Ê
-¤«¤Ã¤¿¾ì¹ç¤Ï@code{nil}¤¬Ê֤롥
-
-@item ~ self
-
-@code{$_ =~ self}¤ÈƱµÁ¡¥
-
-@item self[@var{nth}]
-@item self[@var{beg}..@var{end}]
-@item self[@var{beg}, @var{len}]
-
-ÆâÍƤμè¤ê½Ð¤·¡¥1ÈÖÌܤηÁ¼°¤Ç¤Ï@var{nth}¥Ð¥¤¥ÈÌܤΥǡ¼¥¿¤òFixnum¤È¤·¤Æ
-ÊÖ¤¹¡¥2ÈÖÌܤηÁ¼°¤Ç¤Ï@var{beg}¥Ð¥¤¥ÈÌܤ«¤é@var{end}¥Ð¥¤¥ÈÌܤޤǤÎÉôʬ
-ʸ»úÎó¤òÊÖ¤¹(ξü¤ò´Þ¤à)¡¥3ÈÖÌܤηÁ¼°¤Ç¤Ï@var{beg}¥Ð¥¤¥ÈÌܤ«¤é
-@var{len}¥Ð¥¤¥Èʬ¤ÎÉôʬʸ»úÎó¤òÊÖ¤¹¡¥
-
-@item self[@var{nth}] = @var{val}
-@item self[@var{beg}..@var{end}] = @var{val}
-@item self[@var{beg}, @var{len}] = @var{val}
-
-ÆâÍƤι¹¿·¡¥1ÈÖÌܤηÁ¼°¤Ç¤Ï@var{nth}¥Ð¥¤¥ÈÌܤΥǡ¼¥¿¤ò@var{val}(À°¿ô)
-¤ËÊѹ¹¤¹¤ë¡¥2ÈÖÌܤηÁ¼°¤Ï@var{beg}¥Ð¥¤¥ÈÌܤ«¤é@var{end}¥Ð¥¤¥ÈÌܤޤǤÎ
-Éôʬʸ»úÎó¤ò@var{val}¤È¤·¤ÆÍ¿¤¨¤é¤ì¤¿Ê¸»úÎó¤ÇÃÖ¤­´¹¤¨¤ë¡¥3ÈÖÌܤηÁ¼°¤Ï
-@var{beg}¥Ð¥¤¥ÈÌܤ«¤é@var{len}¥Ð¥¤¥Èʬ¤ÎÉôʬʸ»úÎó¤ò@var{val}¤È¤·¤ÆÍ¿
-¤¨¤é¤ì¤¿Ê¸»úÎó¤ÇÃÖ¤­´¹¤¨¤ë¡¥
-
-@item capitalize
-@itemx capitalize!
-
-ʸ»úÎóÃæ¤ÎºÇ½é¤Îʸ»ú¤ò(¤½¤ì¤¬¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤Ç¤¢¤ì¤Ð)¡¤Âçʸ»ú¤ËÊÑ´¹¤·¡¤
-»Ä¤ëʸ»úÎóÃæ¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤ò¾®Ê¸»ú¤ËÃÖ¤­´¹¤¨¤ë¡¥
-
-@item chop
-@itemx chop!
-
-ʸ»úÎó¤ÎºÇ¸å¤Î¥Ð¥¤¥È¤òÀÚ¤êÍî¤È¤¹¡¥¸µ¤Îʸ»úÎó¤òÊѹ¹¤¹¤ë¤³¤È¤ËÃí°Õ¤¹¤ë¤³
-¤È¡¥@code{chop!}¤Ï¸µ¤Îʸ»úÎó¤ò¹¹¿·¤¹¤ë¡¥
-
-@item crypt(@var{salt})
-
-@samp{crypt(3)}¤òÍѤ¤¤Æ°Å¹æ²½¤·¤¿Ê¸»úÎó¤òÊÖ¤¹¡¥@var{salt}¤Ï2¥Ð¥¤¥È°Ê¾å
-¤ÎŤµ¤ÎǤ°Õ¤Îʸ»úÎó¤Ç¤¢¤ë¡¥
-
-@item delete(@var{str})
-@itemx delete!(@var{str})
-
-ʸ»úÎó¤Î¤¦¤Á¡¤@var{str}¤Ë´Þ¤Þ¤ì¤ëʸ»ú¤òºï½ü¤¹¤ë¡¥Ê¸»úÎó¤Î»ØÄê¤Ï
-@code{tr}¤ÈƱÍͤǤ¢¤ê¡¤@code{a-b}¤Ç@code{a}¤«¤é@code{b}¤Þ¤Ç¤ÎÈϰϤò¡¤
-ÀèƬ¤Î@code{^}¤Çʸ»úÎó¤ÎÈÝÄê(´Þ¤Þ¤ì¤Æ¤Ê¤¤¤â¤Î¤ò»ØÄê)¤ò°ÕÌ£¤¹¤ë¡¥
-
-@item dup
-
-@code{self}¤ÈƱ¤¸ÆâÍƤò»ý¤Äʸ»úÎó¤òÀ¸À®¤¹¤ë¡¥@code{clone}¤Ï
-@code{freeze}¾õÂ֤⥳¥Ô¡¼¤¹¤ë¤¬¡¤@code{dup}¤ÏÆâÍƤÀ¤±¤¬Åù¤·¤¤Ê¸»úÎó¤ò
-À¸À®¤¹¤ë¡¥
-
-@item downcase
-@itemx downcase!
-
-ʸ»úÎóÃæ¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤òÁ´¤Æ¾®Ê¸»ú¤ËÃÖ¤­´¹¤¨¤¿Ê¸»úÎó¤òÊÖ¤¹¡¥
-@code{tr("A-Z", "a-z")}¤è¤ê¾¯¤·Â®¤¤¡¥
-
-@item each @{|@var{char}|@dots{}@}
-@itemx each_byte @{|@var{char}|@dots{}@}
-
-ʸ»úÎó¤Î¤½¤ì¤¾¤ì¤Î¥Ð¥¤¥È¤Ë¤Ä¤¤¤Æ·«¤êÊÖ¤¹¥¤¥Æ¥ì¡¼¥¿¡¥
-
-@item each_line @{|@var{line}|@dots{}@}
-
-ʸ»úÎ󤫤é1¹Ô¤º¤ÄÆɤ߹þ¤ó¤Ç¤¯¤ë¥¤¥Æ¥ì¡¼¥¿¡¥
-
-@item freeze
-
-ʸ»úÎó¤ò¹¹¿·ÉԲĤˤ¹¤ë¡¥°ìÅÙ¹¹¿·ÉԲĤËÀßÄꤵ¤ì¤¿Ê¸»úÎó¤ÎÆâÍƤòÊѹ¹¤·¤è
-¤¦¤È¤¹¤ë¤ÈÎã³°¤¬È¯À¸¤¹¤ë¡¥
-
-@item gsub(@var{pattern}, @var{replace})
-@itemx gsub(@var{pattern}) @{@dots{}@}
-@itemx gsub!(@var{pattern}, @var{replace})
-@itemx gsub!(@var{pattern}) @{@dots{}@}
-
-ʸ»úÎóÃæ¤Ç@var{pattern}¤Ë¥Þ¥Ã¥Á¤¹¤ëÉôʬ¤òÁ´¤Æ@var{replace}¤ËÃÖ¤­´¹¤¨¤ë¡¥
-ÃÖ´¹Ê¸»úÎó@var{replace}Ãæ¤Î@samp{&}¤È@samp{\0}¤Ï¥Þ¥Ã¥Á¤·¤¿Ê¸»úÎó¤Ë¡¤
-@samp{\1@dots{}\9}¤ÏnÈÖÌܤγç¸Ì¤ÎÆâÍƤËÃÖ¤­´¹¤¨¤é¤ì¤ë¡¥°ú¿ô
-@var{replace}¤¬¾Êά¤µ¤ì¤¿»þ¤Ë¤Ï¥¤¥Æ¥ì¡¼¥¿¤È¤·¤ÆÆ°ºî¤·¡¤¥Ö¥í¥Ã¥¯¤òɾ²Á
-¤·¤¿·ë²Ì¤ÇÃÖ´¹¤¹¤ë¡¥
-
-@code{gsub}¤ÏÃÖ´¹¤µ¤ì¤¿Ê¸»úÎó¤òÊÖ¤¹(ÃÖ´¹¤¬¹Ô¤Ê¤ï¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¸µ¤Îʸ
-»úÎó¤òÊÖ¤¹)¡¥@code{gsub!}¤ÏÃÖ´¹¤¬¹Ô¤Ê¤ï¤ì¤¿»þ¤Ë¤ÏÂоݤȤʤëʸ»úÎó¤ò¡¤
-¹Ô¤Ê¤ï¤ì¤Ê¤«¤Ã¤¿»þ¤Ë¤Ï@code{nil}¤òÊÖ¤¹¡¥
-
-@item hex
-
-ʸ»úÎó¤ò16¿Ê¿ô¤òɽ¤¹Ê¸»úÎó¤È²ò¼á¤·¤Æ¡¤À°¿ô¤ËÊÑ´¹¤¹¤ë¡¥
-
-@item index(@var{substr}[, @var{pos}])
-
-@var{substr}¤¬ºÇ½é¤Ë½Ð¸½¤¹¤ë°ÌÃÖ¤òÊÖ¤¹¡¥@var{pos}¤òÍ¿¤¨¤ë¤È¤½¤Î°ÌÃÖ¤«
-¤é¸¡º÷¤ò³«»Ï¤¹¤ë¡¥¸«¤Ä¤«¤é¤Ê¤¤»þ¤Ë¤Ï@code{nil}¤òÊÖ¤¹¡¥
-
-@item intern
-
-ʸ»úÎó¤Ë°ì°Õ¤ËÂбþ¤¹¤ëÀ°¿ô¤òÊÖ¤¹¡¥Ê¸»úÎó¤Ï¥Ê¥ëʸ»ú¤ò´Þ¤ó¤Ç¤Ï¤Ê¤é¤Ê¤¤¡¥
-
-@item length
-@itemx size
-
-ʸ»úÎó¤ÎŤµ(¥Ð¥¤¥È¿ô)¤òÊÖ¤¹¡¥
-
-@item ljust(@var{width})
-@itemx rjust(@var{width})
-@itemx center(@var{width})
-
-ʸ»úÎó¤ò¤½¤ì¤¾¤ì¡¤±¦µÍ¤á¡¤º¸µÍ¤á¡¤¿¿Ãæ´ó¤»¤·¤¿Éý@var{width}¤Îʸ»úÎó¤ò
-ÊÖ¤¹¡¥Ê¸»úÎóŤ¬@var{width}¤è¤êŤ¤¾ì¹ç¤Ï¸µ¤Îʸ»úÎó¤òÊÖ¤·¡¤ÀÚ¤êµÍ¤á¤Ê
-¤¤¡¥
-
-@item next
-
-@code{self}¤Î¡Ö¼¡¤Î¡×ʸ»úÎó¤òÊÖ¤¹¡¥¼¡¤Îʸ»úÎó¤È¤Ï¿ô»ú¤Ï¿ô»ú¤È¤·¤Æ¡¤±Ñ
-ʸ»ú¤Ï±Ñʸ»ú¤È¤·¤ÆÁý²Ã¤·¡¤·å¾å¤¬¤ê¤Î½èÍý¤¬¹Ô¤Ê¤ï¤ì¤¿¤â¤Î¤Ç¤¢¤ë¡¥
-
-@example
-"aa".next @result{} "ab"
-"99".next @result{} "100"
-"a9".next @result{} "b0"
-@end example
-
-@item oct
-
-ʸ»úÎó¤ò8¿Ê¿ô¤òɽ¤¹Ê¸»úÎó¤È²ò¼á¤·¤Æ¡¤À°¿ô¤ËÊÑ´¹¤¹¤ë¡¥8¿Ê¿ô¤ÎÄêµÁ¤Ï
-@code{/[0-7]+/}¤Ç¤¢¤ê¡¤Ê¸»úÎó¤ÎÀèƬ¤«¤é¤³¤Î¥Ñ¥¿¡¼¥ó¤Ë¥Þ¥Ã¥Á¤¹¤ëÉôʬ¤ò
-À°¿ô¤ËÊÑ´¹¤¹¤ë¡¥¤³¤ÎÄêµÁ¤ËÁ´¤¯Åö¤Æ¤Ï¤Þ¤é¤Ê¤¤Ê¸»úÎó¤ËÂФ·¤Æ¤Ï0¤òÊÖ¤¹¡¥
-perl¤È¤Ï°ã¤Ã¤Æʸ»úÎó¤¬0x¤«¤é»Ï¤Þ¤Ã¤Æ¤¤¤ë¤«¤é¤È¤¤¤Ã¤Æ 16¿Ê¿ô¤À¤È¸«¤Ê¤·
-¤Æ¤¯¤ì¤¿¤ê¤Ï¤·¤Ê¤¤¡¥¤½¤ì¤é¤ÏÀèƬ¤Î0¤¬8¿Ê¿ô¤Èǧ¼±¤µ¤ì¡¤0¤òÊÖ¤¹¡¥
-
-@item reverse
-@itemx reverse!
-
-ʸ»úÎó¤Î³Æ¥Ð¥¤¥È¤òµÕ½ç¤Ëʤ٤¿Ê¸»úÎó¤òÊÖ¤¹¡¥Ê¸»úÎó¤¬2¥Ð¥¤¥È¤Ç¹½À®¤µ¤ì
-¤ëʸ»ú¤ò´Þ¤ó¤Ç¤¤¤Æ¤â¤ª¹½¤¤¤Ê¤·¤Ë¥Ð¥¤¥Èñ°Ì¤Çȿž¤¹¤ë¡¥@code{split}¤Ï2
-¥Ð¥¤¥Èʸ»ú¤òÍý²ò¤¹¤ë¤Î¤Ç¡¤2¥Ð¥¤¥Èʸ»ú¤ò´Þ¤àʸ»úÎó¤òʸ»úñ°Ì¤Ëȿž¤¹¤ë
-¤Ë¤Ï
-
-@example
-"Á´³Ñʸ»úÎó".split(//).reverse.join("")
-@end example
-
-¤È¤¹¤ì¤Ð¤è¤¤¡¥
-
-@item rindex(@var{substr}[, @var{pos}])
-
-ʸ»úÎó@var{substr}¤¬ºÇ¸å¤Ë½Ð¸½¤¹¤ë°ÌÃÖ¤òÊÖ¤¹¡¥@var{pos}¤òÍ¿¤¨¤ë¤È¤½¤Î
-°ÌÃ֤Ǹ¡º÷¤ò½ªÎ»¤¹¤ë¡¥¸«¤Ä¤«¤é¤Ê¤¤»þ¤Ë¤Ï@code{nil}¤òÊÖ¤¹¡¥@code{index}
-¤È¤ÎÁê°ãÅÀ¤Ï
-
-@itemize
-@item
-ʸ»úÎó¤ÎËöÈø¤«¤é¸¡º÷¤¹¤ë¡¥
-@item
-substr¤È¤·¤ÆÀµµ¬É½¸½¤ò¼õ¤±ÉÕ¤±¤Ê¤¤¡¥
-@end itemize
-
-¤Î2ÅÀ¤Ç¤¢¤ë¡¥
-
-@item split([@var{sep}[, @var{limit}]])
-
-ʸ»úÎó¤ò@var{sep}¤Ç»ØÄꤵ¤ì¤¿¥Ñ¥¿¡¼¥ó¤Ë¤è¤Ã¤Æ¡¤¥Õ¥£¡¼¥ë¥É¤Ëʬ³ä¤¹¤ë¡¥
-@var{sep}¤¬¾Êά¤µ¤ì¤¿»þ¤Î¥Ç¥Õ¥©¥ë¥È¤Ï¥·¥¹¥Æ¥àÊÑ¿ô@code{$;}¤ÎÃͤ¬ÍѤ¤¤é
-¤ì¤ë¡¥@var{limit}¤¬»ØÄꤵ¤ì¤¿»þ¤Ë¤ÏºÇÂç@var{limit}¸Ä¤Î¥Õ¥£¡¼¥ë¥É¤Ëʬ³ä
-¤¹¤ë¡¥s@code{plit}¤Ïʬ³ä¤µ¤ì¤¿Ê¸»úÎó¤ò´Þ¤àÇÛÎó¤òÊÖ¤¹¡¥@var{sep}¤Ç»ØÄê
-¤µ¤ì¤¿¥Ñ¥¿¡¼¥ó¤¬¶õʸ»úÎó¤È¥Þ¥Ã¥Á¤¹¤ë¾ì¹ç¤Ïʸ»úÎó¤¬1ʸ»ú¤º¤Ä¤Ëʬ³ä¤µ¤ì
-¤ë¡¥
-
-@item squeeze([@var{str}])
-@itemx squeeze!([@var{str}])
-
-ʸ»úÎó¤Î¤¦¤Á¡¤@var{str}¤Ë´Þ¤Þ¤ì¤ëʸ»ú¤¬Ï¢Â³¤·¤Æ¤¤¤¿¾ì¹ç¡¤°ìʸ»ú¤Ë°µ½Ì
-¤¹¤ë¡¥@var{str}¤¬¾Êά¤µ¤ì¤¿¾ì¹ç¡¤¤¹¤Ù¤Æ¤Îʸ»ú¤òÂоݤȤ¹¤ë¡¥Ê¸»úÎó¤Î»Ø
-Äê¤Ïtr¤ÈƱÍͤǤ¢¤ê¡¤@code{a-b}¤Ç@code{a}¤«¤é@code{b}¤Þ¤Ç¤ÎÈϰϤò¡¤ÀèƬ
-¤Î@code{^}¤Çʸ»úÎó¤ÎÈÝÄê(´Þ¤Þ¤ì¤Æ¤Ê¤¤¤â¤Î¤ò»ØÄê)¤ò°ÕÌ£¤¹¤ë¡¥
-
-@item strip
-@itemx strip!
-
-ʸ»úÎó¤ÎÁ°¸å¤Î¶õÇò¤ò¼è¤ê½ü¤¯¡¥
-
-@item sub(@var{pattern}, @var{replace})
-@itemx sub(@var{pattern}) @{@dots{}@}
-@itemx sub!(@var{pattern}, @var{replace})
-@itemx sub!(@var{pattern}) @{@dots{}@}
-
-ʸ»úÎó¤Î@var{pattern}¤Ë¥Þ¥Ã¥Á¤¹¤ëºÇ½é¤ÎÉôʬ¤ò@var{replace}¤ËÃÖ¤­´¹¤¨¤ë¡¥
-ÃÖ´¹Ê¸»úÎó@var{replace}Ãæ¤Î@samp{&}¤È@samp{\0}¤Ï¥Þ¥Ã¥Á¤·¤¿Ê¸»úÎó¤Ë¡¤
-@samp{\1@dots{}\9}¤Ï nÈÖÌܤγç¸Ì¤ÎÆâÍƤËÃÖ¤­´¹¤¨¤é¤ì¤ë¡¥°ú¿ô
-@var{replace}¤Î¤Ê¤¤·Á¼°¤Î»þ¤Ë¤Ï¥¤¥Æ¥ì¡¼¥¿¤È¤·¤ÆÆ°ºî¤·¡¤¥Ö¥í¥Ã¥¯¤òɾ²Á
-¤·¤¿·ë²Ì¤ÇÃÖ´¹¤¹¤ë¡¥
-
-@code{sub}¤ÏÃÖ´¹¤µ¤ì¤¿Ê¸»úÎó¤òÊÖ¤¹(ÃÖ´¹¤¬¹Ô¤Ê¤ï¤ì¤Ê¤«¤Ã¤¿¾ì¹ç¤Ï¸µ¤Îʸ
-»úÎó¤òÊÖ¤¹)¡¥@code{sub!}¤ÏÃÖ´¹¤¬¹Ô¤Ê¤ï¤ì¤¿»þ¤Ë¤ÏÂоݤȤʤëʸ»úÎó¤ò¡¤¹Ô
-¤Ê¤ï¤ì¤Ê¤«¤Ã¤¿»þ¤Ë¤Ï@code{nil}¤òÊÖ¤¹¡¥
-
-@item sum([@var{bits}])
-
-ʸ»úÎó¤Î@var{bits}¥Ó¥Ã¥È¤Î¥Á¥§¥Ã¥¯¥µ¥à¤òÆÀ¤ë¡¥¾ÊάÃͤÏ16¤Ç¤¢¤ë¡¥ruby¤Ç
-¤Ï°Ê²¼¤Î¥³¡¼¥É¤ÇSystem V¤Î@code{sum}¥×¥í¥°¥é¥à¤ÈƱ¤¸ÃͤòÆÀ¤é¤ì¤ë¡¥
-
-@example
-while gets()
- sum += $_.sum
-end
-sum %= 65536
-@end example
-
-@item swapcase
-@itemx swapcase!
-
-ʸ»úÎóÃæ¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤Î¤¦¤ÁÂçʸ»ú¤ò¾®Ê¸»ú¤Ë¡¤¾®Ê¸»ú¤òÂçʸ»ú¤ËÃÖ¤­´¹
-¤¨¤ë¡¥
-
-@item to_f
-
-ʸ»úÎó¤òFloat¤ËÊÑ´¹¤¹¤ë¡¥
-
-@item to_i
-
-ʸ»úÎó¤ò10¿Ê¿ô¤òɽ¤¹Ê¸»úÎó¤È²ò¼á¤·¤Æ¡¤À°¿ô¤ËÊÑ´¹¤¹¤ë¡¥
-
-@item tr(@var{search}, @var{replace})
-@itemx tr!(@var{search}, @var{replace})
-
-ʸ»úÎó¤ÎÃæ¤Ë@var{search}ʸ»úÎó¤Ë´Þ¤Þ¤ì¤ëʸ»ú¤¬Â¸ºß¤¹¤ì¤Ð¡¤
-@var{replace}ʸ»úÎó¤ÎÂбþ¤¹¤ëʸ»ú¤ÇÃÖ¤­´¹¤¨¤ë¡¥@var{replace}ʸ»úÎ󤬾Ê
-ά¤µ¤ì¤¿¾ì¹ç¤Ï¶õʸ»úÎó¤¬Í¿¤¨¤é¤ì¤¿¤È¸«¤Ê¤¹¡¥@var{replace}ʸ»úÎó¤¬
-@var{search}ʸ»úÎó¤è¤ê¤âû¤¤»þ¤Ï@var{replace}ʸ»úÎó¤ÎºÇ¸å¤Îʸ»ú¤¬·«¤ê
-ÊÖ¤µ¤ì¤Æ¤¤¤ë¤È¸«¤Ê¤¹¡¥@var{search}ʸ»úÎó¤ÎÊý¤¬Ã»¤¤»þ¤Ë¤ÏÂбþ¤¹¤ëʸ»ú¤Î
-¤Ê¤¤@var{replace}Éô¤Ïñ¤Ë̵»ë¤µ¤ì¤ë(BSD¤Î@samp{tr}¤ÎÆ°ºî)¡¥
-
-@var{search}ʸ»úÎó¡¤@var{replace}ʸ»úÎóÃæ¤Ë@code{a-b}¤È¤¤¤¦·Á¼°¤¬¸½¤ì
-¤¿¾ì¹ç¡¤¤½¤Î@code{a}¤«¤é@code{b}¤Þ¤Ç¤ÎÈϰϤÎʸ»ú¤òASCII¤Î¾º½ç¤Ç»ØÄꤷ
-¤¿¤³¤È¤Ë¤Ê¤ë¡¥¤Þ¤¿¡¤@var{search}ʸ»úÎó¤ÎºÇ½é¤Îʸ»ú¤¬@code{^}¤Ç¤¢¤ë¾ì¹ç¡¤
-³¤¯Ê¸»úÎó¤Ë*´Þ¤Þ¤ì¤Ê¤¤*ʸ»úÎó¤¬ÃÖ´¹¤ÎÂоݤˤʤ롥
-
-@samp{tr(1)}¤Îµ¡Ç½¤Î¤¦¤Á¡¤Ê¸»ú¤òºï½ü¤¹¤ëµ¡Ç½¡¤Ï¢Â³¤¹¤ëʸ»ú¤ò°µ½Ì¤¹¤ëµ¡
-ǽ¤ÏÊ̤Υ᥽¥Ã¥É¤Ëʬ³ä¤µ¤ì¤Æ¤¤¤ë¡¥¤½¤ì¤é¤Îµ¡Ç½¤Ë¤Ä¤¤¤Æ¤Ï@code{delete}¡¤
-@code{squeeze}¤ò»²¾È¤Î¤³¤È¡¥
-
-´ÊÊؤΤ¿¤á¡¤@code{str.tr(src,repl).squeeze(repl)}¤ËÁêÅö¤¹¤ë¥á¥½¥Ã¥É
-@code{tr_s(src,repl)}¤¬Ä󶡤µ¤ì¤Æ¤¤¤ë¡¥
-
-@item unpack(@var{template})
-
-ʸ»úÎó¤ò@var{template}ʸ»úÎó¤Ë¤·¤¿¤¬¤Ã¤Æ¥¢¥ó¥Ñ¥Ã¥¯¤·¡¤¤½¤ì¤é¤ÎÍ×ÁǤò´Þ
-¤àÇÛÎó¤òÊÖ¤¹¡¥@var{template}ʸ»úÎó¤ÏArray¥¯¥é¥¹¤Îpack¥á¥½¥Ã¥É¤È¤Û¤ÜƱ
-ÍͤǤ¢¤ë¡¥
-
-@display
-a ASCIIʸ»úÎó(¸å³¤¹¤ënullʸ»ú¤ä¥¹¥Ú¡¼¥¹¤ò»Ä¤¹)
-A ASCIIʸ»úÎó(¸å³¤¹¤ënullʸ»ú¤ä¥¹¥Ú¡¼¥¹¤òºï½ü)
-b ¥Ó¥Ã¥È¥¹¥È¥ê¥ó¥°(²¼°Ì¥Ó¥Ã¥È¤«¤é¾å°Ì¥Ó¥Ã¥È)
-B ¥Ó¥Ã¥È¥¹¥È¥ê¥ó¥°(¾å°Ì¥Ó¥Ã¥È¤«¤é²¼°Ì¥Ó¥Ã¥È)
-h 16¿Êʸ»úÎó(²¼°Ì¥Ë¥Ö¥ë¤¬Àè)
-H 16¿Êʸ»úÎó(¾å°Ì¥Ë¥Ö¥ë¤¬Àè)
-c char
-C unsigned char
-s sort
-S unsigned sort
-i int
-I unsigned int
-l long
-L unsigned int
-n ¥Í¥Ã¥È¥ï¡¼¥¯¥Ð¥¤¥È¥ª¡¼¥À¡¼¤Îshort
-N ¥Í¥Ã¥È¥ï¡¼¥¯¥Ð¥¤¥È¥ª¡¼¥À¡¼¤Îlong
-f ñÀºÅÙÉâÆ°¾®¿ôÅÀ¿ô(µ¡¼ï°Í¸)
-d ÇÜÀºÅÙÉâÆ°¾®¿ôÅÀ¿ô(µ¡¼ï°Í¸)
-x 1¥Ð¥¤¥ÈÆɤßÈô¤Ð¤¹
-X 1¥Ð¥¤¥È¸åÂà
-@@ ÀäÂаÌÃ֤ؤΰÜÆ°
-@end display
-
-ruby¤Î@code{unpack}¤Ïperl¤È°ã¤Ã¤Æ¥Á¥§¥Ã¥¯¥µ¥à¤Î·×»»µ¡Ç½¤¬¤Ê¤¤¤³¤È¤ËÃí
-°Õ¤¹¤ë¤³¤È¡¥
-
-
-@item upcase
-@itemx upcase!
-
-ʸ»úÎóÃæ¤Î¥¢¥ë¥Õ¥¡¥Ù¥Ã¥È¤òÁ´¤ÆÂçʸ»ú¤ËÃÖ¤­´¹¤¨¤¿Ê¸»úÎó¤òÊÖ¤¹¡¥
-@code{tr("a-z", "A-Z")}¤è¤ê¾¯¤·Â®¤¤¡¥
-
-@item upto(@var{end}) @{@dots{}@}
-
-@code{self}¤«¤é»Ï¤Þ¤Ã¤Æ¡¤@var{end}¤Þ¤Ç¡Ö¼¡¤Î¡×ʸ»úÎó¤ò½ç¤ËÍ¿¤¨¤ë¥¤¥Æ¥ì¡¼
-¥¿¡¥¼¡¤Îʸ»úÎó¤È¤Ï@code{str.next}¤ÇÍ¿¤¨¤é¤ì¤ëʸ»úÎó¤Ç¤¢¤ë¡¥
-
-¤³¤Î¥á¥½¥Ã¥É¤Ï@code{Range:each}¤ÇÍѤ¤¤é¤ì¤Æ¤¤¤ë¤Î¤Ç¡¤°Ê²¼¤Î¤è¤¦¤Ê½èÍý
-¤¬²Äǽ¤Ç¤¢¤ë¡¥
-
-@example
-for i in "a" .. "ba"
- print(i, "\n");
-end
-@end example
-
-¤³¤ì¤Ï@samp{a, b, c,@dots{}aa,@dots{}az, ba}¤Þ¤Ç¤ò³Æ¹Ô¤Ë½ÐÎϤ¹¤ë¡¥
-@end ftable
-
-Single Methods:
-
-@ftable @code
-@item new(@var{string})
-
-@var{string}¤ÈƱ¤¸ÆâÍƤò»ý¤Ä¿·¤·¤¤Ê¸»úÎó¤òÊÖ¤¹¡¥
-@end ftable
-
-@xref{Object}
-@xref{Enumerable}
-@xref{Comparable}
-
-@node Struct, Time, String, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Struct
-
-¹½Â¤ÂÎ¥¯¥é¥¹¡¥¤³¤Î¥¯¥é¥¹¤Î¥µ¥Ö¥¯¥é¥¹¤ÏÊ£¿ô¤Î¥Ç¡¼¥¿¤ò¤Þ¤È¤á¤ë»þ¤ËÍѤ¤¤é
-¤ì¤ë(Îã: @code{Time:times})¡¥¥Ç¡¼¥¿¤ò¤Þ¤È¤á¤ë»þ¤Ë¤ÏÇÛÎ󥯥饹¤¬ÍѤ¤¤é
-¤ì¤ë¤³¤È¤â¤¢¤ë¤¬(Îã: @code{select})¡¤¹½Â¤ÂΤò»È¤¦¤Ù¤­»þ¤Ï°Ê²¼¤Î¤è¤¦¤Ê
-¾ì¹ç¤Ç¤¢¤ë¡¥@code{Struct:new}¤Ï@code{Struct}¤Î¥µ¥Ö¥¯¥é¥¹¤ò¿·¤¿¤ËÀ¸À®¤·
-¤Æ¡¤¤½¤ì¤òÊÖ¤¹¡¥¹½Â¤ÂΤϤ½¤Î¥µ¥Ö¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤È¤Ê¤ë¡¥
-
-@enumerate
-@item
-Í×ÁǤοô¤¬¸ÇÄê
-
-Í×ÁǤοô¤¬ÊÑÆ°¤¹¤ë¤â¤Î¤Ï¹½Â¤ÂΤò»È¤¦¤Î¤Ë¤Ï¸þ¤«¤Ê¤¤¡¥
-
-@item
-Í×ÁǤοô¤¬Â¿¤¤
-
-¿Í´Ö¤¬°ìÅÙ¤ËÍưפ˰·¤¨¤ë³µÇ°¤Î¿ô¤Ï7¤Ä¤Þ¤Ç¤Ç¤¢¤ë¤È¤¤¤¦²¾À⤬¤¢¤ë¡¥¤³¤Î
-²¾Àâ¤Ë½¾¤¨¤Ð¡¤Í×ÁǤ¬4¤Ä°Ê¾å¤¢¤ë¥Ç¡¼¥¿¤Î¾ì¹ç¤ÏÇÛÎó¤òÍѤ¤¤¿¾ì¹ç¡¤Í×ÁÇ¿ô
-¤Î2ÇÜ(¤Ä¤Þ¤ê¥ª¥Õ¥»¥Ã¥È¤È¤½¤Î°ÕÌ£¤ÎÁíÏÂ)¤¬7¤ò±Û¤¨¤ë¡¥¤è¤Ã¤Æ¡¤¤½¤Î¤è¤¦¤Ê
-¾ì¹ç¤Ë¤Ï¹½Â¤ÂΤò»È¤Ã¤¿Êý¤¬Íý²ò¤·¤ä¤¹¤¤¤È»×¤ï¤ì¤ë¡¥
-
-@item
-Ʊ»þ¤ËÂçÎ̤ËÀ¸À®¤µ¤ì¤Ê¤¤
-
-¹½Â¤ÂΤÏÇÛÎó¤è¤ê¤â¼ã´³À¸À®¥³¥¹¥È¤¬¹â¤¤¤Î¤Ç¡¤Â®ÅÙ¤¬ÌäÂê¤Ë¤Ê¤ë¾ì¹ç (Î㤨
-¤ÐƱ»þ¤ËÂçÎ̤ËÀ¸À®¤µ¤ì¤ë¾ì¹ç¤Ê¤É)¤Ï¹½Â¤ÂΤλÈÍѤ¬Å¬ÀڤǤʤ¤²ÄǽÀ­¤¬¤¢
-¤ë¡¥
-@end enumerate
-
-³Æ¹½Â¤ÂΤˤϥá¥ó¥Ð̾¤ÈƱ̾¤Î°ú¿ô¤Î¤Ê¤¤¥á¥½¥Ã¥É¤¬ÄêµÁ¤µ¤ì¤ë¡¥
-
-Ëܥɥ­¥å¥á¥ó¥ÈÆâ¤Ç¡¤¹½Â¤ÂΤòɽ¸½¤¹¤ë¤¿¤á¤Ë¤Ï°Ê²¼¤Î·Á¼°¤ò»È¤¦¡¥
-
-@display
-struct ¹½Â¤ÂÎ̾
- ¥á¥ó¥Ð@dots{}
-end
-@end display
-
-¤·¤«¤·¡¤¥×¥í¥°¥é¥àÃæ¤Ç¤³¤Î·Á¼°¤Ç¹½Â¤ÂΤòÀ¸À®¤¹¤ë¤ï¤±¤Ç¤Ï¤Ê¤¤¡¥
-
-SuperClass: Object
-
-Included Modules: Enumerable
-
-Methods:
-
-@ftable @code
-@item self[@var{idx}]
-
-@var{idx}¤¬¿ô¤Î»þ¤Ï@var{idx}ÈÖÌܤÎÍ×ÁǤòÊÖ¤¹¡¥
-
-@item values
-@itemx to_a
-
-¹½Â¤ÂΤΥá¥ó¥Ð¤ÎÃͤòÍ×ÁǤ˻ý¤ÄÇÛÎó¤òÊÖ¤¹¡¥Î㤨¤Ð°Ê²¼¤Î¥³¡¼¥É¤Ç¼«Ê¬¤Î
-passwd¥¨¥ó¥È¥ê¤ò½ÐÎϤ¹¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥
-
-@example
-print(Etc.getpwuid().values.join(":"), "\n")
-@end example
-
-¤³¤Î½ÐÎϤÏ@samp{grep "$USER" /etc/passwd}¤Î½ÐÎϤÈ;ʬ¤Ê¥Õ¥£¡¼¥ë¥É¤¬¤¤
-¤¯¤Ä¤«(¥·¥¹¥Æ¥à¤Ë¤è¤Ã¤Æ°Û¤Ê¤ë)¤¬¤¢¤ë°Ê³°¤ÏƱ¤¸¤Ç¤¢¤ë¡¥
-@end ftable
-
-Single Methods:
-
-@ftable @code
-@item new(@var{name}, @var{member}@dots{})
-
-@var{name}¤È¤¤¤¦Ì¾Á°¤ò»ý¤Ä¹½Â¤ÂΤΥ¯¥é¥¹¤òÀ¸À®¤¹¤ë¡¥@var{member_value}
-¤Ï¹½Â¤ÂΤΥá¥ó¥Ð¤òɽ¤¹Ê¸»úÎó¤Ç¤¢¤ë¡¥À¸À®¤µ¤ì¤¿¹½Â¤ÂÎ¥¯¥é¥¹¤Ë¤Ï¥á¥ó¥Ð¤Ç
-»ØÄꤵ¤ì¤¿Ì¾Á°¤Î¥á¥½¥Ã¥É¤¬ÄêµÁ¤µ¤ì¤Æ¤¤¤Æ¡¤¤½¤Î¥á¥½¥Ã¥É¤Ë¤è¤Ã¤Æ¥á¥ó¥Ð¤Î
-ÆâÍƤòÆÀ¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥
-@end ftable
-
-Single Methods for subclasses:
-
-@ftable @code
-@item new(@var{value}@dots{})
-
-¹½Â¤ÂÎ¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤òÀ¸À®¤¹¤ë¡¥@var{value}¤Ï¹½Â¤ÂΤΥá¥ó¥Ð¤ÎÃÍ
-¤Ç¤¢¤ë¡¥¥á¥ó¥Ð¤Î¿ô¤¬¹½Â¤ÂÎ¥¯¥é¥¹¤ÇÄêµÁ¤µ¤ì¤¿¿ô¤È°Û¤Ê¤ë»þ¤Ë¤ÏÎã³°¤¬È¯À¸
-¤¹¤ë¡¥
-@end ftable
-
-@xref{Object}
-@xref{Enumerable}
-
-@node Time, , Struct, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë
-@comment node-name, next, previous, up
-@section Time
-
-»þ´Ö¤òɽ¤¹¥¯¥é¥¹¡¥Âç¾®Èæ³Ó¤Ê¤É¤¬¤Ç¤­¤ë¡¥@code{Time.now}¤Ç¸½ºß¤Î»þ´Ö¤ò
-ÆÀ¤ë¤³¤È¤¬¤Ç¤­¤ë¡¥¤Þ¤¿¥Õ¥¡¥¤¥ë¤Î¥¿¥¤¥à¥¹¥¿¥ó¥×¤òÆÀ¤ë¥á¥½¥Ã¥É¤ÎÌá¤êÃͤâ
-¤³¤Î¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ç¤¢¤ë¡¥
-
-SuperClass: Object
-
-Included Modules: Comparable
-
-Methods:
-
-@ftable @code
-@item self <=> @var{other}
-
-@var{other}¤ÏTime¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤«À°¿ô¡¥À°¿ô¤¬Í¿¤¨¤é¤ì¤¿¾ì¹ç¤Ë¤Ï
-@samp{1970ǯ1·î 1Æü 00:00:00 GMT}¤«¤é¤ÎÉÿô¤Ç¤¢¤ë¤È¤·¤Æ»þ¹ï¤È¤ÎÈæ³Ó¤ò
-¹Ô¤Ê¤¦¡¥
-
-@item asctime
-@itemx ctime
-@itemx to_s
-
-»þ¹ï¤ò@samp{date(1)}·Á¼°¤Îʸ»úÎó¤ËÊÑ´¹¤¹¤ë¡¥
-
-@item gmtime
-
-¥¿¥¤¥à¥¾¡¼¥ó¤Î½¤Àµ¤ò¹Ô¤Ê¤ï¤Ê¤¤GMT¤Ç¤Î»þ¹ï¤òÆÀ¤ë¡¥¤³¤Î¥á¥½¥Ã¥É¤ò¼õ¤±¤È¤Ã
-¤¿Time¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤Ï¡¤°Ê¸å¤Î»þ¹ïÊÑ´¹¤òGMT¤Ç¹Ô¤Ê¤¦¡¥
-@code{gmtime}¤Ï¼«Ê¬¼«¿È¤òÊÖ¤¹¡¥
-
-¥í¥ó¥É¥ó¤Î»þ¹ï¤òɽ¼¨¤¹¤ë¤Ë¤Ï@code{print(Time.now.gmtime, "\n")}¤È¤¹¤ì
-¤Ð¤è¤¤¡¥
-
-@item localtime
-
-¥¿¥¤¥à¥¾¡¼¥ó¤Î½¤Àµ¤ò¹Ô¤Ê¤Ã¤¿»þ¹ï¤òÆÀ¤ë(¥Ç¥Õ¥©¥ë¥È)¡¥@code{localtime}¤Ï
-¼«Ê¬¼«¿È¤òÊÖ¤¹¡¥
-
-@item to_i
-@itemx tv_sec
-
-@samp{1970ǯ 1·î 1Æü 00:00:00 GMT}¤«¤é»þ¹ï¤Þ¤Ç¤ÎÉÿô¤òÀ°¿ô¤ÇÊÖ¤¹¡¥»þ¹ï
-¤Îsecond¤ÎÉôʬ¤Ç¤â¤¢¤ë¡¥
-
-@item sec
-@itemx min
-@itemx hour
-@itemx mday
-@itemx year
-@itemx wday
-@itemx yday
-@itemx zone
-@itemx isdst
-
-ÆâÉôŪ¤ËÊÝ»ý¤·¤Æ¤¤¤ë@code{tm}¹½Â¤ÂΤÎÆâÍƤòÊÖ¤¹¡¥@code{zone}°Ê³°¤ÏÀ°¿ô
-¤òÊÖ¤¹¡¥@code{zone}¤Ï¥¿¥¤¥à¥¾¡¼¥ó¤òɽ¤¹Ê¸»úÎó¤òÊÖ¤¹¡¥(cf
-@samp{localtime(3)})
-
-@item strftime(@var{format})
-
-»þ¹ï¤ò@var{format}ʸ»úÎó¤Ë½¾¤Ã¤Æʸ»úÎó¤ËÊÑ´¹¤·¤¿·ë²Ì¤òÊÖ¤¹¡¥
-@var{format}ʸ»úÎó¤È¤·¤Æ»ØÄê¤Ç¤­¤ë¤â¤Î¤Ï °Ê²¼¤ÎÄ̤ê¤Ç¤¢¤ë¡¥
-
-@display
-%A ÍËÆü¤Î̾¾Î(Sunday, Monday@dots{})
-%a ÍËÆü¤Î¾Êά̾(Sun, Mon@dots{})
-%B ·î¤Î̾¾Î(January, February@dots{})
-%b ·î¤Î¾Êά̾(Jan, Feb@dots{})
-%c »þ¹ïɽ¸½(cf @samp{ctime(3)})
-%d ½½¿Ê¿ô¤Ç¤ÎÆü(01-31)
-%H 24»þ´ÖÀ©¤Î»þ(00-23)
-%I 12»þ´ÖÀ©¤Î»þ(01-12)
-%j ǯÃæ¤ÎÄÌ»»Æü(001-366)
-%M ʬ(00-59)
-%m ·î¤òɽ¤¹¿ô»ú(01-12)
-%p ¸áÁ°¤Þ¤¿¤Ï¸á¸å(AM,PM)
-%S ÉÃ(00-61)
-%U ½µ¤òɽ¤¹¿ô»ú¡¥ºÇ½é¤ÎÆüÍËÆü¤¬Âè1½µ¤Î
- »Ï¤Þ¤ê(00-53)
-%W ½µ¤òɽ¤¹¿ô»ú¡¥ºÇ½é¤Î·îÍËÆü¤¬Âè1½µ¤Î
- »Ï¤Þ¤ê(00-53)
-%w ÍËÆü¤òɽ¤¹¿ô»ú¡¥ÆüÍËÆü¤¬0(0-6)
-%X »þ¹ï(Îã: 15:01:06)
-%x ÆüÉÕ(Îã: Fri Jan 14 1994)
-%Y À¾Îñ¤òɽ¤¹¿ô»ú
-%y À¾Îñ¤Î²¼2·å(00-99)
-%Z ¥¿¥¤¥à¥¾¡¼¥ó
-%% %¼«¿È
-@end display
-
-@item usec
-@itemx tv_usec
-
-»þ¹ï¤Îmicro second¤ÎÉôʬ¤òÊÖ¤¹¡¥
-@end ftable
-
-Single Methods:
-
-@ftable @code
-@item now
-
-¸½ºß¤Î»þ¹ï¤òɽ¤¹@code{Time}¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤òÀ¸À®¤¹¤ë¡¥
-
-@item at(@var{time})
-
-@var{time}¤ÈƱ¤¸»þ¹ï¤òɽ¤¹@code{Time}¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤òÀ¸À®¤¹¤ë¡¥
-@var{time}¤Ï@code{Time}¥¯¥é¥¹¤Î¥¤¥ó¥¹¥¿¥ó¥¹¤«¤¢¤ë¤¤¤Ï¿ô(À°¿ô/ÉâÆ°¾®¿ô
-ÅÀ¿ô)¤Ç¤¢¤ê¡¤¿ô¤Î¾ì¹ç¤Ï@samp{1970ǯ 1·î 1Æü 00:00:00 GMT}¤«¤é¤ÎÉÿô¤Ç
-¤¢¤ë¤È¤·¤Æ»þ¹ï¤ò·×»»¤¹¤ë¡¥
-
-@item times
-
-¸½ºß¤Î¥×¥í¥»¥¹¤È¤½¤Î»Ò¥×¥í¥»¥¹¤¬¾ÃÈñ¤·¤¿¥æ¡¼¥¶/¥·¥¹¥Æ¥àCPU¥¿¥¤¥à¤ÎÀÑ»»
-¤ò¹½Â¤ÂΤȤ·¤ÆÊÖ¤¹(@xref{Struct})¡¥
-
-@display
-struct tms
- utime # ¥×¥í¥»¥¹¤Î¥æ¡¼¥¶»þ´Ö
- stime # ¥×¥í¥»¥¹¤Î¥·¥¹¥Æ¥à»þ´Ö
- cutime # »Ò¥×¥í¥»¥¹¤Î¥æ¡¼¥¶»þ´Ö
- cstime # »Ò¥×¥í¥»¥¹¤Î¥·¥¹¥Æ¥à»þ´Ö
-end
-@end display
-
-»þ´Ö¤Îñ°Ì¤ÏÉäǤ¢¤ê¡¤ÉâÆ°¾®¿ôÅÀ¿ô¤ÇÍ¿¤¨¤é¤ì¤ë¡¥¾ÜºÙ¤Ï@samp{times(3)}
-¤ò»²¾È¤Î¤³¤È¡¥
-@end ftable
-
-@xref{Object}
-@xref{Comparable}
-
-@node C¸À¸ì¤È¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹, ¼Õ¼­, ÁȤ߹þ¤ß¥¯¥é¥¹¤È¥â¥¸¥å¡¼¥ë, Top
-@comment node-name, next, previous, up
-@chapter C¸À¸ì¤È¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹
-
-ruby¤ÏC¸À¸ì¤È¤Î¥¤¥ó¥¿¡¼¥Õ¥§¡¼¥¹¤òÄ󶡤·¡¤C¸À¸ì¤«¤é¤Î¥¯¥é¥¹¡¤¥â¥¸¥å¡¼¥ë
-¤ÎÄêµÁ¡¤C¸À¸ì¤Çµ­½Ò¤·¤¿¥á¥½¥Ã¥É¤ÎÄêµÁ¡¤ruby¤Î¥á¥½¥Ã¥É¤Î¸Æ¤Ó½Ð¤·¡¤¥¤¥Æ
-¥ì¡¼¥¿¤Î¸Æ¤Ó½Ð¤·¡¤Îã³°½èÍý¤Ê¤É¤ò¹Ô¤Ê¤¦¤³¤È¤¬½ÐÍè¤ë¡¥¤Þ¤¿¡¤OS¤¬µö¤»¤Ð¼Â
-¹Ô»þ¤ËC¤Ç½ñ¤«¤ì¤¿¥â¥¸¥å¡¼¥ë¤ò¥í¡¼¥É¤¹¤ë¤³¤È¤â½ÐÍè¤ë¡¥
-
-¶ñÂÎŪ¤Ê¥¤¥ó¥¿¥Õ¥§¡¼¥¹¤Ë´Ø¤·¤Æ¤Ï¡¤Ê̥ɥ­¥å¥á¥ó¥È(źÉÕ¥Õ¥¡¥¤¥ë C-IF)¤ò
-»²¾È¤Î¤³¤È¡¥
-
-@node ¼Õ¼­, ʸˡ, C¸À¸ì¤È¤Î¥¤¥ó¥¿¥Õ¥§¡¼¥¹, Top
-@comment node-name, next, previous, up
-@chapter ¼Õ¼­
-
-Ruby¤Î¸À¸ì»ÅÍͤϿô¿¤¯¤Î¸À¸ì¤Î±Æ¶Á¤ò¼õ¤±¤Æ¤¤¤ë¡¥°Ê²¼¤Ë¤¢¤²¤ë¤Î¤Ï¤½¤Î¼ç
-¤Ê¸À¸ì¤Ç¤¢¤ë¡¥
-
- C, Perl, CLU, Sather, CLOS, Eiffel, Icon, tcl, AWK, bourne shell,
- Smalltalk, Emacs Lisp.
-
-¤Þ¤¿ruby¤Î¸À¸ì»ÅÍͤò·èÄꤹ¤ë¤¿¤á¤Ë¶¨ÎϤ·¤Æ²¼¤µ¤Ã¤¿Êý¡¹¤ò°Ê²¼¤Ë¤¢¤²¤ë¡¥
-
- ÀÐÄÍ·½¼ù¡¤ÂçÄí¹¯À¸¡¤°ËÆ£½ã°ìϺ¡¤Ã漡÷£Î£Å£Ã¡¥´Øº¬¡÷ÆüËܣģţá¤
- ¤¿¤Ê¤«¡÷ÀÖºä.ÉÙ»ÎÄÌ(·É¾Îά)¡¥
-
-@node ʸˡ, Variables Index, ¼Õ¼­, Top
-@comment node-name, next, previous, up
-@chapter ʸˡ
-
-°Ê²¼¤Ïµ¿»÷BNF¤Çµ­½Ò¤·¤¿ruby¤Îʸˡ¤Ç¤¢¤ë¡¥¤è¤êÀµ³Î¤Êµ­½Ò¤Ïparse.y¤ò»²¾È
-¤µ¤ì¤¿¤¤¡¥
-
-@example
-PROGRAM : COMPEXPR
-
-COMPEXPR : EXPR (TERM EXPR)* [TERM]
-
-EXPR : MLHS `=' ARGS
- | return ARGS
- | fail ARGS
- | yield ARGS
- | defined? ARG
- | identifier CALL_ARGS0
- | PRIMARY `.' identifier CALL_ARGS0
- | super CALL_ARGS
- | undef FNAME
- | alias FNAME FNAME
- | include identifier (`,' identifier)*
- | EXPR if EXPR
- | EXPR while EXPR
- | EXPR and EXPR
- | EXPR or EXPR
- | ASSOCS
- | ARG
-
-ARG : LHS `=' ARG
- | LHS OP_ASGN ARG
- | ARG `..' ARG
- | ARG `...' ARG
- | ARG `+' ARG
- | ARG `-' ARG
- | ARG `*' ARG
- | ARG `/' ARG
- | ARG `%' ARG
- | ARG `**' ARG
- | `+' ARG
- | `-' ARG
- | ARG `|' ARG
- | ARG `^' ARG
- | ARG `&' ARG
- | ARG `<=>' ARG
- | ARG `>' ARG
- | ARG `>=' ARG
- | ARG `<' ARG
- | ARG `<=' ARG
- | ARG `==' ARG
- | ARG `!=' ARG
- | ARG `=~' ARG
- | ARG `!~' ARG
- | `!' ARG
- | `~' ARG
- | ARG `<<' ARG
- | ARG `>>' ARG
- | ARG `&&' ARG
- | ARG `||' ARG
- | ARG `::' identifier
- | PRIMARY
-
-PRIMARY : `(' COMPEXPR `)'
- | LITERAL
- | VARIABLE
- | super `(' [CALL_ARGS] `)'
- | super
- | PRIMARY `[' [ARGS] `]'
- | `[' [ARGS [`,']] `]'
- | `@{' [ (ARGS|ASSOCS) [`,'] ] `@}'
- | redo
- | break
- | continue
- | retry
- | return
- | fail [`(' [ARGS] `)']
- | yield [`(' [ARGS] `)']
- | defined? `(' ARG `)'
- | PRIMARY `@{' [`|' [ITER_VAR] `|'] COMPEXPR `@}'
- | OPERATION `(' [CALL_ARGS] `)'
- | PRIMARY `.' OPERATION `(' [CALL_ARGS] `)'
- | PRIMARY `.' OPERATION
- | if EXPR THEN
- COMPEXPR
- (elsif EXPR THEN COMPEXPR)*
- [else COMPEXPR]
- end
- | while EXPR TERM COMPEXPR end
- | case COMPEXPR
- (when ARGS THEN)+
- [else COMPEXPR]
- end
- | for ITER_VAR in EXPR TERM
- COMPEXPR
- end
- | begin
- COMPEXPR
- [rescue COMPEXPR]
- [ensure COMPEXPR]
- end
- | class identifier `:' identifier
- COMPEXPR
- end
- | module identifier
- COMPEXPR
- end
- | def FNAME ARGLIST
- COMPEXPR
- end
- | def SINGLETON `.' FNAME ARGLIST
- COMPEXPR
- end
-
-THEN : TERM
- | then
- | TERM then
-
-ITER_VAR : LHS
- | MLHS
-
-MLHS : LHS `,' [LHS (`,' LHS)*] [`*' LHS]
-
-LHS : VARIABLE
- | PRIMARY `[' [ARGS] `]'
- | PRIMARY `.' identifier
-
-CALL_ARGS : ARGS
- | ASSOCS
- | ARGS [`,' ASSOCS] [`,' `*' ARG]
- | `*' ARG
-
-ARGS : ARG (`,' ARG)*
-
-ARGLIST : `('[identifier(`,'identifier)*][`*'identifier]`)'
- | TERM
-
-SINGLETON : VARIABLE
- | `(' EXPR `)'
-
-ASSOCS : ASSOC (`,' ASSOC)*
-
-ASSOC : ARG `=>' ARG
-
-VARIABLE : VARNAME
- | nil
- | self
- | `__FILE__'
- | `__LINE__'
-
-LITERAL : numeric
- | SYMBOL
- | STRING
- | REGEXP
-
-TERM : `;'
- | `\n'
-
-@end example
-
-¤³¤³¤è¤ê²¼¤Ï»ú¶ç²òÀÏÉô¤Çǧ¼±¤µ¤ì¤ë¡¥
-
-@example
-
-SYMBOL : `:'FNAME
- | `:'VARNAME
-
-FNAME : identifier | `..' | `|' | `^' | `&'
- | `<=>' | `==' | `=~' | `>' | `>=' | `<' | `<='
- | `<<' | `>>' | `+' | `-' | `*' | `/' | `%' | `**'
- | `~' | `+@@' | `-@@' | `[]' | `[]='
-
-OPERATION : identifier
- | identifier'!'
- | identifier'?'
-
-VARNAME : GLOBAL
- | `@@'identifier
- | identifier
-
-GLOBAL : `$'identifier
- | `$'any_char
-
-STRING : `"' any_char* `"'
- | `'' any_char* `''
- | ``' any_char* ``'
-
-REGEXP : `/' any_char* `/'[i]
-
-@end example
-
-@node Variables Index, Concept Index, Function Index, Top
-@comment node-name, next, previous, up
-@unnumbered Variable Index
-
-@printindex vr
-
-@node Concept Index, Function Index , Variables Index, Top
-@comment node-name, next, previous, up
-@unnumbered Concept Index
-
-@printindex cp
-
-@node Function Index, Top , Concept Index, Top
-@comment node-name, next, previous, up
-@unnumbered Function Index
-
-@printindex fn
-
-@summarycontents
-@contents
-@bye
-
-Local variables:
-fill-column: 70
-end:
diff --git a/sample/clnt.rb b/sample/clnt.rb
index c8c4b2db9f..7998379aa2 100644
--- a/sample/clnt.rb
+++ b/sample/clnt.rb
@@ -3,15 +3,15 @@
require "socket"
-host=(if $ARGV.length == 2; $ARGV.shift; else "localhost"; end)
+host=(if ARGV.length == 2; ARGV.shift; else "localhost"; end)
print("Trying ", host, " ...")
STDOUT.flush
-s = TCPsocket.open(host, $ARGV.shift)
+s = TCPsocket.open(host, ARGV.shift)
print(" done\n")
print("addr: ", s.addr.join(":"), "\n")
print("peer: ", s.peeraddr.join(":"), "\n")
while gets()
s.write($_)
- print(s.gets)
+ print(s.readline)
end
s.close
diff --git a/sample/dir.rb b/sample/dir.rb
index 3349dc7b6d..1fc0bb2aa8 100644
--- a/sample/dir.rb
+++ b/sample/dir.rb
@@ -1,9 +1,9 @@
# directory access
# list all files but .*/*~/*.o
dirp = Dir.open(".")
-dirp.rewind
for f in dirp
- if !(~/^\./ || ~/~$/ || ~/\.o/)
+ $_ = f
+ if (~/^\./ || ~/~$/ || ~/\.o/)
print f, "\n"
end
end
diff --git a/sample/eval.rb b/sample/eval.rb
new file mode 100644
index 0000000000..da31b77153
--- /dev/null
+++ b/sample/eval.rb
@@ -0,0 +1,41 @@
+line = ''
+indent=0
+print "ruby> "
+while TRUE
+ l = gets
+ if not l
+ break if line == ''
+ else
+ line = line + l
+ if l =~ /,\s*$/
+ print "ruby| "
+ next
+ end
+ if l =~ /^\s*(class|module|def|if|case|while|for|begin)\b[^_]/
+ indent += 1
+ end
+ if l =~ /^\s*end\b[^_]/
+ indent -= 1
+ end
+ if l =~ /{\s*(\|.*\|)?\s*$/
+ indent += 1
+ end
+ if l =~ /^\s*\}/
+ indent -= 1
+ end
+ if indent > 0
+ print "ruby| "
+ next
+ end
+ end
+ begin
+ print eval(line).inspect, "\n"
+ rescue
+ $! = 'exception raised' if not $!
+ print "ERR: ", $!, "\n"
+ end
+ break if not l
+ line = ''
+ print "ruby> "
+end
+print "\n"
diff --git a/sample/evaldef.rb b/sample/evaldef.rb
deleted file mode 100644
index 2cedd54999..0000000000
--- a/sample/evaldef.rb
+++ /dev/null
@@ -1,26 +0,0 @@
-# method definition by eval()
-# output:
-# bar
-# (eval):26: method `baz' not available for "#<foo: 0xbfc5c>"(foo)
-
-class Foo
- def foo
- eval("
-def baz
- print(\"bar\n\")
-end")
- end
-end
-
-class Bar : Foo
- def bar
- baz()
- end
-end
-
-f = Foo.new
-b = Bar.new
-
-b.foo
-b.bar
-f.baz
diff --git a/sample/export.rb b/sample/export.rb
index 2d05d8afd7..750b5c1948 100644
--- a/sample/export.rb
+++ b/sample/export.rb
@@ -28,7 +28,7 @@ f.printf "%s\n", Foo
f.quux
-class Bar : Foo
+class Bar<Foo
def quux
super
baz()
diff --git a/sample/fact.rb b/sample/fact.rb
new file mode 100644
index 0000000000..49678bc9d0
--- /dev/null
+++ b/sample/fact.rb
@@ -0,0 +1,8 @@
+def fact(n)
+ if n == 0
+ 1
+ else
+ n * fact(n-1)
+ end
+end
+print fact(ARGV[0].to_i), "\n"
diff --git a/sample/from.rb b/sample/from.rb
index 2f5fcebe12..2ef000face 100755
--- a/sample/from.rb
+++ b/sample/from.rb
@@ -5,15 +5,15 @@ require "base64"
include ParseDate
-if $ARGV[0] == '-w'
+if ARGV[0] == '-w'
wait = TRUE
- $ARGV.shift
+ ARGV.shift
end
class Mail
def Mail.new(f)
- if !f.is_kind_of?(IO)
+ if !f.kind_of?(IO)
f = open(f, "r")
me = super
f.close
@@ -28,7 +28,7 @@ class Mail
@body = []
while f.gets()
$_.chop!
- continue if /^From / # skip From-line
+ next if /^From / # skip From-line
break if /^$/ # end of header
if /^(\S+):\s*(.*)/
@header[attr = $1.capitalize] = $2
@@ -56,7 +56,7 @@ class Mail
end
-$ARGV[0] = '/usr/spool/mail/' + ENV['USER'] if $ARGV.length == 0
+ARGV[0] = '/usr/spool/mail/' + ENV['USER'] if ARGV.length == 0
$outcount = 0;
def fromout(date, from, subj)
@@ -72,8 +72,8 @@ def fromout(date, from, subj)
$outcount += 1
end
-for file in $ARGV
- continue if !File.exists?(file)
+for file in ARGV
+ next if !File.exist?(file)
f = open(file, "r")
while !f.eof
mail = Mail.new(f)
diff --git a/sample/fullpath.pl b/sample/fullpath.pl
deleted file mode 100644
index a07b90edd4..0000000000
--- a/sample/fullpath.pl
+++ /dev/null
@@ -1,22 +0,0 @@
-#! /usr/local/bin/perl
-# convert ls-lR filename into fullpath.
-
-$path = shift;
-if (!defined $path) {
- $path = "";
-}
-elsif ($path !~ /\/$/) {
- $path .= "/"
-}
-
-while (<>) {
- if (/:$/) {
- chop; chop;
- $path = $_ . "/";
- } elsif (/^total/ || /^d/) {
- next;
- } elsif (/^(.*\d )(.+)$/) {
- print $1, $path, $2, "\n";
- }
-}
-
diff --git a/sample/fullpath.rb b/sample/fullpath.rb
index 6c528f6f96..ce268e20b9 100644
--- a/sample/fullpath.rb
+++ b/sample/fullpath.rb
@@ -1,9 +1,9 @@
#! /usr/local/bin/ruby
# convert ls-lR filename into fullpath.
-if $ARGV[0] =~ /-p/
- $ARGV.shift
- path = $ARGV.shift
+if ARGV[0] =~ /-p/
+ ARGV.shift
+ path = ARGV.shift
end
if path == nil
diff --git a/sample/getopts.test b/sample/getopts.test
index adef7628db..2866bccea8 100755
--- a/sample/getopts.test
+++ b/sample/getopts.test
@@ -3,13 +3,16 @@
load("parsearg.rb")
def usage()
- printf("Usage:\n")
- printf("This is Getopt test program \n")
+ printf "Usage:\n"
+ printf "%s -d [-x x] [-y y] [--geometry geom] [--version] [string ...]\n", $0
end
$USAGE = 'usage'
-parseArgs(0, !nil, "d", "x:", "y:", "version", "geometry:")
+parseArgs(0, "d&(x|y)", "dfg", "x:", "y:", "geometry:800x600", "version")
if ($OPT_d)
+ if $OPT_version
+ printf "version 1.0\n"
+ end
if ($OPT_x)
printf("x = %d\n", $OPT_x.to_i)
end
@@ -19,13 +22,15 @@ if ($OPT_d)
if ($OPT_geometry)
printf("geometry = %s\n", $OPT_geometry)
end
+ if $OPT_f
+ printf "f = TRUE\n"
+ end
+ if $OPT_g
+ printf "g = TRUE\n"
+ end
end
-if ($OPT_version)
- printf("version 1.00\n")
-end
-
-while ($ARGV.length != 0)
- print ("other = ", $ARGV[0], "\n")
- $ARGV.shift
+while (ARGV.length != 0)
+ print "other = ", ARGV[0], "\n"
+ ARGV.shift
end
diff --git a/sample/io.rb b/sample/io.rb
index c12e4f4498..0b38d2112d 100644
--- a/sample/io.rb
+++ b/sample/io.rb
@@ -15,8 +15,8 @@ for i in "abc\n\ndef\nghi\n"
print("tt: ", i)
end
-printf("%s:(%d)%s\n", $0, $ARGV.length, $ARGV[0])
-passwd = open($ARGV[0], "r")
+printf("%s:(%d)%s\n", $0, ARGV.length, ARGV[0])
+passwd = open(ARGV[0], "r")
#printf("%s", passwd.find{i|i =~ /\*/})
n = 1
diff --git a/sample/less.rb b/sample/less.rb
index b0906d5d22..8be359108f 100755
--- a/sample/less.rb
+++ b/sample/less.rb
@@ -3,8 +3,8 @@
ZCAT = "/usr/local/bin/zcat"
LESS = "/usr/local/bin/less"
-FILE = $ARGV.pop
-OPTION = (if $ARGV.length == 0; "" else $ARGV.join(" "); end)
+FILE = ARGV.pop
+OPTION = (if ARGV.length == 0; "" else ARGV.join(" "); end)
if FILE =~ /\.(Z|gz)$/
exec(format("%s %s | %s %s", ZCAT, FILE, LESS, OPTION))
diff --git a/sample/list.rb b/sample/list.rb
index 93e3182f84..76035e67d6 100644
--- a/sample/list.rb
+++ b/sample/list.rb
@@ -4,20 +4,20 @@ class MyElem
def initialize(item)
# @ÊÑ¿ô¤Ï¥¤¥ó¥¹¥¿¥ó¥¹ÊÑ¿ô(Àë¸À¤ÏÍפé¤Ê¤¤)
@data = item
- @next = nil
+ @succ = nil
end
def data
@data
end
- def next
- @next
+ def succ
+ @succ
end
# ¡Öobj.data = val¡×¤È¤·¤¿¤È¤­¤Ë°ÅÌۤ˸ƤФì¤ë¥á¥½¥Ã¥É
- def next=(new)
- @next = new
+ def succ=(new)
+ @succ = new
end
end
@@ -25,7 +25,7 @@ class MyList
def add_to_list(obj)
elt = MyElem.new(obj)
if @head
- @tail.next = elt
+ @tail.succ = elt
else
@head = elt
end
@@ -36,7 +36,7 @@ class MyList
elt = @head
while elt
yield elt
- elt = elt.next
+ elt = elt.succ
end
end
diff --git a/sample/mpart.rb b/sample/mpart.rb
index 2374ae0938..6c40d50e18 100755
--- a/sample/mpart.rb
+++ b/sample/mpart.rb
@@ -4,12 +4,12 @@
lines = 1000
-if ($ARGV[0] =~ /^-(\d+)$/ )
+if (ARGV[0] =~ /^-(\d+)$/ )
lines = $1.to_i;
- $ARGV.shift;
+ ARGV.shift;
end
-basename = $ARGV[0]
+basename = ARGV[0]
extname = "part"
part = 1
diff --git a/sample/observ.rb b/sample/observ.rb
new file mode 100644
index 0000000000..f7b1e73137
--- /dev/null
+++ b/sample/observ.rb
@@ -0,0 +1,31 @@
+#! /usr/local/bin/ruby
+
+require "thread"
+require "observer"
+
+class Tick
+ include Observable
+ def initialize
+ Thread.start do
+ while TRUE
+ sleep 0.999
+ changed
+ notify_observers(Time.now.strftime("%H:%M:%S"))
+ end
+ end
+ end
+end
+
+class Clock
+ def initialize
+ @tick = Tick.new
+ @tick.add_observer(self)
+ end
+ def update(time)
+ print "\e[8D", time
+ STDOUT.flush
+ end
+end
+
+clock = Clock.new
+sleep
diff --git a/sample/philos.rb b/sample/philos.rb
new file mode 100644
index 0000000000..ee0a8cd5fc
--- /dev/null
+++ b/sample/philos.rb
@@ -0,0 +1,54 @@
+#
+# The Dining Philosophers - thread example
+#
+require "thread"
+
+srand
+#srand
+N=9 # number of philosophers
+$forks = []
+for i in 0..N-1
+ $forks[i] = Mutex.new
+end
+$state = "-o"*N
+
+def wait
+ sleep rand(20)/10.0
+end
+
+def think(n)
+ wait
+end
+
+def eat(n)
+ wait
+end
+
+def philosopher(n)
+ while TRUE
+ think n
+ $forks[n].lock
+ if not $forks[(n+1)%N].try_lock
+ $forks[n].unlock # avoid deadlock
+ continue
+ end
+ $state[n*2] = ?|;
+ $state[(n+1)%N*2] = ?|;
+ $state[n*2+1] = ?*;
+ print $state, "\n"
+ eat(n)
+ $state[n*2] = ?-;
+ $state[(n+1)%N*2] = ?-;
+ $state[n*2+1] = ?o;
+ print $state, "\n"
+ $forks[n].unlock
+ $forks[(n+1)%N].unlock
+ end
+end
+
+for i in 0..N-1
+ Thread.start{philosopher(i)}
+ sleep 0.1
+end
+
+sleep
diff --git a/sample/pi.rb b/sample/pi.rb
new file mode 100644
index 0000000000..49067cc347
--- /dev/null
+++ b/sample/pi.rb
@@ -0,0 +1,18 @@
+#!/usr/local/bin/ruby
+
+k, a, b, a1, b1 = 2, 4, 1, 12, 4
+
+while TRUE
+ # Next approximation
+ p, q, k = k*k, 2*k+1, k+1
+ a, b, a1, b1 = a1, b1, p*a+q*a1, p*b+q*b1
+ # Print common digits
+ d = a / b
+ d1 = a1 / b1
+ while d == d1
+ print d
+ $stdout.flush
+ a, a1 = 10*(a%b), 10*(a1%b1)
+ d, d1 = a/b, a1/b1
+ end
+end
diff --git a/sample/rcs.rb b/sample/rcs.rb
index 13476267b2..3f74da9ef2 100644
--- a/sample/rcs.rb
+++ b/sample/rcs.rb
@@ -7,7 +7,7 @@ hdw = dw / 2.0
w = 20.0 # —¼Šá‚Ì•
h =1.0 # ‰æ–ʂƊʂ̋——£
d = 0.2 # ’PˆÊ“–‚½‚è‚Ì•‚‚«ã‚ª‚è•û
-ss="abcdefghijklmnopqrstuvwxyz0123456789!#$%^&*()-=\\[];'`,./"
+ss="abcdefghijklmnopqrstuvwxyz0123456789#!$%^&*()-=\\[];'`,./"
rnd = srand()
while gets()
diff --git a/sample/regx.rb b/sample/regx.rb
new file mode 100644
index 0000000000..b9d8ca6e14
--- /dev/null
+++ b/sample/regx.rb
@@ -0,0 +1,23 @@
+st = "\033[7m"
+en = "\033[m"
+#st = "<<"
+#en = ">>"
+
+while TRUE
+ print "str> "
+ STDOUT.flush
+ input = gets
+ break if not input
+ if input != ""
+ str = input
+ str.chop!
+ end
+ print "pat> "
+ STDOUT.flush
+ re = gets
+ break if not re
+ re.chop!
+ str.gsub! re, "#{st}&#{en}"
+ print str, "\n"
+end
+print "\n"
diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el
index b555994fea..9dfde8588c 100644
--- a/sample/ruby-mode.el
+++ b/sample/ruby-mode.el
@@ -7,8 +7,18 @@
;;; created at: Fri Feb 4 14:49:13 JST 1994
;;;
+(defconst ruby-mode-version "1.0.2")
+
(defconst ruby-block-beg-re
- "class\\|module\\|def\\|if\\|case\\|while\\|for\\|begin"
+ "class\\|module\\|def\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin\\|do"
+ )
+
+(defconst ruby-indent-beg-re
+ "\\(\\s *\\(class\\|module\\|def\\)\\)\\|if\\|unless\\|case\\|while\\|until\\|for\\|begin"
+ )
+
+(defconst ruby-modifier-re
+ "if\\|unless\\|while\\|until"
)
(defconst ruby-block-mid-re
@@ -18,13 +28,13 @@
(defconst ruby-block-end-re "end")
(defconst ruby-delimiter
- (concat "[?$/(){}#\"'`]\\|\\[\\|\\]\\|\\<\\("
- ruby-block-beg-re "\\|" ruby-block-end-re "\\)\\>")
+ (concat "[?$/%(){}#\"'`]\\|\\[\\|\\]\\|\\<\\("
+ ruby-block-beg-re "\\|" ruby-block-end-re "\\)\\>")
)
(defconst ruby-negative
- (concat "^[ \t]*\\(\\b\\(" ruby-block-mid-re "\\)\\|\\("
- ruby-block-end-re "\\)\\>\\|\\}\\|\\]\\)")
+ (concat "^[ \t]*\\(\\(" ruby-block-mid-re "\\)\\|\\("
+ ruby-block-end-re "\\)\\>\\|\\}\\|\\]\\)")
)
(defconst ruby-operator-chars "[,.+*/%-&|^~=<>:]")
@@ -44,6 +54,10 @@
(define-key ruby-mode-map "}" 'ruby-electric-brace)
(define-key ruby-mode-map "\e\C-a" 'ruby-beginning-of-defun)
(define-key ruby-mode-map "\e\C-e" 'ruby-end-of-defun)
+ (define-key ruby-mode-map "\e\C-b" 'ruby-beginning-of-block)
+ (define-key ruby-mode-map "\e\C-f" 'ruby-end-of-block)
+ (define-key ruby-mode-map "\e\C-p" 'ruby-beginning-of-block)
+ (define-key ruby-mode-map "\e\C-n" 'ruby-end-of-block)
(define-key ruby-mode-map "\t" 'ruby-indent-command)
(define-key ruby-mode-map "\C-m" 'ruby-reindent-then-newline-and-indent)
(define-key ruby-mode-map "\C-j" 'newline))
@@ -60,7 +74,7 @@
(modify-syntax-entry ?\n ">" ruby-mode-syntax-table)
(modify-syntax-entry ?\\ "'" ruby-mode-syntax-table)
(modify-syntax-entry ?$ "/" ruby-mode-syntax-table)
- (modify-syntax-entry ?? "/" ruby-mode-syntax-table)
+ (modify-syntax-entry ?? "_" ruby-mode-syntax-table)
(modify-syntax-entry ?_ "_" ruby-mode-syntax-table)
(modify-syntax-entry ?< "." ruby-mode-syntax-table)
(modify-syntax-entry ?> "." ruby-mode-syntax-table)
@@ -121,17 +135,6 @@ The variable ruby-indent-level controls the amount of indentation.
(back-to-indentation)
(current-column)))
-(defun ruby-delete-indentation ()
- (let
- ((b nil)
- (m nil))
- (save-excursion
- (beginning-of-line)
- (setq b (point))
- (back-to-indentation)
- (setq m (point)))
- (delete-region b m)))
-
(defun ruby-indent-line (&optional flag)
"Correct indentation of the current ruby line."
(ruby-indent-to (ruby-calculate-indent)))
@@ -141,222 +144,294 @@ The variable ruby-indent-level controls the amount of indentation.
(ruby-indent-line t))
(defun ruby-indent-to (x)
- (let ((p nil) beg end)
- (if (null x)
- nil
- (setq p (- (current-column) (ruby-current-indentation)))
- (ruby-delete-indentation)
- (beginning-of-line)
- (save-excursion
+ (if x
+ (let (shift top beg)
+ (and (< x 0)
+ (error "invalid nest"))
+ (setq shift (current-column))
+ (beginning-of-line)
(setq beg (point))
- (forward-line 1)
- (setq end (point)))
- (indent-to x)
- (if (> p 0) (forward-char p)))))
+ (back-to-indentation)
+ (setq top (current-column))
+ (skip-chars-backward " \t")
+ (cond
+ ((>= x shift)
+ (setq shift 0))
+ ((>= shift top)
+ (setq shift (- shift top)))
+ (t (setq shift 0)))
+ (if (and (bolp)
+ (= x top))
+ (move-to-column (+ x shift))
+ (move-to-column top)
+ (delete-region beg (point))
+ (beginning-of-line)
+ (indent-to x)
+ (move-to-column (+ x shift))))))
(defun ruby-expr-beg ()
(save-excursion
- (skip-chars-backward " \t")
- (or (bolp) (forward-char -1))
- (or (looking-at ruby-operator-chars)
- (looking-at "[\\[({]")
- (bolp)
- (and (looking-at ruby-symbol-chars)
- (forward-word -1)
- (or
- (looking-at ruby-block-beg-re)
- (looking-at ruby-block-mid-re))))))
+ (if (looking-at "\\?")
+ (progn
+ (or (bolp) (forward-char -1))
+ (not (looking-at "\\sw")))
+ (skip-chars-backward " \t")
+ (or (bolp) (forward-char -1))
+ (or (looking-at ruby-operator-chars)
+ (looking-at "[\\[({]")
+ (bolp)
+ (and (looking-at ruby-symbol-chars)
+ (forward-word -1)
+ (or
+ (looking-at ruby-block-beg-re)
+ (looking-at ruby-block-mid-re)))))))
(defun ruby-parse-region (start end)
(let ((indent-point end)
- (indent 0)
- (in-string nil)
- (in-paren nil)
- (depth 0)
- (nest nil))
+ (indent 0)
+ (in-string nil)
+ (in-paren nil)
+ (depth 0)
+ (nest nil)
+ (pcol nil))
(save-excursion
- (if start
- (goto-char start)
- (ruby-beginning-of-defun))
- (save-restriction
- (narrow-to-region (point) end)
- (while (and (> indent-point (point))
- (re-search-forward ruby-delimiter indent-point t))
- (let ((pnt (point)) w)
- (goto-char (match-beginning 0))
- (cond
-
- ((or (looking-at "\"") ;skip string
- (looking-at "'")
- (looking-at "`"))
- (setq w (char-after (point)))
- (cond
- ((and (not (eobp))
- (equal w (char-after (point)))
- (re-search-forward (format "[^\\]%c" w) indent-point t))
- nil)
- (t
- (goto-char indent-point)
- (setq in-string t))))
- ((looking-at "/")
- (if (and (ruby-expr-beg)
- (goto-char pnt)
- (looking-at "\\([^/\n]\\|\\\\/\\)*")
- (eq ?/ (char-after (match-end 0))))
- (goto-char (1+ (match-end 0)))
- (goto-char indent-point)
- (setq in-string t)))
- ((looking-at "\\?") ;skip ?char
+ (if start
+ (goto-char start)
+ (ruby-beginning-of-indent))
+ (save-restriction
+ (narrow-to-region (point) end)
+ (while (and (> indent-point (point))
+ (re-search-forward ruby-delimiter indent-point t))
+ (let ((pnt (point)) w)
+ (goto-char (match-beginning 0))
(cond
- ((ruby-expr-beg)
- (looking-at "?\\(\\\\C-\\|\\\\M-\\)*.")
- (goto-char (match-end 0)))
- (t
- (goto-char pnt))))
- ((looking-at "\\$") ;skip $char
- (goto-char pnt)
- (forward-char 1))
- ((looking-at "#") ;skip comment
- (forward-line 1)
- (goto-char pnt))
- ((looking-at "[\\[({]")
- (setq nest (cons (cons (char-after (point)) pnt) nest))
- (setq depth (1+ depth))
- (goto-char pnt))
- ((looking-at "[])}]")
- (setq nest (cdr nest))
- (setq depth (1- depth))
- (goto-char pnt))
- ((looking-at ruby-block-end-re)
- (if (and (not (bolp))
- (progn
- (forward-char -1)
- (eq ?_ (char-after (point))))
- (progn
- (goto-char pnt)
- (eq ?_ (char-after (point)))))
- nil
+ ((or (looking-at "\"") ;skip string
+ (looking-at "'")
+ (looking-at "`"))
+ (setq w (char-after (point)))
+ (cond
+ ((and (not (eobp))
+ (re-search-forward (format "[^\\]%c" w) indent-point t))
+ nil)
+ (t
+ (setq in-string (point))
+ (goto-char indent-point))))
+ ((looking-at "/")
+ (cond
+ ((and (not (eobp)) (ruby-expr-beg))
+ (if (re-search-forward "[^\\]/" indent-point t)
+ nil
+ (setq in-string (point))
+ (goto-char indent-point)))
+ (t
+ (goto-char pnt))))
+ ((looking-at "%")
+ (cond
+ ((and (not (eobp)) (ruby-expr-beg)
+ (looking-at "%[Qq\"'Rr/Xx`]\\(.\\)"))
+ (setq w (buffer-substring (match-beginning 1)
+ (match-end 1)))
+ (cond
+ ((string= w "[") (setq w "]"))
+ ((string= w "{") (setq w "}"))
+ ((string= w "(") (setq w ")"))
+ ((string= w "<") (setq w ">")))
+ (goto-char (match-end 0))
+ (if (search-forward w indent-point t)
+ nil
+ (setq in-string (point))
+ (goto-char indent-point)))
+ (t
+ (goto-char pnt))))
+ ((looking-at "\\?") ;skip ?char
+ (cond
+ ((ruby-expr-beg)
+ (looking-at "?\\(\\\\C-\\|\\\\M-\\)*.")
+ (goto-char (match-end 0)))
+ (t
+ (goto-char pnt))))
+ ((looking-at "\\$") ;skip $char
+ (goto-char pnt)
+ (forward-char 1))
+ ((looking-at "#") ;skip comment
+ (forward-line 1)
+ (goto-char (point))
+ )
+ ((looking-at "(")
+ (setq nest (cons (cons (char-after (point)) pnt) nest))
+ (setq pcol (cons (cons pnt depth) pcol))
+ (setq depth 0)
+ (goto-char pnt)
+ )
+ ((looking-at "[\\[{]")
+ (setq nest (cons (cons (char-after (point)) pnt) nest))
+ (setq depth (1+ depth))
+ (goto-char pnt)
+ )
+ ((looking-at ")")
(setq nest (cdr nest))
- (setq depth (1- depth)))
- (goto-char pnt))
- ((looking-at ruby-block-beg-re)
- (and
- (or (bolp)
- (progn
- (forward-char -1)
- (not (eq ?_ (char-after (point))))))
- (save-excursion
- (goto-char pnt)
- (not (eq ?_ (char-after (point)))))
- (skip-chars-backward " \t")
- (or (bolp)
- (save-excursion
- (forward-char -1)
- (looking-at ruby-operator-chars)))
- (progn
- (setq nest (cons (cons nil pnt) nest))
- (setq depth (1+ depth))))
- (goto-char pnt))
- (t
- (error (format "bad string %s"
- (buffer-substring (point) pnt)
- )))))))
- (list in-string (car nest) depth))))
+ (setq depth (cdr (car pcol)))
+ (setq pcol (cdr pcol))
+ (goto-char pnt))
+ ((looking-at "[])}]")
+ (setq nest (cdr nest))
+ (setq depth (1- depth))
+ (goto-char pnt))
+ ((looking-at ruby-block-end-re)
+ (if (and (not (bolp))
+ (progn
+ (forward-char -1)
+ (eq ?_ (char-after (point))))
+ (progn
+ (goto-char pnt)
+ (eq ?_ (char-after (point)))))
+ nil
+ (setq nest (cdr nest))
+ (setq depth (1- depth)))
+ (goto-char pnt))
+ ((looking-at ruby-block-beg-re)
+ (and
+ (or (bolp)
+ (progn
+ (forward-char -1)
+ (not (eq ?_ (char-after (point))))))
+ (save-excursion
+ (goto-char pnt)
+ (setq w (char-after (point)))
+ (and (not (eq ?_ w))
+ (not (eq ?! w))
+ (not (eq ?? w))))
+ (progn
+ (goto-char (match-beginning 0))
+ (if (looking-at ruby-modifier-re)
+ (ruby-expr-beg)
+ t))
+ (progn
+ (setq nest (cons (cons nil pnt) nest))
+ (setq depth (1+ depth))))
+ (if (looking-at "def\\s *[/`]")
+ (goto-char (match-end 0))
+ (goto-char pnt)))
+ (t
+ (error (format "bad string %s"
+ (buffer-substring (point) pnt)
+ )))))))
+ (list in-string (car nest) depth (car (car pcol))))))
(defun ruby-calculate-indent (&optional parse-start)
(save-excursion
(beginning-of-line)
(let ((indent-point (point))
- (case-fold-search nil)
- state bol eol
- (indent 0))
- (if parse-start
- (goto-char parse-start)
- (ruby-beginning-of-defun)
- (setq parse-start (point)))
- (setq state (ruby-parse-region parse-start indent-point))
- (cond
- ((nth 0 state) ; within string
- (setq indent nil)) ; do nothing
-
- ((nth 1 state) ; in paren
- (goto-char (cdr (nth 1 state)))
- (setq indent
- (if (and (eq (car (nth 1 state)) ?\( )
- (not (looking-at "(\\s *$")))
- (current-column)
- (+ (current-indentation) ruby-indent-level))))
-
- ((> (nth 2 state) 0) ; in nest
- (goto-char (cdr (nth 1 state)))
- (forward-word -1) ; skip back a keyword
- (setq indent (+ (current-column) ruby-indent-level)))
-
- (t ; toplevel
- (setq indent 0)))
-
- (cond
- (indent
- (goto-char indent-point)
- (end-of-line)
- (setq eol (point))
- (beginning-of-line)
- (cond
- ((re-search-forward ruby-negative eol t)
- (setq indent (- indent ruby-indent-level)))
- ;;operator terminated lines
- ((and
- (save-excursion
- (beginning-of-line)
- (not (bobp)))
- (or (null (car (nth 1 state))) ;not in parens
- (and (eq (car (nth 1 state)) ?\{)
- (save-excursion ;except non-block braces
- (goto-char (cdr (nth 1 state)))
- (or (bobp) (forward-char -1))
- (not (ruby-expr-beg))))))
- (beginning-of-line)
- (skip-chars-backward " \t\n")
- (beginning-of-line) ; goto beginning of non-empty line
- (setq bol (point))
+ (case-fold-search nil)
+ state bol eol
+ (indent 0))
+ (if parse-start
+ (goto-char parse-start)
+ (ruby-beginning-of-indent)
+ (setq parse-start (point)))
+ (back-to-indentation)
+ (setq indent (current-column))
+ (setq state (ruby-parse-region parse-start indent-point))
+ (cond
+ ((nth 0 state) ; within string
+ (setq indent nil)) ; do nothing
+
+ ((car (nth 1 state)) ; in paren
+ (goto-char (cdr (nth 1 state)))
+ (if (eq (car (nth 1 state)) ?\( )
+ (let ((column (current-column))
+ (s (ruby-parse-region (point) indent-point)))
+ (cond
+ ((> (nth 2 s) 0)
+ (goto-char (cdr (nth 1 s)))
+ (forward-word -1)
+ (setq indent (+ (current-column) ruby-indent-level)))
+ (t
+ (setq indent (current-column)))))
+ (cond
+ ((nth 3 state)
+ (goto-char (nth 3 state))
+ (setq indent (+ (current-column) ruby-indent-level)))
+ (t
+ (goto-char parse-start)
+ (back-to-indentation)
+ (setq indent (+ (current-column) (* (nth 2 state) ruby-indent-level)))))
+ ))
+
+ ((> (nth 2 state) 0) ; in nest
+ (goto-char (cdr (nth 1 state)))
+ (forward-word -1) ; skip back a keyword
+ (cond
+ ((looking-at "do") ; iter block is a special case
+ (cond
+ ((nth 3 state)
+ (goto-char (nth 3 state))
+ (setq indent (+ (current-column) ruby-indent-level)))
+ (t
+ (goto-char parse-start)
+ (back-to-indentation)
+ (setq indent (+ (current-column) (* (nth 2 state) ruby-indent-level))))))
+ (t
+ (setq indent (+ (current-column) ruby-indent-level)))))
+
+ ((< (nth 2 state) 0) ; in negative nest
+ (setq indent (+ (current-column) (* (nth 2 state) ruby-indent-level)))))
+
+ (cond
+ (indent
+ (goto-char indent-point)
(end-of-line)
(setq eol (point))
- (and (search-backward "#" bol t) ; check for comment line
- (not (eq ?? (char-after (1- (point)))))
- (not (nth 0 (ruby-parse-region parse-start (point))))
- (setq eol (point)))
- (goto-char eol)
- (skip-chars-backward " \t")
- (or (bobp) (forward-char -1))
- (and (looking-at ruby-operator-chars)
-;; (or (not (eq ?/ (char-after (point))))
-;; (progn
-;; (not (nth 0 (ruby-parse-region parse-start (point))))))
- (or (not (eq ?/ (char-after (point))))
- (null (nth 0 (ruby-parse-region parse-start (point)))))
- (save-excursion
- (goto-char parse-start)
- (sit-for 1))
- (not (eq (char-after (1- (point))) ?$))
- (or (not (eq ?| (char-after (point))))
- (save-excursion
- (or (eolp) (forward-char -1))
- (and (search-backward "|" bol t)
- (skip-chars-backward " \t\n")
- (and (not (eolp))
- (progn
- (forward-char -1)
- (not (looking-at "\\{")))))))
- (setq indent (+ indent ruby-indent-level)))))))
- indent)))
-
+ (beginning-of-line)
+ (cond
+ ((re-search-forward ruby-negative eol t)
+ (setq indent (- indent ruby-indent-level)))
+ ;;operator terminated lines
+ ((and
+ (save-excursion
+ (beginning-of-line)
+ (not (bobp)))
+ (or (null (car (nth 1 state))) ;not in parens
+ (and (eq (car (nth 1 state)) ?\{)
+ (save-excursion ;except non-block braces
+ (goto-char (cdr (nth 1 state)))
+ (or (bobp) (forward-char -1))
+ (not (ruby-expr-beg))))))
+ (beginning-of-line)
+ (skip-chars-backward " \t\n")
+ (beginning-of-line) ; goto beginning of non-empty line
+ (setq bol (point))
+ (end-of-line)
+ (skip-chars-backward " \t")
+ (or (bobp) (forward-char -1))
+ (and (looking-at ruby-operator-chars)
+ (or (not (or (eq ?/ (char-after (point)))))
+ (null (nth 0 (ruby-parse-region parse-start (point)))))
+ (save-excursion
+ (goto-char parse-start))
+ (not (eq (char-after (1- (point))) ?$))
+ (or (not (eq ?| (char-after (point))))
+ (save-excursion
+ (or (eolp) (forward-char -1))
+ (and (search-backward "|")
+ (skip-chars-backward " \t\n")
+ (and (not (eolp))
+ (progn
+ (forward-char -1)
+ (not (looking-at "\\{")))
+ (progn
+ (forward-word -1)
+ (not (looking-at "do\\>[^_]")))))))
+ (setq indent (+ indent ruby-indent-level)))))))
+ indent)))
+
(defun ruby-electric-brace (arg)
(interactive "P")
(self-insert-command (prefix-numeric-value arg))
(ruby-indent-line t))
(defun ruby-beginning-of-defun (&optional arg)
- "Move backward to next beginning-of-defun.
+ "Move backward to next beginning-of-defun.
With argument, do this that many times.
Returns t unless search stops due to end of buffer."
(interactive "p")
@@ -364,6 +439,13 @@ Returns t unless search stops due to end of buffer."
nil 'move (or arg 1))
(progn (beginning-of-line) t)))
+(defun ruby-beginning-of-indent ()
+ (and (re-search-backward (concat "^\\(" ruby-indent-beg-re "\\)\\b")
+ nil 'move)
+ (progn
+ (beginning-of-line)
+ t)))
+
(defun ruby-end-of-defun (&optional arg)
"Move forward to next end of defun.
An end of a defun is found by moving forward from the beginning of one."
@@ -373,6 +455,42 @@ An end of a defun is found by moving forward from the beginning of one."
(progn (beginning-of-line) t))
(forward-line 1))
+(defun ruby-move-to-block (n)
+ (let (start pos done down)
+ (setq start (ruby-calculate-indent))
+ (if (eobp)
+ nil
+ (while (and (not (bobp)) (not done))
+ (forward-line n)
+ (cond
+ ((looking-at "^$"))
+ ((looking-at "^\\s *#"))
+ (t
+ (setq pos (current-indentation))
+ (cond
+ ((< start pos)
+ (setq down t))
+ ((and down (= pos start))
+ (setq done t))
+ ((> start pos)
+ (setq done t)))))
+ (if done
+ (progn
+ (back-to-indentation)
+ (if (looking-at ruby-block-mid-re)
+ (setq done nil)))))))
+ (back-to-indentation))
+
+(defun ruby-beginning-of-block ()
+ "Move backward to next beginning-of-block"
+ (interactive)
+ (ruby-move-to-block -1))
+
+(defun ruby-end-of-block ()
+ "Move forward to next beginning-of-block"
+ (interactive)
+ (ruby-move-to-block 1))
+
(defun ruby-reindent-then-newline-and-indent ()
(interactive "*")
(save-excursion
@@ -383,39 +501,32 @@ An end of a defun is found by moving forward from the beginning of one."
(indent-according-to-mode))
(indent-according-to-mode))
-(defun ruby-encomment-region (beg end)
- (interactive "r")
- (save-excursion
- (goto-char beg)
- (while (re-search-forward "^" end t)
- (replace-match "#" nil nil))))
+(fset 'ruby-encomment-region (symbol-function 'comment-region))
(defun ruby-decomment-region (beg end)
(interactive "r")
(save-excursion
(goto-char beg)
(while (re-search-forward "^\\([ \t]*\\)#" end t)
- (replace-match "\\1" nil nil))))
+ (replace-match "\\1" nil nil)
+ (save-excursion
+ (ruby-indent-line)))))
(if (featurep 'hilit19)
(hilit-set-mode-patterns
'ruby-mode
- '(("\\s #.*$" nil comment)
- ("^#.*$" nil comment)
- ("\\$\\(.\\|\\sw+\\)" nil type)
- ("[^$\\?]\\(\"[^\\\"]*\\(\\\\\\(.\\|\n\\)[^\\\"]*\\)*\"\\)" 1 string)
+ '(("[^$\\?]\\(\"[^\\\"]*\\(\\\\\\(.\\|\n\\)[^\\\"]*\\)*\"\\)" 1 string)
("[^$\\?]\\('[^\\']*\\(\\\\\\(.\\|\n\\)[^\\']*\\)*'\\)" 1 string)
- ("^/\\([^/\n]\\|\\\\/\\)*/" nil string)
- ("[^a-zA-Z_]\\s *\\(/\\([^/\n]\\|\\\\/\\)*/\\)" 1 string)
- ("\\(begin\\|case\\|else\\|elsif\\|end\\|ensure\\|for\\|if\\|rescue\\|then\\|when\\|while\\)\\s *\\(/\\([^/\n]\\|\\\\/\\)*/\\)" 2 string)
- ("^\\s *require.*$" nil include)
- ("^\\s *load.*$" nil include)
+ ("[^$\\?]\\(`[^\\`]*\\(\\\\\\(.\\|\n\\)[^\\`]*\\)*`\\)" 1 string)
+ ("^\\s *#.*$" nil comment)
+ ("[^$@?\\]\\(#[^$@{].*$\\)" 1 comment)
+ ("[^a-zA-Z_]\\(\\?\\(\\\\[CM]-\\)*.\\)" 1 string)
+ ("^\\s *\\(require\\|load\\).*$" nil include)
("^\\s *\\(include\\|alias\\|undef\\).*$" nil decl)
("^\\s *\\<\\(class\\|def\\|module\\)\\>" "[)\n;]" defun)
- ("[^_]\\<\\(begin\\|case\\|else\\|elsif\\|end\\|ensure\\|for\\|if\\|rescue\\|then\\|when\\|while\\)\\>[^_]" 1 defun)
- ("[^_]\\<\\(and\\|break\\|continue\\|fail\\|in\\|not\\|or\\|redo\\|retry\\|return\\|super\\|yield\\)\\>[^_]" 1 keyword)
- ("[^_]\\<\\(self\\|nil\\|TRUE\\|FALSE\\|__LINE__\\|__FILE__\\)\\>[^_]" 1 define)
- ("$.[a-zA-Z_0-9]*" nil struct)
- ("@[a-zA-Z_0-9]+" nil struct)
- ("[^_]\\<[A-Z].[a-zA-Z_0-9]*" nil define)
+ ("[^_]\\<\\(begin\\|case\\|else\\|elsif\\|end\\|ensure\\|for\\|if\\|unless\\|rescue\\|then\\|when\\|while\\|until\\|do\\)\\>[^_]" 1 defun)
+ ("[^_]\\<\\(and\\|break\\|next\\|raise\\|fail\\|in\\|not\\|or\\|redo\\|retry\\|return\\|super\\|yield\\)\\>[^_]" 1 keyword)
+ ("[^_]\\<\\(self\\|nil\\|[A-Z][a-zA-Z_0-9]*\\)\\>[^_]" 1 define)
+ ("\\$\\(.\\|\\sw+\\)" nil type)
+ ("[$@].[a-zA-Z_0-9]*" nil struct)
("^__END__" nil label))))
diff --git a/sample/sieve.rb b/sample/sieve.rb
index a953784284..03ff8a67f4 100644
--- a/sample/sieve.rb
+++ b/sample/sieve.rb
@@ -1,6 +1,6 @@
# sieve of Eratosthenes
sieve = []
-if ! max = $ARGV.shift; max = 100; end
+if ! max = ARGV.shift; max = 100; end
max = max.to_i
print "1"
diff --git a/sample/svr.rb b/sample/svr.rb
index 460c16bedf..14aded8c3f 100644
--- a/sample/svr.rb
+++ b/sample/svr.rb
@@ -11,7 +11,7 @@ socks = [gs]
while TRUE
nsock = select(socks);
- if nsock == nil; continue end
+ next if nsock == nil
for s in nsock[0]
if s == gs
ns = s.accept
diff --git a/sample/test.rb b/sample/test.rb
index 7f26433181..aacddbc56a 100644
--- a/sample/test.rb
+++ b/sample/test.rb
@@ -1,6 +1,8 @@
#! /usr/local/bin/ruby
$testnum=0
+$ntest=0
+$failed = 0
def check(what)
printf "%s\n", what
@@ -8,15 +10,16 @@ def check(what)
$testnum = 0
end
-def ok
+def ok(cond)
$testnum+=1
- printf "ok %d\n", $testnum
-end
-
-def notok
- $testnum+=1
- printf "not ok %s %d\n", $what, $testnum
- $failed = TRUE
+ $ntest+=1
+ if cond
+ printf "ok %d\n", $testnum
+ else
+ where = caller[0]
+ printf "not ok %s %d -- %s\n", $what, $testnum, where
+ $failed+=1
+ end
end
# make sure conditional operators work
@@ -25,50 +28,62 @@ check "condition"
$x = '0';
-$x == $x && ok
-$x != $x && notok
-$x == $x || notok
-$x != $x || ok
+$x == $x && ok(TRUE)
+$x != $x && ok(FALSE)
+$x == $x || ok(FALSE)
+$x != $x || ok(TRUE)
# first test to see if we can run the tests.
-check "if";
+check "if/unless";
$x = 'test';
-if $x == $x then ok else notok end
-if $x != $x then notok else ok end
+ok(if $x == $x then TRUE else FALSE end)
+$bad = FALSE
+unless $x == $x
+ $bad = TRUE
+end
+ok(!$bad)
+ok(unless $x != $x then TRUE else FALSE end)
check "case"
case 5
when 1, 2, 3, 4, 6, 7, 8
- notok
+ ok(FALSE)
when 5
- ok
+ ok(TRUE)
end
case 5
when 5
- ok
+ ok(TRUE)
when 1..10
- notok
+ ok(FALSE)
+end
+
+case 5
+when 1..10
+ ok(TRUE)
+else
+ ok(FALSE)
end
case 5
when 5
- ok
+ ok(TRUE)
else
- notok
+ ok(FALSE)
end
case "foobar"
when /^f.*r$/
- ok
+ ok(TRUE)
else
- notok
+ ok(FALSE)
end
-check "while";
+check "while/until";
tmp = open("while_tmp", "w")
tmp.print "tvi925\n";
@@ -81,30 +96,23 @@ tmp.close
# test break
tmp = open("while_tmp", "r")
+ok(tmp.type == "File")
while tmp.gets()
break if /vt100/
end
-if !tmp.eof && /vt100/ then
- ok
-else
- notok
-end
+ok(!tmp.eof && /vt100/)
tmp.close
-# test continue
+# test next
$bad = FALSE
tmp = open("while_tmp", "r")
while tmp.gets()
- continue if /vt100/;
+ next if /vt100/;
$bad = 1 if /vt100/;
end
-if !tmp.eof || /vt100/ || $bad
- notok
-else
- ok
-end
+ok(!(!tmp.eof || /vt100/ || $bad))
tmp.close
# test redo
@@ -118,37 +126,39 @@ while tmp.gets()
$bad = 1 if /vt100/;
$bad = 1 if /VT100/;
end
-if !tmp.eof || $bad
- notok
-else
- ok
-end
+ok(tmp.eof && !$bad)
tmp.close
# test interval
$bad = FALSE
tmp = open("while_tmp", "r")
while tmp.gets()
- break if not 1..2
+ break unless 1..2
if /vt100/ || /Amiga/ || /paper/
$bad = TRUE
- notok
break
end
end
-ok if not $bad
+ok(!$bad)
tmp.close
File.unlink "while_tmp" or `/bin/rm -f "while_tmp"`
+ok(!File.exist?("while_tmp"))
+
+i = 0
+until i>4
+ i+=1
+end
+ok(i>4)
# exception handling
check "exception";
begin
fail "this must be handled"
- notok
+ ok(FALSE)
rescue
- ok
+ ok(TRUE)
end
$bad = TRUE
@@ -158,10 +168,10 @@ rescue
if $bad
$bad = FALSE
retry
- notok
+ ok(FALSE)
end
end
-ok
+ok(TRUE)
$bad = TRUE
$string = "this must be handled no.3"
@@ -170,9 +180,9 @@ begin
rescue
ensure
$bad = FALSE
- ok
+ ok(TRUE)
end
-notok if $bad || $! != $string
+ok(FALSE) if $bad || $! != $string
# exception in rescue clause
begin
@@ -181,164 +191,163 @@ begin
rescue
fail "exception in rescue clause"
end
- notok
+ ok(FALSE)
rescue
- ok
+ ok(TRUE)
end
-check "array"
-$x = [0, 1, 2, 3, 4, 5]
-if $x[2] == 2
- ok
-else
- notok
+# exception in ensure clause
+begin
+ begin
+ fail "this must be handled no.5"
+ ensure
+ fail "exception in ensure clause"
+ end
+ ok(FALSE)
+rescue
+ ok(TRUE)
end
-if $x[1..3] == [1, 2, 3]
- ok
-else
- notok
+$bad = TRUE
+begin
+ begin
+ fail "this must be handled no.5"
+ ensure
+ $bad = FALSE
+ end
+rescue
end
+ok(!$bad)
-if $x[1,3] == [1, 2, 3]
- ok
-else
- notok
+$bad = TRUE
+begin
+ begin
+ fail "this must be handled no.5"
+ ensure
+ $bad = FALSE
+ end
+rescue
end
+ok(!$bad)
-if [1, 2] + [3, 4] == [1, 2, 3, 4]
- ok
-else
- notok
+$bad = TRUE
+while TRUE
+ begin
+ break
+ ensure
+ $bad = FALSE
+ end
end
+ok(!$bad)
+
+check "array"
+ok([1, 2] + [3, 4] == [1, 2, 3, 4])
+ok([1, 2] * 2 == [1, 2, 1, 2])
+ok([1, 2] * ":" == "1:2")
+
+ok([1, 2].hash == [1, 2].hash)
+
+ok([1,2,3] & [2,3,4] == [2,3])
+ok([1,2,3] | [2,3,4] == [1,2,3,4])
+ok([1,2,3] - [2,3] == [1])
+
+$x = [0, 1, 2, 3, 4, 5]
+ok($x[2] == 2)
+ok($x[1..3] == [1, 2, 3])
+ok($x[1,3] == [1, 2, 3])
$x[0, 2] = 10
-if $x[0] == 10 && $x[1] == 2
- ok
-else
- notok
-end
+ok($x[0] == 10 && $x[1] == 2)
$x[0, 0] = -1
-if $x[0] == -1 && $x[1] == 10
- ok
-else
- notok
-end
+ok($x[0] == -1 && $x[1] == 10)
$x[-1, 1] = 20
-if $x[-1] == 20 && $x.pop == 20
- ok
-else
- notok
-end
+ok($x[-1] == 20 && $x.pop == 20)
+# compact
+$x = [nil, 1, nil, nil, 5, nil, nil]
+$x.compact!
+ok($x == [1, 5])
+
+# empty?
+ok(!$x.empty?)
+$x = []
+ok($x.empty?)
+
+# sort
$x = ["it", "came", "to", "pass", "that", "..."]
$x = $x.sort.join(" ")
-if $x == "... came it pass that to"
- ok
-else
- notok
-end
+ok($x == "... came it pass that to")
+$x = [2,5,3,1,7]
+$x.sort!{|a,b| a<=>b} # sort with condition
+ok($x == [1,2,3,5,7])
+$x.sort!{|a,b| b-a} # reverse sort
+ok($x == [7,5,3,2,1])
# split test
-if "1 byte string".split(//).reverse.join(":") == "g:n:i:r:t:s: :e:t:y:b: :1"
- ok
-else
- notok
-end
+$x = "The Book of Mormon"
+ok($x.split(//).reverse!.join == "nomroM fo kooB ehT")
+ok("1 byte string".split(//).reverse.join(":") == "g:n:i:r:t:s: :e:t:y:b: :1")
+$x = "a b c d"
+ok($x.split == ['a', 'b', 'c', 'd'])
+ok($x.split(' ') == ['a', 'b', 'c', 'd'])
$x = [1]
-if ($x * 5).join(":") == '1:1:1:1:1' then ok else notok end
-if ($x * 1).join(":") == '1' then ok else notok end
-if ($x * 0).join(":") == '' then ok else notok end
+ok(($x * 5).join(":") == '1:1:1:1:1')
+ok(($x * 1).join(":") == '1')
+ok(($x * 0).join(":") == '')
+
+*$x = 1..7
+ok($x.size == 7)
+ok($x == [1, 2, 3, 4, 5, 6, 7])
check "hash"
$x = {1=>2, 2=>4, 3=>6}
$y = {1, 2, 2, 4, 3, 6}
-if $x[1] == 2
- ok
-else
- notok
-end
+ok($x[1] == 2)
-begin
- for k,v in $y
- fail if k*2 != v
- end
- ok
-rescue
- notok
-end
-
-if $x.length == 3
- ok
-else
- notok
-end
-
-if $x.has_key?(1)
- ok
-else
- notok
-end
-
-if $x.has_value?(4)
- ok
-else
- notok
-end
+ok(begin
+ for k,v in $y
+ fail if k*2 != v
+ end
+ TRUE
+ rescue
+ FALSE
+ end)
-if $x.indexes(2,3) == [4,6]
- ok
-else
- notok
-end
+ok($x.length == 3)
+ok($x.has_key?(1))
+ok($x.has_value?(4))
+ok($x.indexes(2,3) == [4,6])
+ok($x == (1=>2, 2=>4, 3=>6))
$z = $y.keys.join(":")
-if $z == "1:2:3"
- ok
-else
- notok
-end
+ok($z == "1:2:3")
$z = $y.values.join(":")
-if $z == "2:4:6"
- ok
-else
- notok
-end
-
-if $x == $y
- ok
-else
- notok
-end
+ok($z == "2:4:6")
+ok($x == $y)
$y.shift
-if $y.length == 2
- ok
-else
- notok
-end
+ok($y.length == 2)
+
+$z = [1,2]
+$y[$z] = 256
+ok($y[$z] == 256)
check "iterator"
-if iterator? then notok else ok end
+ok(!iterator?)
def ttt
- if iterator? then ok else notok end
+ ok(iterator?)
end
ttt{}
# yield at top level
-begin
- yield
- notok
-rescue
- ok
-end
+ok(!defined?(yield))
$x = [1, 2, 3, 4]
$y = []
@@ -347,11 +356,7 @@ $y = []
for i in $x
$y.push i
end
-if $x == $y
- ok
-else
- notok
-end
+ok($x == $y)
# nested iterator
def tt
@@ -361,59 +366,54 @@ def tt
end
tt{|i| break if i == 5}
-if i == 5
- ok
+ok(i == 5)
+
+# iterator break/redo/next/retry
+unless defined? loop
+ def loop
+ while TRUE
+ yield
+ end
+ end
+ ok(FALSE)
else
- notok
+ ok(TRUE)
end
-# iterator break/redo/continue/retry
done = TRUE
loop{
break
done = FALSE
- notok
}
-ok if done
+ok(done)
-done = TRUE
+done = FALSE
$bad = FALSE
loop {
- break if not done
- done = FALSE
- continue
+ break if done
+ done = TRUE
+ next
$bad = TRUE
}
-if $bad
- notok
-else
- ok
-end
+ok(!$bad)
-done = TRUE
+done = FALSE
$bad = FALSE
loop {
- break if not done
- done = FALSE
+ break if done
+ done = TRUE
redo
$bad = TRUE
}
-if $bad
- notok
-else
- ok
-end
+ok(!$bad)
$x = []
for i in 1 .. 7
- $x.push(i)
-end
-if $x.size == 7
- ok
-else
- notok
+ $x.push i
end
-# $x == [1, 2, 3, 4, 5, 6, 7]
+ok($x.size == 7)
+ok($x == [1, 2, 3, 4, 5, 6, 7])
+
$done = FALSE
$x = []
for i in 1 .. 7 # see how retry works in iterator loop
@@ -423,102 +423,56 @@ for i in 1 .. 7 # see how retry works in iterator loop
end
$x.push(i)
end
-# $x == [1, 2, 3, 1, 2, 3, 4, 5, 6, 7]
-if $x.size == 10
- ok
-else
- notok
-end
+ok($x.size == 10)
+ok($x == [1, 2, 3, 1, 2, 3, 4, 5, 6, 7])
check "bignum"
def fact(n)
return 1 if n == 0
return n*fact(n-1)
end
-if fact(40) == 815915283247897734345611269596115894272000000000
- ok
-else
- notok
-end
-if fact(40) == 815915283247897734345611269596115894272000000001
- notok
-else
- ok
-end
+$x = fact(40)
+ok($x == $x)
+ok($x == fact(40))
+ok($x < $x+2)
+ok($x > $x-2)
+ok($x == 815915283247897734345611269596115894272000000000)
+ok($x != 815915283247897734345611269596115894272000000001)
+ok($x+1 == 815915283247897734345611269596115894272000000001)
+ok($x/fact(20) == 335367096786357081410764800000)
+$x = -$x
+ok($x == -815915283247897734345611269596115894272000000000)
+ok(2-(2**32) == -(2**32-2))
+ok(2**32 - 5 == (2**32-3)-2)
check "string & char"
-if "abcd" == "abcd"
- ok
-else
- notok
-end
-
-if "abcd" =~ "abcd"
- ok
-else
- notok
-end
+ok("abcd" == "abcd")
+ok("abcd" =~ "abcd")
+ok("abcd" === "abcd")
$foo = "abc"
-if "#$foo = abc" == "abc = abc"
- ok
-else
- notok
-end
-
-if "#{$foo} = abc" == "abc = abc"
- ok
-else
- notok
-end
+ok("#$foo = abc" == "abc = abc")
+ok("#{$foo} = abc" == "abc = abc")
foo = "abc"
-if "#{foo} = abc" == "abc = abc"
- ok
-else
- notok
-end
+ok("#{foo} = abc" == "abc = abc")
-if '-' * 5 == '-----' then ok else notok end
-if '-' * 1 == '-' then ok else notok end
-if '-' * 0 == '' then ok else notok end
+ok('-' * 5 == '-----')
+ok('-' * 1 == '-')
+ok('-' * 0 == '')
foo = '-'
-if foo * 5 == '-----' then ok else notok end
-if foo * 1 == '-' then ok else notok end
-if foo * 0 == '' then ok else notok end
+ok(foo * 5 == '-----')
+ok(foo * 1 == '-')
+ok(foo * 0 == '')
# character constants(assumes ASCII)
-if "a"[0] == ?a
- ok
-else
- notok
-end
-
-if ?a == ?a
- ok
-else
- notok
-end
-
-if ?\C-a == 1
- ok
-else
- notok
-end
-
-if ?\M-a == 225
- ok
-else
- notok
-end
-
-if ?\M-\C-a == 129
- ok
-else
- notok
-end
+ok("a"[0] == ?a)
+ok(?a == ?a)
+ok(?\C-a == 1)
+ok(?\M-a == 225)
+ok(?\M-\C-a == 129)
$x = "abcdef"
$y = [ ?a, ?b, ?c, ?d, ?e, ?f ]
@@ -529,33 +483,28 @@ $x.each_byte {|i|
break
end
}
-if not $bad
- ok
-else
- notok
-end
+ok(!$bad)
check "asignment"
a = nil
-if a == nil
- ok
-else
- notok
-end
+ok(defined?(a))
+ok(a == nil)
+# multiple asignment
a, b = 1, 2
-if a == 1 and b == 2 then
- ok
-else
- notok
-end
+ok(a == 1 && b == 2)
+
+a, b = b, a
+ok(a == 2 && b == 1)
+
+a, = 1,2
+ok(a == 1)
a, *b = 1, 2, 3
-if a == 1 and b == [2, 3] then
- ok
-else
- notok
-end
+ok(a == 1 && b == [2, 3])
+
+*a = 1, 2, 3
+ok(a == [1, 2, 3])
check "call"
def aaa(a, b=100, *rest)
@@ -564,191 +513,167 @@ def aaa(a, b=100, *rest)
return res
end
+# not enough argument
begin
- aaa()
- notok
+ aaa() # need at least 1 arg
+ ok(FALSE)
rescue
- ok
+ ok(TRUE)
end
begin
- aaa
- notok
+ aaa # no arg given (exception raised)
+ ok(FALSE)
rescue
- ok
+ ok(TRUE)
end
begin
if aaa(1) == [1, 100]
- ok
+ ok(TRUE)
else
fail
end
rescue
- notok
+ ok(FALSE)
end
begin
if aaa(1, 2) == [1, 2]
- ok
+ ok(TRUE)
else
fail
end
rescue
- notok
+ ok(FALSE)
end
-begin
- if aaa(1, 2, 3, 4) == [1, 2, 3, 4]
- ok
- else
- fail
- end
-rescue
- notok
-end
-
-begin
- if aaa(1, *[2, 3, 4]) == [1, 2, 3, 4]
- ok
- else
- fail
- end
-rescue
- notok
-end
+ok(aaa(1, 2, 3, 4) == [1, 2, 3, 4])
+ok(aaa(1, *[2, 3, 4]) == [1, 2, 3, 4])
check "proc"
$proc = proc{|i| i}
-if $proc.call(2) == 2
- ok
-else
- notok
-end
+ok($proc.call(2) == 2)
+ok($proc.call(3) == 3)
$proc = proc{|i| i*2}
-if $proc.call(2) == 4
- ok
-else
- notok
-end
+ok($proc.call(2) == 4)
+ok($proc.call(3) == 6)
proc{
iii=5 # dynamic local variable
- $proc = proc{ |i|
+ $proc = proc{|i|
iii = i
}
$proc2 = proc {
$x = iii # dynamic variables shared by procs
}
- if defined?(iii) # dynamic variables' scope
- ok
- else
- notok
- end
+ # scope of dynamic variables
+ ok(defined?(iii))
}.call
-if defined?(iii) # out of scope
- notok
-else
- ok
-end
+ok(!defined?(iii)) # out of scope
+
$x=0
$proc.call(5)
$proc2.call
-if $x == 5
- ok
-else
- notok
-end
+ok($x == 5)
-check "signal"
-begin
- kill "SIGINT", $$
- sleep 1
- notok
-rescue
- ok
-end
+if defined? Process.kill
+ check "signal"
-$x = 0
-trap "SIGINT", proc{|sig| $x = sig;fail}
-begin
- kill "SIGINT", $$
- sleep 1
- notok
-rescue
- if $x == 2
- ok
- else
- notok
- end
-end
+ $x = 0
+ trap "SIGINT", proc{|sig| $x = sig}
+ Process.kill "SIGINT", $$
+ sleep 0.1
+ ok($x == 2)
-$x = FALSE
-trap "SIGINT", "$x = TRUE;fail"
-begin
- kill "SIGINT", $$
- sleep 1
- notok
-rescue
- if $x
- ok
- else
- notok
+ trap "SIGINT", proc{fail "Interrupt"}
+
+ x = FALSE
+ begin
+ Process.kill "SIGINT", $$
+ sleep 0.1
+ rescue
+ x = $!
end
+ ok(x =~ /Interrupt/)
+else
+ ok(FALSE)
end
check "eval"
$bad=FALSE
-eval 'while FALSE; $bad = TRUE; print "foo\n" end
-if not $bad then ok else notok end'
+eval 'while FALSE; $bad = TRUE; print "foo\n" end'
+ok(!$bad)
-$foo = 'ok'
+ok(eval('TRUE'))
+
+$foo = 'ok(TRUE)'
begin
eval $foo
rescue
- notok
+ ok(FALSE)
end
-check "system"
-if `echo foobar` == "foobar\n"
- ok
-else
- notok
+ok(eval("$foo") == 'ok(TRUE)')
+ok(eval("TRUE") == TRUE)
+i = 5
+ok(eval("i == 5"))
+ok(eval("i") == 5)
+ok(eval("defined? i"))
+
+# eval with binding
+def test_ev
+ local1 = "local1"
+ lambda {
+ local2 = "local2"
+ return binding
+ }.call
end
-if `./ruby -e 'print "foobar"'` == 'foobar'
- ok
-else
- notok
+$x = test_ev
+ok(eval("local1", $x) == "local1") # static local var
+ok(eval("local2", $x) == "local2") # dynamic local var
+$bad = TRUE
+begin
+ p eval("local1")
+rescue NameError # must raise error
+ $bad = FALSE
end
+ok(!$bad)
+
+module EvTest
+ EVTEST1 = 25
+ evtest2 = 125
+ $x = binding
+end
+ok(eval("EVTEST1", $x) == 25) # constant in module
+ok(eval("evtest2", $x) == 125) # local var in module
+$bad = TRUE
+begin
+ eval("EVTEST1")
+rescue NameError # must raise error
+ $bad = FALSE
+end
+ok(!$bad)
+
+check "system"
+ok(`echo foobar` == "foobar\n")
+ok(`./ruby -e 'print "foobar"'` == 'foobar')
tmp = open("script_tmp", "w")
tmp.print "print $zzz\n";
tmp.close
-if `./ruby -s script_tmp -zzz` == 't'
- ok
-else
- notok
-end
-
-if `./ruby -s script_tmp -zzz=555` == '555'
- ok
-else
- notok
-end
+ok(`./ruby -s script_tmp -zzz` == 'TRUE')
+ok(`./ruby -s script_tmp -zzz=555` == '555')
tmp = open("script_tmp", "w")
tmp.print "#! /usr/local/bin/ruby -s\n";
tmp.print "print $zzz\n";
tmp.close
-if `./ruby script_tmp -zzz=678` == '678'
- ok
-else
- notok
-end
+ok(`./ruby script_tmp -zzz=678` == '678')
tmp = open("script_tmp", "w")
tmp.print "this is a leading junk\n";
@@ -758,17 +683,8 @@ tmp.print "__END__\n";
tmp.print "this is a trailing junk\n";
tmp.close
-if `./ruby -x script_tmp` == 'nil'
- ok
-else
- notok
-end
-
-if `./ruby -x script_tmp -zzz=555` == '555'
- ok
-else
- notok
-end
+ok(`./ruby -x script_tmp` == 'nil')
+ok(`./ruby -x script_tmp -zzz=555` == '555')
tmp = open("script_tmp", "w")
for i in 1..5
@@ -780,13 +696,14 @@ tmp.close
done = TRUE
tmp = open("script_tmp", "r")
while tmp.gets
+ print "c: ", $_
if $_.to_i % 5 != 0
done = FALSE
- notok
break
end
end
-ok if done
+tmp.close
+ok(done)
File.unlink "script_tmp" or `/bin/rm -f "script_tmp"`
File.unlink "script_tmp.bak" or `/bin/rm -f "script_tmp.bak"`
@@ -807,19 +724,11 @@ end
include Const
-if [TEST1,TEST2,TEST3,TEST4] == [1,2,3,4]
- ok
-else
- notok
-end
+ok([TEST1,TEST2,TEST3,TEST4] == [1,2,3,4])
include Const2
-
-if [TEST1,TEST2,TEST3,TEST4] == [1,2,6,8]
- ok
-else
- notok
-end
+STDERR.print "intentionally redefines TEST3, TEST4\n" if $VERBOSE
+ok([TEST1,TEST2,TEST3,TEST4] == [1,2,6,8])
check "clone"
foo = Object.new
@@ -831,200 +740,124 @@ def bar.test2
"test2"
end
-if bar.test2 == "test2"
- ok
-else
- notok
-end
-
-if bar.test == "test"
- ok
-else
- notok
-end
-
-if foo.test == "test"
- ok
-else
- notok
-end
+ok(bar.test2 == "test2")
+ok(bar.test == "test")
+ok(foo.test == "test")
begin
foo.test2
- notok
+ ok FALSE
rescue
- ok
+ ok TRUE
end
check "pack"
$format = "c2x5CCxsdila6";
# Need the expression in here to force ary[5] to be numeric. This avoids
-# test2 failing because ary2 goes str->numeric->str and ary doesn't.
+# test2 failing because ary2 goes str->numeric->str and ary does not.
ary = [1,-100,127,128,32767,987.654321098 / 100.0,12345,123456,"abcdef"]
$x = ary.pack($format)
ary2 = $x.unpack($format)
-if ary.length == ary2.length then ok else notok end
-
-if ary.join(':') == ary2.join(':') then ok else notok end
-
-if $x =~ /def/ then ok else notok end
+ok(ary.length == ary2.length)
+ok(ary.join(':') == ary2.join(':'))
+ok($x =~ /def/)
check "math"
-if Math.sqrt(4) == 2
- ok
-else
- notok
-end
+ok(Math.sqrt(4) == 2)
include Math
-if sqrt(4) == 2
- ok
-else
- notok
-end
+ok(sqrt(4) == 2)
check "struct"
struct_test = Struct.new("Test", :foo, :bar)
-if struct_test == Struct::Test
- ok
-else
- notok
-end
+ok(struct_test == Struct::Test)
+
test = struct_test.new(1, 2)
-if test.foo == 1 && test.bar == 2
- ok
-else
- notok
-end
-if test[0] == 1 && test[1] == 2
- ok
-else
- notok
-end
+ok(test.foo == 1 && test.bar == 2)
+ok(test[0] == 1 && test[1] == 2)
+
a, b = test
-if a == 1 && b == 2
- ok
-else
- notok
-end
+ok(a == 1 && b == 2)
+
test[0] = 22
-if test.foo == 22
- ok
-else
- notok
-end
+ok(test.foo == 22)
+
test.bar = 47
-if test.bar == 47
- ok
-else
- notok
-end
+ok(test.bar == 47)
check "variable"
-if $$.is_instance_of? Fixnum
- ok
-else
- notok
-end
+ok($$.instance_of?(Fixnum))
+# read-only variable
begin
$$ = 5
- notok
+ ok FALSE
rescue
- ok
+ ok TRUE
end
foobar = "foobar"
$_ = foobar
-if $_ == foobar
- ok
-else
- notok
-end
+ok($_ == foobar)
check "trace"
$x = 1234
$y = 0
trace_var :$x, proc{$y = $x}
$x = 40414
-if $y == $x
- ok
-else
- notok
-end
+ok($y == $x)
untrace_var :$x
$x = 19660208
-if $y != $x
- ok
-else
- notok
-end
+ok($y != $x)
trace_var :$x, proc{$x *= 2}
$x = 5
-if $x == 10
- ok
-else
- notok
-end
+ok($x == 10)
+
untrace_var :$x
check "defined?"
-if defined? $x
- ok
-else
- notok
-end
+
+ok(defined?($x)) # global variable
+ok(defined?($x) == 'global-variable')# returns description
foo=5
-if defined? foo
- ok
-else
- notok
-end
+ok(defined?(foo)) # local variable
-if defined? Array
- ok
-else
- notok
-end
+ok(defined?(Array)) # constant
+ok(defined?(Object.new)) # method
+ok(!defined?(Object.print)) # private method
+ok(defined?(1 == 2)) # operator expression
-if defined? Object.new
- ok
-else
- notok
+def defined_test
+ return !defined?(yield)
end
-if defined? 1 == 2
- ok
-else
- notok
-end
+ok(defined_test) # not iterator
+ok(!defined_test{}) # called as iterator
-if defined? fail
- ok
-else
- notok
+check "alias"
+class Alias0
+ def foo; "foo" end
end
-
-def defined_test
- return defined?(yield)
+class Alias1<Alias0
+ alias bar foo
+ def foo; "foo+" + super end
end
-
-if defined_test
- notok
-else
- ok
+class Alias2<Alias1
+ alias baz foo
+ undef foo
end
-if defined_test{}
- ok
-else
- notok
-end
+x = Alias2.new
+ok(x.bar == "foo")
+ok(x.baz == "foo+foo")
+
+# check for cache
+ok(x.baz == "foo+foo")
check "gc"
begin
@@ -1032,9 +865,13 @@ begin
tmp = [0,1,2,3,4,5,6,7,8,9]
}
tmp = nil
- ok
+ ok TRUE
rescue
- notok
+ ok FALSE
end
-print "end of test\n" if not $failed
+if $failed > 0
+ printf "test: %d failed %d\n", $ntest, $failed
+else
+ printf "end of test(test: %d)\n", $ntest
+end
diff --git a/sample/time.rb b/sample/time.rb
index 715d98ac9e..f4f4ec4883 100755
--- a/sample/time.rb
+++ b/sample/time.rb
@@ -1,5 +1,5 @@
#! /usr/local/bin/ruby
-cmd = $ARGV.join(" ")
+cmd = ARGV.join(" ")
b = Time.now
system(cmd)
e = Time.now
diff --git a/sample/tkbiff.rb b/sample/tkbiff.rb
index 9b406010cb..24860c11a6 100644
--- a/sample/tkbiff.rb
+++ b/sample/tkbiff.rb
@@ -1,17 +1,23 @@
#! /usr/local/bin/ruby
-if $ARGV.length == 0
+if ARGV[0] != '-d'
+ unless $DEBUG
+ exit if fork
+ end
+else
+ ARGV.shift
+end
+
+if ARGV.length == 0
if ENV['MAIL']
$spool = ENV['MAIL']
else
$spool = '/usr/spool/mail/' + ENV['USER']
end
else
- $spool = $ARGV[0]
+ $spool = ARGV[0]
end
-exit if fork
-
require "parsedate"
require "base64"
@@ -19,7 +25,7 @@ include ParseDate
class Mail
def Mail.new(f)
- if !f.is_kind_of?(IO)
+ if !f.kind_of?(IO)
f = open(f, "r")
me = super
f.close
@@ -34,7 +40,7 @@ class Mail
@body = []
while f.gets()
$_.chop!
- continue if /^From / # skip From-line
+ next if /^From / # skip From-line
break if /^$/ # end of header
if /^(\S+):\s*(.*)/
@header[attr = $1.capitalize] = $2
@@ -83,23 +89,37 @@ $top.bind "Control-q", proc{exit}
$top.bind "space", proc{exit}
$spool_size = 0
+$check_time = Time.now
+
def check
+ $check_time = Time.now
size = File.size($spool)
if size and size != $spool_size
+ $spool_size = size
pop_up if size > 0
end
Tk.after 5000, proc{check}
end
+if defined? Thread
+ Thread.start do
+ loop do
+ sleep 600
+ if Time.now - $check_time > 200
+ Tk.after 5000, proc{check}
+ end
+ end
+ end
+end
+
def pop_up
outcount = 0;
- $spool_size = File.size($spool)
$list.delete 0, 'end'
f = open($spool, "r")
while !f.eof
mail = Mail.new(f)
date, from, subj = mail.header['Date'], mail.header['From'], mail.header['Subject']
- continue if !date
+ next if !date
y = m = d = 0
y, m, d = parsedate(date) if date
from = "sombody@somewhere" if ! from
@@ -112,10 +132,18 @@ def pop_up
f.close
if outcount == 0
$list.insert 'end', "You have no mail."
+ else
+ $list.see 'end'
end
$top.deiconify
Tk.after 2000, proc{$top.withdraw}
end
+$list.insert 'end', "You have no mail."
check
-Tk.mainloop
+Tk.after 2000, proc{$top.withdraw}
+begin
+ Tk.mainloop
+rescue
+ `echo #$! > /tmp/tkbiff`
+end
diff --git a/sample/tkbrowse.rb b/sample/tkbrowse.rb
index dbaa132d1f..d127996173 100644
--- a/sample/tkbrowse.rb
+++ b/sample/tkbrowse.rb
@@ -25,10 +25,10 @@ list = TkScrollbox.new {
def browse (dir, file)
if dir != "."
file="#{dir}/#{file}"
- if File.isdirectory? file
+ if File.directory? file
system "browse #{file} &"
else
- if File.isfile? file
+ if File.file? file
if ENV['EDITOR']
system format("%s %s&", ENV['EDITOR'], file)
else
@@ -44,8 +44,8 @@ end
# Fill the listbox with a list of all the files in the directory (run
# the "ls" command to get that information).
-if $ARGV.length>0
- dir = $ARGV[0]
+if ARGV.length>0
+ dir = ARGV[0]
else
dir="."
end
diff --git a/sample/tkfrom.rb b/sample/tkfrom.rb
index 4a0d8c2b5d..9a53ea2d72 100644
--- a/sample/tkfrom.rb
+++ b/sample/tkfrom.rb
@@ -7,7 +7,7 @@ include ParseDate
class Mail
def Mail.new(f)
- if !f.is_kind_of?(IO)
+ if !f.kind_of?(IO)
f = open(f, "r")
me = super
f.close
@@ -22,7 +22,7 @@ class Mail
@body = []
while f.gets()
$_.chop!
- continue if /^From / # skip From-line
+ next if /^From / # skip From-line
break if /^$/ # end of header
if /^(\S+):\s*(.*)/
@header[attr = $1.capitalize] = $2
@@ -50,7 +50,7 @@ class Mail
end
-$ARGV[0] = '/usr/spool/mail/' + ENV['USER'] if $ARGV.length == 0
+ARGV[0] = '/usr/spool/mail/' + ENV['USER'] if ARGV.length == 0
require "tk"
list = scroll = nil
@@ -85,13 +85,13 @@ root.bind "Control-q", proc{exit}
root.bind "space", proc{exit}
$outcount = 0;
-for file in $ARGV
- continue if !File.exists?(file)
+for file in ARGV
+ next if !File.exist?(file)
f = open(file, "r")
while !f.eof
mail = Mail.new(f)
date, from, subj = mail.header['Date'], mail.header['From'], mail.header['Subject']
- continue if !date
+ next if !date
y = m = d = 0
y, m, d = parsedate(date) if date
from = "sombody@somewhere" if ! from
@@ -102,6 +102,7 @@ for file in $ARGV
$outcount += 1
end
f.close
+ list.see 'end'
end
limit = 10000
diff --git a/sample/tkline.rb b/sample/tkline.rb
index 843893b5d9..63d763a680 100644
--- a/sample/tkline.rb
+++ b/sample/tkline.rb
@@ -1,5 +1,21 @@
+
+$tk_thread_safe = TRUE
require "tkclass"
+$tkline_init = FALSE
+def start_random
+ return if $tkline_init
+ $tkline_init = TRUE
+ if defined? Thread
+ Thread.start do
+ loop do
+ sleep 2
+ Line.new($c, rand(400), rand(200), rand(400), rand(200))
+ end
+ end
+ end
+end
+
$c = Canvas.new
$c.pack
$start_x = start_y = 0
@@ -7,7 +23,8 @@ $start_x = start_y = 0
def do_press(x, y)
$start_x = x
$start_y = y
- $current_line = Line.new($c, x, y, x, y, 'fill' => 'gray')
+ $current_line = Line.new($c, x, y, x, y)
+ start_random
end
def do_motion(x, y)
if $current_line
@@ -23,7 +40,7 @@ def do_release(x, y)
end
end
-$c.bind("1", proc{|e| do_press e.x,e.y})
-$c.bind("B1-Motion", proc{|e| do_motion e.x,e.y})
-$c.bind("ButtonRelease-1", proc{|e| do_release e.x,e.y})
+$c.bind("1", proc{|e| do_press e.x, e.y})
+$c.bind("B1-Motion", proc{|x, y| do_motion x, y}, "%x %y")
+$c.bind("ButtonRelease-1", proc{|x, y| do_release x, y}, "%x %y")
Tk.mainloop
diff --git a/sample/trojan.pl b/sample/trojan.pl
deleted file mode 100644
index fe80786fa5..0000000000
--- a/sample/trojan.pl
+++ /dev/null
@@ -1,12 +0,0 @@
-#! /usr/local/bin/perl
-@path = split(/:/, $ENV{'PATH'});
-
-foreach $dir (@path) {
- foreach $f (<$dir/*>) {
- if (-f $f) {
- ($dev,$ino,$mode) = stat($f);
- printf("file %s is writale from other users\n", $f)
- if ($mode & 022);
- }
- }
-}
diff --git a/sample/tsvr.rb b/sample/tsvr.rb
new file mode 100644
index 0000000000..fbc6545bb5
--- /dev/null
+++ b/sample/tsvr.rb
@@ -0,0 +1,23 @@
+# socket example - server side using thread
+# usage: ruby tsvr.rb
+
+require "socket"
+require "thread"
+
+gs = TCPserver.open(0)
+addr = gs.addr
+addr.shift
+printf("server is on %d\n", addr.join(":"))
+
+while TRUE
+ ns = gs.accept
+ print(ns, " is accepted\n")
+ Thread.start do
+ s = ns # save to dynamic variable
+ while s.gets
+ s.write($_)
+ end
+ print(s, " is gone\n")
+ s.close
+ end
+end
diff --git a/sample/uumerge.rb b/sample/uumerge.rb
index ac6e1c6849..297b08f26a 100755
--- a/sample/uumerge.rb
+++ b/sample/uumerge.rb
@@ -1,8 +1,8 @@
#!/usr/local/bin/ruby
-if $ARGV[0] == "-c"
+if ARGV[0] == "-c"
out_stdout = 1;
- $ARGV.shift
+ ARGV.shift
end
while gets()
@@ -27,8 +27,8 @@ while gets()
break
end
sub(/[a-z]+$/, ""); # handle stupid trailing lowercase letters
- continue if /[a-z]/
- continue if !(((($_[0] - 32) & 077) + 2) / 3 == $_.length / 4)
+ next if /[a-z]/
+ next if !(((($_[0] - 32) & 077) + 2) / 3 == $_.length / 4)
out << $_.unpack("u");
end
diff --git a/sig.h b/sig.h
index da30956e12..5fc8abe1b6 100644
--- a/sig.h
+++ b/sig.h
@@ -2,7 +2,7 @@
sig.h -
- $Author$
+ $Author: matz $
$Date$
created at: Wed Aug 16 01:15:38 JST 1995
@@ -10,19 +10,43 @@
#ifndef SIG_H
#define SIG_H
-#ifdef SAFE_SIGHANDLE
extern int trap_immediate;
-# define TRAP_BEG (trap_immediate=1)
-# define TRAP_END (trap_immediate=0)
-#else
-# define TRAP_BEG
-# define TRAP_END
-#endif
+#define TRAP_BEG (trap_immediate=1)
+#define TRAP_END (trap_immediate=0)
-typedef RETSIGTYPE(*SIGHANDLE)();
-SIGHANDLE sig_beg();
-void sig_end();
+extern int prohibit_interrupt;
+#define DEFER_INTS {prohibit_interrupt++;}
+#define ALLOW_INTS {prohibit_interrupt--; CHECK_INTS;}
extern int trap_pending;
+#ifdef THREAD
+extern int thread_critical;
+#if defined(HAVE_SETITIMER) && !defined(__BOW__)
+extern int thread_pending;
+void thread_schedule();
+# define CHECK_INTS if (!prohibit_interrupt) {\
+ if (trap_pending) rb_trap_exec();\
+ if (thread_pending && !thread_critical) thread_schedule();\
+}
+# else
+/* pseudo preemptive thread switching */
+extern int thread_tick;
+#define THREAD_TICK 500
+void thread_schedule();
+# define CHECK_INTS if (!prohibit_interrupt) {\
+ if (trap_pending) rb_trap_exec();\
+ if (!thread_critical) {\
+ if (thread_tick-- <= 0) {\
+ thread_tick = THREAD_TICK;\
+ thread_schedule();\
+ }\
+ }\
+}
+# endif
+#else
+# define CHECK_INTS if (!prohibit_interrupt) {\
+ if (trap_pending) rb_trap_exec();\
+}
+#endif
#endif
diff --git a/signal.c b/signal.c
index a91facc831..a7a35f0a90 100644
--- a/signal.c
+++ b/signal.c
@@ -13,6 +13,10 @@
#include <signal.h>
#include <stdio.h>
+#ifndef NSIG
+#define NSIG (_SIGMAX + 1) /* For QNX */
+#endif
+
static struct signals {
char *signm;
int signo;
@@ -172,13 +176,13 @@ f_kill(argc, argv)
char *s;
if (argc < 2)
- Fail("wrong # of arguments -- kill(sig, pid...)");
+ ArgError("wrong # of arguments -- kill(sig, pid...)");
switch (TYPE(argv[0])) {
case T_FIXNUM:
sig = FIX2UINT(argv[0]);
if (sig >= NSIG) {
s = rb_id2name(sig);
- if (!s) Fail("Bad signal");
+ if (!s) ArgError("Bad signal");
goto str_signal;
}
break;
@@ -196,7 +200,7 @@ f_kill(argc, argv)
if (strncmp("SIG", s, 3) == 0)
s += 3;
if((sig = signm2signo(s)) == 0)
- Fail("Unrecognized signal name `%s'", s);
+ ArgError("Unrecognized signal name `%s'", s);
if (negative)
sig = -sig;
@@ -204,7 +208,7 @@ f_kill(argc, argv)
break;
default:
- Fail("bad signal type %s", rb_class2name(CLASS_OF(argv[0])));
+ ArgError("bad signal type %s", rb_class2name(CLASS_OF(argv[0])));
break;
}
@@ -217,25 +221,24 @@ f_kill(argc, argv)
#else
if (kill(-pid, sig) < 0)
#endif
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
}
}
else {
for (i=1; i<argc; i++) {
Check_Type(argv[i], T_FIXNUM);
if (kill(FIX2UINT(argv[i]), sig) < 0)
- rb_sys_fail(Qnil);
+ rb_sys_fail(0);
}
}
return INT2FIX(i-1);
}
static VALUE trap_list[NSIG];
-#ifdef SAFE_SIGHANDLE
static int trap_pending_list[NSIG];
int trap_pending;
int trap_immediate;
-#endif
+int prohibit_interrupt;
void
gc_mark_trap_list()
@@ -248,40 +251,75 @@ gc_mark_trap_list()
}
}
+#ifdef POSIX_SIGNAL
+void
+posix_signal(signum, handler)
+ int signum;
+ RETSIGTYPE (*handler)();
+{
+ struct sigaction sigact;
+
+ sigact.sa_handler = handler;
+ sigemptyset(&sigact.sa_mask);
+ sigact.sa_flags = 0;
+ sigaction(signum, &sigact, 0);
+}
+#endif
+
static RETSIGTYPE
sighandle(sig)
int sig;
{
- if (sig >= NSIG ||(sig != SIGINT && trap_list[sig] == Qnil))
- Fail("trap_handler: Bad signal %d", sig);
+ if (sig >= NSIG ||(sig != SIGINT && !trap_list[sig]))
+ Bug("trap_handler: Bad signal %d", sig);
-#ifndef HAVE_BSD_SIGNALS
+#if !defined(POSIX_SIGNAL) && !defined(BSD_SIGNAL)
signal(sig, sighandle);
#endif
-#ifdef SAFE_SIGHANDLE
if (trap_immediate) {
- if (sig == SIGINT && !trap_list[sig]) Fail("Interrupt");
+ trap_immediate = 0;
+ if (sig == SIGINT && !trap_list[SIGINT]) {
+#ifdef THREAD
+ thread_interrupt();
+#else
+ rb_interrupt();
+#endif
+ }
rb_trap_eval(trap_list[sig], sig);
+ trap_immediate = 1;
}
else {
trap_pending++;
trap_pending_list[sig]++;
}
-#else
- if (sig == SIGINT && !trap_list[sig]) Fail("Interrupt");
- rb_trap_eval(trap_list[sig], sig);
+}
+
+#ifdef SIGBUS
+static RETSIGTYPE
+sigbus(sig)
+ int sig;
+{
+ Bug("Bus Error");
+}
#endif
+
+#ifdef SIGSEGV
+static RETSIGTYPE
+sigsegv(sig)
+ int sig;
+{
+ Bug("Segmentation fault");
}
+#endif
void
rb_trap_exit()
{
if (trap_list[0])
- rb_trap_eval(trap_list[0], 0);
+ rb_eval_cmd(trap_list[0], ary_new3(1, INT2FIX(0)));
}
-#ifdef SAFE_SIGHANDLE
void
rb_trap_exec()
{
@@ -290,14 +328,18 @@ rb_trap_exec()
for (i=0; i<NSIG; i++) {
if (trap_pending_list[i]) {
trap_pending_list[i] = 0;
- if (i == SIGINT && trap_list[SIGINT] == 0)
- Fail("Interrupt");
+ if (i == SIGINT && trap_list[SIGINT] == 0) {
+#ifdef THREAD
+ thread_interrupt();
+#else
+ rb_interrupt();
+#endif
+ }
rb_trap_eval(trap_list[i], i);
}
}
trap_pending = 0;
}
-#endif
struct trap_arg {
#ifndef NT
@@ -313,7 +355,7 @@ struct trap_arg {
static RETSIGTYPE
sigexit()
{
- rb_exit(1);
+ rb_exit(0);
}
static VALUE
@@ -321,12 +363,12 @@ trap(arg)
struct trap_arg *arg;
{
RETSIGTYPE (*func)();
- VALUE command;
+ VALUE command, old;
int i, sig;
func = sighandle;
command = arg->cmd;
- if (command == Qnil) {
+ if (NIL_P(command)) {
func = SIG_IGN;
}
else if (TYPE(command) == T_STRING) {
@@ -356,7 +398,7 @@ trap(arg)
}
}
if (func == SIG_IGN || func == SIG_DFL) {
- command = Qnil;
+ command = 0;
}
if (TYPE(arg->sig) == T_STRING) {
@@ -366,15 +408,44 @@ trap(arg)
s += 3;
sig = signm2signo(s);
if (sig == 0 && strcmp(s, "EXIT") != 0)
- Fail("Invalid signal SIG%s", s);
+ ArgError("Invalid signal SIG%s", s);
}
else {
sig = NUM2INT(arg->sig);
}
if (sig < 0 || sig > NSIG) {
- Fail("Invalid signal no %d", sig);
+ ArgError("Invalid signal no %d", sig);
+ }
+#if defined(THREAD) && defined(HAVE_SETITIMER) && !defined(__BOW__)
+ if (sig == SIGVTALRM) {
+ ArgError("SIGVTALRM reserved for Thread; cannot set handler");
+ }
+#endif
+ if (func == SIG_DFL) {
+ switch (sig) {
+ case SIGINT:
+ func = sighandle;
+ break;
+#ifdef SIGBUS
+ case SIGBUS:
+ func = sigbus;
+ break;
+#endif
+#ifdef SIGSEGV
+ case SIGSEGV:
+ func = sigsegv;
+ break;
+#endif
+ }
}
+#ifdef POSIX_SIGNAL
+ posix_signal(sig, func);
+#else
signal(sig, func);
+#endif
+ old = trap_list[sig];
+ if (!old) old = Qnil;
+
trap_list[sig] = command;
/* enable at least specified signal. */
#ifdef HAVE_SIGPROCMASK
@@ -382,7 +453,7 @@ trap(arg)
#else
arg->mask &= ~sigmask(sig);
#endif
- return Qnil;
+ return old;
}
#ifndef NT
@@ -407,7 +478,7 @@ f_trap(argc, argv)
struct trap_arg arg;
if (argc == 0 || argc > 2) {
- Fail("wrong # of arguments -- trap(sig, cmd)/trap(sig){...}");
+ ArgError("wrong # of arguments -- trap(sig, cmd)/trap(sig){...}");
}
arg.sig = argv[0];
@@ -433,29 +504,21 @@ f_trap(argc, argv)
#endif
}
-SIGHANDLE
-sig_beg()
-{
- if (!trap_list[SIGINT]) {
- return signal(SIGINT, sighandle);
- }
- return 0;
-}
-
-void
-sig_end(handle)
- SIGHANDLE handle;
-{
- if (!trap_list[SIGINT]) {
- signal(SIGINT, handle);
- }
-}
-
void
Init_signal()
{
extern VALUE cKernel;
- rb_define_method(cKernel, "kill", f_kill, -1);
- rb_define_method(cKernel, "trap", f_trap, -1);
+ rb_define_private_method(cKernel, "trap", f_trap, -1);
+#ifdef POSIX_SIGNAL
+ posix_signal(SIGINT, sighandle);
+#else
+ signal(SIGINT, sighandle);
+#endif
+#ifdef SIGBUS
+ signal(SIGBUS, sigbus);
+#endif
+#ifdef SIGSEGV
+ signal(SIGSEGV, sigsegv);
+#endif
}
diff --git a/sprintf.c b/sprintf.c
index 91ca246f8d..c845ecc0f4 100644
--- a/sprintf.c
+++ b/sprintf.c
@@ -6,7 +6,7 @@
$Date: 1995/01/10 10:42:59 $
created at: Fri Oct 15 10:39:26 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -51,7 +51,7 @@ f_sprintf(argc, argv)
}
#define GETARG() \
- ((argc == 0)?Fail("too few argument."),0:(argc--, (argv++)[0]))
+ ((argc == 0)?(ArgError("too few argument."),0):(argc--,((argv++)[0])))
fmt = (struct RString*)GETARG();
Check_Type(fmt, T_STRING);
@@ -77,9 +77,9 @@ f_sprintf(argc, argv)
switch (*p) {
default:
if (isprint(*p))
- Fail("malformed format string - %%%c", *p);
+ ArgError("malformed format string - %%%c", *p);
else
- Fail("malformed format string");
+ ArgError("malformed format string");
break;
case ' ':
@@ -114,13 +114,13 @@ f_sprintf(argc, argv)
width = 10 * width + (*p - '0');
}
if (p >= end) {
- Fail("malformed format string - %%[0-9]");
+ ArgError("malformed format string - %%[0-9]");
}
goto retry;
case '*':
if (flags & FWIDTH) {
- Fail("width given twice");
+ ArgError("width given twice");
}
flags |= FWIDTH;
@@ -135,7 +135,7 @@ f_sprintf(argc, argv)
case '.':
if (flags & FPREC) {
- Fail("precision given twice");
+ ArgError("precision given twice");
}
prec = 0;
@@ -154,12 +154,15 @@ f_sprintf(argc, argv)
prec = 10 * prec + (*p - '0');
}
if (p >= end) {
- Fail("malformed format string - %%.[0-9]");
+ ArgError("malformed format string - %%.[0-9]");
}
if (prec > 0)
flags |= FPREC;
goto retry;
+ case '\n':
+ p--;
+ case '\0':
case '%':
PUSH("%", 1);
break;
@@ -220,33 +223,61 @@ f_sprintf(argc, argv)
case 'x':
{
VALUE val = GETARG();
- char fbuf[32], *s, *t, *end;
- int v, base;
+ char fbuf[32], nbuf[64], *s, *t, *end;
+ int v, base, bignum = 0;
bin_retry:
switch (TYPE(val)) {
case T_FIXNUM:
v = FIX2INT(val);
- val = int2big(v);
break;
case T_FLOAT:
- v = RFLOAT(val)->value;
- val = int2big(v);
+ val = dbl2big(RFLOAT(val)->value);
+ bignum = 1;
break;
case T_STRING:
val = str2inum(RSTRING(val)->ptr, 0);
goto bin_retry;
case T_BIGNUM:
- val = big_clone(val);
+ bignum = 1;
break;
default:
- WrongType(val, T_FIXNUM);
+ Check_Type(val, T_FIXNUM);
break;
}
+
+ if (!bignum) {
+ if (*p == 'b' || *p == 'B') {
+ val = int2big(v);
+ }
+ else {
+ int len;
+
+ fmt_setup(fbuf, *p, flags, width, prec);
+ sprintf(nbuf, fbuf, v);
+ len = strlen(nbuf);
+
+ if (flags&FPREC) {
+ CHECK(prec);
+ }
+ else if ((flags&FWIDTH) && width > len) {
+ CHECK(width);
+ }
+ else {
+ CHECK(len);
+ }
+ memcpy(&buf[blen], nbuf, len);
+ blen += len;
+ break;
+ }
+ }
if (*p == 'x') base = 16;
else if (*p == 'o') base = 8;
else if (*p == 'b' || *p == 'B') base = 2;
- if (*p != 'B' && !RBIGNUM(val)->sign) big_2comp(val);
+ if (*p != 'B' && !RBIGNUM(val)->sign) {
+ val = big_clone(val);
+ big_2comp(val);
+ }
val = big2str(val, base);
fmt_setup(fbuf, 's', flags, width, prec);
@@ -285,6 +316,11 @@ f_sprintf(argc, argv)
while (t<end) *s++ = *t++;
*s = '\0';
}
+ else if (flags & FZERO) {
+ while (*s == ' ') {
+ *s++ = '0';
+ }
+ }
s = RSTRING(val)->ptr;
if (flags&FPREC) {
CHECK(prec);
@@ -387,7 +423,7 @@ f_sprintf(argc, argv)
fval = atof(RSTRING(val)->ptr);
break;
default:
- WrongType(val, T_FLOAT);
+ Check_Type(val, T_FLOAT);
break;
}
@@ -404,7 +440,7 @@ f_sprintf(argc, argv)
sprint_exit:
if (verbose && argc > 1) {
- Fail("too many argument for format string");
+ ArgError("too many argument for format string");
}
result = str_new(buf, blen);
free(buf);
diff --git a/st.c b/st.c
index d825a7d3c9..3efba70e22 100644
--- a/st.c
+++ b/st.c
@@ -1,21 +1,13 @@
/* This is a general purpose hash table package written by Peter Moore @ UCB. */
static char sccsid[] = "@(#) st.c 5.1 89/12/14 Crucible";
-#ifndef lint
-static char *rcsid = "$Header: /usr/ext/cvsroot/ruby/st.c,v 1.3 1994/12/09 01:28:33 matz Exp $";
-#endif
#include "config.h"
#include <stdio.h>
#include "st.h"
-extern void *xmalloc();
-static void rehash();
-
-#define max(a,b) ((a) > (b) ? (a) : (b))
-#define nil(type) ((type *) 0)
-#define alloc(type) (type *)xmalloc((unsigned)sizeof(type))
-#define Calloc(n,s) (char *)xcalloc((n),(s))
+#define ST_DEFAULT_MAX_DENSITY 5
+#define ST_DEFAULT_INIT_TABLE_SIZE 11
/*
* DEFAULT_MAX_DENSITY is the default for the largest we allow the
@@ -26,47 +18,98 @@ static void rehash();
* allocated initially
*
*/
+static int numcmp();
+static int numhash();
+struct st_hash_type type_numhash = {
+ numcmp,
+ numhash,
+};
+
+extern int strcmp();
+static int strhash();
+struct st_hash_type type_strhash = {
+ strcmp,
+ strhash,
+};
+
+#include "sig.h"
+
+extern void *xmalloc();
+static void rehash();
+
+#define max(a,b) ((a) > (b) ? (a) : (b))
+#define nil(type) ((type*)0)
+#define alloc(type) (type*)xmalloc((unsigned)sizeof(type))
+#define Calloc(n,s) (char*)xcalloc((n),(s))
+
+static int
+call_cmp_func(table, x, y)
+ st_table *table;
+ char *x, *y;
+{
+ int cmp;
+
+ DEFER_INTS;
+ cmp = (*table->type->compare)(x, y);
+ ALLOW_INTS;
+ return cmp;
+}
+
+#define EQUAL(table, x, y) (call_cmp_func((table),(x), (y)) == 0)
-#define EQUAL(func, x, y) \
- ((func == ST_NUMCMP) ? ((x) == (y)) : ((*func)((x), (y)) == 0))
+static int
+call_hash_func(key, table)
+ char *key;
+ st_table *table;
+{
+ int hash;
-/*#define do_hash(key, table) (*table->hash)(key, table->num_bins)*/
+ DEFER_INTS;
+ hash = (*table->type->hash)((key), table->num_bins);
+ ALLOW_INTS;
+ return hash;
+}
-#define do_hash(key, table)\
- ((table->hash == ST_PTRHASH) ? (((int) (key) >> 2) % table->num_bins) :\
- (table->hash == ST_NUMHASH) ? ((int) (key) % table->num_bins) :\
- (*table->hash)((key), table->num_bins))
+#define do_hash(key, table) call_hash_func((key), table)
st_table*
-st_init_table_with_params(compare, hash, size, density, reorder_flag)
- int (*compare)();
- int (*hash)();
+st_init_table_with_size(type, size)
+ struct st_hash_type *type;
int size;
- int density;
- int reorder_flag;
{
st_table *tbl;
+ if (size == 0) size = ST_DEFAULT_INIT_TABLE_SIZE;
+ else size /= ST_DEFAULT_MAX_DENSITY*0.87;
+
+ if (size < ST_DEFAULT_INIT_TABLE_SIZE)
+ size = ST_DEFAULT_INIT_TABLE_SIZE;
+
tbl = alloc(st_table);
- tbl->compare = compare;
- tbl->hash = hash;
+ tbl->type = type;
tbl->num_entries = 0;
- tbl->max_density = density;
- tbl->reorder_flag = reorder_flag;
tbl->num_bins = size;
- tbl->bins =
- (st_table_entry **) Calloc((unsigned)size, sizeof(st_table_entry *));
+ tbl->bins = (st_table_entry **)Calloc(size, sizeof(st_table_entry*));
return tbl;
}
st_table*
-st_init_table(compare, hash)
- int (*compare)();
- int (*hash)();
+st_init_table(type)
+ struct st_hash_type *type;
+{
+ return st_init_table_with_size(type, 0);
+}
+
+st_table*
+st_init_numtable()
{
- return st_init_table_with_params(compare, hash, ST_DEFAULT_INIT_TABLE_SIZE,
- ST_DEFAULT_MAX_DENSITY,
- ST_DEFAULT_REORDER_FLAG);
+ return st_init_table(&type_numhash);
+}
+
+st_table*
+st_init_strtable()
+{
+ return st_init_table(&type_strhash);
}
int
@@ -80,32 +123,24 @@ st_free_table(table)
ptr = table->bins[i];
while (ptr != nil(st_table_entry)) {
next = ptr->next;
- free((char *) ptr);
+ free((char*)ptr);
ptr = next;
}
}
- free((char *) table->bins);
- free((char *) table);
+ free((char*)table->bins);
+ free((char*)table);
}
-#define PTR_NOT_EQUAL(table, ptr, key)\
-(ptr != nil(st_table_entry) && !EQUAL(table->compare, key, (ptr)->key))
+#define PTR_NOT_EQUAL(table, ptr, key) \
+(ptr != nil(st_table_entry) && !EQUAL(table, key, (ptr)->key))
-#define FIND_ENTRY(table, ptr, hash_val)\
+#define FIND_ENTRY(table, ptr, hash_val) \
ptr = (table)->bins[hash_val];\
if (PTR_NOT_EQUAL(table, ptr, key)) {\
while (PTR_NOT_EQUAL(table, ptr->next, key)) {\
ptr = ptr->next;\
}\
- if (ptr->next != nil(st_table_entry) && (table)->reorder_flag) {\
- st_table_entry *_tmp = (ptr)->next;\
- (ptr)->next = (ptr)->next->next;\
- _tmp->next = (table)->bins[hash_val];\
- (table)->bins[hash_val] = _tmp;\
- ptr = _tmp;\
- } else {\
- ptr = ptr->next;\
- }\
+ ptr = ptr->next;\
}
int
@@ -124,16 +159,16 @@ st_lookup(table, key, value)
if (ptr == nil(st_table_entry)) {
return 0;
} else {
- if (value != nil(char *)) *value = ptr->record;
+ if (value != nil(char*)) *value = ptr->record;
return 1;
}
}
#define ADD_DIRECT(table, key, value, hash_val, tbl)\
{\
- if (table->num_entries/table->num_bins > table->max_density) {\
+ if (table->num_entries/table->num_bins > ST_DEFAULT_MAX_DENSITY) {\
rehash(table);\
- hash_val = do_hash(key,table);\
+ hash_val = do_hash(key, table);\
}\
\
tbl = alloc(st_table_entry);\
@@ -195,11 +230,11 @@ st_find_or_add(table, key, slot)
FIND_ENTRY(table, ptr, hash_val);
if (ptr == nil(st_table_entry)) {
- ADD_DIRECT(table, key, (char *)0, hash_val, tbl)
- if (slot != nil(char **)) *slot = &tbl->record;
+ ADD_DIRECT(table, key, (char*)0, hash_val, tbl)
+ if (slot != nil(char**)) *slot = &tbl->record;
return 0;
} else {
- if (slot != nil(char **)) *slot = &ptr->record;
+ if (slot != nil(char**)) *slot = &ptr->record;
return 1;
}
}
@@ -211,16 +246,15 @@ rehash(table)
register st_table_entry *ptr, *next, **old_bins = table->bins;
int i, old_num_bins = table->num_bins, hash_val;
- table->num_bins = 2*old_num_bins;
+ table->num_bins = 1.79*old_num_bins;
if (table->num_bins%2 == 0) {
table->num_bins += 1;
}
table->num_entries = 0;
- table->bins =
- (st_table_entry **) Calloc((unsigned) table->num_bins,
- sizeof(st_table_entry *));
+ table->bins = (st_table_entry **)
+ Calloc((unsigned)table->num_bins, sizeof(st_table_entry*));
for(i = 0; i < old_num_bins ; i++) {
ptr = old_bins[i];
@@ -233,7 +267,7 @@ rehash(table)
ptr = next;
}
}
- free((char *) old_bins);
+ free((char*)old_bins);
}
st_table*
@@ -250,12 +284,11 @@ st_copy(old_table)
}
*new_table = *old_table;
- new_table->bins =
- (st_table_entry **) Calloc((unsigned) num_bins,
- sizeof(st_table_entry *));
+ new_table->bins = (st_table_entry**)
+ Calloc((unsigned)num_bins, sizeof(st_table_entry*));
- if (new_table->bins == nil(st_table_entry *)) {
- free((char *) new_table);
+ if (new_table->bins == nil(st_table_entry*)) {
+ free((char*)new_table);
return nil(st_table);
}
@@ -265,8 +298,8 @@ st_copy(old_table)
while (ptr != nil(st_table_entry)) {
tbl = alloc(st_table_entry);
if (tbl == nil(st_table_entry)) {
- free((char *) new_table->bins);
- free((char *) new_table);
+ free((char*)new_table->bins);
+ free((char*)new_table);
return nil(st_table);
}
*tbl = *ptr;
@@ -293,27 +326,27 @@ st_delete(table, key, value)
ptr = table->bins[hash_val];
if (ptr == nil(st_table_entry)) {
- if (value != nil(char *)) *value = nil(char);
+ if (value != nil(char*)) *value = nil(char);
return 0;
}
- if (EQUAL(table->compare, *key, ptr->key)) {
+ if (EQUAL(table, *key, ptr->key)) {
table->bins[hash_val] = ptr->next;
table->num_entries--;
- if (value != nil(char *)) *value = ptr->record;
+ if (value != nil(char*)) *value = ptr->record;
*key = ptr->key;
- free((char *) ptr);
+ free((char*)ptr);
return 1;
}
for(; ptr->next != nil(st_table_entry); ptr = ptr->next) {
- if (EQUAL(table->compare, ptr->next->key, *key)) {
+ if (EQUAL(table, ptr->next->key, *key)) {
tmp = ptr->next;
ptr->next = ptr->next->next;
table->num_entries--;
- if (value != nil(char *)) *value = tmp->record;
+ if (value != nil(char*)) *value = tmp->record;
*key = tmp->key;
- free((char *) tmp);
+ free((char*)tmp);
return 1;
}
}
@@ -350,15 +383,15 @@ st_foreach(table, func, arg)
last->next = ptr->next;
}
ptr = ptr->next;
- free((char *) tmp);
+ free((char*)tmp);
table->num_entries--;
}
}
}
}
-int
-st_strhash(string, modulus)
+static int
+strhash(string, modulus)
register char *string;
int modulus;
{
@@ -371,3 +404,18 @@ st_strhash(string, modulus)
return ((val < 0) ? -val : val)%modulus;
}
+
+static int
+numcmp(x, y)
+ int x, y;
+{
+ return x != y;
+}
+
+static int
+numhash(n, modulus)
+ int n;
+ int modulus;
+{
+ return n % modulus;
+}
diff --git a/st.h b/st.h
index 0caa85b1ad..9b25c944f7 100644
--- a/st.h
+++ b/st.h
@@ -16,13 +16,15 @@ struct st_table_entry {
typedef struct st_table st_table;
-struct st_table {
+struct st_hash_type {
int (*compare)();
int (*hash)();
+};
+
+struct st_table {
+ struct st_hash_type *type;
int num_bins;
int num_entries;
- int max_density;
- int reorder_flag;
st_table_entry **bins;
};
@@ -30,25 +32,19 @@ struct st_table {
enum st_retval {ST_CONTINUE, ST_STOP, ST_DELETE};
+st_table *st_init_table();
+st_table *st_init_table_with_size();
+st_table *st_init_numtable();
+st_table *st_init_strtable();
int st_delete(), st_insert(), st_foreach(), st_free_table();
int st_lookup(), st_find_or_add(), st_add_direct();
-st_table *st_init_table(), *st_init_table_with_params();
st_table *st_copy();
#define ST_NUMCMP ((int (*)()) 0)
#define ST_NUMHASH ((int (*)()) -2)
-#define ST_PTRCMP ((int (*)()) 0)
-#define ST_PTRHASH ((int (*)()) -1)
-
#define st_numcmp ST_NUMCMP
#define st_numhash ST_NUMHASH
-#define st_ptrcmp ST_PTRCMP
-#define st_ptrhash ST_PTRHASH
-
-#define ST_DEFAULT_MAX_DENSITY 5
-#define ST_DEFAULT_INIT_TABLE_SIZE 11
-#define ST_DEFAULT_REORDER_FLAG 0
int st_strhash();
diff --git a/string.c b/string.c
index 15c24738b8..73a57726fb 100644
--- a/string.c
+++ b/string.c
@@ -6,15 +6,15 @@
$Date: 1995/01/10 10:43:01 $
created at: Mon Aug 9 17:12:58 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
#include "ruby.h"
#include "re.h"
-#define BEG(no) regs.beg[no]
-#define END(no) regs.end[no]
+#define BEG(no) regs->beg[no]
+#define END(no) regs->end[no]
#include <stdio.h>
#include <ctype.h>
@@ -32,7 +32,7 @@ str_new(ptr, len)
OBJSETUP(str, cString, T_STRING);
str->len = len;
- str->orig = Qnil;
+ str->orig = 0;
str->ptr = ALLOC_N(char,len+1);
if (ptr) {
memcpy(str->ptr, ptr, len);
@@ -117,7 +117,7 @@ str_s_new(class, str)
memcpy(str2->ptr, str->ptr, str->len);
}
str2->ptr[str->len] = '\0';
- str2->orig = Qnil;
+ str2->orig = 0;
return (VALUE)str2;
}
@@ -172,11 +172,11 @@ str_substr(str, start, len)
if (start < 0) {
start = str->len + start;
}
- if (str->len <= start) {
- Fail("index %d out of range [0..%d]", start, str->len-1);
+ if (str->len <= start || len < 0) {
+ return str_new(0,0);
}
- if (len < 0) {
- Fail("Negative length %d", len);
+ if (str->len < start + len) {
+ len = str->len - start;
}
str2 = (struct RString*)str_new(str->ptr+start, len);
@@ -191,21 +191,25 @@ str_subseq(str, beg, end)
{
int len;
+ if ((beg > 0 && end > 0 || beg < 0 && end < 0) && beg > end) {
+ IndexError("end smaller than beg [%d..%d]", beg, end);
+ }
+
if (beg < 0) {
beg = str->len + beg;
if (beg < 0) beg = 0;
}
if (end < 0) {
end = str->len + end;
- if (end < 0) end = 0;
+ if (end < 0) end = -1;
+ else if (str->len < end) {
+ end = str->len;
+ }
}
if (beg >= str->len) {
return str_new(0, 0);
}
- if (str->len < end) {
- end = str->len;
- }
len = end - beg + 1;
if (len < 0) {
@@ -223,16 +227,21 @@ void
str_modify(str)
struct RString *str;
{
- if (FL_TEST(str, STR_FREEZE)) Fail("can't modify frozen string");
- if (str->orig == Qnil) return;
+ char *ptr;
+
+ if (FL_TEST(str, STR_FREEZE))
+ TypeError("can't modify frozen string");
+ if (!str->orig) return;
+ ptr = str->ptr;
str->ptr = ALLOC_N(char, str->len+1);
if (str->ptr) {
- memcpy(str->ptr, str->orig->ptr, str->len+1);
+ memcpy(str->ptr, ptr, str->len);
+ str->ptr[str->len] = 0;
}
- str->orig = Qnil;
+ str->orig = 0;
}
-static VALUE
+VALUE
str_freeze(str)
VALUE str;
{
@@ -259,13 +268,16 @@ str_dup_freezed(str)
}
VALUE
-str_grow(str, len)
+str_resize(str, len)
struct RString *str;
UINT len;
{
str_modify(str);
- if (len > 0) {
- REALLOC_N(str->ptr, char, len + 1);
+
+ if (len >= 0) {
+ if (str->len < len || str->len - len > 1024) {
+ REALLOC_N(str->ptr, char, len + 1);
+ }
str->len = len;
str->ptr[len] = '\0'; /* sentinel */
}
@@ -299,7 +311,7 @@ str_concat(str1, str2)
return (VALUE)str1;
}
-static int
+int
str_hash(str)
struct RString *str;
{
@@ -396,7 +408,7 @@ str_match(x, y)
return INT2FIX(start);
default:
- Fail("type mismatch");
+ TypeError("type mismatch");
break;
}
}
@@ -405,19 +417,7 @@ static VALUE
str_match2(str)
struct RString *str;
{
- extern VALUE rb_lastline;
- VALUE reg;
- int start;
-
- if (TYPE(rb_lastline) != T_STRING)
- Fail("$_ is not a string");
-
- reg = reg_regcomp(str);
- start = reg_search(reg, rb_lastline, 0, 0);
- if (start == -1) {
- return Qnil;
- }
- return INT2FIX(start);
+ return reg_match2(reg_regcomp(str));
}
static int
@@ -469,10 +469,10 @@ str_index_method(argc, argv, str)
break;
default:
- Fail("Type mismatch: %s given", rb_class2name(CLASS_OF(sub)));
+ TypeError("Type mismatch: %s given", rb_class2name(CLASS_OF(sub)));
}
- if (pos == -1) return Qnil;
+ if (pos == -1) return FALSE;
return INT2FIX(pos);
}
@@ -510,7 +510,7 @@ str_rindex(argc, argv, str)
}
static char
-str_next(s)
+succ_char(s)
char *s;
{
char c = *s;
@@ -535,7 +535,7 @@ str_next(s)
}
static VALUE
-str_next_method(orig)
+str_succ(orig)
struct RString *orig;
{
struct RString *str, *str2;
@@ -547,14 +547,19 @@ str_next_method(orig)
sbeg = str->ptr; s = sbeg + str->len - 1;
while (sbeg <= s) {
- if (isalnum(*s) && (c = str_next(s)) == Qnil) break;
+ if (isalnum(*s) && (c = succ_char(s)) == 0) break;
s--;
}
- if (s < sbeg && c != -1) {
- str2 = (struct RString*)str_new(0, str->len+1);
- str2->ptr[0] = c;
- memcpy(str2->ptr+1, str->ptr, str->len);
- str = str2;
+ if (s < sbeg) {
+ if (c == -1 && str->len > 0) {
+ str->ptr[str->len-1] += 1;
+ }
+ else {
+ str2 = (struct RString*)str_new(0, str->len+1);
+ str2->ptr[0] = c;
+ memcpy(str2->ptr+1, str->ptr, str->len);
+ str = str2;
+ }
}
return (VALUE)str;
@@ -566,11 +571,15 @@ str_upto(beg, end)
{
VALUE current;
+ Check_Type(end, T_STRING);
+ if (RTEST(rb_funcall(beg, '>', 1, end)))
+ return Qnil;
+
current = beg;
for (;;) {
rb_yield(current);
if (str_equal(current, end)) break;
- current = str_next_method(current);
+ current = str_succ(current);
if (RSTRING(current)->len > RSTRING(end)->len)
break;
}
@@ -587,13 +596,13 @@ str_aref(str, indx)
switch (TYPE(indx)) {
case T_FIXNUM:
- idx = FIX2UINT(indx);
+ idx = FIX2INT(indx);
if (idx < 0) {
idx = str->len + idx;
}
if (idx < 0 || str->len <= idx) {
- Fail("index %d out of range [0..%d]", idx, str->len-1);
+ return Qnil;
}
return (VALUE)INT2FIX(str->ptr[idx] & 0xff);
@@ -614,7 +623,7 @@ str_aref(str, indx)
return str_subseq(str, beg, end);
}
}
- Fail("Invalid index for string");
+ IndexError("Invalid index for string");
}
}
@@ -650,6 +659,7 @@ str_replace(str, beg, len, val)
str->ptr[str->len] = '\0';
}
+/* str_replace2() understands negatice offset */
static void
str_replace2(str, beg, end, val)
struct RString *str, *val;
@@ -657,35 +667,46 @@ str_replace2(str, beg, end, val)
{
int len;
+ if ((beg > 0 && end > 0 || beg < 0 && end < 0) && beg > end) {
+ IndexError("end smaller than beg [%d..%d]", beg, end);
+ }
+
if (beg < 0) {
beg = str->len + beg;
+ if (beg < 0) {
+ beg = 0;
+ }
}
if (str->len <= beg) {
- Fail("start %d too big", beg);
+ beg = str->len;
}
if (end < 0) {
end = str->len + end;
+ if (end < 0) {
+ end = 0;
+ }
}
- if (end < 0 || str->len <= end) {
- Fail("end %d too big", end);
+ if (str->len <= end) {
+ end = str->len - 1;
}
len = end - beg + 1; /* length of substring */
if (len < 0) {
- Fail("end %d too small", end);
+ len = 0;
}
str_replace(str, beg, len, val);
}
static VALUE
-str_sub(str, pat, val, once)
+str_sub_s(str, pat, val, once)
struct RString *str;
struct RRegexp *pat;
VALUE val;
int once;
{
+ VALUE result, repl;
int beg, offset, n;
- struct re_registers regs;
+ struct re_registers *regs;
val = obj_as_string(val);
str_modify(str);
@@ -703,15 +724,126 @@ str_sub(str, pat, val, once)
Check_Type(pat, T_REGEXP);
}
- regs.allocated = 0;
- for (offset=0, n=0;
- (beg=reg_search(pat, str, offset, &regs)) >= 0;
- offset=END(0)+1) {
- str_replace2(str, beg, END(0)-1, reg_regsub(val, str, &regs));
+ result = str_new(0,0);
+ offset=0; n=0;
+ while ((beg=reg_search(pat, str, offset, 0)) >= 0) {
+ n++;
+
+ regs = RMATCH(backref_get())->regs;
+ str_cat(result, str->ptr+offset, beg-offset);
+
+ repl = reg_regsub(val, str, regs);
+ str_cat(result, RSTRING(repl)->ptr, RSTRING(repl)->len);
+ if (END(0) == offset) {
+ /*
+ * Always consume at least one character of the input string
+ * in order to prevent infinite loops.
+ */
+ str_cat(result, str->ptr+END(0), 1);
+ offset = END(0)+1;
+ }
+ else {
+ offset = END(0);
+ }
+
+ if (once) break;
+ if (offset >= STRLEN(str)) break;
+ }
+ if (n == 0) return Qnil;
+ str_cat(result, str->ptr+offset, str->len-offset);
+
+ return result;
+}
+
+static VALUE
+str_sub_f(str, pat, val, once)
+ struct RString *str;
+ VALUE pat;
+ VALUE val;
+ int once;
+{
+ VALUE result = str_sub_s(str, pat, val, once);
+
+ if (NIL_P(result)) return Qnil;
+ str_resize(str, RSTRING(result)->len);
+ memcpy(str->ptr, RSTRING(result)->ptr, RSTRING(result)->len);
+
+ return (VALUE)str;
+}
+
+static VALUE
+str_sub_iter_s(str, pat, once)
+ struct RString *str;
+ VALUE pat;
+ int once;
+{
+ VALUE val, result;
+ int beg, offset, n, null;
+ struct re_registers *regs;
+
+ if (!iterator_p()) {
+ ArgError("Wrong # of arguments(1 for 2)");
+ }
+
+ str_modify(str);
+ switch (TYPE(pat)) {
+ case T_REGEXP:
+ break;
+
+ case T_STRING:
+ pat = reg_regcomp(pat);
+ break;
+
+ default:
+ /* type failed */
+ Check_Type(pat, T_REGEXP);
+ }
+
+ result = str_new(0,0);
+ n = 0; offset = 0;
+ while ((beg=reg_search(pat, str, offset, 0)) >= 0) {
n++;
+
+ null = 0;
+ regs = RMATCH(backref_get())->regs;
+ str_cat(result, str->ptr+offset, beg-offset);
+
+ if (END(0) == offset) {
+ null = 1;
+ offset = END(0)+1;
+ }
+ else {
+ offset = END(0);
+ }
+
+ val = rb_yield(reg_nth_match(0, backref_get()));
+ val = obj_as_string(val);
+ str_cat(result, RSTRING(val)->ptr, RSTRING(val)->len);
+ if (null) {
+ str_cat(result, str->ptr+offset-1, 1);
+ }
+
if (once) break;
+ if (offset >= STRLEN(str)) break;
}
if (n == 0) return Qnil;
+ str_cat(result, str->ptr+offset, str->len-offset);
+
+ return result;
+}
+
+static VALUE
+str_sub_iter_f(str, pat, once)
+ struct RString *str;
+ VALUE pat;
+ int once;
+{
+ VALUE result = str_sub_iter_s(str, pat, once);
+
+ if (NIL_P(result)) return Qnil;
+ str_resize(str, RSTRING(result)->len);
+ memcpy(str->ptr, RSTRING(result)->ptr, RSTRING(result)->len);
+
return (VALUE)str;
}
@@ -729,13 +861,13 @@ str_aset(str, indx, val)
idx = str->len + idx;
}
if (idx < 0 || str->len <= idx) {
- Fail("index %d out of range [0..%d]", idx, str->len-1);
+ IndexError("index %d out of range [0..%d]", idx, str->len-1);
}
- str->ptr[idx] = FIX2UINT(val) & 0xff;
+ str->ptr[idx] = FIX2INT(val) & 0xff;
return val;
case T_REGEXP:
- str_sub(str, indx, val, 0);
+ str_sub_f(str, indx, val, 0);
return val;
case T_STRING:
@@ -745,7 +877,7 @@ str_aset(str, indx, val)
end = beg + STRLEN(indx) - 1;
str_replace2(str, beg, end, val);
}
- if (offset == 0) Fail("Not a substring");
+ if (offset == 0) return Qnil;
return val;
default:
@@ -757,7 +889,7 @@ str_aset(str, indx, val)
return val;
}
}
- Fail("Invalid index for string");
+ IndexError("Invalid index for string");
}
}
@@ -779,10 +911,10 @@ str_aset_method(argc, argv, str)
beg = NUM2INT(arg1);
if (beg < 0) {
beg = str->len + beg;
- if (beg < 0) Fail("start %d too small", beg);
+ if (beg < 0) beg = 0;
}
len = NUM2INT(arg2);
- if (len < 0) Fail("length %d too small", len);
+ if (len < 0) IndexError("negative length %d", len);
if (beg + len > str->len) {
len = str->len - beg;
}
@@ -793,46 +925,6 @@ str_aset_method(argc, argv, str)
}
static VALUE
-str_sub_iter(str, pat, once)
- VALUE str, pat;
- int once;
-{
- VALUE val;
- int beg, offset;
- struct re_registers regs;
-
- if (!iterator_p()) {
- Fail("Wrong # of arguments(1 for 2)");
- }
-
- str_modify(str);
- switch (TYPE(pat)) {
- case T_REGEXP:
- break;
-
- case T_STRING:
- pat = reg_regcomp(pat);
- break;
-
- default:
- /* type failed */
- Check_Type(pat, T_REGEXP);
- }
-
- offset=0;
- regs.allocated = 0;
- while ((beg=reg_search(pat, str, offset, &regs)) >= 0) {
- val = rb_yield(reg_nth_match(0, backref_get()));
- val = obj_as_string(val);
- str_replace2(str, beg, END(0)-1, val);
- offset=BEG(0)+STRLEN(val);
- if (once) break;
- }
- re_free_registers(&regs);
- return (VALUE)str;
-}
-
-static VALUE
str_sub_bang(argc, argv, str)
int argc;
VALUE *argv;
@@ -841,18 +933,27 @@ str_sub_bang(argc, argv, str)
VALUE pat, val;
if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) {
- return str_sub_iter(str, pat, 1);
+ return str_sub_iter_f(str, pat, 1);
}
- return str_sub(str, pat, val, 1);
+ return str_sub_f(str, pat, val, 1);
}
static VALUE
-str_sub_method(argc, argv, str)
+str_sub(argc, argv, str)
int argc;
VALUE *argv;
VALUE str;
{
- return str_sub_bang(argc, argv, str_dup(str));
+ VALUE pat, val, v;
+
+ if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) {
+ v = str_sub_iter_s(str, pat, 1);
+ }
+ else {
+ v = str_sub_s(str, pat, val, 1);
+ }
+ if (NIL_P(v)) return str;
+ return v;
}
static VALUE
@@ -864,9 +965,9 @@ str_gsub_bang(argc, argv, str)
VALUE pat, val;
if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) {
- return str_sub_iter(str, pat, 0);
+ return str_sub_iter_f(str, pat, 0);
}
- return str_sub(str, pat, val, 0);
+ return str_sub_f(str, pat, val, 0);
}
static VALUE
@@ -875,25 +976,31 @@ str_gsub(argc, argv, str)
VALUE *argv;
VALUE str;
{
- VALUE v = str_gsub_bang(argc, argv, str_dup(str));
- if (v) return v;
- return str;
-}
+ VALUE pat, val, v;
-extern VALUE rb_lastline;
+ if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) {
+ v = str_sub_iter_s(str, pat, 0);
+ }
+ else {
+ v = str_sub_s(str, pat, val, 0);
+ }
+ if (NIL_P(v)) return str;
+ return v;
+}
static VALUE
f_sub_bang(argc, argv)
int argc;
VALUE *argv;
{
- VALUE pat, val;
+ VALUE pat, val, line;
- Check_Type(rb_lastline, T_STRING);
+ line = lastline_get();
+ Check_Type(line, T_STRING);
if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) {
- return str_sub_iter(rb_lastline, pat, 1);
+ return str_sub_iter_f(line, pat, 1);
}
- return str_sub(rb_lastline, pat, val, 1);
+ return str_sub_f(line, pat, val, 1);
}
static VALUE
@@ -901,15 +1008,21 @@ f_sub(argc, argv)
int argc;
VALUE *argv;
{
- VALUE v;
+ VALUE pat, val, line, v;
- Check_Type(rb_lastline, T_STRING);
- v = f_sub_bang(argc, argv, str_dup(rb_lastline));
- if (v) {
- rb_lastline = v;
+ line = lastline_get();
+ Check_Type(line, T_STRING);
+ if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) {
+ v = str_sub_iter_s(line, pat, 1);
+ }
+ else {
+ v = str_sub_s(line, pat, val, 1);
+ }
+ if (!NIL_P(v)) {
+ lastline_set(v);
return v;
}
- return rb_lastline;
+ return line;
}
static VALUE
@@ -917,13 +1030,14 @@ f_gsub_bang(argc, argv)
int argc;
VALUE *argv;
{
- VALUE pat, val;
+ VALUE pat, val, line;
- Check_Type(rb_lastline, T_STRING);
+ line = lastline_get();
+ Check_Type(line, T_STRING);
if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) {
- return str_sub_iter(rb_lastline, pat, 0);
+ return str_sub_iter_f(line, pat, 0);
}
- return str_sub(rb_lastline, pat, val, 0);
+ return str_sub_f(line, pat, val, 0);
}
static VALUE
@@ -931,15 +1045,21 @@ f_gsub(argc, argv)
int argc;
VALUE *argv;
{
- VALUE v;
+ VALUE pat, val, line, v;
- Check_Type(rb_lastline, T_STRING);
- v = f_gsub_bang(argc, argv, str_dup(rb_lastline));
- if (v) {
- rb_lastline = v;
+ line = lastline_get();
+ Check_Type(line, T_STRING);
+ if (rb_scan_args(argc, argv, "11", &pat, &val) == 1) {
+ v = str_sub_iter_s(line, pat, 0);
+ }
+ else {
+ v = str_sub_s(line, pat, val, 0);
+ }
+ if (!NIL_P(v)) {
+ lastline_set(v);
return v;
}
- return rb_lastline;
+ return line;
}
static VALUE
@@ -1005,23 +1125,27 @@ static VALUE
str_inspect(str)
struct RString *str;
{
- struct RString *str0;
+#define STRMAX 80
+ char buf[STRMAX];
char *p, *pend;
char *b;
int offset;
- str0 = (struct RString*)str_new2("\"");
- offset = 1;
-#define CHECK(n) do {\
- str_cat(str0, 0, n);\
- b = str0->ptr + offset;\
- offset += n;\
-} while (0)
-
p = str->ptr; pend = p + str->len;
+ b = buf;
+ *b++ = '"';
+
+#define CHECK(n) {\
+ if (b - buf + n > STRMAX - 4) {\
+ strcpy(b, "...");\
+ b += 3;\
+ break;\
+ }\
+}
+
while (p < pend) {
- char c = *p++;
- if (ismbchar(c) && p+1 < pend) {
+ unsigned char c = *p++;
+ if (ismbchar(c) && p < pend) {
CHECK(2);
*b++ = c;
*b++ = *p++;
@@ -1082,8 +1206,8 @@ str_inspect(str)
b += 3;
}
}
- str_cat(str0, "\"", 1);
- return (VALUE)str0;
+ *b++ = '"';
+ return str_new(buf, b - buf);
}
static VALUE
@@ -1227,14 +1351,17 @@ trnext(t)
}
}
+static VALUE str_delete_bang();
+
static VALUE
-str_tr_bang(str, src, repl)
+tr_trans(str, src, repl, sflag)
struct RString *str, *src, *repl;
+ int sflag;
{
struct tr trsrc, trrepl;
int cflag = 0;
char trans[256];
- int i, c;
+ int i, c, c0;
char *s, *send, *t;
Check_Type(src, T_STRING);
@@ -1244,6 +1371,7 @@ str_tr_bang(str, src, repl)
trsrc.p++;
}
Check_Type(repl, T_STRING);
+ if (repl->len == 0) return str_delete_bang(str, src);
trrepl.p = repl->ptr; trrepl.pend = trrepl.p + repl->len;
trsrc.gen = trrepl.gen = 0;
trsrc.now = trrepl.now = 0;
@@ -1286,21 +1414,40 @@ str_tr_bang(str, src, repl)
str_modify(str);
t = s = str->ptr; send = s + str->len;
- while (s < send) {
- c = *s++ & 0xff;
- c = trans[c] & 0xff;
- *t++ = c;
+ c0 = -1;
+ if (sflag) {
+ while (s < send) {
+ c = trans[*s++ & 0xff] & 0xff;
+ if (s[-1] == c || c != c0) {
+ c0 = (s[-1] == c)?-1:c;
+ *t++ = c;
+ }
+ }
+ }
+ else {
+ while (s < send) {
+ c = trans[*s++ & 0xff] & 0xff;
+ *t++ = c;
+ }
}
*t = '\0';
+ if (sflag) str->len = (t - str->ptr);
return (VALUE)str;
}
static VALUE
+str_tr_bang(str, src, repl)
+ VALUE str, src, repl;
+{
+ return tr_trans(str, src, repl, 0);
+}
+
+static VALUE
str_tr(str, src, repl)
- struct RString *str, *src, *repl;
+ VALUE str, src, repl;
{
- return str_tr_bang(str_dup(str), src, repl);
+ return tr_trans(str_dup(str), src, repl, 0);
}
static void
@@ -1314,7 +1461,7 @@ tr_setup_table(str, table)
tr.p = str->ptr; tr.pend = tr.p + str->len;
tr.gen = tr.now = tr.max = 0;
- if (str->len > 2 && str->ptr[0] == '^') {
+ if (str->len > 1 && str->ptr[0] == '^') {
cflag++;
tr.p++;
}
@@ -1426,9 +1573,8 @@ str_tr_s_bang(str, src, repl)
{
Check_Type(src, T_STRING);
Check_Type(repl, T_STRING);
- str_tr(str, src, repl);
- tr_squeeze(str, repl);
- return str;
+
+ return tr_trans(str, src, repl, 1);
}
static VALUE
@@ -1452,13 +1598,13 @@ str_split_method(argc, argv, str)
VALUE result, tmp;
rb_scan_args(argc, argv, "02", &spat, &limit);
- if (limit) {
+ if (!NIL_P(limit)) {
lim = NUM2INT(limit);
i = 1;
}
- if (spat == Qnil) {
- if (FS) {
+ if (NIL_P(spat)) {
+ if (!NIL_P(FS)) {
spat = (struct RRegexp*)FS;
goto fs_set;
}
@@ -1478,7 +1624,7 @@ str_split_method(argc, argv, str)
case T_REGEXP:
break;
default:
- Fail("split(): bad separator");
+ ArgError("split(): bad separator");
}
}
@@ -1505,7 +1651,7 @@ str_split_method(argc, argv, str)
else {
if (isspace(*ptr)) {
ary_push(result, str_substr(str, beg, end-beg));
- if (limit && lim <= ++i) break;
+ if (!NIL_P(limit) && lim <= ++i) break;
skip = 1;
beg = end + 1;
}
@@ -1519,7 +1665,7 @@ str_split_method(argc, argv, str)
for (end = beg = 0; ptr<eptr; ptr++) {
if (*ptr == char_sep) {
ary_push(result, str_substr(str, beg, end-beg));
- if (limit && lim <= ++i) break;
+ if (!NIL_P(limit) && lim <= ++i) break;
beg = end + 1;
}
end++;
@@ -1530,18 +1676,18 @@ str_split_method(argc, argv, str)
int start = beg;
int last_null = 0;
int idx;
- struct re_registers regs;
+ struct re_registers *regs;
- regs.allocated = 0;
- while ((end = reg_search(spat, str, start, &regs)) >= 0) {
- if (start == end && regs.beg[0] == regs.end[0]) {
+ while ((end = reg_search(spat, str, start, 0)) >= 0) {
+ regs = RMATCH(backref_get())->regs;
+ if (start == end && BEG(0) == END(0)) {
if (last_null == 1) {
if (ismbchar(str->ptr[beg]))
ary_push(result, str_substr(str, beg, 2));
else
ary_push(result, str_substr(str, beg, 1));
beg = start;
- if (limit && lim <= ++i) break;
+ if (!NIL_P(limit) && lim <= ++i) break;
}
else {
start += ismbchar(str->ptr[start])?2:1;
@@ -1551,23 +1697,20 @@ str_split_method(argc, argv, str)
}
else {
ary_push(result, str_substr(str, beg, end-beg));
- beg = start = regs.end[0];
- if (limit && lim <= ++i) break;
+ beg = start = END(0);
}
last_null = 0;
- for (idx=1; idx < 10; idx++) {
- if (regs.beg[idx] == -1) break;
- if (regs.beg[idx] == regs.end[idx])
+ for (idx=1; idx < regs->num_regs; idx++) {
+ if (BEG(idx) == -1) continue;
+ if (BEG(idx) == END(idx))
tmp = str_new(0, 0);
else
- tmp = str_subseq(str, regs.beg[idx], regs.end[idx]-1);
+ tmp = str_subseq(str, BEG(idx), END(idx)-1);
ary_push(result, tmp);
- if (limit && lim <= ++i) break;
}
-
+ if (!NIL_P(limit) && lim <= ++i) break;
}
- re_free_registers(&regs);
}
if (str->len > beg) {
ary_push(result, str_subseq(str, beg, -1));
@@ -1583,32 +1726,56 @@ str_split(str, sep0)
{
VALUE sep;
+ Check_Type(str, T_STRING);
sep = str_new2(sep0);
return str_split_method(1, &sep, str);
}
static VALUE
-str_each_line(str)
+f_split(argc, argv)
+ int argc;
+ VALUE *argv;
+{
+ VALUE line;
+
+ line = lastline_get();
+ Check_Type(line, T_STRING);
+ return str_split_method(argc, argv, line);
+}
+
+static VALUE
+str_each_line(argc, argv, str)
+ int argc;
+ VALUE *argv;
struct RString* str;
{
extern VALUE RS;
+ VALUE rs;
int newline;
int rslen;
char *p = str->ptr, *pend = p + str->len, *s;
char *ptr = p;
int len = str->len;
+ VALUE line;
- if (RS == Qnil) {
+ if (rb_scan_args(argc, argv, "01", &rs) == 1) {
+ if (!NIL_P(rs)) Check_Type(rs, T_STRING);
+ }
+ else {
+ rs = RS;
+ }
+
+ if (NIL_P(rs)) {
rb_yield(str);
- return (VALUE)str;
+ return Qnil;
}
- rslen = RSTRING(RS)->len;
+ rslen = RSTRING(rs)->len;
if (rslen == 0) {
newline = '\n';
}
else {
- newline = RSTRING(RS)->ptr[rslen-1];
+ newline = RSTRING(rs)->ptr[rslen-1];
}
for (s = p, p += rslen; p < pend; p++) {
@@ -1619,9 +1786,10 @@ str_each_line(str)
}
if (*p == newline &&
(rslen <= 1 ||
- memcmp(RSTRING(RS)->ptr, p-rslen+1, rslen) == 0)) {
- rb_lastline = str_new(s, p - s + 1);
- rb_yield(rb_lastline);
+ memcmp(RSTRING(rs)->ptr, p-rslen+1, rslen) == 0)) {
+ line = str_new(s, p - s + 1);
+ lastline_set(line);
+ rb_yield(line);
if (str->ptr != ptr || str->len != len)
Fail("string modified");
s = p + 1;
@@ -1629,11 +1797,12 @@ str_each_line(str)
}
if (s != pend) {
- rb_lastline = str_new(s, p - s);
- rb_yield(rb_lastline);
+ line = str_new(s, p - s);
+ lastline_set(line);
+ rb_yield(line);
}
- return (VALUE)str;
+ return Qnil;
}
static VALUE
@@ -1645,7 +1814,7 @@ str_each_byte(str)
for (i=0; i<str->len; i++) {
rb_yield(INT2FIX(str->ptr[i] & 0xff));
}
- return (VALUE)str;
+ return Qnil;
}
static VALUE
@@ -1656,6 +1825,10 @@ str_chop_bang(str)
str->len--;
str->ptr[str->len] = '\0';
+ if (str->len > 1 && str->ptr[str->len-1] == '\r') {
+ str->len--;
+ str->ptr[str->len] = '\0';
+ }
return (VALUE)str;
}
@@ -1668,6 +1841,27 @@ str_chop(str)
}
static VALUE
+f_chop_bang(str)
+ struct RString *str;
+{
+ VALUE line;
+
+ line = lastline_get();
+ Check_Type(line, T_STRING);
+ return str_chop_bang(line);
+}
+
+static VALUE
+f_chop()
+{
+ VALUE line;
+
+ line = lastline_get();
+ Check_Type(line, T_STRING);
+ return str_chop_bang(str_dup(line));
+}
+
+static VALUE
str_strip_bang(str)
struct RString *str;
{
@@ -1702,6 +1896,70 @@ str_strip_bang(str)
}
static VALUE
+scan_once(str, pat, start)
+ struct RString *str;
+ struct RRegexp *pat;
+ int *start;
+{
+ VALUE result;
+ struct re_registers *regs;
+ int idx;
+
+ if (reg_search(pat, str, *start, 0) >= 0) {
+ regs = RMATCH(backref_get())->regs;
+ result = ary_new2(regs->num_regs);
+ for (idx=1; idx < regs->num_regs; idx++) {
+ if (BEG(idx) == -1) {
+ ary_push(result, Qnil);
+ }
+ else if (BEG(idx) == END(idx)) {
+ ary_push(result, str_new(0, 0));
+ }
+ else {
+ ary_push(result, str_subseq(str, BEG(idx), END(idx)-1));
+ }
+ }
+ if (END(0) == *start) {
+ *start = END(0)+1;
+ }
+ else {
+ *start = END(0);
+ }
+
+ return result;
+ }
+ return Qnil;
+}
+
+static VALUE
+str_scan(str, pat)
+ struct RString *str;
+ struct RRegexp *pat;
+{
+ VALUE result;
+ int start = 0;
+
+ switch (TYPE(pat)) {
+ case T_STRING:
+ pat = (struct RRegexp*)reg_regcomp(pat);
+ break;
+ case T_REGEXP:
+ break;
+ default:
+ Check_Type(pat, T_REGEXP);
+ }
+
+ if (!iterator_p()) {
+ return scan_once(str, pat, &start);
+ }
+
+ while (!NIL_P(result = scan_once(str, pat, &start))) {
+ rb_yield(result);
+ }
+ return Qnil;
+}
+
+static VALUE
str_strip(str)
struct RString *str;
{
@@ -1728,7 +1986,7 @@ str_crypt(str, salt)
{
salt = as_str(salt);
if (salt->len < 2)
- Fail("salt too short(need >2 bytes)");
+ ArgError("salt too short(need >2 bytes)");
return str_new2(crypt(str->ptr, salt->ptr));
}
@@ -1737,7 +1995,7 @@ str_intern(str)
struct RString *str;
{
if (strlen(str->ptr) != str->len)
- Fail("string contains `\0'");
+ ArgError("string contains `\0'");
return rb_intern(str->ptr)|FIXNUM_FLAG;
}
@@ -1753,7 +2011,7 @@ str_sum(argc, argv, str)
char *p, *pend;
rb_scan_args(argc, argv, "01", &vbits);
- if (vbits == Qnil) bits = 16;
+ if (NIL_P(vbits)) bits = 16;
else bits = NUM2INT(vbits);
p = str->ptr; pend = p + str->len;
@@ -1862,6 +2120,7 @@ Init_String()
rb_define_method(cString, "dup", str_dup, 0);
rb_define_method(cString, "<=>", str_cmp_method, 1);
rb_define_method(cString, "==", str_equal, 1);
+ rb_define_method(cString, "===", str_equal, 1);
rb_define_method(cString, "hash", str_hash_method, 0);
rb_define_method(cString, "+", str_plus, 1);
rb_define_method(cString, "*", str_times, 1);
@@ -1871,8 +2130,8 @@ Init_String()
rb_define_alias(cString, "size", "length");
rb_define_method(cString, "=~", str_match, 1);
rb_define_method(cString, "~", str_match2, 0);
- rb_define_method(cString, "next", str_next_method, 0);
- rb_define_method(cString, "upto", str_next, 1);
+ rb_define_method(cString, "succ", str_succ, 0);
+ rb_define_method(cString, "upto", str_upto, 1);
rb_define_method(cString, "index", str_index_method, -1);
rb_define_method(cString, "rindex", str_rindex, -1);
@@ -1903,11 +2162,13 @@ Init_String()
rb_define_method(cString, "crypt", str_crypt, 1);
rb_define_method(cString, "intern", str_intern, 0);
+ rb_define_method(cString, "scan", str_scan, 1);
+
rb_define_method(cString, "ljust", str_ljust, 1);
rb_define_method(cString, "rjust", str_rjust, 1);
rb_define_method(cString, "center", str_center, 1);
- rb_define_method(cString, "sub", str_sub_method, -1);
+ rb_define_method(cString, "sub", str_sub, -1);
rb_define_method(cString, "gsub", str_gsub, -1);
rb_define_method(cString, "chop", str_chop, 0);
rb_define_method(cString, "strip", str_strip, 0);
@@ -1927,9 +2188,9 @@ Init_String()
rb_define_method(cString, "delete!", str_delete_bang, 1);
rb_define_method(cString, "squeeze!", str_squeeze_bang, -1);
- rb_define_method(cString, "each_line", str_each_line, 0);
+ rb_define_method(cString, "each_line", str_each_line, -1);
+ rb_define_method(cString, "each", str_each_line, -1);
rb_define_method(cString, "each_byte", str_each_byte, 0);
- rb_define_method(cString, "each", str_each_byte, 0);
rb_define_method(cString, "sum", str_sum, -1);
@@ -1939,5 +2200,10 @@ Init_String()
rb_define_private_method(cKernel, "sub!", f_sub_bang, -1);
rb_define_private_method(cKernel, "gsub!", f_gsub_bang, -1);
+ rb_define_private_method(cKernel, "chop", f_chop, 0);
+ rb_define_private_method(cKernel, "chop!", f_chop_bang, 0);
+
+ rb_define_private_method(cKernel, "split", f_split, -1);
+
pr_str = rb_intern("to_s");
}
diff --git a/struct.c b/struct.c
index 2f4c35f397..bf8a468787 100644
--- a/struct.c
+++ b/struct.c
@@ -15,6 +15,34 @@ VALUE cStruct;
extern VALUE mEnumerable;
static VALUE
+struct_s_members(obj)
+ VALUE obj;
+{
+ struct RArray *member;
+ VALUE ary, *p, *pend;
+
+ member = RARRAY(rb_ivar_get(obj, rb_intern("__member__")));
+ if (NIL_P(member)) {
+ Fatal("non-initialized struct");
+ }
+ ary = ary_new2(member->len);
+ p = member->ptr; pend = p + member->len;
+ while (p < pend) {
+ ary_push(ary, str_new2(rb_id2name(FIX2INT(*p))));
+ p++;
+ }
+
+ return ary;
+}
+
+static VALUE
+struct_members(obj)
+ VALUE obj;
+{
+ return struct_s_members(CLASS_OF(obj));
+}
+
+static VALUE
struct_ref(obj)
struct RStruct *obj;
{
@@ -23,8 +51,8 @@ struct_ref(obj)
nstr = CLASS_OF(obj);
member = rb_ivar_get(nstr, rb_intern("__member__"));
- if (member == Qnil) {
- Fail("non-initialized struct");
+ if (NIL_P(member)) {
+ Fatal("non-initialized struct");
}
slot = INT2FIX(rb_frame_last_func());
for (i=0; i<RARRAY(member)->len; i++) {
@@ -32,8 +60,8 @@ struct_ref(obj)
return obj->ptr[i];
}
}
- Fail("not struct member");
- return Qnil; /* not reached */
+ NameError("not struct member");
+ /* not reached */
}
static VALUE struct_ref0(obj) struct RStruct *obj; {return obj->ptr[0];}
@@ -70,8 +98,8 @@ struct_set(obj, val)
nstr = CLASS_OF(obj);
member = rb_ivar_get(nstr, rb_intern("__member__"));
- if (member == Qnil) {
- Fail("non-initialized struct");
+ if (NIL_P(member)) {
+ Fatal("non-initialized struct");
}
for (i=0; i<RARRAY(member)->len; i++) {
slot = RARRAY(member)->ptr[i];
@@ -79,11 +107,11 @@ struct_set(obj, val)
return obj->ptr[i] = val;
}
}
- Fail("not struct member");
- return Qnil; /* not reached */
+ NameError("not struct member");
+ /* not reached */
}
-static VALUE struct_s_new();
+VALUE struct_alloc();
static VALUE
make_struct(name, member)
@@ -97,7 +125,8 @@ make_struct(name, member)
rb_ivar_set(nstr, rb_intern("__size__"), INT2FIX(member->len));
rb_ivar_set(nstr, rb_intern("__member__"), member);
- rb_define_singleton_method(nstr, "new", struct_s_new, -1);
+ rb_define_singleton_method(nstr, "new", struct_alloc, -2);
+ rb_define_singleton_method(nstr, "members", struct_s_members, 0);
for (i=0; i< member->len; i++) {
ID id = FIX2INT(member->ptr[i]);
if (i<10) {
@@ -149,7 +178,8 @@ struct_s_def(argc, argv)
rb_scan_args(argc, argv, "1*", &name, &rest);
Check_Type(name, T_STRING);
for (i=0; i<rest->len; i++) {
- Check_Type(rest->ptr[i], T_FIXNUM);
+ ID id = rb_to_id(rest->ptr[i]);
+ rest->ptr[i] = INT2FIX(id);
}
return make_struct(name, rest);
}
@@ -165,7 +195,7 @@ struct_alloc(class, values)
size = rb_ivar_get(class, rb_intern("__size__"));
n = FIX2INT(size);
if (n < values->len) {
- Fail("struct size differs");
+ ArgError("struct size differs");
}
else {
NEWOBJ(st, struct RStruct);
@@ -173,11 +203,11 @@ struct_alloc(class, values)
st->len = n;
st->ptr = ALLOC_N(VALUE, n);
MEMCPY(st->ptr, values->ptr, VALUE, values->len);
- MEMZERO(st->ptr+values->len, VALUE, n - values->len);
+ memclear(st->ptr+values->len, n - values->len);
return (VALUE)st;
}
- return Qnil; /* not reached */
+ /* not reached */
}
VALUE
@@ -186,11 +216,15 @@ struct_new(class, va_alist)
va_dcl
{
VALUE val, mem;
+ int size;
va_list args;
+ val = rb_ivar_get(class, rb_intern("__size__"));
+ size = FIX2INT(val);
mem = ary_new();
va_start(args);
- while (val = va_arg(args, VALUE)) {
+ while (size--) {
+ val = va_arg(args, VALUE);
ary_push(mem, val);
}
va_end(args);
@@ -199,17 +233,6 @@ struct_new(class, va_alist)
}
static VALUE
-struct_s_new(argc, argv, obj)
- int argc;
- VALUE *argv;
-{
- VALUE member, slot;
-
- member = ary_new4(argc, argv);
- return struct_alloc(obj, member);
-}
-
-static VALUE
struct_each(s)
struct RStruct *s;
{
@@ -241,14 +264,13 @@ struct_inspect(s)
struct RStruct *s;
{
char *name = rb_class2name(CLASS_OF(s));
- ID inspect = rb_intern("inspect");
VALUE str, member;
char buf[256];
int i;
member = rb_ivar_get(CLASS_OF(s), rb_intern("__member__"));
- if (member == Qnil) {
- Fail("non-initialized struct");
+ if (NIL_P(member)) {
+ Fatal("non-initialized struct");
}
sprintf(buf, "#<%s%s: ", HDR, name);
@@ -264,7 +286,7 @@ struct_inspect(s)
p = rb_id2name(FIX2INT(slot));
str_cat(str, p, strlen(p));
str_cat(str, "=", 1);
- str2 = rb_funcall(s->ptr[i], inspect, 0, 0);
+ str2 = rb_inspect(s->ptr[i]);
str2 = obj_as_string(str2);
str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len);
}
@@ -303,9 +325,9 @@ struct_aref(s, idx)
i = NUM2INT(idx);
if (i < 0) i = s->len - i;
if (i < 0)
- Fail("offset %d too small for struct(size:%d)", i, s->len);
+ IndexError("offset %d too small for struct(size:%d)", i, s->len);
if (s->len <= i)
- Fail("offset %d too large for struct(size:%d)", i, s->len);
+ IndexError("offset %d too large for struct(size:%d)", i, s->len);
return s->ptr[i];
}
@@ -319,9 +341,9 @@ struct_aset(s, idx, val)
i = NUM2INT(idx);
if (i < 0) i = s->len - i;
if (i < 0)
- Fail("offset %d too small for struct(size:%d)", i, s->len);
+ IndexError("offset %d too small for struct(size:%d)", i, s->len);
if (s->len <= i)
- Fail("offset %d too large for struct(size:%d)", i, s->len);
+ IndexError("offset %d too large for struct(size:%d)", i, s->len);
return s->ptr[i] = val;
}
@@ -334,7 +356,7 @@ struct_equal(s, s2)
if (TYPE(s2) != T_STRUCT) return FALSE;
if (CLASS_OF(s) != CLASS_OF(s2)) return FALSE;
if (s->len != s2->len) {
- Fail("incomsistent struct");
+ Bug("inconsistent struct"); /* should never happen */
}
for (i=0; i<s->len; i++) {
@@ -364,6 +386,7 @@ Init_Struct()
rb_include_module(cStruct, mEnumerable);
rb_define_singleton_method(cStruct, "new", struct_s_def, -1);
+ rb_define_singleton_method(cStruct, "members", struct_s_members, 0);
rb_define_method(cStruct, "clone", struct_clone, 0);
@@ -378,4 +401,6 @@ Init_Struct()
rb_define_method(cStruct, "each", struct_each, 0);
rb_define_method(cStruct, "[]", struct_aref, 1);
rb_define_method(cStruct, "[]=", struct_aset, 2);
+
+ rb_define_method(cStruct, "members", struct_members, 0);
}
diff --git a/time.c b/time.c
index b8ebe05230..1cfac22160 100644
--- a/time.c
+++ b/time.c
@@ -6,7 +6,7 @@
$Date: 1994/12/06 09:30:28 $
created at: Tue Dec 28 14:31:59 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -43,27 +43,19 @@ struct time_object {
int tm_got;
};
-static ID id_tv;
-
#define GetTimeval(obj, tobj) {\
- if (!id_tv) id_tv = rb_intern("tv");\
- Get_Data_Struct(obj, id_tv, struct time_object, tobj);\
-}
-
-#define MakeTimeval(obj,tobj) {\
- if (!id_tv) id_tv = rb_intern("tv");\
- Make_Data_Struct(obj, id_tv, struct time_object, 0, 0, tobj);\
- tobj->tm_got=0;\
+ Get_Data_Struct(obj, struct time_object, tobj);\
}
static VALUE
time_s_now(class)
VALUE class;
{
- VALUE obj = obj_alloc(class);
+ VALUE obj;
struct time_object *tobj;
- MakeTimeval(obj, tobj);
+ obj = Make_Data_Struct(class, struct time_object, 0, 0, tobj);
+ tobj->tm_got=0;
if (gettimeofday(&(tobj->tv), 0) == -1) {
rb_sys_fail("gettimeofday");
@@ -77,10 +69,11 @@ time_new_internal(class, sec, usec)
VALUE class;
int sec, usec;
{
- VALUE obj = obj_alloc(class);
+ VALUE obj;
struct time_object *tobj;
- MakeTimeval(obj, tobj);
+ obj = Make_Data_Struct(class, struct time_object, 0, 0, tobj);
+ tobj->tm_got=0;
tobj->tv.tv_sec = sec;
tobj->tv.tv_usec = usec;
@@ -94,18 +87,18 @@ time_new(sec, usec)
return time_new_internal(cTime, sec, usec);
}
-struct timeval*
+struct timeval
time_timeval(time)
VALUE time;
{
struct time_object *tobj;
- static struct timeval t;
+ struct timeval t;
switch (TYPE(time)) {
case T_FIXNUM:
t.tv_sec = FIX2UINT(time);
if (t.tv_sec < 0)
- Fail("time must be positive");
+ ArgError("time must be positive");
t.tv_usec = 0;
break;
@@ -114,7 +107,7 @@ time_timeval(time)
double seconds, microseconds;
if (RFLOAT(time)->value < 0.0)
- Fail("time must be positive");
+ ArgError("time must be positive");
seconds = floor(RFLOAT(time)->value);
microseconds = (RFLOAT(time)->value - seconds) * 1000000.0;
t.tv_sec = seconds;
@@ -122,26 +115,153 @@ time_timeval(time)
}
break;
+ case T_BIGNUM:
+ t.tv_sec = NUM2INT(time);
+ t.tv_usec = 0;
+ break;
+
default:
if (!obj_is_kind_of(time, cTime)) {
- Fail("Can't convert %s into Time", rb_class2name(CLASS_OF(time)));
+ TypeError("Can't convert %s into Time",
+ rb_class2name(CLASS_OF(time)));
}
GetTimeval(time, tobj);
t = tobj->tv;
break;
}
- return &t;
+ return t;
}
static VALUE
time_s_at(class, time)
VALUE class, time;
{
- struct timeval *tp;
+ struct timeval tv;
+
+ tv = time_timeval(time);
+ return time_new_internal(class, tv.tv_sec, tv.tv_usec);
+}
+
+static char *months [12] = {
+ "jan", "feb", "mar", "apr", "may", "jun",
+ "jul", "aug", "sep", "oct", "nov", "dec",
+};
+
+static void
+time_arg(argc, argv, args)
+ int argc;
+ VALUE *argv;
+ int *args;
+{
+ VALUE v[6];
+ int i;
+
+ rb_scan_args(argc, argv, "15", &v[0], &v[1], &v[2], &v[3], &v[4], &v[5]);
+
+ args[0] = NUM2INT(v[0]);
+ if (args[0] < 70) args[0] += 100;
+ if (args[0] > 1900) args[0] -= 1900;
+ if (v[1] == Qnil) {
+ args[1] = 0;
+ }
+ else if (TYPE(v[1]) == T_STRING) {
+ args[1] = -1;
+ for (i=0; i<12; i++) {
+ if (strcasecmp(months[i], RSTRING(v[1])->ptr) == 0) {
+ args[1] = i;
+ break;
+ }
+ }
+ }
+ else {
+ args[1] = NUM2INT(v[1]) - 1;
+ }
+ if (v[2] == Qnil) {
+ args[2] = 1;
+ }
+ else {
+ args[2] = NUM2INT(v[2]);
+ }
+ for (i=3;i<6;i++) {
+ if (v[i] == Qnil) {
+ args[i] = 0;
+ }
+ else {
+ args[i] = NUM2INT(v[i]);
+ }
+ }
+
+ /* value validation */
+ if ( args[0] < 70|| args[1] > 137
+ || args[1] < 0 || args[1] > 11
+ || args[2] < 1 || args[2] > 31
+ || args[3] < 0 || args[3] > 23
+ || args[4] < 0 || args[4] > 60
+ || args[5] < 0 || args[5] > 61)
+ ArgError("argument out of range");
+}
+
+static VALUE
+time_gm_or_local(argc, argv, gm_or_local)
+ int argc;
+ VALUE *argv;
+ int gm_or_local;
+{
+ int args[6];
+ struct timeval tv;
+ struct tm *tm;
+ time_t guess, t;
+ int diff;
+ struct tm *(*fn)();
+
+ fn = (gm_or_local) ? gmtime : localtime;
+ time_arg(argc, argv, args);
+
+ gettimeofday(&tv, 0);
+ guess = tv.tv_sec;
+
+ tm = (*fn)(&guess);
+ if (!tm) goto error;
+ t = args[0];
+ while (diff = t - tm->tm_year) {
+ guess += diff * 364 * 24 * 3600;
+ if (guess < 0) ArgError("too far future");
+ tm = (*fn)(&guess);
+ if (!tm) goto error;
+ }
+ t = args[1];
+ while (diff = t - tm->tm_mon) {
+ guess += diff * 27 * 24 * 3600;
+ tm = (*fn)(&guess);
+ if (!tm) goto error;
+ }
+ guess += (args[2] - tm->tm_mday) * 3600 * 24;
+ guess += (args[3] - tm->tm_hour) * 3600;
+ guess += (args[4] - tm->tm_min) * 60;
+ guess += args[5] - tm->tm_sec;
+
+ return time_new_internal(cTime, guess, 0);
- tp = time_timeval(time);
- return time_new_internal(class, tp->tv_sec, tp->tv_usec);
+ error:
+ ArgError("gmtime error");
+}
+static VALUE
+time_s_timegm(argc, argv, obj)
+ int argc;
+ VALUE *argv;
+ VALUE obj;
+{
+ return time_gm_or_local(argc, argv, 1);
+}
+
+static VALUE
+time_s_timelocal(argc, argv, obj)
+ int argc;
+ VALUE *argv;
+ VALUE obj;
+{
+ return time_gm_or_local(argc, argv, 0);
}
static VALUE
@@ -182,6 +302,25 @@ time_cmp(time1, time2)
int i;
GetTimeval(time1, tobj1);
+ switch (TYPE(time2)) {
+ case T_FIXNUM:
+ i = FIX2INT(time2);
+ if (tobj1->tv.tv_sec == i) return INT2FIX(0);
+ if (tobj1->tv.tv_sec > i) return INT2FIX(1);
+ return FIX2INT(-1);
+
+ case T_FLOAT:
+ {
+ double t;
+
+ if (tobj1->tv.tv_sec == (int)RFLOAT(time2)->value) return INT2FIX(0);
+ t = (double)tobj1->tv.tv_sec + (double)tobj1->tv.tv_usec*1e-6;
+ if (tobj1->tv.tv_sec == RFLOAT(time2)->value) return INT2FIX(0);
+ if (tobj1->tv.tv_sec > RFLOAT(time2)->value) return INT2FIX(1);
+ return FIX2INT(-1);
+ }
+ }
+
if (obj_is_instance_of(time2, cTime)) {
GetTimeval(time2, tobj2);
if (tobj1->tv.tv_sec == tobj2->tv.tv_sec) {
@@ -271,6 +410,13 @@ static VALUE
time_coerce(time1, time2)
VALUE time1, time2;
{
+ if (TYPE(time2) == T_FLOAT) {
+ double d = RFLOAT(time2)->value;
+ unsigned int i = (unsigned int) d;
+
+ return time_new_internal(i, (int)(d - (double)i)*1e6);
+ }
+
return time_new(CLASS_OF(time1), NUM2INT(time2), 0);
}
@@ -282,7 +428,11 @@ time_plus(time1, time2)
int sec, usec;
GetTimeval(time1, tobj1);
- if (obj_is_instance_of(time2, cTime)) {
+ if (TYPE(time2) == T_FLOAT) {
+ sec = tobj1->tv.tv_sec + (unsigned int)RFLOAT(time2)->value;
+ usec = tobj1->tv.tv_usec + (RFLOAT(time2)->value - (double)sec)*1e6;
+ }
+ else if (obj_is_instance_of(time2, cTime)) {
GetTimeval(time2, tobj2);
sec = tobj1->tv.tv_sec + tobj2->tv.tv_sec;
usec = tobj1->tv.tv_usec + tobj2->tv.tv_usec;
@@ -290,10 +440,11 @@ time_plus(time1, time2)
else {
sec = tobj1->tv.tv_sec + NUM2INT(time2);
usec = tobj1->tv.tv_usec;
- if (usec >= 1000000) {
- sec++;
- usec -= 1000000;
- }
+ }
+
+ if (usec >= 1000000) { /* usec overflow */
+ sec++;
+ usec -= 1000000;
}
return time_new(sec, usec);
}
@@ -307,18 +458,28 @@ time_minus(time1, time2)
GetTimeval(time1, tobj1);
if (obj_is_instance_of(time2, cTime)) {
+ double f;
+
GetTimeval(time2, tobj2);
- sec = tobj1->tv.tv_sec - tobj2->tv.tv_sec;
- usec = tobj1->tv.tv_usec - tobj2->tv.tv_usec;
- if (usec < 0) {
- sec--;
- usec += 1000000;
- }
+ f = tobj1->tv.tv_sec - tobj2->tv.tv_sec;
+
+ f += (tobj1->tv.tv_usec - tobj2->tv.tv_usec)*1e-6;
+
+ return float_new(f);
+ }
+ else if (TYPE(time2) == T_FLOAT) {
+ sec = tobj1->tv.tv_sec - (int)RFLOAT(time2)->value;
+ usec = tobj1->tv.tv_usec - (RFLOAT(time2)->value - (double)sec)*1e6;
}
else {
sec = tobj1->tv.tv_sec - NUM2INT(time2);
usec = tobj1->tv.tv_usec;
}
+
+ if (usec < 0) { /* usec underflow */
+ sec--;
+ usec += 1000000;
+ }
return time_new(sec, usec);
}
@@ -522,13 +683,12 @@ time_s_times(obj)
#endif /* HZ */
struct tms buf;
- if (times(&buf) == -1) rb_sys_fail(Qnil);
+ if (times(&buf) == -1) rb_sys_fail(0);
return struct_new(S_Tms,
float_new((double)buf.tms_utime / HZ),
float_new((double)buf.tms_stime / HZ),
float_new((double)buf.tms_cutime / HZ),
- float_new((double)buf.tms_cstime / HZ),
- Qnil);
+ float_new((double)buf.tms_cstime / HZ));
#else
#ifdef NT
FILETIME create, exit, kernel, user;
@@ -537,14 +697,12 @@ time_s_times(obj)
hProc = GetCurrentProcess();
GetProcessTimes(hProc,&create, &exit, &kernel, &user);
return struct_new(S_Tms,
- float_new((double)(kernel.dwHighDateTime*2E32+kernel.dwLowDateTime)/2E6),
- float_new((double)(user.dwHighDateTime*2E32+user.dwLowDateTime)/2E6),
- float_new((double)0),
+ float_new((double)(kernel.dwHighDateTime*2e32+kernel.dwLowDateTime)/2e6),
+ float_new((double)(user.dwHighDateTime*2e32+user.dwLowDateTime)/2e6),
float_new((double)0),
- Qnil);
+ float_new((double)0));
#else
- Fail("can't call times");
- return Qnil;
+ rb_notimplement();
#endif
#endif
}
@@ -558,6 +716,9 @@ Init_Time()
rb_define_singleton_method(cTime, "now", time_s_now, 0);
rb_define_singleton_method(cTime, "new", time_s_now, 0);
rb_define_singleton_method(cTime, "at", time_s_at, 1);
+ rb_define_singleton_method(cTime, "gm", time_s_timegm, -1);
+ rb_define_singleton_method(cTime, "local", time_s_timelocal, -1);
+ rb_define_singleton_method(cTime, "mktime", time_s_timelocal, -1);
rb_define_singleton_method(cTime, "times", time_s_times, 0);
@@ -596,6 +757,6 @@ Init_Time()
rb_define_method(cTime, "strftime", time_strftime, 1);
#if defined(HAVE_TIMES) || defined(NT)
- S_Tms = struct_define("Tms", "utime", "stime", "cutime", "cstime", Qnil);
+ S_Tms = struct_define("Tms", "utime", "stime", "cutime", "cstime", 0);
#endif
}
diff --git a/top.sed b/top.sed
new file mode 100644
index 0000000000..371190875a
--- /dev/null
+++ b/top.sed
@@ -0,0 +1,37 @@
+s/@srcdir@/./
+s/@CC@/gcc/
+s/@CPP@/gcc -E/
+s/@CPPFLAGS@//
+s/@YACC@/bison -y/
+s/@INSTALL@/ginstall -c/
+s/@INSTALL_PROGRAM@/${INSTALL}/
+s/@INSTALL_DATA@/${INSTALL} -m 644/
+s/@SET_MAKE@//
+s/@CFLAGS@/-g -O -I./
+s/@STATIC@//
+s/@LDFLAGS@//
+s/@LIBS@//
+s/@LIBOBJS@/crypt.o/
+s/@ALLOCA@//
+s!@prefix@!/usr/local!
+s/@exec_prefix@/${prefix}/
+s/@STRIP@/strip/
+s!/bin/rm!rm!
+s/@LDEXT@/so/
+s/@CCDLFLAGS@/-fpic/
+s!@arclib@!/usr/local/lib/ruby/i386-msdos!
+/\/dev\/null/s,/dev/null 2>&1, nul,
+/if older/s/"ruby"/"ruby.exe"/g
+/`rm -f ruby`/s//`rm -f ruby.exe`/
+/`cp miniruby ruby`/s//`cp miniruby.exe ruby.exe`/
+/^extruby:/ {
+ n;N;N;N;c\
+ cd ext\
+ ../miniruby ./extmk.rb\
+ cd ..
+}
+/^clean:;/ {
+ n;n;s!cd.*!cd ext\
+ ../miniruby ./extmk.rb clean\
+ cd ..!
+}
diff --git a/util.c b/util.c
index 19a0416794..717e0beed9 100644
--- a/util.c
+++ b/util.c
@@ -6,7 +6,7 @@
$Date$
created at: Fri Mar 10 17:22:34 JST 1995
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
diff --git a/util.h b/util.h
index 91805d99c5..570d894ccb 100644
--- a/util.h
+++ b/util.h
@@ -6,7 +6,7 @@
$Date$
created at: Thu Mar 9 11:55:53 JST 1995
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
#ifndef UTIL_H
diff --git a/variable.c b/variable.c
index 9721c1c2d4..1d6449bcab 100644
--- a/variable.c
+++ b/variable.c
@@ -10,20 +10,21 @@
#include "ruby.h"
#include "env.h"
+#include "node.h"
#include "st.h"
-st_table *rb_global_tbl;
+static st_table *rb_global_tbl;
st_table *rb_class_tbl;
#define global_tbl rb_global_tbl
#define class_tbl rb_class_tbl
-VALUE rb_const_defined();
+int rb_const_defined();
VALUE rb_const_get();
st_table *
new_idhash()
{
- return st_init_table(ST_NUMCMP, ST_NUMHASH);
+ return st_init_numtable();
}
void
@@ -39,10 +40,13 @@ rb_class2path(class)
{
VALUE path;
- while (TYPE(class) == T_ICLASS) {
+ while (TYPE(class) == T_ICLASS || FL_TEST(class, FL_SINGLETON)) {
class = (VALUE)RCLASS(class)->super;
}
path = rb_ivar_get(class, rb_intern("__classpath__"));
+ if (NIL_P(path)) {
+ return rb_class2name(class);
+ }
if (TYPE(path) != T_STRING) Bug("class path does not set properly");
return RSTRING(path)->ptr;
}
@@ -55,7 +59,6 @@ rb_class_path(class)
if (strchr(name, ':')) {
VALUE ary = str_split(str_new2(name), ":");
- ary_pop(ary);
ary = ary_reverse(ary);
return ary_join(ary, str_new2("::"));
}
@@ -70,6 +73,7 @@ rb_set_class_path(class, under, name)
VALUE str;
char *s;
+ if (cObject == under) return;
str = str_new2(name);
if (under) {
str_cat(str, ":", 1);
@@ -93,8 +97,9 @@ rb_path2class(path)
*p++;
}
if (*p == '\0') { /* pre-defined class */
- if (!st_lookup(class_tbl, rb_intern(path), &class)) {
- Fail("Undefined class -- %s", path);
+ if (!st_lookup(RCLASS(cObject)->iv_tbl, rb_intern(path), &class)
+ && !st_lookup(class_tbl, rb_intern(path), &class)) {
+ NameError("Undefined class -- %s", path);
}
return class;
}
@@ -107,14 +112,14 @@ rb_path2class(path)
*s = '\0';
id = rb_intern(name);
if (!rb_const_defined(class, id))
- Fail("%s not defined", name);
+ Fatal("%s not defined", name);
class = rb_const_get(class, id);
switch (TYPE(class)) {
case T_CLASS:
case T_MODULE:
break;
default:
- Fail("%s not a module/class");
+ Fatal("0x%x is not a class/module", class);
}
return class;
}
@@ -124,7 +129,7 @@ rb_name_class(class, id)
VALUE class;
ID id;
{
- rb_ivar_set(class, rb_intern("__classname__"), INT2FIX(id));
+ rb_ivar_set(class, rb_intern("__classname__"), id);
}
static st_table *autoload_tbl = 0;
@@ -173,16 +178,15 @@ rb_class2name(class)
case T_MODULE:
break;
default:
- Fail("0x%x is not a class/module", class);
+ Fatal("0x%x is not a class/module", class);
}
- while (FL_TEST(class, FL_SINGLE) || TYPE(class) == T_ICLASS) {
+ while (FL_TEST(class, FL_SINGLETON) || TYPE(class) == T_ICLASS) {
class = (struct RClass*)class->super;
}
name = rb_ivar_get(class, rb_intern("__classname__"));
- if (name) {
- name = FIX2INT(name);
+ if (!NIL_P(name)) {
return rb_id2name((ID)name);
}
Bug("class 0x%x not named", class);
@@ -194,6 +198,8 @@ struct trace_var {
struct trace_var *next;
};
+VALUE f_untrace_var();
+
struct global_entry {
ID id;
void *data;
@@ -241,7 +247,7 @@ static VALUE
undef_getter(id)
ID id;
{
- Warning("global var %s not initialized", rb_id2name(id));
+ Warning("global variable `%s' not initialized", rb_id2name(id));
return Qnil;
}
@@ -315,12 +321,12 @@ var_marker(var)
}
static void
-readonly_setter(id, var, val)
+readonly_setter(val, id, var)
ID id;
void *var;
VALUE val;
{
- Fail("Can't set variable %s", rb_id2name(id));
+ NameError("Can't set variable %s", rb_id2name(id));
}
static int
@@ -405,8 +411,6 @@ rb_define_virtual_variable(name, getter, setter)
rb_define_hooked_variable(name, 0, getter, setter);
}
-void rb_trace_eval();
-
void
rb_trace_eval(cmd, val)
VALUE cmd, val;
@@ -427,9 +431,12 @@ f_trace_var(argc, argv)
if (rb_scan_args(argc, argv, "11", &var, &cmd) == 1) {
cmd = f_lambda();
}
+ if (NIL_P(cmd)) {
+ return f_untrace_var(argc, argv, Qnil);
+ }
id = rb_to_id(var);
if (!st_lookup(global_tbl, id, &entry)) {
- Fail("undefined global variable %s", rb_id2name(id));
+ NameError("undefined global variable %s", rb_id2name(id));
}
trace = ALLOC(struct trace_var);
trace->next = entry->trace;
@@ -441,29 +448,52 @@ f_trace_var(argc, argv)
}
VALUE
-f_untrace_var(obj, var)
- VALUE obj, var;
+f_untrace_var(argc, argv)
+ int argc;
+ VALUE *argv;
{
+ VALUE var, cmd;
ID id;
struct global_entry *entry;
struct trace_var *trace;
- VALUE ary;
+ rb_scan_args(argc, argv, "11", &var, &cmd);
id = rb_to_id(var);
if (!st_lookup(global_tbl, id, &entry)) {
- Fail("undefined global variable %s", rb_id2name(id));
+ NameError("undefined global variable %s", rb_id2name(id));
}
- ary = ary_new();
- trace = entry->trace;
- while (trace) {
- struct trace_var *next = trace->next;
- ary_push(ary, trace->data);
- free(trace);
- trace = next;
- }
- entry->trace = 0;
+ if (NIL_P(cmd)) {
+ VALUE ary = ary_new();
+
+ trace = entry->trace;
+ while (trace) {
+ struct trace_var *next = trace->next;
+ ary_push(ary, trace->data);
+ free(trace);
+ trace = next;
+ }
+ entry->trace = 0;
- return ary;
+ return ary;
+ }
+ else {
+ struct trace_var t;
+ struct trace_var *next;
+
+ t.next = entry->trace;
+ trace = &t;
+ while (trace->next) {
+ next = trace->next;
+ if (next->data == (void*)cmd) {
+ trace->next = next->next;
+ free(next);
+ entry->trace = t.next;
+ return ary_new3(1, cmd);
+ }
+ trace = next;
+ }
+ }
+ return Qnil;
}
VALUE
@@ -549,8 +579,8 @@ rb_ivar_get(obj, id)
return val;
return Qnil;
default:
- Fail("class %s can not have instance variables",
- rb_class2name(CLASS_OF(obj)));
+ Fatal("class %s can not have instance variables",
+ rb_class2name(CLASS_OF(obj)));
break;
}
Warning("instance var %s not initialized", rb_id2name(id));
@@ -571,8 +601,8 @@ rb_ivar_set(obj, id, val)
st_insert(obj->iv_tbl, id, val);
break;
default:
- Fail("class %s can not have instance variables",
- rb_class2name(CLASS_OF(obj)));
+ Fatal("class %s can not have instance variables",
+ rb_class2name(CLASS_OF(obj)));
break;
}
return val;
@@ -595,6 +625,22 @@ rb_ivar_defined(obj, id)
}
VALUE
+rb_const_get_at(class, id)
+ struct RClass *class;
+ ID id;
+{
+ VALUE value;
+
+ if (class->iv_tbl && st_lookup(class->iv_tbl, id, &value)) {
+ return value;
+ }
+ NameError("Uninitialized constant %s::%s",
+ RSTRING(rb_class_path(class))->ptr,
+ rb_id2name(id));
+ /* not reached */
+}
+
+VALUE
rb_const_get(class, id)
struct RClass *class;
ID id;
@@ -624,21 +670,32 @@ rb_const_get(class, id)
st_delete(autoload_tbl, &id, &modname);
module = str_new2(modname);
free(modname);
- f_require(Qnil, module);
+ f_require(0, module);
return rb_const_get(class, id);
}
/* Uninitialized constant */
if (class && (VALUE)class != cObject)
- Fail("Uninitialized constant %s::%s",
- RSTRING(rb_class_path(class))->ptr,
- rb_id2name(id));
+ NameError("Uninitialized constant %s::%s",
+ RSTRING(rb_class_path(class))->ptr,
+ rb_id2name(id));
else
- Fail("Uninitialized constant %s",rb_id2name(id));
+ NameError("Uninitialized constant %s",rb_id2name(id));
/* not reached */
}
-VALUE
+int
+rb_const_defined_at(class, id)
+ struct RClass *class;
+ ID id;
+{
+ if (class->iv_tbl && st_lookup(class->iv_tbl, id, 0)) {
+ return TRUE;
+ }
+ return FALSE;
+}
+
+int
rb_const_defined(class, id)
struct RClass *class;
ID id;
@@ -656,16 +713,31 @@ rb_const_defined(class, id)
return FALSE;
}
+int
+rb_autoload_defined(id)
+ ID id;
+{
+ if (autoload_tbl && st_lookup(autoload_tbl, id, 0))
+ return TRUE;
+ return FALSE;
+}
+
void
rb_const_set(class, id, val)
struct RClass *class;
ID id;
VALUE val;
{
- if (rb_const_defined(class, id))
- Fail("already initialized constnant %s", rb_id2name(id));
+ if (!class->iv_tbl) {
+ class->iv_tbl = new_idhash();
+ }
+ else if (st_lookup(class->iv_tbl, id, 0)) {
+ NameError("already initialized constnant %s", rb_id2name(id));
+ }
+ if (!rb_autoload_defined(id) && rb_const_defined(class, id)) {
+ Warning("already initialized constnant %s", rb_id2name(id));
+ }
- if (!class->iv_tbl) class->iv_tbl = new_idhash();
st_insert(class->iv_tbl, id, val);
}
@@ -678,6 +750,16 @@ rb_define_const(class, name, val)
rb_const_set(class, rb_intern(name), val);
}
+extern VALUE cKernel;
+
+void
+rb_define_global_const(name, val)
+ char *name;
+ VALUE val;
+{
+ rb_define_const(cKernel, name, val);
+}
+
VALUE
rb_iv_get(obj, name)
VALUE obj;
@@ -698,33 +780,3 @@ rb_iv_set(obj, name, val)
return rb_ivar_set(obj, id, val);
}
-
-VALUE
-backref_get()
-{
- int cnt, max;
-
- if (!the_scope->local_vars) return Qnil;
- for (cnt=1, max=the_scope->local_tbl[0]+1; cnt<max ;cnt++) {
- if (the_scope->local_tbl[cnt] == '~') {
- cnt--;
- if (the_scope->local_vars[cnt])
- return the_scope->local_vars[cnt];
- else
- return 1;
- }
- }
- return Qnil;
-}
-
-void
-backref_set(val)
- VALUE val;
-{
- int cnt, max;
-
- for (cnt=1, max=the_scope->local_tbl[0]+1; cnt<max ;cnt++) {
- if (the_scope->local_tbl[cnt] == '~') break;
- }
- the_scope->local_vars[cnt-1] = val;
-}
diff --git a/version.c b/version.c
index dba5f6c8b5..26ef8d054f 100644
--- a/version.c
+++ b/version.c
@@ -7,7 +7,7 @@
$Date: 1995/01/12 08:54:54 $
created at: Thu Sep 30 20:08:01 JST 1993
- Copyright (C) 1993-1995 Yukihiro Matsumoto
+ Copyright (C) 1993-1996 Yukihiro Matsumoto
************************************************/
@@ -20,18 +20,18 @@ extern VALUE cKernel;
void
Init_version()
{
- rb_define_const(cKernel, "VERSION", str_new2(RUBY_VERSION));
+ rb_define_global_const("VERSION", str_new2(RUBY_VERSION));
}
void
show_version()
{
- fprintf(stderr, "ruby - version %s (%s)\n", RUBY_VERSION, VERSION_DATE);
+ fprintf(stderr, "ruby - version %s\n", RUBY_VERSION, VERSION_DATE);
}
void
show_copyright()
{
- fprintf(stderr, "ruby - Copyright (C) 1993-1995 Yukihiro Matsumoto\n");
+ fprintf(stderr, "ruby - Copyright (C) 1993-1996 Yukihiro Matsumoto\n");
exit(0);
}
diff --git a/version.h b/version.h
index f019bbdae3..3ed36e70e2 100644
--- a/version.h
+++ b/version.h
@@ -1,2 +1,2 @@
-#define RUBY_VERSION "0.95"
-#define VERSION_DATE "95/12/21"
+#define RUBY_VERSION "0.99.4-961224"
+#define VERSION_DATE "96/12/24"