1
0
Fork 0
mirror of https://github.com/ruby/ruby.git synced 2022-11-09 12:17:21 -05:00

This commit was generated by cvs2svn to compensate for changes in r372,

which included commits to RCS files with non-trunk default branches.


git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@373 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1999-01-20 04:59:39 +00:00
parent 9c5b1986a3
commit 210367ec88
140 changed files with 25635 additions and 14037 deletions

332
COPYING
View file

@ -1,37 +1,40 @@
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
Version 1, February 1989 Version 2, June 1991
Copyright (C) 1989 Free Software Foundation, Inc. Copyright (C) 1989, 1991 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed. of this license document, but changing it is not allowed.
Preamble Preamble
The license agreements of most software companies try to keep users The licenses for most software are designed to take away your
at the mercy of those companies. By contrast, our General Public freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. The software--to make sure the software is free for all its users. This
General Public License applies to the Free Software Foundation's General Public License applies to most of the Free Software
software and to any other program whose authors commit to using it. Foundation's software and to any other program whose authors commit to
You can use it for your programs, too. using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not When we speak of free software, we are referring to freedom, not
price. Specifically, the General Public License is designed to make price. Our General Public Licenses are designed to make sure that you
sure that you have the freedom to give away or sell copies of free have the freedom to distribute copies of free software (and charge for
software, that you receive source code or can get it if you want it, this service if you wish), that you receive source code or can get it
that you can change the software or use pieces of it in new free if you want it, that you can change the software or use pieces of it
programs; and that you know you can do these things. in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights. anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it. distribute copies of the software, or if you modify it.
For example, if you distribute copies of a such a program, whether For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the you have. You must make sure that they, too, receive or can get the
source code. And you must tell them their rights. source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy, (2) offer you this license which gives you legal permission to copy,
@ -44,120 +47,207 @@ want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original that any problems introduced by others will not reflect on the original
authors' reputations. authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and The precise terms and conditions for copying, distribution and
modification follow. modification follow.
GNU GENERAL PUBLIC LICENSE GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any program or other work which 0. This License applies to any program or other work which contains
contains a notice placed by the copyright holder saying it may be a notice placed by the copyright holder saying it may be distributed
distributed under the terms of this General Public License. The under the terms of this General Public License. The "Program", below,
"Program", below, refers to any such program or work, and a "work based refers to any such program or work, and a "work based on the Program"
on the Program" means either the Program or any work containing the means either the Program or any derivative work under copyright law:
Program or a portion of it, either verbatim or with modifications. Each that is to say, a work containing the Program or a portion of it,
licensee is addressed as "you". either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
1. You may copy and distribute verbatim copies of the Program's source Activities other than copying, distribution and modification are not
code as you receive it, in any medium, provided that you conspicuously and covered by this License; they are outside its scope. The act of
appropriately publish on each copy an appropriate copyright notice and running the Program is not restricted, and the output from the Program
disclaimer of warranty; keep intact all the notices that refer to this is covered only if its contents constitute a work based on the
General Public License and to the absence of any warranty; and give any Program (independent of having been made by running the Program).
other recipients of the Program a copy of this General Public License Whether that is true depends on what the Program does.
along with the Program. You may charge a fee for the physical act of
transferring a copy.
2. You may modify your copy or copies of the Program or any portion of 1. You may copy and distribute verbatim copies of the Program's
it, and copy and distribute such modifications under the terms of Paragraph source code as you receive it, in any medium, provided that you
1 above, provided that you also do the following: conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
a) cause the modified files to carry prominent notices stating that You may charge a fee for the physical act of transferring a copy, and
you changed the files and the date of any change; and you may at your option offer warranty protection in exchange for a fee.
b) cause the whole of any work that you distribute or publish, that 2. You may modify your copy or copies of the Program or any portion
in whole or in part contains the Program or any part thereof, either of it, thus forming a work based on the Program, and copy and
with or without modifications, to be licensed at no charge to all distribute such modifications or work under the terms of Section 1
third parties under the terms of this General Public License (except above, provided that you also meet all of these conditions:
that you may choose to grant warranty protection to some or all
third parties, at your option).
c) If the modified program normally reads commands interactively when a) You must cause the modified files to carry prominent notices
run, you must cause it, when started running for such interactive use stating that you changed the files and the date of any change.
in the simplest and most usual way, to print or display an
announcement including an appropriate copyright notice and a notice
that there is no warranty (or else, saying that you provide a
warranty) and that users may redistribute the program under these
conditions, and telling the user how to view a copy of this General
Public License.
d) You may charge a fee for the physical act of transferring a b) You must cause any work that you distribute or publish, that in
copy, and you may at your option offer warranty protection in whole or in part contains or is derived from the Program or any
exchange for a fee. part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
Mere aggregation of another independent work with the Program (or its c) If the modified program normally reads commands interactively
derivative) on a volume of a storage or distribution medium does not bring when run, you must cause it, when started running for such
the other work under the scope of these terms. interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
3. You may copy and distribute the Program (or a portion or derivative of These requirements apply to the modified work as a whole. If
it, under Paragraph 2) in object code or executable form under the terms of identifiable sections of that work are not derived from the Program,
Paragraphs 1 and 2 above provided that you also do one of the following: and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
a) accompany it with the complete corresponding machine-readable Thus, it is not the intent of this section to claim rights or contest
source code, which must be distributed under the terms of your rights to work written entirely by you; rather, the intent is to
Paragraphs 1 and 2 above; or, exercise the right to control the distribution of derivative or
collective works based on the Program.
b) accompany it with a written offer, valid for at least three In addition, mere aggregation of another work not based on the Program
years, to give any third party free (except for a nominal charge with the Program (or with a work based on the Program) on a volume of
for the cost of distribution) a complete machine-readable copy of the a storage or distribution medium does not bring the other work under
corresponding source code, to be distributed under the terms of the scope of this License.
Paragraphs 1 and 2 above; or,
c) accompany it with the information you received as to where the 3. You may copy and distribute the Program (or a work based on it,
corresponding source code may be obtained. (This alternative is under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you allowed only for noncommercial distribution and only if you
received the program in object code or executable form alone.) received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
Source code for a work means the preferred form of the work for making The source code for a work means the preferred form of the work for
modifications to it. For an executable file, complete source code means making modifications to it. For an executable work, complete source
all the source code for all modules it contains; but, as a special code means all the source code for all modules it contains, plus any
exception, it need not include source code for modules which are standard associated interface definition files, plus the scripts used to
libraries that accompany the operating system on which the executable control compilation and installation of the executable. However, as a
file runs, or for standard header files or definitions files that special exception, the source code distributed need not include
accompany that operating system. anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
4. You may not copy, modify, sublicense, distribute or transfer the If distribution of executable or object code is made by offering
Program except as expressly provided under this General Public License. access to copy from a designated place, then offering equivalent
Any attempt otherwise to copy, modify, sublicense, distribute or transfer access to copy the source code from the same place counts as
the Program is void, and will automatically terminate your rights to use distribution of the source code, even though third parties are not
the Program under this License. However, parties who have received compelled to copy the source along with the object code.
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties 4. You may not copy, modify, sublicense, or distribute the Program
remain in full compliance. except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. By copying, distributing or modifying the Program (or any work based 5. You are not required to accept this License, since you have not
on the Program) you indicate your acceptance of this license to do so, signed it. However, nothing else grants you permission to modify or
and all its terms and conditions. distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the 6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the original Program), the recipient automatically receives a license from the
licensor to copy, distribute or modify the Program subject to these original licensor to copy, distribute or modify the Program subject to
terms and conditions. You may not impose any further restrictions on the these terms and conditions. You may not impose any further
recipients' exercise of the rights granted herein. restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
7. The Free Software Foundation may publish revised and/or new versions 8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to be similar in spirit to the present version, but may differ in detail to
address new problems or concerns. address new problems or concerns.
Each version is given a distinguishing version number. If the Program Each version is given a distinguishing version number. If the Program
specifies a version number of the license which applies to it and "any specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of Software Foundation. If the Program does not specify a version number of
the license, you may choose any version ever published by the Free Software this License, you may choose any version ever published by the Free Software
Foundation. Foundation.
8. If you wish to incorporate parts of the Program into other free 10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes Software Foundation, write to the Free Software Foundation; we sometimes
@ -167,7 +257,7 @@ of promoting the sharing and reuse of software generally.
NO WARRANTY NO WARRANTY
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
@ -177,7 +267,7 @@ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION. REPAIR OR CORRECTION.
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
@ -189,25 +279,24 @@ POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS END OF TERMS AND CONDITIONS
Appendix: How to Apply These Terms to Your New Programs How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest If you develop a new program, and you want it to be of the greatest
possible use to humanity, the best way to achieve this is to make it possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these free software which everyone can redistribute and change under these terms.
terms.
To do so, attach the following notices to the program. It is safest to To do so, attach the following notices to the program. It is safest
attach them to the start of each source file to most effectively convey to attach them to the start of each source file to most effectively
the exclusion of warranty; and each file should have at least the convey the exclusion of warranty; and each file should have at least
"copyright" line and a pointer to where the full notice is found. the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.> <one line to give the program's name and a brief idea of what it does.>
Copyright (C) 19yy <name of author> Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2 of the License, or
any later version. (at your option) any later version.
This program is distributed in the hope that it will be useful, This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of but WITHOUT ANY WARRANTY; without even the implied warranty of
@ -216,33 +305,36 @@ the exclusion of warranty; and each file should have at least the
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software 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
Also add information on how to contact you by electronic and paper mail. Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this If the program is interactive, make it output a short notice like this
when it starts in an interactive mode: when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) 19xx name of author Gnomovision version 69, Copyright (C) 19yy name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details. under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the The hypothetical commands `show w' and `show c' should show the appropriate
appropriate parts of the General Public License. Of course, the parts of the General Public License. Of course, the commands you use may
commands you use may be called something other than `show w' and `show be called something other than `show w' and `show c'; they could even be
c'; they could even be mouse-clicks or menu items--whatever suits your mouse-clicks or menu items--whatever suits your program.
program.
You should also get your employer (if you work as a programmer) or your You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here a sample; alter the names: necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the Yoyodyne, Inc., hereby disclaims all copyright interest in the program
program `Gnomovision' (a program to direct compilers to make passes `Gnomovision' (which makes passes at compilers) written by James Hacker.
at assemblers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989 <signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice Ty Coon, President of Vice
That's all there is to it! This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

2354
ChangeLog

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,7 @@ Makefile.in
README README
README.jp README.jp
README.EXT README.EXT
README.EXT.jp
ToDo ToDo
array.c array.c
bignum.c bignum.c
@ -13,7 +14,8 @@ compar.c
configure configure
configure.bat configure.bat
configure.in configure.in
config.dj config_h.dj
config_s.dj
config.guess config.guess
config.sub config.sub
defines.h defines.h
@ -36,7 +38,6 @@ install-sh
instruby.rb instruby.rb
intern.h intern.h
io.c io.c
io.h
keywords keywords
lex.c lex.c
main.c main.c
@ -47,6 +48,7 @@ node.h
numeric.c numeric.c
object.c object.c
pack.c pack.c
parse.c
parse.y parse.y
process.c process.c
random.c random.c
@ -58,8 +60,9 @@ regex.h
ruby.1 ruby.1
ruby.c ruby.c
ruby.h ruby.h
rubyio.h
rubysig.h
rubytest.rb rubytest.rb
sig.h
signal.c signal.c
sprintf.c sprintf.c
st.c st.c
@ -73,74 +76,89 @@ util.c
variable.c variable.c
version.c version.c
version.h version.h
beos/ruby.def.in
ext/Setup ext/Setup
ext/Setup.dj ext/Setup.dj
ext/Setup.nt ext/Setup.nt
ext/Setup.x68 ext/Setup.x68
ext/aix_ld.rb
ext/cygwin32_ld.rb
ext/extmk.rb.in ext/extmk.rb.in
ext/extmk.rb.nt ext/extmk.rb.nt
ext/aix_ld.rb
lib/English.rb lib/English.rb
lib/Env.rb
lib/README
lib/base64.rb lib/base64.rb
lib/cgi-lib.rb lib/cgi-lib.rb
lib/complex.rb lib/complex.rb
lib/date.rb lib/date.rb
lib/date2.rb
lib/debug.rb lib/debug.rb
lib/delegate.rb lib/delegate.rb
lib/e2mmap.rb lib/e2mmap.rb
lib/eregex.rb lib/eregex.rb
lib/find.rb lib/find.rb
lib/final.rb
lib/finalize.rb lib/finalize.rb
lib/ftplib.rb lib/ftplib.rb
lib/ftools.rb lib/ftools.rb
lib/getopts.rb lib/getopts.rb
lib/getoptlong.rb
lib/importenv.rb lib/importenv.rb
lib/jcode.rb lib/jcode.rb
lib/mailread.rb lib/mailread.rb
lib/mathn.rb lib/mathn.rb
lib/matrix.rb lib/matrix.rb
lib/mkmf.rb lib/mkmf.rb
lib/monitor.rb
lib/mutex_m.rb lib/mutex_m.rb
lib/observer.rb lib/observer.rb
lib/open3.rb
lib/ostruct.rb lib/ostruct.rb
lib/parsearg.rb lib/parsearg.rb
lib/parsedate.rb lib/parsedate.rb
lib/ping.rb lib/ping.rb
lib/profile.rb
lib/pstore.rb lib/pstore.rb
lib/rational.rb lib/rational.rb
lib/readbytes.rb
lib/shellwords.rb lib/shellwords.rb
lib/singleton.rb
lib/sync.rb lib/sync.rb
lib/telnet.rb
lib/tempfile.rb
lib/thread.rb lib/thread.rb
lib/thwait.rb lib/thwait.rb
lib/tk.rb lib/timeout.rb
lib/tkcanvas.rb
lib/tkclass.rb
lib/tkdialog.rb
lib/tkentry.rb
lib/tkscrollbox.rb
lib/tktext.rb
lib/tracer.rb lib/tracer.rb
lib/weakref.rb lib/weakref.rb
misc/README
misc/inf-ruby.el
misc/ruby-mode.el
misc/rubydb2x.el
misc/rubydb3x.el
missing/alloca.c missing/alloca.c
missing/crypt.c missing/crypt.c
missing/dir.h missing/dir.h
missing/dup2.c missing/dup2.c
missing/file.h missing/file.h
missing/flock.c missing/flock.c
missing/memcmp.c
missing/memmove.c missing/memmove.c
missing/mkdir.c missing/mkdir.c
missing/nt.c
missing/nt.h
missing/setenv.c
missing/strcasecmp.c missing/strcasecmp.c
missing/strchr.c
missing/strdup.c missing/strdup.c
missing/strerror.c missing/strerror.c
missing/strftime.c missing/strftime.c
missing/strstr.c missing/strstr.c
missing/strtol.c missing/strtol.c
missing/strtoul.c missing/strtoul.c
missing/vsnprintf.c
missing/x68.c missing/x68.c
sample/README
sample/biorhythm.rb sample/biorhythm.rb
sample/cal.rb
sample/cbreak.rb sample/cbreak.rb
sample/clnt.rb sample/clnt.rb
sample/dbmtest.rb sample/dbmtest.rb
@ -151,44 +169,38 @@ sample/exyacc.rb
sample/fact.rb sample/fact.rb
sample/fib.awk sample/fib.awk
sample/fib.pl sample/fib.pl
sample/fib.py
sample/fib.rb sample/fib.rb
sample/fib.scm sample/fib.scm
sample/freq.rb sample/freq.rb
sample/from.rb sample/from.rb
sample/fullpath.rb sample/fullpath.rb
sample/getopts.test sample/getopts.test
sample/goodfriday.rb
sample/less.rb sample/less.rb
sample/list.rb sample/list.rb
sample/list2.rb sample/list2.rb
sample/list3.rb sample/list3.rb
sample/mrshtest.rb sample/mine.rb
sample/mkproto.rb sample/mkproto.rb
sample/mpart.rb sample/mpart.rb
sample/mrshtest.rb
sample/observ.rb sample/observ.rb
sample/occur.pl sample/occur.pl
sample/occur.rb sample/occur.rb
sample/occur2.rb sample/occur2.rb
sample/philos.rb sample/philos.rb
sample/pi.rb sample/pi.rb
sample/rename.rb
sample/rbc.rb sample/rbc.rb
sample/rcs.awk sample/rcs.awk
sample/rcs.dat sample/rcs.dat
sample/rcs.rb sample/rcs.rb
sample/regx.rb sample/regx.rb
sample/ruby-mode.el
sample/rubydb2x.el
sample/rubydb3x.el
sample/sieve.rb sample/sieve.rb
sample/svr.rb sample/svr.rb
sample/test.rb sample/test.rb
sample/time.rb sample/time.rb
sample/tkbiff.rb
sample/tkbrowse.rb
sample/tkdialog.rb
sample/tkfrom.rb
sample/tkhello.rb
sample/tkline.rb
sample/tktimer.rb
sample/trojan.rb sample/trojan.rb
sample/tsvr.rb sample/tsvr.rb
sample/uumerge.rb sample/uumerge.rb
@ -198,6 +210,8 @@ win32/ntsetup.bat
win32/ruby.def win32/ruby.def
win32/sdbm.c win32/sdbm.c
win32/sdbm.h win32/sdbm.h
win32/win32.c
win32/win32.h
x68/fconvert.c x68/fconvert.c
x68/select.c x68/select.c
x68/_dtos18.c x68/_dtos18.c

View file

@ -8,19 +8,26 @@ VPATH = @srcdir@:@srcdir@/missing
CC = @CC@ CC = @CC@
YACC = @YACC@ YACC = @YACC@
PURIFY = PURIFY =
AUTOCONF = autoconf
@SET_MAKE@ @SET_MAKE@
CFLAGS = @CFLAGS@ -I@srcdir@ prefix = @prefix@
CFLAGS = @CFLAGS@ -I. -I@srcdir@ -I@includedir@
LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@ LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@
EXTLIBS =
LIBS = @LIBS@ $(EXTLIBS) LIBS = @LIBS@ $(EXTLIBS)
MISSING = @LIBOBJS@ @ALLOCA@ MISSING = @LIBOBJS@ @ALLOCA@
LDSHARED = @LDSHARED@
DLDFLAGS = @DLDFLAGS@
SOLIBS = @SOLIBS@
binsuffix = @binsuffix@ binsuffix = @binsuffix@
#### End of system configuration section. #### #### End of system configuration section. ####
LIBRUBY = libruby.a LIBRUBY = @LIBRUBY@
LIBRUBYARG = @LIBRUBYARG@
EXTOBJS = EXTOBJS =
@ -42,8 +49,8 @@ OBJS = array.o \
hash.o \ hash.o \
inits.o \ inits.o \
io.o \ io.o \
math.o \
marshal.o \ marshal.o \
math.o \
numeric.o \ numeric.o \
object.o \ object.o \
pack.o \ pack.o \
@ -66,44 +73,58 @@ OBJS = array.o \
$(MISSING) $(MISSING)
all: miniruby$(binsuffix) rbconfig.rb all: miniruby$(binsuffix) rbconfig.rb
@cd ext; ../miniruby$(binsuffix) ./extmk.rb @EXTSTATIC@ @./miniruby$(binsuffix) -Xext extmk.rb @EXTSTATIC@
miniruby$(binsuffix): $(OBJS) $(MAINOBJ) dmyext.o miniruby$(binsuffix): libruby.a $(MAINOBJ) dmyext.o
@rm -f $@ @rm -f $@
$(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(OBJS) dmyext.o $(LIBS) -o miniruby $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) dmyext.o libruby.a $(LIBS) -o $@
ruby$(binsuffix): $(LIBRUBY) $(MAINOBJ) $(EXTOBJS) ruby$(binsuffix): $(LIBRUBY) $(MAINOBJ) $(EXTOBJS)
@rm -f $@ @rm -f $@
$(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY) $(LIBS) -o ruby $(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@
$(LIBRUBY): $(OBJS) dmyext.o libruby.a: $(OBJS) dmyext.o
@AR@ rcu $(LIBRUBY) $(OBJS) dmyext.o @AR@ rcu $@ $(OBJS) dmyext.o
@-@RANLIB@ $(LIBRUBY) 2> /dev/null || true @-@RANLIB@ $@ 2> /dev/null || true
libruby.so: $(OBJS) dmyext.o
$(LDSHARED) $(DLDFLAGS) $(SOLIBS) $(OBJS) dmyext.o -o $@
install: rbconfig.rb install: rbconfig.rb
./miniruby$(binsuffix) $(srcdir)/instruby.rb ./miniruby$(binsuffix) $(srcdir)/instruby.rb $(DESTDIR)
clean:; @rm -f $(OBJS) $(LIBRUBY) $(MAINOBJ) rbconfig.rb clean:; @rm -f $(OBJS) $(LIBRUBY) $(MAINOBJ) rbconfig.rb
@rm -f ext/extinit.c ext/extinit.o dmyext.o @rm -f ext/extinit.c ext/extinit.o dmyext.o
@if test -f ./miniruby; then cd ext; ../miniruby ./extmk.rb clean; fi @if test -f ./miniruby$(binsuffix); then \
./miniruby$(binsuffix) -Xext extmk.rb clean; \
fi
realclean: clean distclean: clean
@rm -f Makefile ext/extmk.rb ext/config.cache @rm -f Makefile ext/extmk.rb config.h
@rm -f config.cache config.h config.log config.status @rm -f ext/config.cache config.cache config.log config.status
@rm -f parse.c lex.c *~ core *.core gmon.out @rm -f parse.c *~ core *.core gmon.out y.tab.c y.output
@rm -f ruby$(binsuffix) miniruby$(binsuffix) @rm -f ruby$(binsuffix) miniruby$(binsuffix)
realclean: distclean
@rm -f lex.c
test: miniruby$(binsuffix) test: miniruby$(binsuffix)
@./miniruby$(binsuffix) $(srcdir)/rubytest.rb @./miniruby$(binsuffix) $(srcdir)/rubytest.rb
rbconfig.rb: config.status miniruby$(binsuffix) rbconfig.rb: config.status miniruby$(binsuffix)
@./miniruby$(binsuffix) $(srcdir)/mkconfig.rb rbconfig.rb @./miniruby$(binsuffix) $(srcdir)/mkconfig.rb rbconfig.rb
config.status: $(srcdir)/configure
$(SHELL) ./config.status --recheck
$(srcdir)/configure: $(srcdir)/configure.in
cd $(srcdir) && $(AUTOCONF)
.c.o: .c.o:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $< $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
lex.c: keywords lex.c: keywords
gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$$ keywords > lex.c gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$$ @srcdir@/keywords > lex.c
parse.c: parse.y parse.c: parse.y
$(YACC) $< $(YACC) $<
@ -121,24 +142,30 @@ dup2.o: @srcdir@/missing/dup2.c
flock.o: @srcdir@/missing/flock.c flock.o: @srcdir@/missing/flock.c
$(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/flock.c $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/flock.c
memcmp.o: @srcdir@/missing/memcmp.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/memcmp.c
memmove.o: @srcdir@/missing/memmove.c memmove.o: @srcdir@/missing/memmove.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/memmove.c $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/memmove.c
mkdir.o: @srcdir@/missing/mkdir.c mkdir.o: @srcdir@/missing/mkdir.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/mkdir.c $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/mkdir.c
setenv.o: @srcdir@/missing/setenv.c vsnprintf.o: @srcdir@/missing/vsnprintf.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/setenv.c $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/vsnprintf.c
strcasecmp.o: @srcdir@/missing/strcasecmp.c strcasecmp.o: @srcdir@/missing/strcasecmp.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strcasecmp.c $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strcasecmp.c
strerror.o: @srcdir@/missing/strerror.c strchr.o: @srcdir@/missing/strchr.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strerror.c $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strchr.c
strdup.o: @srcdir@/missing/strdup.c strdup.o: @srcdir@/missing/strdup.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strdup.c $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strdup.c
strerror.o: @srcdir@/missing/strerror.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strerror.c
strftime.o: @srcdir@/missing/strftime.c strftime.o: @srcdir@/missing/strftime.c
$(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strftime.c $(CC) -I. $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strftime.c
@ -160,40 +187,43 @@ x68.o: @srcdir@/missing/x68.c
# Prevent GNU make v3 from overflowing arg limit on SysV. # Prevent GNU make v3 from overflowing arg limit on SysV.
.NOEXPORT: .NOEXPORT:
### ###
parse.o : parse.y ruby.h defines.h config.h intern.h env.h node.h st.h regex.h lex.c parse.o: parse.y ruby.h config.h defines.h intern.h env.h node.h st.h regex.h util.h lex.c
### ###
array.o: array.c ruby.h config.h defines.h intern.h array.o: array.c ruby.h config.h defines.h intern.h
bignum.o: bignum.c ruby.h config.h defines.h intern.h bignum.o: bignum.c ruby.h config.h defines.h intern.h
class.o: class.c ruby.h config.h defines.h intern.h node.h st.h class.o: class.c ruby.h config.h defines.h intern.h node.h st.h
compar.o: compar.c ruby.h config.h defines.h intern.h compar.o: compar.c ruby.h config.h defines.h intern.h
dir.o: dir.c ruby.h config.h defines.h intern.h dir.o: dir.c ruby.h config.h defines.h intern.h
dln.o: dln.c config.h defines.h dln.h st.h dln.o: dln.c config.h defines.h dln.h
dmyext.o: dmyext.c dmyext.o: dmyext.c
enum.o: enum.c ruby.h config.h defines.h intern.h enum.o: enum.c ruby.h config.h defines.h intern.h
error.o: error.c ruby.h config.h defines.h intern.h env.h error.o: error.c ruby.h config.h defines.h intern.h env.h
eval.o: eval.c ruby.h config.h defines.h intern.h env.h node.h sig.h st.h dln.h eval.o: eval.c ruby.h config.h defines.h intern.h node.h env.h rubysig.h st.h dln.h
file.o: file.c ruby.h config.h defines.h intern.h io.h sig.h file.o: file.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
gc.o: gc.c ruby.h config.h defines.h intern.h env.h sig.h st.h node.h re.h regex.h fnmatch.o: fnmatch.c config.h fnmatch.h
hash.o: hash.c ruby.h config.h defines.h intern.h st.h gc.o: gc.c ruby.h config.h defines.h intern.h rubysig.h st.h node.h env.h re.h regex.h
glob.o: config.h glob.c fnmatch.h
hash.o: hash.c ruby.h config.h defines.h intern.h st.h rubysig.h
inits.o: inits.c ruby.h config.h defines.h intern.h inits.o: inits.c ruby.h config.h defines.h intern.h
io.o: io.c ruby.h config.h defines.h intern.h io.h sig.h io.o: io.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
main.o: main.c main.o: main.c ruby.h config.h defines.h intern.h
marshal.o: marshal.c ruby.h config.h defines.h intern.h io.h sig.h st.h marshal.o: marshal.c ruby.h config.h defines.h intern.h rubyio.h st.h
math.o: math.c ruby.h config.h defines.h intern.h math.o: math.c ruby.h config.h defines.h intern.h
numeric.o: numeric.c ruby.h config.h defines.h intern.h numeric.o: numeric.c ruby.h config.h defines.h intern.h
object.o: object.c ruby.h config.h defines.h intern.h st.h object.o: object.c ruby.h config.h defines.h intern.h st.h
pack.o: pack.c ruby.h config.h defines.h intern.h pack.o: pack.c ruby.h config.h defines.h intern.h
process.o: process.c ruby.h config.h defines.h intern.h sig.h st.h process.o: process.c ruby.h config.h defines.h intern.h rubysig.h st.h
random.o: random.c ruby.h config.h defines.h intern.h random.o: random.c ruby.h config.h defines.h intern.h
range.o: range.c ruby.h config.h defines.h intern.h range.o: range.c ruby.h config.h defines.h intern.h
re.o: re.c ruby.h config.h defines.h intern.h re.h regex.h re.o: re.c ruby.h config.h defines.h intern.h re.h regex.h
ruby.o: ruby.c ruby.h config.h defines.h intern.h re.h regex.h dln.h regex.o: regex.c config.h regex.h util.h
signal.o: signal.c ruby.h config.h defines.h intern.h sig.h ruby.o: ruby.c ruby.h config.h defines.h intern.h dln.h util.h
signal.o: signal.c ruby.h config.h defines.h intern.h rubysig.h
sprintf.o: sprintf.c ruby.h config.h defines.h intern.h sprintf.o: sprintf.c ruby.h config.h defines.h intern.h
st.o: st.c config.h st.h st.o: st.c config.h st.h
string.o: string.c ruby.h config.h defines.h intern.h re.h regex.h string.o: string.c ruby.h config.h defines.h intern.h re.h regex.h
struct.o: struct.c ruby.h config.h defines.h intern.h struct.o: struct.c ruby.h config.h defines.h intern.h
time.o: time.c ruby.h config.h defines.h intern.h time.o: time.c ruby.h config.h defines.h intern.h
util.o: util.c defines.h intern.h config.h util.h util.o: util.c ruby.h config.h defines.h intern.h util.h
variable.o: variable.c ruby.h config.h defines.h intern.h env.h st.h variable.o: variable.c ruby.h config.h defines.h intern.h env.h node.h st.h
version.o: version.c ruby.h config.h defines.h intern.h version.h version.o: version.c ruby.h config.h defines.h intern.h version.h

42
README
View file

@ -3,7 +3,7 @@
Ruby is the interpreted scripting language for quick and Ruby is the interpreted scripting language for quick and
easy object-oriented programming. It has many features to easy object-oriented programming. It has many features to
process text files and to do system management tasks (as in process text files and to do system management tasks (as in
perl). It is simple, straight-forward, and extensible. Perl). It is simple, straight-forward, and extensible.
* Features of Ruby * Features of Ruby
@ -15,7 +15,8 @@ perl). It is simple, straight-forward, and extensible.
+ Iterators and Closures + Iterators and Closures
+ Garbage Collection + Garbage Collection
+ Dynamic Loading of Object files(on some architecture) + Dynamic Loading of Object files(on some architecture)
+ Highly Portable(works on many UNIX machines) + Highly Portable(works on many UNIX machines, and on DOS,
Windows, Mac, BeOS etc.)
* How to get Ruby * How to get Ruby
@ -31,21 +32,26 @@ This is what you need to do to compile and install Ruby:
2. Edit defines.h if you need. Probably this step will not need. 2. Edit defines.h if you need. Probably this step will not need.
3. Remove comment mark(#) before the module names from ext/Setup, if 3. Remove comment mark(#) before the module names from ext/Setup (or
you want to link modules statically. add module names if not present), if you want to link modules
statically.
If you want to link all the extension modules, remove comment If you don't want to compile non static extension modules
mark from the line "#option nodynamic". (probably on architectures which does not allow dynamic loading),
remove comment mark from the line "#option nodynamic" in
ext/Setup.
4. Run make. 4. Run make.
5. Optionally, run 'make test' to check that the compiled Ruby 5. Optionally, run 'make test' to check whether the compiled Ruby
interpreter works well. If you see the message "test succeeded", interpreter works well. If you see the message "test succeeded",
your Ruby works as it should (hopefully). your ruby works as it should (hopefully).
6. Run 'make install' 6. Run 'make install'
If you fail to compile Ruby, please send the detailed error report with You may have to be a super user to install ruby.
If you fail to compile ruby, please send the detailed error report with
the error log and machine/OS type, to help others. the error log and machine/OS type, to help others.
* Copying * Copying
@ -61,12 +67,13 @@ You can redistribute it and/or modify it under either the terms of the GPL
2. You may modify your copy of the software in any way, provided that 2. You may modify your copy of the software in any way, provided that
you do at least ONE of the following: you do at least ONE of the following:
a) place your modifications in the Public Domain or otherwise make them a) place your modifications in the Public Domain or otherwise
Freely Available, such as by posting said modifications to Usenet make them Freely Available, such as by posting said
or an equivalent medium, or by allowing the author to include your modifications to Usenet or an equivalent medium, or by allowing
modifications in the software. the author to include your modifications in the software.
b) use the modified software only within your corporation or organization. b) use the modified software only within your corporation or
organization.
c) rename any non-standard executables so the names do not conflict c) rename any non-standard executables so the names do not conflict
with standard executables, which must also be provided. with standard executables, which must also be provided.
@ -84,8 +91,7 @@ You can redistribute it and/or modify it under either the terms of the GPL
the software. the software.
c) give non-standard executables non-standard names, with c) give non-standard executables non-standard names, with
instructions on where to get the original software instructions on where to get the original software distribution.
distribution.
d) make other distribution arrangements with the author. d) make other distribution arrangements with the author.
@ -94,7 +100,7 @@ You can redistribute it and/or modify it under either the terms of the GPL
are not written by the author, so that they are not under this terms. are not written by the author, so that they are not under this terms.
They are gc.c(partly), utils.c(partly), regex.[ch], fnmatch.[ch], They are gc.c(partly), utils.c(partly), regex.[ch], fnmatch.[ch],
glob.c, st.[ch] and some files under the ./missing directory. See glob.c, st.[ch] and some files under the ./missing directory. See
each files for the copying condition. each file for the copying condition.
5. The scripts and library files supplied as input to or produced as 5. The scripts and library files supplied as input to or produced as
output from the software do not automatically fall under the output from the software do not automatically fall under the

View file

@ -1,21 +1,16 @@
.\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995 .\" README.EXT - -*- Text -*- created at: Mon Aug 7 16:45:54 JST 1995
This document explains how to make extention modules for ruby. This document explains how to make extention modules for Ruby.
1Basic knowledge 1Basic knowledge
In C, variables have types and data do not have types. In contrast, In C, variables have types and data do not have types. In contrast,
ruby variables do not have static type and data themselves have Ruby variables do not have static type and data themselves have
types. So, data need to be converted across the languages. types. So, data need to be converted across the languages.
Data in ruby represented C type `VALUE'. Each VALUE data have its Data in Ruby represented C type `VALUE'. Each VALUE data have its
data-type. data-type.
rubyのデータはVALUEというCの型で表現されますVALUE型のデー
タはそのデータタイプを自分で知っています.このデータタイプと
いうのはデータ(オブジェクト)の実際の構造を意味していてruby
のクラスとはまた違ったものです.
To retrieve an C data from the VALUE, you need to: To retrieve an C data from the VALUE, you need to:
(1) Identify VALUE's data type (1) Identify VALUE's data type
@ -38,7 +33,7 @@ Ruby interpreter has data-types as below:
T_ARRAY array T_ARRAY array
T_FIXNUM Fixnum(31bit integer) T_FIXNUM Fixnum(31bit integer)
T_HASH assosiative array T_HASH assosiative array
T_STRUCT (ruby) structure T_STRUCT (Ruby) structure
T_BIGNUM multi precision integer T_BIGNUM multi precision integer
T_TRUE true T_TRUE true
T_FALSE false T_FALSE false
@ -89,37 +84,28 @@ There are faster check-macros for fixnums and nil.
1.3 Convert VALUE into C data 1.3 Convert VALUE into C data
データタイプがT_NIL, T_FALSE, T_TRUEである時データはそれぞ The data for type T_NIL, T_FALSE, T_TRUE are nil, true, false
れnil, FALSE, TRUEですこのデータタイプのオブジェクトはひと respectively. They are singletons for the data type.
つずつしか存在しません.
データタイプがT_FIXNUMの時これは31bitのサイズを持つ整数で The T_FIXNUM data is the 31bit length fixed integer (63bit length on
FIXNUMをCの整数に変換するためにはマクロ「FIX2INT()」を使 some machines), which can be conver to the C integer by using
いますそれからFIXNUMに限らずrubyのデータを整数に変換する FIX2INT() macro. There also be NUM2INT() which converts any Ruby
「NUM2INT()」というマクロがあります.このマクロはデータタイ numbers into C integer. The NUM2INT() macro includes type check, so
プのチェック無しで使えます(整数に変換できない場合には例外が the exception will be raised if conversion failed.
発生する)
それ以外のデータタイプは対応するCの構造体があります対応す Other data types have corresponding C structures, e.g. struct RArray
る構造体のあるVALUEはそのままキャスト(型変換)すれば構造体の for T_ARRAY etc. VALUE of the type which has corresponding structure
ポインタに変換できます. can be cast to retrieve the pointer to the struct. The casting macro
RXXXX for each data type like RARRAY(obj). see "ruby.h".
構造体は「struct RXxxxx」という名前でruby.hで定義されていま For example, `RSTRING(size)->len' is the way to get the size of the
例えば文字列は「struct RString」です実際に使う可能性が Ruby String object. The allocated region can be accessed by
あるのは文字列と配列くらいだと思います. `RSTRING(str)->ptr'. For arrays, `RARRAY(ary)->len' and
`RARRAY(ary)->ptr' respectively.
ruby.hでは構造体へキャストするマクロも「RXXXXX()」(全部大文 Notice: Do not change the value of the structure directly, unless you
字にしたもの)という名前で提供されています(例: RSTRING()) are responsible about the result. It will be the cause of interesting
bugs.
例えば文字列strの長さを得るためには「RSTRING(str)->len」と
文字列strをchar*として得るためには「RSTRING(str)->ptr」
とします配列の場合にはそれぞれ「RARRAT(str)->len」
「RARRAT(str)->ptr」となります
rubyの構造体を直接アクセスする時に気をつけなければならないこ
とは,配列や文字列の構造体の中身は参照するだけで,直接変更し
ないことです.直接変更した場合,オブジェクトの内容の整合性が
とれなくなって,思わぬバグの原因になります.
1.4 Convert C data into VALUE 1.4 Convert C data into VALUE
@ -137,10 +123,10 @@ VALUE
うかわかるわけです(ポインタのLSBが立っていないことを仮定して うかわかるわけです(ポインタのLSBが立っていないことを仮定して
いる) いる)
ですからFIXNUM以外のrubyのオブジェクトの構造体は単にVALUE ですからFIXNUM以外のRubyのオブジェクトの構造体は単にVALUE
にキャストするだけでVALUEに変換出来ますただし任意の構造 にキャストするだけでVALUEに変換出来ますただし任意の構造
体がVALUEにキャスト出来るわけではありませんキャストするの 体がVALUEにキャスト出来るわけではありませんキャストするの
rubyの知っている構造体(ruby.hで定義されているstruct RXxxx Rubyの知っている構造体(ruby.hで定義されているstruct RXxxx
のもの)だけにしておいてください. のもの)だけにしておいてください.
FIXNUMに関しては変換マクロを経由する必要がありますCの整数 FIXNUMに関しては変換マクロを経由する必要がありますCの整数
@ -153,256 +139,241 @@ FIXNUM
INT2NUM()は整数がFIXNUMの範囲に収まらない場合Bignumに変換 INT2NUM()は整数がFIXNUMの範囲に収まらない場合Bignumに変換
してくれます(が,少し遅い) してくれます(が,少し遅い)
1.5 Manipulate ruby data 1.5 Manipulate Ruby data
先程も述べた通りrubyの構造体をアクセスする時に内容の更新を As I already told, it is not recommended to modify object's internal
行うことは勧められませんrubyのデータを操作する時には structure. To manipulate objects, use functions supplied by Ruby
rubyが用意している関数を用いてください interpreter. Useful functions are listed below (not all):
ここではもっとも使われるであろう文字列と配列の生成/操作を行
い関数をあげます(全部ではないです)
String funtions String funtions
str_new(char *ptr, int len) rb_str_new(char *ptr, int len)
Creates a new ruby string. Creates a new Ruby string.
str_new2(char *ptr) rb_str_new2(char *ptr)
Creates a new ruby string from C string. This is equivalent to Creates a new Ruby string from C string. This is equivalent to
str_new(ptr, strlen(ptr)). rb_str_new(ptr, strlen(ptr)).
str_cat(VALUE str, char *ptr, int len) rb_str_cat(VALUE str, char *ptr, int len)
Appends len bytes data from ptr to the ruby string. Appends len bytes data from ptr to the Ruby string.
Array functions Array functions
ary_new() rb_ary_new()
Creates an array with no element. Creates an array with no element.
ary_new2(int len) rb_ary_new2(int len)
Creates an array with no element, with allocating internal buffer Creates an array with no element, with allocating internal buffer
for len elements. for len elements.
ary_new3(int n, ...) rb_ary_new3(int n, ...)
Creates an n-elements array from arguments. Creates an n-elements array from arguments.
ary_new4(int n, VALUE *elts) rb_ary_new4(int n, VALUE *elts)
Creates an n-elements array from C array. Creates an n-elements array from C array.
ary_push(VALUE ary) rb_ary_push(VALUE ary, VALUE val)
ary_pop(VALUE ary, VALUE val) rb_ary_pop(VALUE ary)
ary_shift(VALUE ary) rb_ary_shift(VALUE ary)
ary_unshift(VALUE ary, VALUE val) rb_ary_unshift(VALUE ary, VALUE val)
ary_entry(VALUE ary, int idx) rb_ary_entry(VALUE ary, int idx)
Array operations. The first argument to each functions must be an Array operations. The first argument to each functions must be an
array. They may dump core if other types given. array. They may dump core if other types given.
2. Extend ruby with C 2. Extend Ruby with C
原理的にrubyで書けることはCでも書けますrubyそのものがCで記 原理的にRubyで書けることはCでも書けますRubyそのものがCで記
述されているんですから,当然といえば当然なんですけど.ここで 述されているんですから,当然といえば当然なんですけど.ここで
rubyの拡張に使うことが多いだろうと予測される機能を中心に紹 Rubyの拡張に使うことが多いだろうと予測される機能を中心に紹
介します. 介します.
2.1 Add new features to ruby 2.1 Add new features to Ruby
rubyで提供されている関数を使えばrubyインタプリタに新しい機能 Rubyで提供されている関数を使えばRubyインタプリタに新しい機能
を追加することができます.rubyでは以下の機能を追加する関数が を追加することができます.Rubyでは以下の機能を追加する関数が
提供されています. 提供されています.
* クラス,モジュール * Classes, Modules
* メソッド,特異メソッドなど * Methods, Singleton Methods
* 定数 * Constants
では順に紹介します. では順に紹介します.
2.1.1 Class/module definition 2.1.1 Class/module definition
クラスやモジュールを定義するためには,以下の関数を使います. To define class or module, use functions below:
VALUE rb_define_class(char *name, VALUE super) VALUE rb_define_class(char *name, VALUE super)
VALUE rb_define_module(char *name) VALUE rb_define_module(char *name)
これらの関数は新しく定義されたクラスやモジュールを返します. These functions return the newly created class ot module. You may
メソッドや定数の定義にこれらの値が必要なので,ほとんどの場合 want to save this reference into the variable to use later.
は戻り値を変数に格納しておく必要があるでしょう.
2.1.2 Method/singleton method definition 2.1.2 Method/singleton method definition
メソッドや特異メソッドを定義するには以下の関数を使います. To define methods or singleton methods, use functions below:
void rb_define_method(VALUE class, char *name, void rb_define_method(VALUE class, char *name,
VALUE (*func)(), int argc) VALUE (*func)(), int argc)
void rb_define_singleton_method(VALUE object, char *name, void rb_define_singleton_method(VALUE object, char *name,
VALUE (*func)(), int argc) VALUE (*func)(), int argc)
The `argc' represents the number of the arguments to the C function,
which must be less than 17. But I believe you don't need that much. :-)
念のため説明すると「特異メソッド」とは,その特定のオブジェク If `argc' is negative, it specifies calling sequence, not number of
トに対してだけ有効なメソッドですrubyではよくSmalltalkにお the arguments.
けるクラスメソッドとして,クラスに対する特異メソッドが使われ
ます.
これらの関数の argcという引数はCの関数へ渡される引数の数(と If argc is -1, the function will be called like:
形式)を決めますargcが正の時は関数に引き渡す引数の数を意味
します16個以上の引数は使えません(が,要りませんよね,そん
なに)
argcが負の時は引数の数ではなく形式を指定したことになります VALUE func(int argc, VALUE *argv, VALUE obj)
argcが-1の時は引数を配列に入れて渡されますargcが-2の時は引
数はrubyの配列として渡されます
メソッドを定義する関数はもう二つありますひとつはprivateメ where argc is the actual number of arguments, argv is the C array of
ソッドを定義する関数で引数はrb_define_method()と同じです. the arguments, and obj is the receiver.
if argc is -2, the arguments are passed in Ruby array. The function
will be called like:
VALUE func(VALUE obj, VALUE args)
where obj is the receiver, and args is the Ruby array containing
actual arguments.
There're two more functions to define method. One is to define
private method:
void rb_define_private_method(VALUE class, char *name, void rb_define_private_method(VALUE class, char *name,
VALUE (*func)(), int argc) VALUE (*func)(), int argc)
privateメソッドとは関数形式でしか呼び出すことの出来ないメソッ The other is to define module function, which is private AND singleton
ドです. method of the module. For example, sqrt is the module function
defined in Math module. It can be call in the form like:
もうひとつはモジュール関数を定義するものです.モジュール関数
とはモジュールの特異メソッドであり同時にprivateメソッドで
もあるものです例をあげるとMathモジュールのsqrt()などがあげ
られます.このメソッドは
Math.sqrt(4) Math.sqrt(4)
という形式でも or
include Math include Math
sqrt(4) sqrt(4)
という形式でも使えます.モジュール関数を定義する関数は以下の To define module function
通りです.
void rb_define_module_function(VALUE module, char *name, void rb_define_module_function(VALUE module, char *name,
VALUE (*func)(), int argc) VALUE (*func)(), int argc)
関数的メソッド(Kernelモジュールのprivaet method)を定義するた Oh, in addition, function-like method, which is private method defined
めの関数は以下の通りです. in Kernel module, can be defined using:
void rb_define_global_function(char *name, VALUE (*func)(), int argc) void rb_define_global_function(char *name, VALUE (*func)(), int argc)
2.1.3 Constant definition 2.1.3 Constant definition
拡張モジュールが必要な定数はあらかじめ定義しておいた方が良い We have 2 functions to define constants:
でしょう.定数を定義する関数は二つあります.
void rb_define_const(VALUE class, char *name, VALUE val) void rb_define_const(VALUE class, char *name, VALUE val)
void rb_define_global_const(char *name, VALUE val) void rb_define_global_const(char *name, VALUE val)
前者は特定のクラス/モジュールに属する定数を定義するもの,後 The former is to define constant under specified class/module. The
者はグローバルな定数を定義するものです. latter is to define global constant.
2.2 Use ruby features from C 2.2 Use Ruby features from C
既に『1.5 rubyのデータを操作する』で一部紹介したような関数を There are several ways to invoke Ruby's features from C code.
使えばrubyの機能を実現している関数を直接呼び出すことが出来
ます.
# このような関数の一覧表はいまのところありません.ソースを見 2.2.1 Evaluate Ruby Program in String
# るしかないですね.
それ以外にもrubyの機能を呼び出す方法はいくつかあります Easiest way to call Ruby's function from C program is to evaluate the
string as Ruby program. This function will do the job.
2.2.1 rubyのプログラムをevalする
Cからrubyの機能を呼び出すもっとも簡単な方法として文字列で
与えられたrubyのプログラムを評価する関数があります
VALUE rb_eval_string(char *str) VALUE rb_eval_string(char *str)
この評価は現在の環境で行われます.つまり,現在のローカル変数 Evaluation is done under current context, thus current local variables
などを受け継ぎます. of the innermost method (which is defined by Ruby) can be accessed.
2.2.2 ID or Symbol 2.2.2 ID or Symbol
Cから文字列を経由せずにrubyのメソッドを呼び出すこともできま You can invoke methods directly, without parsing the string. First I
その前にrubyインタプリタ内でメソッドや変数名を指定する need to explain about symbols (which data type is ID). ID is the
時に使われているIDについて説明しておきましょう integer number to represent Ruby's identifiers such as variable names.
It can be accessed from Ruby in the form like:
IDとは変数名メソッド名を表す整数ですrubyの中では :Identifier
:識別子 You can get the symbol value from string within C code, by using
でアクセスできますCからこの整数を得るためには関数
rb_intern(char *name) rb_intern(char *name)
を使います.また一文字の演算子はその文字コードがそのままシン In addition, the symbols for one character operators (e.g +) is the
ボルになっています. code for that character.
2.2.3 Invoke ruby method from C 2.2.3 Invoke Ruby method from C
Cから文字列を経由せずにrubyのメソッドを呼び出すためには以下 To invoke methods directly, you can use the function below
の関数を使います.
VALUE rb_funcall(VALUE recv, ID mid, int argc, ...) VALUE rb_funcall(VALUE recv, ID mid, int argc, ...)
この関数はオブジェクトrecvのmidで指定されるメソッドを呼び出 This function invokes the method of the recv, which name is specified
します. by the symbol mid.
2.2.4 変数/定数を参照/更新する 2.2.4 Accessing the variables and constants
Cから関数を使って参照・更新できるのはクラス定数インスタ Cから関数を使って参照・更新できるのはクラス定数インスタ
ンス変数です大域変数は一部のものはCの大域変数としてアクセ ンス変数です大域変数は一部のものはCの大域変数としてアクセ
スできます.ローカル変数を参照する方法は公開していません. スできます.ローカル変数を参照する方法は公開していません.
オブジェクトのインスタンス変数を参照・更新する関数は以下の通 The functions to access/modify instance variables are below:
りです.
VALUE rb_ivar_get(VALUE obj, ID id) VALUE rb_ivar_get(VALUE obj, ID id)
VALUE rb_ivar_set(VALUE obj, ID id, VALUE val) VALUE rb_ivar_set(VALUE obj, ID id, VALUE val)
idはrb_intern()で得られるものを使ってください. id must be the symbol, which can be retrieved by rb_intern().
クラス定数を参照するには以下の関数を使ってください. To access the constants of the class/module:
VALUE rb_const_get(VALUE obj, ID id) VALUE rb_const_get(VALUE obj, ID id)
クラス定数を新しく定義するためには『2.1.3 定数定義』で紹介さ See 2.1.3 for defining new constant.
れている関数を使ってください.
3. Informatin sharing between ruby and C 3. Informatin sharing between Ruby and C
C言語とrubyの間で情報を共有する方法について解説します C言語とRubyの間で情報を共有する方法について解説します
3.1 Ruby constant that Cから参照できるrubyの定数 3.1 Ruby constant that Cから参照できるRubyの定数
Following ruby constants can be referred from C. Following Ruby constants can be referred from C.
TRUE Qtrue
FALSE Qfalse
Boolean values. FALSE is false in the C also (i.e. 0). Boolean values. Qfalse is false in the C also (i.e. 0).
Qnil Qnil
Ruby nil in C scope. Ruby nil in C scope.
3.2 Global variables shared between C and ruby 3.2 Global variables shared between C and Ruby
Cとrubyで大域変数を使って情報を共有できます共有できる大域 CとRubyで大域変数を使って情報を共有できます共有できる大域
変数にはいくつかの種類があります.そのなかでもっとも良く使わ 変数にはいくつかの種類があります.そのなかでもっとも良く使わ
れると思われるのはrb_define_variable()です. れると思われるのはrb_define_variable()です.
void rb_define_variable(char *name, VALUE *var) void rb_define_variable(char *name, VALUE *var)
この関数はrubyとCとで共有する大域変数を定義します変数名が この関数はRubyとCとで共有する大域変数を定義します変数名が
`$'で始まらない時には自動的に追加されます.この変数の値を変 `$'で始まらない時には自動的に追加されます.この変数の値を変
更すると自動的にrubyの対応する変数の値も変わります 更すると自動的にRubyの対応する変数の値も変わります
またruby側からは更新できない変数もありますこのread onlyの またRuby側からは更新できない変数もありますこのread onlyの
変数は以下の関数で定義します. 変数は以下の関数で定義します.
void rb_define_readonly_variable(char *name, VALUE *var) void rb_define_readonly_variable(char *name, VALUE *var)
@ -421,13 +392,13 @@ setter
# getterもsetterも0ならばrb_define_variable()と同じになる. # getterもsetterも0ならばrb_define_variable()と同じになる.
それからCの関数によって実現されるrubyの大域変数を定義する それからCの関数によって実現されるRubyの大域変数を定義する
関数があります. 関数があります.
void rb_define_virtual_variable(char *name, void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)()) VALUE (*getter)(), VALUE (*setter)())
この関数によって定義されたrubyの大域変数が参照された時には この関数によって定義されたRubyの大域変数が参照された時には
getterが変数に値がセットされた時にはsetterが呼ばれます getterが変数に値がセットされた時にはsetterが呼ばれます
The prototypes of the getter and setter functions are as following: The prototypes of the getter and setter functions are as following:
@ -435,14 +406,14 @@ The prototypes of the getter and setter functions are as following:
(*getter)(ID id, void *data, struct global_entry* entry); (*getter)(ID id, void *data, struct global_entry* entry);
(*setter)(VALUE val, ID id, void *data, struct global_entry* entry); (*setter)(VALUE val, ID id, void *data, struct global_entry* entry);
3.3 Encapsulate C data into ruby object 3.3 Encapsulate C data into Ruby object
Cの世界で定義されたデータ(構造体)をrubyのオブジェクトとして Cの世界で定義されたデータ(構造体)をRubyのオブジェクトとして
取り扱いたい場合がありえますこのような場合にはDataという 取り扱いたい場合がありえますこのような場合にはDataという
rubyオブジェクトにCの構造体(へのポインタ)をくるむことでruby RubyオブジェクトにCの構造体(へのポインタ)をくるむことでRuby
オブジェクトとして取り扱えるようになります. オブジェクトとして取り扱えるようになります.
Dataオブジェクトを生成して構造体をrubyオブジェクトにカプセル Dataオブジェクトを生成して構造体をRubyオブジェクトにカプセル
化するためには,以下のマクロを使います. 化するためには,以下のマクロを使います.
Data_Wrap_Struct(class,mark,free,ptr) Data_Wrap_Struct(class,mark,free,ptr)
@ -450,7 +421,7 @@ Data
このマクロの戻り値は生成されたDataオブジェクトです このマクロの戻り値は生成されたDataオブジェクトです
classはこのDataオブジェクトのクラスですptrはカプセル化する classはこのDataオブジェクトのクラスですptrはカプセル化する
Cの構造体へのポインタですmarkはこの構造体がrubyのオブジェ Cの構造体へのポインタですmarkはこの構造体がRubyのオブジェ
クトへの参照がある時に使う関数です.そのような参照を含まない クトへの参照がある時に使う関数です.そのような参照を含まない
時には0を指定します 時には0を指定します
@ -482,47 +453,38 @@ C
4Example - Create dbm module 4Example - Create dbm module
ここまでの説明でとりあえず拡張モジュールは作れるはずです. ここまでの説明でとりあえず拡張ライブラリは作れるはずです.
rubyのextディレクトリにすでに含まれているdbmモジュールを例に Rubyのextディレクトリにすでに含まれているdbmモジュールを例に
して段階的に説明します. して段階的に説明します.
(1) make the directory (1) make the directory
% mkdir ext/dbm % mkdir ext/dbm
rubyを展開したディレクトリの下extディレクトリの中に拡張モ Make a directory for the extension library under ext directory.
ジュール用のディレクトリを作ります.名前は適当に選んで構いま
せん.
(2) create MANIFEST file (2) create MANIFEST file
% cd ext/dbm % cd ext/dbm
% touch MANIFEST % touch MANIFEST
拡張モジュールのディレクトリの下にはMANIFESTというファイルが There should be MANIFEST file in the directory for the extension
必要なので,とりあえず空のファイルを作っておきます.後でこの library. Make empty file now.
ファイルには必要なファイル一覧が入ることになります.
MANIFESTというファイルはmakeの時にディレクトリが拡張モジュー
ルを含んでいるかどうか判定するために使われれています.
(3) design the library (3) design the library
まあ,当然なんですけど,どういう機能を実現するかどうかまず設 You need to design the library features, before making it.
計する必要があります.どんなクラスをつくるか,そのクラスには
どんなメソッドがあるか,クラスが提供する定数などについて設計
しますdbmクラスについてはext/dbm.docを参照してください
(4) write C code. (4) write C code.
拡張モジュール本体となるC言語のソースを書きますC言語のソー 拡張ライブラリ本体となるC言語のソースを書きますC言語のソー
スがひとつの時には「モジュール名.c」を選ぶと良いでしょうC スがひとつの時には「モジュール名.c」を選ぶと良いでしょうC
言語のソースが複数の場合には逆に「モジュール名.c」というファ 言語のソースが複数の場合には逆に「モジュール名.c」というファ
イル名は避ける必要があります.オブジェクトファイルとモジュー イル名は避ける必要があります.オブジェクトファイルとモジュー
ル生成時に中間的に生成される「モジュール名.o」というファイル ル生成時に中間的に生成される「モジュール名.o」というファイル
とが衝突するからです. とが衝突するからです.
rubyは拡張モジュールをロードする時に「Init_モジュール名」と Rubyは拡張ライブラリをロードする時に「Init_モジュール名」と
いう関数を自動的に実行しますdbmモジュールの場合「Init_dbm」 いう関数を自動的に実行しますdbmモジュールの場合「Init_dbm」
です.この関数の中でクラス,モジュール,メソッド,定数などの です.この関数の中でクラス,モジュール,メソッド,定数などの
定義を行いますdbm.cから一部引用します 定義を行いますdbm.cから一部引用します
@ -530,27 +492,25 @@ ruby
-- --
Init_dbm() Init_dbm()
{ {
/* DBMクラスを定義する */ /* define DBM class */
cDBM = rb_define_class("DBM", cObject); cDBM = rb_define_class("DBM", rb_cObject);
/* DBMはEnumerateモジュールをインクルードする */ /* DBM includes Enumerate module */
rb_include_module(cDBM, mEnumerable); rb_include_module(cDBM, rb_mEnumerable);
/* DBMクラスのクラスメソッドopen(): 引数はCの配列で受ける */ /* DBM has class method open(): arguments are received as C array */
rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1); rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1);
/* DBMクラスのメソッドclose(): 引数はなし */ /* DBM instance method close(): no args */
rb_define_method(cDBM, "close", fdbm_close, 0); rb_define_method(cDBM, "close", fdbm_close, 0);
/* DBMクラスのメソッド[]: 引数は1個 */ /* DBM instance method []: 1 argument */
rb_define_method(cDBM, "[]", fdbm_fetch, 1); rb_define_method(cDBM, "[]", fdbm_fetch, 1);
: :
/* DBMデータを格納するインスタンス変数名のためのID */
id_dbm = rb_intern("dbm");
} }
-- --
DBMモジュールはdbmのデータと対応するオブジェクトになるはずで DBMモジュールはdbmのデータと対応するオブジェクトになるはずで
すからCの世界のdbmをrubyの世界に取り込む必要があります すからCの世界のdbmをRubyの世界に取り込む必要があります
dbm.cではData_Make_Structを以下のように使っています dbm.cではData_Make_Structを以下のように使っています
@ -600,7 +560,7 @@ fdbm_delete(obj, keystr)
引数の数が固定のタイプは第1引数がself第2引数以降がメソッド 引数の数が固定のタイプは第1引数がself第2引数以降がメソッド
の引数となります. の引数となります.
引数の数が不定のものはCの配列で受けるものとrubyの配列で受け 引数の数が不定のものはCの配列で受けるものとRubyの配列で受け
るものとがありますdbmモジュールの中でCの配列で受けるもの るものとがありますdbmモジュールの中でCの配列で受けるもの
はDBMのクラスメソッドであるopen()です.これを実装している関 はDBMのクラスメソッドであるopen()です.これを実装している関
数fdbm_s_open()はこうなっています. 数fdbm_s_open()はこうなっています.
@ -634,7 +594,7 @@ fdbm_s_open(argc, argv, class)
2つまで許されるという意味になります省略されている時の 2つまで許されるという意味になります省略されている時の
変数の値はnil(C言語のレベルではQnil)になります. 変数の値はnil(C言語のレベルではQnil)になります.
rubyの配列で引数を受け取るものはindexesがあります実装はこ Rubyの配列で引数を受け取るものはindexesがあります実装はこ
うです. うです.
-- --
@ -647,15 +607,14 @@ fdbm_indexes(obj, args)
} }
-- --
第1引数はself第2引数はrubyの配列ですここではキャストを減 第1引数はself第2引数はRubyの配列ですここではキャストを減
らすため struct RArray* で受けていますがVALUEでも同じこと らすため struct RArray* で受けていますがVALUEでも同じこと
です. です.
** 注意事項 ** Notice
rubyと共有はしないがrubyのオブジェクトを格納する可能性のある GC should know about global variables which refers Ruby's objects, but
Cの大域変数は以下の関数を使ってrubyインタプリタに変数の存在 not exported to the Ruby world. You need to protect them by
を教えてあげてくださいでないとGCでトラブルを起こします
void rb_global_variable(VALUE *var) void rb_global_variable(VALUE *var)
@ -665,7 +624,7 @@ C
make時に実行されますなければ適当にMakefileが生成されます make時に実行されますなければ適当にMakefileが生成されます
extconf.rbはモジュールのコンパイルに必要な条件のチェックなど extconf.rbはモジュールのコンパイルに必要な条件のチェックなど
を行うことが目的ですextconf.rbの中では以下のruby関数を使う を行うことが目的ですextconf.rbの中では以下のRuby関数を使う
ことが出来ます. ことが出来ます.
have_library(lib, func): ライブラリの存在チェック have_library(lib, func): ライブラリの存在チェック
@ -704,31 +663,31 @@ make
(8) make (8) make
rubyのディレクトリでmakeを実行するとMakefileを生成からmake Rubyのディレクトリでmakeを実行するとMakefileを生成からmake
必要によってはそのモジュールのrubyへのリンクまで自動的に実行 必要によってはそのモジュールのRubyへのリンクまで自動的に実行
してくれますextconf.rbを書き換えるなどしてMakefileの再生成 してくれますextconf.rbを書き換えるなどしてMakefileの再生成
が必要な時はまたrubyディレクトリでmakeしてください が必要な時はまたRubyディレクトリでmakeしてください
(9) debug (9) debug
まあデバッグしないと動かないでしょうねext/Setupにディレ You may need to rb_debug the module. The modules can be linked
クトリ名を書くと静的にリンクするのでデバッガが使えるようにな statically by adding directory name in the ext/Setup file,
ります.その分コンパイルが遅くなりますけど. so that you can inspect the module by the debugger.
(10) done, now you have the extension module (10) done, now you have the extension library
後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお 後はこっそり使うなり,広く公開するなり,売るなり,ご自由にお
使いください.rubyの作者は拡張モジュールに関して一切の権利を 使いください.Rubyの作者は拡張ライブラリに関して一切の権利を
主張しません. 主張しません.
Appendix A. rubyのソースコードの分類 Appendix A. Rubyのソースコードの分類
rubyのソースはいくつかに分類することが出来ますこのうちクラ Rubyのソースはいくつかに分類することが出来ますこのうちクラ
スライブラリの部分は基本的に拡張モジュールと同じ作り方になっ スライブラリの部分は基本的に拡張ライブラリと同じ作り方になっ
ています.これらのソースは今までの説明でほとんど理解できると ています.これらのソースは今までの説明でほとんど理解できると
思います. 思います.
coore ruby language ruby language core
class.c class.c
error.c error.c
@ -780,13 +739,13 @@ class library
Appendix B. 拡張用関数リファレンス Appendix B. 拡張用関数リファレンス
C言語からrubyの機能を利用するAPIは以下の通りである C言語からRubyの機能を利用するAPIは以下の通りである
** 型 ** 型
VALUE VALUE
rubyオブジェクトを表現する型必要に応じてキャストして用いる Rubyオブジェクトを表現する型必要に応じてキャストして用いる
組み込み型を表現するCの型はruby.hに記述してあるRで始まる構造 組み込み型を表現するCの型はruby.hに記述してあるRで始まる構造
体であるVALUE型をこれらにキャストするためにRで始まる構造体 体であるVALUE型をこれらにキャストするためにRで始まる構造体
名を全て大文字にした名前のマクロが用意されている. 名を全て大文字にした名前のマクロが用意されている.
@ -797,21 +756,21 @@ ruby
const: nil object const: nil object
TRUE Qtrue
const: TRUE object(default true value) const: Qtrue object(default true value)
FALSE Qfalse
const: FALSE object const: Qfalse object
** Cデータのカプセル化 ** Cデータのカプセル化
Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval) Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval)
Cの任意のポインタをカプセル化したrubyオブジェクトを返す Cの任意のポインタをカプセル化したRubyオブジェクトを返す
のポインタがrubyからアクセスされなくなった時freeで指定した のポインタがRubyからアクセスされなくなった時freeで指定した
関数が呼ばれる.また,このポインタの指すデータが他のrubyオブ 関数が呼ばれる.また,このポインタの指すデータが他のRubyオブ
ジェクトを指している場合markに指定する関数でマークする必要 ジェクトを指している場合markに指定する関数でマークする必要
がある. がある.
@ -828,20 +787,20 @@ data
VALUE rb_define_class(char *name, VALUE super) VALUE rb_define_class(char *name, VALUE super)
superのサブクラスとして新しいrubyクラスを定義する superのサブクラスとして新しいRubyクラスを定義する
VALUE rb_define_class_under(VALUE module, char *name, VALUE super) VALUE rb_define_class_under(VALUE module, char *name, VALUE super)
superのサブクラスとして新しいrubyクラスを定義しmoduleの定 superのサブクラスとして新しいRubyクラスを定義しmoduleの定
数として定義する. 数として定義する.
VALUE rb_define_module(char *name) VALUE rb_define_module(char *name)
新しいrubyモジュールを定義する 新しいRubyモジュールを定義する
VALUE rb_define_module_under(VALUE module, char *name, VALUE super) VALUE rb_define_module_under(VALUE module, char *name, VALUE super)
新しいrubyモジュールを定義しmoduleの定数として定義する 新しいRubyモジュールを定義しmoduleの定数として定義する
void rb_include_module(VALUE class, VALUE module) void rb_include_module(VALUE class, VALUE module)
@ -852,61 +811,70 @@ super
オブジェクトをモジュール(で定義されているメソッド)で拡張する. オブジェクトをモジュール(で定義されているメソッド)で拡張する.
** 大域変数定義 ** Defining Global Variables
void rb_define_variable(char *name, VALUE *var) void rb_define_variable(char *name, VALUE *var)
rubyとCとで共有するグローバル変数を定義する変数名が`$'で始 Defines a global variable which is shared between C and Ruby. If name
まらない時には自動的に追加されるnameとしてrubyの識別子とし contains the character which is not allowed to be part of the symbol,
て許されない文字(例えば` ')を含む場合にはrubyプログラムから it can't be seen from Ruby programs.
は見えなくなる.
void rb_define_readonly_variable(char *name, VALUE *var) void rb_define_readonly_variable(char *name, VALUE *var)
rubyとCとで共有するread onlyのグローバル変数を定義するread Defines a read-only global variable. Works just like
onlyであること以外はrb_define_variable()と同じ. rb_define_variable(), except defined variable is read-only.
void rb_define_virtual_variable(char *name, void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)()) VALUE (*getter)(), VALUE (*setter)())
関数によって実現されるruby変数を定義する変数が参照された時 Defines a virtual variable, whose behavior is defined by pair of C
にはgetterが変数に値がセットされた時にはsetterが呼ばれる functions. The getter function is called when the variable is
referred. The setter function is called when the value is set to the
variable. The prototype for getter/setter functions are:
VALUE getter(ID id)
void setter(VALUE val, ID id)
The getter function must return the value for the access.
void rb_define_hooked_variable(char *name, VALUE *var, void rb_define_hooked_variable(char *name, VALUE *var,
VALUE (*getter)(), VALUE (*setter)()) VALUE (*getter)(), VALUE (*setter)())
関数によってhookのつけられたグローバル変数を定義する変数が Defines hooked variable. It's virtual variable with C variable. The
参照された時にはgetterが関数に値がセットされた時にはsetter getter is called as
が呼ばれるgetterやsetterに0を指定した時にはhookを指定しな
いのと同じ事になる. VALUE getter(ID id, VALUE *var)
returning new value. The setter is called as
void setter(VALUE val, ID id, VALUE *var)
GC requires to mark the C global variables which hold Ruby values.
void rb_global_variable(VALUE *var) void rb_global_variable(VALUE *var)
GCのためrubyプログラムからはアクセスされないが, rubyオブジェ Tells GC to protect these variables.
クトを含む大域変数をマークする.
** クラス定数 ** Constant Definition
void rb_define_const(VALUE class, char *name, VALUE val) void rb_define_const(VALUE klass, char *name, VALUE val)
クラス定数を定義する. Defines a new constant under the class/module.
void rb_define_global_const(char *name, VALUE val) void rb_define_global_const(char *name, VALUE val)
大域定数を定義する. Defines global contant. This is just work as
rb_define_const(cKernal, name, val) rb_define_const(cKernal, name, val)
と同じ意味. ** Method Definition
** メソッド定義
rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc) rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc)
メソッドを定義するargcはselfを除く引数の数argcが-1の時, メソッドを定義するargcはselfを除く引数の数argcが-1の時,
関数には引数の数(selfを含まない)を第1引数, 引数の配列を第2引 関数には引数の数(selfを含まない)を第1引数, 引数の配列を第2引
数とする形式で与えられる(第3引数はself)argcが-2の時, 第1引 数とする形式で与えられる(第3引数はself)argcが-2の時, 第1引
数がself, 第2引数がargs(argsは引数を含むrubyの配列)という形 数がself, 第2引数がargs(argsは引数を含むRubyの配列)という形
式で与えられる. 式で与えられる.
rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc) rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc)
@ -927,7 +895,7 @@ argc,argv
数に対応する引数が与えられていない場合は変数にQnilが代入され 数に対応する引数が与えられていない場合は変数にQnilが代入され
る. る.
** rubyメソッド呼び出し ** Rubyメソッド呼び出し
VALUE rb_funcall(VALUE recv, ID mid, int narg, ...) VALUE rb_funcall(VALUE recv, ID mid, int narg, ...)
@ -939,7 +907,7 @@ argc,argv
VALUE rb_eval_string(char *str) VALUE rb_eval_string(char *str)
文字列をrubyとスクリプトしてコンパイル・実行する 文字列をRubyとスクリプトしてコンパイル・実行する
ID rb_intern(char *name) ID rb_intern(char *name)
@ -959,7 +927,7 @@ class
VALUE rb_iv_get(VALUE obj, char *name) VALUE rb_iv_get(VALUE obj, char *name)
objのインスタンス変数の値を得る`@'で始まらないインスタンス objのインスタンス変数の値を得る`@'で始まらないインスタンス
変数は rubyプログラムからアクセスできない「隠れた」インスタ 変数は Rubyプログラムからアクセスできない「隠れた」インスタ
ンス変数になる. ンス変数になる.
VALUE rb_iv_set(VALUE obj, char *name, VALUE val) VALUE rb_iv_set(VALUE obj, char *name, VALUE val)
@ -993,69 +961,66 @@ val
** 例外・エラー ** 例外・エラー
void Warning(char *fmt, ...) void rb_warning(char *fmt, ...)
verbose時に標準エラー出力に警告情報を表示する引数はprintf()と同じ. rb_verbose時に標準エラー出力に警告情報を表示する引数はprintf()と同じ.
void Fail(char *fmt, ...) void rb_raise(rb_eRuntimeError, char *fmt, ...)
例外を発生させる引数はprintf()と同じ. 例外を発生させる引数はprintf()と同じ.
void Fatal(char *fmt, ...) void rb_fatal(char *fmt, ...)
致命的例外を発生させる.通常の例外処理は行なわれず, インター 致命的例外を発生させる.通常の例外処理は行なわれず, インター
プリタが終了する(ただしensureで指定されたコードは終了前に実 プリタが終了する(ただしensureで指定されたコードは終了前に実
行される) 行される)
void Bug(char *fmt, ...) void rb_bug(char *fmt, ...)
インタープリタなどプログラムのバグでしか発生するはずのない状 インタープリタなどプログラムのバグでしか発生するはずのない状
況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.例外 況の時呼ぶ.インタープリタはコアダンプし直ちに終了する.例外
処理は一切行なわれない. 処理は一切行なわれない.
** rubyの初期化・実行 ** Initialize and Starts the Interpreter
rubyをアプリケーションに埋め込む場合には以下のインタフェース The embedding API are below (not needed for extension libraries):
を使う.通常の拡張モジュールには必要ない.
void ruby_init(int argc, char **argv, char **envp) void ruby_init(int argc, char **argv, char **envp)
rubyインタプリタの初期化を行なう Initializes the interpreter.
void ruby_run() void ruby_run()
rubyインタプリタを実行する Starts execution of the interpreter.
void ruby_script(char *name) void ruby_script(char *name)
rubyのスクリプト名($0)を設定する. Specifies the name of the script ($0).
Appendix B. extconf.rbで使える関数たち Appendix B. Functions Available in extconf.rb
extconf.rbの中では利用可能なコンパイル条件チェックの関数は以 extconf.rbの中では利用可能なコンパイル条件チェックの関数は以
下の通りである. 下の通りである.
have_library(lib, func) have_library(lib, func)
関数funcを定義しているライブラリlibの存在をチェックする Checks whether library which contains specified function exists.
イブラリが存在する時TRUEを返す Returns true if the library exists.
have_func(func) have_func(func)
関数funcの存在をチェックするfuncが標準ではリンクされないラ Checks whether func exists. Returns true if the function exists. To
イブラリ内のものである時には先にhave_libraryでそのライブラリ check functions in the additional library, you need to check that
をチェックしておく事関数が存在する時TRUEを返す library first using have_library().
have_header(header) have_header(header)
ヘッダファイルの存在をチェックする.ヘッダファイルが存在する Checks for the header files. Returns true if the header file exists.
時TRUEを返す
create_makefile(target) create_makefile(target)
拡張モジュール用のMakefileを生成するこの関数を呼ばなければ Generates the Makefile for the extension library. If you don't invoke
そのモジュールはコンパイルされないtargetはモジュール名を表 this method, the compilation will not be done.
す.
/* /*
* Local variables: * Local variables:

View file

@ -5,7 +5,7 @@ Ruby
すから,オブジェクト指向プログラミングを手軽に行う事が出来ま すから,オブジェクト指向プログラミングを手軽に行う事が出来ま
す.もちろん通常の手続き型のプログラミングも可能です. す.もちろん通常の手続き型のプログラミングも可能です.
Rubyはテキスト処理関係の能力などに優れperlと同じくらい強力 Rubyはテキスト処理関係の能力などに優れPerlと同じくらい強力
です.さらにシンプルな文法と,例外処理やイテレータなどの機構 です.さらにシンプルな文法と,例外処理やイテレータなどの機構
によって,より分かりやすいプログラミングが出来ます. によって,より分かりやすいプログラミングが出来ます.
@ -20,7 +20,8 @@ Ruby
+ イテレータとクロージャ + イテレータとクロージャ
+ ガーベージコレクタ + ガーベージコレクタ
+ ダイナミックローディング (アーキテクチャによる) + ダイナミックローディング (アーキテクチャによる)
+ 移植性が高い多くのUNIX上で動く + 移植性が高い多くのUNIX上で動くだけでなくDOSやWindows
MacBeOSなどの上でも動く
* 入手法 * 入手法
@ -41,14 +42,14 @@ Ruby
です. です.
* メリングリスト * メリングリスト
Rubyに関わる話題のためのメリングリストを開設しました.ア Rubyに関わる話題のためのメリングリストを開設しました.ア
ドレスは ドレスは
ruby-list@netlab.co.jp ruby-list@netlab.co.jp
です.このアドレスにメルを送れば,自動的に登録されます. です.このアドレスにメルを送れば,自動的に登録されます.
* コンパイル・インストール * コンパイル・インストール
@ -81,6 +82,8 @@ Ruby
6. make install 6. make install
rootで作業する必要があるかもしれません
もし,コンパイル時にエラーが発生した場合にはエラーのログとマ もし,コンパイル時にエラーが発生した場合にはエラーのログとマ
シンOSの種類を含むできるだけ詳しいレポートを作者に送ってく シンOSの種類を含むできるだけ詳しいレポートを作者に送ってく
ださると他の方のためにもなります. ださると他の方のためにもなります.
@ -92,7 +95,7 @@ UNIX
すが,思わぬ見落としがあった場合(あるに違いない),作者にその すが,思わぬ見落としがあった場合(あるに違いない),作者にその
ことをレポートすれば,解決できるかも知れません. ことをレポートすれば,解決できるかも知れません.
アーテクチャにもっとも依存するのはGC部ですRubyのGCは対象 アーテクチャにもっとも依存するのはGC部ですRubyのGCは対象
のアーキテクチャがsetjmp()によって全てのレジスタを jmp_bufに のアーキテクチャがsetjmp()によって全てのレジスタを jmp_bufに
格納することとjmp_bufとスタックが32bitアラインメントされて 格納することとjmp_bufとスタックが32bitアラインメントされて
いることを仮定しています.特に前者が成立しない場合の対応は非 いることを仮定しています.特に前者が成立しない場合の対応は非
@ -120,34 +123,37 @@ Licence)
由に変更できます. 由に変更できます.
(a) ネットニューズにポストしたり,作者に変更を送付する (a) ネットニューズにポストしたり,作者に変更を送付する
などの方法で,変更を公開する などの方法で,変更を公開する
(b) 変更したRubyを自分の所属する組織内部だけで使う (b) 変更したRubyを自分の所属する組織内部だけで使う
(c) 変更点を明示したうえ,ソフトウェアの名前を変更する. (c) 変更点を明示したうえ,ソフトウェアの名前を変更する.
そのソフトウェアを配布する時にはもとのRubyも同時に そのソフトウェアを配布する時には変更前のRubyも同時
配布する に配布するまたは変更前のRubyのソースの入手法を明
示する.
(d) その他の変更条件を作者と合意する (d) その他の変更条件を作者と合意する
3. 以下の条件のいずれかを満たす時にRubyをオブジェクトコー 3. 以下の条件のいずれかを満たす時にRubyをオブジェクトコー
ドや実行形式でも配布できます. ドや実行形式でも配布できます.
(a) バイナリを受け取った人がソースを入手できるようにソー (a) バイナリを受け取った人がソースを入手できるように
スの入手法を明示する ソースの入手法を明示する
(b) 機械可読なソースコードを添付する (b) 機械可読なソースコードを添付する
(c) 変更を行ったバイナリは名前を変更したうえ,ソースの (c) 変更を行ったバイナリは名前を変更したうえ,ソースの
入手法を明示する 入手法を明示する
(d) その他の配布条件を作者と合意する (d) その他の配布条件を作者と合意する
4. 他のプログラムへの引用はいかなる目的であれ自由です.た 4. 他のプログラムへの引用はいかなる目的であれ自由です.た
だしRubyに含まれる他の作者によるコードはそれぞれの だしRubyに含まれる他の作者によるコードはそれぞれの
作者の意向による制限が加えられます具体的にはgc.c(一部) 作者の意向による制限が加えられます具体的にはgc.c(一部)
util.c(一部)st.[ch]regex.[ch], fnmatch.[ch], glob.c util.c(一部)st.[ch]regex.[ch], fnmatch.[ch], glob.c
および./missingディレクトリ下のファイル群が該当します および./missingディレクトリ下のファイル群が該当します
それぞれの配布条件などに付いては各ファイルを参照してく
ださい.
5. Rubyへの入力となるスクリプトおよびRubyからの出力の権 5. Rubyへの入力となるスクリプトおよびRubyからの出力の権
利はRubyの作者ではなくそれぞれの入出力を生成した人に 利はRubyの作者ではなくそれぞれの入出力を生成した人に

41
ToDo
View file

@ -1,4 +1,37 @@
* non-blocking open/write for thread Language Spec.
* パッケージまたは大域変数のアクセス制御
* format機能 * package or access control for global variables
* re-write regex code for speed and copyright * named arguments like foo(nation:="german").
* multiple return values, yield values. maybe imcompatible
Hacking Interpreter
* non-blocking open (e.g. named pipe) for thread
* avoid blocking with gethostbyname/gethostbyaddr
* objectify interpreters
* remove rb_eval() recursions
* syntax tree -> bytecode ???
* scrambled script, or script filter
* regular expression bug /(?:\s+\d+){2}/ URGENT!!
Extension Libraries
* mod_ruby, FastCGI ruby
* InterBase module
* ptk.rb pTk wrapper that is compatible to tk.rb
Ruby Libraries
* CGI.rb
* httplib.rb, urllib.rb, nttplib.rb, etc.
* format like perl's
Tools
* extension library maker like XS or SWIG
* freeze or undump to bundle everything
Misc
* translate README.EXT fully into English
* publish Ruby books

1035
array.c

File diff suppressed because it is too large Load diff

562
bignum.c

File diff suppressed because it is too large Load diff

268
class.c
View file

@ -6,40 +6,41 @@
$Date$ $Date$
created at: Tue Aug 10 15:05:44 JST 1993 created at: Tue Aug 10 15:05:44 JST 1993
Copyright (C) 1993-1995 Yukihiro Matsumoto Copyright (C) 1993-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
#include "ruby.h" #include "ruby.h"
#include "node.h" #include "node.h"
#include "st.h" #include "st.h"
#include <ctype.h>
#ifdef USE_CWGUSI
#include <stdio.h>
#endif
struct st_table *new_idhash();
extern st_table *rb_class_tbl; extern st_table *rb_class_tbl;
extern VALUE cClass;
extern VALUE cModule;
VALUE VALUE
class_new(super) rb_class_new(super)
VALUE super; VALUE super;
{ {
NEWOBJ(klass, struct RClass); NEWOBJ(klass, struct RClass);
OBJSETUP(klass, cClass, T_CLASS); OBJSETUP(klass, rb_cClass, T_CLASS);
klass->super = super; klass->super = super;
klass->iv_tbl = 0; klass->iv_tbl = 0;
klass->m_tbl = 0; /* safe GC */ klass->m_tbl = 0; /* safe GC */
klass->m_tbl = new_idhash(); klass->m_tbl = st_init_numtable();
return (VALUE)klass; return (VALUE)klass;
} }
VALUE VALUE
singleton_class_new(super) rb_singleton_class_new(super)
VALUE super; VALUE super;
{ {
VALUE klass = class_new(super); VALUE klass = rb_class_new(super);
FL_SET(klass, FL_SINGLETON); FL_SET(klass, FL_SINGLETON);
return klass; return klass;
@ -56,7 +57,7 @@ clone_method(mid, body, tbl)
} }
VALUE VALUE
singleton_class_clone(klass) rb_singleton_class_clone(klass)
VALUE klass; VALUE klass;
{ {
if (!FL_TEST(klass, FL_SINGLETON)) if (!FL_TEST(klass, FL_SINGLETON))
@ -69,7 +70,7 @@ singleton_class_clone(klass)
clone->super = RCLASS(klass)->super; clone->super = RCLASS(klass)->super;
clone->iv_tbl = 0; clone->iv_tbl = 0;
clone->m_tbl = 0; clone->m_tbl = 0;
clone->m_tbl = new_idhash(); clone->m_tbl = st_init_numtable();
st_foreach(RCLASS(klass)->m_tbl, clone_method, clone->m_tbl); st_foreach(RCLASS(klass)->m_tbl, clone_method, clone->m_tbl);
FL_SET(clone, FL_SINGLETON); FL_SET(clone, FL_SINGLETON);
return (VALUE)clone; return (VALUE)clone;
@ -77,7 +78,7 @@ singleton_class_clone(klass)
} }
void void
singleton_class_attached(klass, obj) rb_singleton_class_attached(klass, obj)
VALUE klass, obj; VALUE klass, obj;
{ {
if (FL_TEST(klass, FL_SINGLETON)) if (FL_TEST(klass, FL_SINGLETON))
@ -91,15 +92,15 @@ rb_define_class_id(id, super)
{ {
VALUE klass; VALUE klass;
if (!super) super = cObject; if (!super) super = rb_cObject;
klass = class_new(super); klass = rb_class_new(super);
rb_name_class(klass, id); rb_name_class(klass, id);
/* make metaclass */ /* make metaclass */
RBASIC(klass)->class = singleton_class_new(RBASIC(super)->class); RBASIC(klass)->klass = rb_singleton_class_new(RBASIC(super)->klass);
singleton_class_attached(RBASIC(klass)->class, klass); rb_singleton_class_attached(RBASIC(klass)->klass, klass);
rb_funcall(super, rb_intern("inherited"), 1, klass); rb_funcall(super, rb_intern("inherited"), 1, klass);
return (VALUE)klass; return klass;
} }
VALUE VALUE
@ -112,14 +113,15 @@ rb_define_class(name, super)
id = rb_intern(name); id = rb_intern(name);
klass = rb_define_class_id(id, super); klass = rb_define_class_id(id, super);
st_add_direct(rb_class_tbl, id, klass); st_add_direct(rb_class_tbl, id, klass);
return klass; return klass;
} }
VALUE VALUE
rb_define_class_under(under, name, super) rb_define_class_under(outer, name, super)
VALUE under; VALUE outer;
char *name; char *name;
VALUE super; VALUE super;
{ {
@ -128,22 +130,22 @@ rb_define_class_under(under, name, super)
id = rb_intern(name); id = rb_intern(name);
klass = rb_define_class_id(id, super); klass = rb_define_class_id(id, super);
rb_const_set(under, id, klass); rb_const_set(outer, id, klass);
rb_set_class_path(klass, under, name); rb_set_class_path(klass, outer, name);
return klass; return klass;
} }
VALUE VALUE
module_new() rb_module_new()
{ {
NEWOBJ(mdl, struct RClass); NEWOBJ(mdl, struct RClass);
OBJSETUP(mdl, cModule, T_MODULE); OBJSETUP(mdl, rb_cModule, T_MODULE);
mdl->super = 0; mdl->super = 0;
mdl->iv_tbl = 0; mdl->iv_tbl = 0;
mdl->m_tbl = 0; mdl->m_tbl = 0;
mdl->m_tbl = new_idhash(); mdl->m_tbl = st_init_numtable();
return (VALUE)mdl; return (VALUE)mdl;
} }
@ -152,9 +154,9 @@ VALUE
rb_define_module_id(id) rb_define_module_id(id)
ID id; ID id;
{ {
extern st_table *rb_class_tbl; VALUE mdl;
VALUE mdl = module_new();
mdl = rb_module_new();
rb_name_class(mdl, id); rb_name_class(mdl, id);
return mdl; return mdl;
@ -175,8 +177,8 @@ rb_define_module(name)
} }
VALUE VALUE
rb_define_module_under(under, name) rb_define_module_under(outer, name)
VALUE under; VALUE outer;
char *name; char *name;
{ {
VALUE module; VALUE module;
@ -184,8 +186,8 @@ rb_define_module_under(under, name)
id = rb_intern(name); id = rb_intern(name);
module = rb_define_module_id(id); module = rb_define_module_id(id);
rb_const_set(under, id, module); rb_const_set(outer, id, module);
rb_set_class_path(module, under, name); rb_set_class_path(module, outer, name);
return module; return module;
} }
@ -195,16 +197,16 @@ include_class_new(module, super)
VALUE module, super; VALUE module, super;
{ {
NEWOBJ(klass, struct RClass); NEWOBJ(klass, struct RClass);
OBJSETUP(klass, cClass, T_ICLASS); OBJSETUP(klass, rb_cClass, T_ICLASS);
klass->m_tbl = RCLASS(module)->m_tbl; klass->m_tbl = RCLASS(module)->m_tbl;
klass->iv_tbl = RCLASS(module)->iv_tbl; klass->iv_tbl = RCLASS(module)->iv_tbl;
klass->super = super; klass->super = super;
if (TYPE(module) == T_ICLASS) { if (TYPE(module) == T_ICLASS) {
RBASIC(klass)->class = RBASIC(module)->class; RBASIC(klass)->klass = RBASIC(module)->klass;
} }
else { else {
RBASIC(klass)->class = module; RBASIC(klass)->klass = module;
} }
return (VALUE)klass; return (VALUE)klass;
@ -217,61 +219,66 @@ rb_include_module(klass, module)
VALUE p; VALUE p;
if (NIL_P(module)) return; if (NIL_P(module)) return;
if (klass == module) return;
switch (TYPE(module)) { switch (TYPE(module)) {
case T_MODULE: case T_MODULE:
case T_CLASS: case T_CLASS:
case T_ICLASS:
break; break;
default: default:
Check_Type(module, T_MODULE); Check_Type(module, T_MODULE);
} }
if (klass == module) return;
rb_clear_cache();
while (module) { while (module) {
/* ignore if the module included already in superclasses */ /* ignore if the module included already in superclasses */
for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) { for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
if (BUILTIN_TYPE(p) == T_ICLASS && if (BUILTIN_TYPE(p) == T_ICLASS &&
RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) RCLASS(p)->m_tbl == RCLASS(module)->m_tbl) {
if (RCLASS(module)->super) {
rb_include_module(p, RCLASS(module)->super);
}
return; return;
}
} }
RCLASS(klass)->super = RCLASS(klass)->super =
include_class_new(module, RCLASS(klass)->super); include_class_new(module, RCLASS(klass)->super);
klass = RCLASS(klass)->super; klass = RCLASS(klass)->super;
module = RCLASS(module)->super; module = RCLASS(module)->super;
} }
rb_clear_cache();
} }
VALUE VALUE
mod_included_modules(mod) rb_mod_included_modules(mod)
VALUE mod; VALUE mod;
{ {
VALUE ary = ary_new(); VALUE ary = rb_ary_new();
VALUE p; VALUE p;
for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) { for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
if (BUILTIN_TYPE(p) == T_ICLASS) { if (BUILTIN_TYPE(p) == T_ICLASS) {
ary_push(ary, RBASIC(p)->class); rb_ary_push(ary, RBASIC(p)->klass);
} }
} }
return ary; return ary;
} }
VALUE VALUE
mod_ancestors(mod) rb_mod_ancestors(mod)
VALUE mod; VALUE mod;
{ {
VALUE ary = ary_new(); VALUE ary = rb_ary_new();
VALUE p; VALUE p;
for (p = mod; p; p = RCLASS(p)->super) { for (p = mod; p; p = RCLASS(p)->super) {
if (FL_TEST(p, FL_SINGLETON))
continue;
if (BUILTIN_TYPE(p) == T_ICLASS) { if (BUILTIN_TYPE(p) == T_ICLASS) {
ary_push(ary, RBASIC(p)->class); rb_ary_push(ary, RBASIC(p)->klass);
} }
else { else {
ary_push(ary, p); rb_ary_push(ary, p);
} }
} }
return ary; return ary;
@ -283,19 +290,43 @@ ins_methods_i(key, body, ary)
NODE *body; NODE *body;
VALUE ary; VALUE ary;
{ {
if (!body->nd_noex) { if ((body->nd_noex&(NOEX_PRIVATE|NOEX_PROTECTED)) == 0) {
VALUE name = str_new2(rb_id2name(key)); VALUE name = rb_str_new2(rb_id2name(key));
if (!ary_includes(ary, name)) { if (!rb_ary_includes(ary, name)) {
if (!body->nd_body) { if (!body->nd_body) {
ary_push(ary, Qnil); rb_ary_push(ary, Qnil);
} }
ary_push(ary, name); rb_ary_push(ary, name);
}
}
else if (body->nd_body && nd_type(body->nd_body) == NODE_ZSUPER) {
rb_ary_push(ary, Qnil);
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
}
return ST_CONTINUE;
}
static int
ins_methods_prot_i(key, body, ary)
ID key;
NODE *body;
VALUE ary;
{
if (!body->nd_body) {
rb_ary_push(ary, Qnil);
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
}
else if (body->nd_noex & NOEX_PROTECTED) {
VALUE name = rb_str_new2(rb_id2name(key));
if (!rb_ary_includes(ary, name)) {
rb_ary_push(ary, name);
} }
} }
else if (nd_type(body->nd_body) == NODE_ZSUPER) { else if (nd_type(body->nd_body) == NODE_ZSUPER) {
ary_push(ary, Qnil); rb_ary_push(ary, Qnil);
ary_push(ary, str_new2(rb_id2name(key))); rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
} }
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -307,19 +338,19 @@ ins_methods_priv_i(key, body, ary)
VALUE ary; VALUE ary;
{ {
if (!body->nd_body) { if (!body->nd_body) {
ary_push(ary, Qnil); rb_ary_push(ary, Qnil);
ary_push(ary, str_new2(rb_id2name(key))); rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
} }
else if (body->nd_noex) { else if (body->nd_noex & NOEX_PRIVATE) {
VALUE name = str_new2(rb_id2name(key)); VALUE name = rb_str_new2(rb_id2name(key));
if (!ary_includes(ary, name)) { if (!rb_ary_includes(ary, name)) {
ary_push(ary, name); rb_ary_push(ary, name);
} }
} }
else if (nd_type(body->nd_body) == NODE_ZSUPER) { else if (nd_type(body->nd_body) == NODE_ZSUPER) {
ary_push(ary, Qnil); rb_ary_push(ary, Qnil);
ary_push(ary, str_new2(rb_id2name(key))); rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
} }
return ST_CONTINUE; return ST_CONTINUE;
} }
@ -334,7 +365,7 @@ method_list(mod, option, func)
VALUE klass; VALUE klass;
VALUE *p, *q, *pend; VALUE *p, *q, *pend;
ary = ary_new(); ary = rb_ary_new();
for (klass = mod; klass; klass = RCLASS(klass)->super) { for (klass = mod; klass; klass = RCLASS(klass)->super) {
st_foreach(RCLASS(klass)->m_tbl, func, ary); st_foreach(RCLASS(klass)->m_tbl, func, ary);
if (!option) break; if (!option) break;
@ -352,7 +383,7 @@ method_list(mod, option, func)
} }
VALUE VALUE
class_instance_methods(argc, argv, mod) rb_class_instance_methods(argc, argv, mod)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE mod; VALUE mod;
@ -364,7 +395,19 @@ class_instance_methods(argc, argv, mod)
} }
VALUE VALUE
class_private_instance_methods(argc, argv, mod) rb_class_protected_instance_methods(argc, argv, mod)
int argc;
VALUE *argv;
VALUE mod;
{
VALUE option;
rb_scan_args(argc, argv, "01", &option);
return method_list(mod, RTEST(option), ins_methods_prot_i);
}
VALUE
rb_class_private_instance_methods(argc, argv, mod)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE mod; VALUE mod;
@ -376,14 +419,14 @@ class_private_instance_methods(argc, argv, mod)
} }
VALUE VALUE
obj_singleton_methods(obj) rb_obj_singleton_methods(obj)
VALUE obj; VALUE obj;
{ {
VALUE ary; VALUE ary;
VALUE klass; VALUE klass;
VALUE *p, *q, *pend; VALUE *p, *q, *pend;
ary = ary_new(); ary = rb_ary_new();
klass = CLASS_OF(obj); klass = CLASS_OF(obj);
while (klass && FL_TEST(klass, FL_SINGLETON)) { while (klass && FL_TEST(klass, FL_SINGLETON)) {
st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary); st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
@ -409,7 +452,7 @@ rb_define_method_id(klass, name, func, argc)
VALUE (*func)(); VALUE (*func)();
int argc; int argc;
{ {
rb_add_method(klass, name, NEW_CFUNC(func, argc), NOEX_PUBLIC); rb_add_method(klass, name, NEW_CFUNC(func,argc), NOEX_PUBLIC|NOEX_CFUNC);
} }
void void
@ -419,15 +462,22 @@ rb_define_method(klass, name, func, argc)
VALUE (*func)(); VALUE (*func)();
int argc; int argc;
{ {
rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PUBLIC); ID id = rb_intern(name);
rb_add_method(klass, id, NEW_CFUNC(func, argc),
((name[0] == 'i' && id == rb_intern("initialize"))?
NOEX_PRIVATE:NOEX_PUBLIC)|NOEX_CFUNC);
} }
void void
rb_undef_method(klass, name) rb_define_protected_method(klass, name, func, argc)
VALUE klass; VALUE klass;
char *name; char *name;
VALUE (*func)();
int argc;
{ {
rb_add_method(klass, rb_intern(name), 0, NOEX_PUBLIC); rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
NOEX_PROTECTED|NOEX_CFUNC);
} }
void void
@ -437,7 +487,16 @@ rb_define_private_method(klass, name, func, argc)
VALUE (*func)(); VALUE (*func)();
int argc; int argc;
{ {
rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc), NOEX_PRIVATE); rb_add_method(klass, rb_intern(name), NEW_CFUNC(func, argc),
NOEX_PRIVATE|NOEX_CFUNC);
}
void
rb_undef_method(klass, name)
VALUE klass;
char *name;
{
rb_add_method(klass, rb_intern(name), 0, NOEX_UNDEF);
} }
VALUE VALUE
@ -445,14 +504,14 @@ rb_singleton_class(obj)
VALUE obj; VALUE obj;
{ {
if (rb_special_const_p(obj)) { if (rb_special_const_p(obj)) {
TypeError("cannot define singleton"); rb_raise(rb_eTypeError, "cannot define singleton");
} }
if (FL_TEST(RBASIC(obj)->class, FL_SINGLETON)) { if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON)) {
return (VALUE)RBASIC(obj)->class; return RBASIC(obj)->klass;
} }
RBASIC(obj)->class = singleton_class_new(RBASIC(obj)->class); RBASIC(obj)->klass = rb_singleton_class_new(RBASIC(obj)->klass);
singleton_class_attached(RBASIC(obj)->class, obj); rb_singleton_class_attached(RBASIC(obj)->klass, obj);
return RBASIC(obj)->class; return RBASIC(obj)->klass;
} }
void void
@ -476,15 +535,13 @@ rb_define_module_function(module, name, func, argc)
rb_define_singleton_method(module, name, func, argc); rb_define_singleton_method(module, name, func, argc);
} }
extern VALUE mKernel;
void void
rb_define_global_function(name, func, argc) rb_define_global_function(name, func, argc)
char *name; char *name;
VALUE (*func)(); VALUE (*func)();
int argc; int argc;
{ {
rb_define_private_method(mKernel, name, func, argc); rb_define_module_function(rb_mKernel, name, func, argc);
} }
void void
@ -496,57 +553,50 @@ rb_define_alias(klass, name1, name2)
} }
void void
rb_define_attr(klass, id, read, write) rb_define_attr(klass, name, read, write)
VALUE klass; VALUE klass;
ID id; char *name;
int read, write; int read, write;
{ {
char *name; rb_attr(klass, rb_intern(name), read, write, Qfalse);
char *buf;
ID attr, attreq, attriv;
name = rb_id2name(id);
attr = rb_intern(name);
buf = ALLOCA_N(char,strlen(name)+2);
sprintf(buf, "%s=", name);
attreq = rb_intern(buf);
sprintf(buf, "@%s", name);
attriv = rb_intern(buf);
if (read) {
rb_add_method(klass, attr, NEW_IVAR(attriv), 0);
}
if (write) {
rb_add_method(klass, attreq, NEW_ATTRSET(attriv), 0);
}
} }
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
#include <varargs.h> #include <varargs.h>
#include <ctype.h> #define va_init_list(a,b) va_start(a)
#endif
int int
#ifdef HAVE_STDARG_PROTOTYPES
rb_scan_args(int argc, VALUE *argv, char *fmt, ...)
#else
rb_scan_args(argc, argv, fmt, va_alist) rb_scan_args(argc, argv, fmt, va_alist)
int argc; int argc;
VALUE *argv; VALUE *argv;
char *fmt; char *fmt;
va_dcl va_dcl
#endif
{ {
int n, i; int n, i;
char *p = fmt; char *p = fmt;
VALUE *var; VALUE *var;
va_list vargs; va_list vargs;
va_start(vargs); va_init_list(vargs, fmt);
if (*p == '*') { if (*p == '*') {
var = va_arg(vargs, VALUE*); var = va_arg(vargs, VALUE*);
*var = ary_new4(argc, argv); *var = rb_ary_new4(argc, argv);
return argc; return argc;
} }
if (isdigit(*p)) { if (ISDIGIT(*p)) {
n = *p - '0'; n = *p - '0';
if (n > argc) if (n > argc)
ArgError("Wrong # of arguments (%d for %d)", argc, n); rb_raise(rb_eArgError, "Wrong # of arguments (%d for %d)", argc, n);
for (i=0; i<n; i++) { for (i=0; i<n; i++) {
var = va_arg(vargs, VALUE*); var = va_arg(vargs, VALUE*);
*var = argv[i]; *var = argv[i];
@ -557,7 +607,7 @@ rb_scan_args(argc, argv, fmt, va_alist)
goto error; goto error;
} }
if (isdigit(*p)) { if (ISDIGIT(*p)) {
n = i + *p - '0'; n = i + *p - '0';
for (; i<n; i++) { for (; i<n; i++) {
var = va_arg(vargs, VALUE*); var = va_arg(vargs, VALUE*);
@ -574,15 +624,15 @@ rb_scan_args(argc, argv, fmt, va_alist)
if(*p == '*') { if(*p == '*') {
var = va_arg(vargs, VALUE*); var = va_arg(vargs, VALUE*);
if (argc > i) { if (argc > i) {
*var = ary_new4(argc-i, argv+i); *var = rb_ary_new4(argc-i, argv+i);
} }
else { else {
*var = ary_new(); *var = rb_ary_new();
} }
} }
else if (*p == '\0') { else if (*p == '\0') {
if (argc > i) { if (argc > i) {
ArgError("Wrong # of arguments(%d for %d)", argc, i); rb_raise(rb_eArgError, "Wrong # of arguments(%d for %d)", argc, i);
} }
} }
else { else {
@ -593,6 +643,6 @@ rb_scan_args(argc, argv, fmt, va_alist)
return argc; return argc;
error: error:
Fatal("bad scan arg format: %s", fmt); rb_fatal("bad scan arg format: %s", fmt);
return 0; return 0;
} }

View file

@ -6,13 +6,13 @@
$Date$ $Date$
created at: Thu Aug 26 14:39:48 JST 1993 created at: Thu Aug 26 14:39:48 JST 1993
Copyright (C) 1993-1996 Yukihiro Matsumoto Copyright (C) 1993-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
#include "ruby.h" #include "ruby.h"
VALUE mComparable; VALUE rb_mComparable;
static ID cmp; static ID cmp;
@ -23,8 +23,8 @@ cmp_eq(x, y)
VALUE c = rb_funcall(x, cmp, 1, y); VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c); int t = NUM2INT(c);
if (t == 0) return TRUE; if (t == 0) return Qtrue;
return FALSE; return Qfalse;
} }
static VALUE static VALUE
@ -34,8 +34,8 @@ cmp_gt(x, y)
VALUE c = rb_funcall(x, cmp, 1, y); VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c); int t = NUM2INT(c);
if (t > 0) return TRUE; if (t > 0) return Qtrue;
return FALSE; return Qfalse;
} }
static VALUE static VALUE
@ -45,8 +45,8 @@ cmp_ge(x, y)
VALUE c = rb_funcall(x, cmp, 1, y); VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c); int t = NUM2INT(c);
if (t >= 0) return TRUE; if (t >= 0) return Qtrue;
return FALSE; return Qfalse;
} }
static VALUE static VALUE
@ -56,8 +56,8 @@ cmp_lt(x, y)
VALUE c = rb_funcall(x, cmp, 1, y); VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c); int t = NUM2INT(c);
if (t < 0) return TRUE; if (t < 0) return Qtrue;
return FALSE; return Qfalse;
} }
static VALUE static VALUE
@ -67,8 +67,8 @@ cmp_le(x, y)
VALUE c = rb_funcall(x, cmp, 1, y); VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c); int t = NUM2INT(c);
if (t <= 0) return TRUE; if (t <= 0) return Qtrue;
return FALSE; return Qfalse;
} }
static VALUE static VALUE
@ -76,25 +76,25 @@ cmp_between(x, min, max)
VALUE x, min, max; VALUE x, min, max;
{ {
VALUE c = rb_funcall(x, cmp, 1, min); VALUE c = rb_funcall(x, cmp, 1, min);
int t = NUM2INT(c); long t = NUM2LONG(c);
if (t < 0) return FALSE; if (t < 0) return Qfalse;
c = rb_funcall(x, cmp, 1, max); c = rb_funcall(x, cmp, 1, max);
t = NUM2INT(c); t = NUM2LONG(c);
if (t > 0) return FALSE; if (t > 0) return Qfalse;
return TRUE; return Qtrue;
} }
void void
Init_Comparable() Init_Comparable()
{ {
mComparable = rb_define_module("Comparable"); rb_mComparable = rb_define_module("Comparable");
rb_define_method(mComparable, "==", cmp_eq, 1); rb_define_method(rb_mComparable, "==", cmp_eq, 1);
rb_define_method(mComparable, ">", cmp_gt, 1); rb_define_method(rb_mComparable, ">", cmp_gt, 1);
rb_define_method(mComparable, ">=", cmp_ge, 1); rb_define_method(rb_mComparable, ">=", cmp_ge, 1);
rb_define_method(mComparable, "<", cmp_lt, 1); rb_define_method(rb_mComparable, "<", cmp_lt, 1);
rb_define_method(mComparable, "<=", cmp_le, 1); rb_define_method(rb_mComparable, "<=", cmp_le, 1);
rb_define_method(mComparable, "between?", cmp_between, 2); rb_define_method(rb_mComparable, "between?", cmp_between, 2);
cmp = rb_intern("<=>"); cmp = rb_intern("<=>");
} }

485
config.guess vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Attempt to guess a canonical system name. # Attempt to guess a canonical system name.
# Copyright (C) 1992, 93, 94, 95, 1996 Free Software Foundation, Inc. # Copyright (C) 1992, 93, 94, 95, 96, 97, 1998 Free Software Foundation, Inc.
# #
# This file is free software; you can redistribute it and/or modify it # 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 # under the terms of the GNU General Public License as published by
@ -63,11 +63,53 @@ trap 'rm -f dummy.c dummy.o dummy; exit 1' 1 2 15
case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
alpha:OSF1:*:*) alpha:OSF1:*:*)
if test $UNAME_RELEASE = "V4.0"; then
UNAME_RELEASE=`/usr/sbin/sizer -v | awk '{print $3}'`
fi
# A Vn.n version is a released version. # A Vn.n version is a released version.
# A Tn.n version is a released field test version. # A Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel. # A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r. # 1.2 uses "1.2" for uname -r.
echo alpha-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//'` cat <<EOF >dummy.s
.globl main
.ent main
main:
.frame \$30,0,\$26,0
.prologue 0
.long 0x47e03d80 # implver $0
lda \$2,259
.long 0x47e20c21 # amask $2,$1
srl \$1,8,\$2
sll \$2,2,\$2
sll \$0,3,\$0
addl \$1,\$0,\$0
addl \$2,\$0,\$0
ret \$31,(\$26),1
.end main
EOF
${CC-cc} dummy.s -o dummy 2>/dev/null
if test "$?" = 0 ; then
./dummy
case "$?" in
7)
UNAME_MACHINE="alpha"
;;
15)
UNAME_MACHINE="alphaev5"
;;
14)
UNAME_MACHINE="alphaev56"
;;
10)
UNAME_MACHINE="alphapca56"
;;
16)
UNAME_MACHINE="alphaev6"
;;
esac
fi
rm -f dummy.s dummy
echo ${UNAME_MACHINE}-dec-osf`echo ${UNAME_RELEASE} | sed -e 's/^[VTX]//' | tr [[A-Z]] [[a-z]]`
exit 0 ;; exit 0 ;;
21064:Windows_NT:50:3) 21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5 echo alpha-dec-winnt3.5
@ -78,17 +120,54 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
amiga:NetBSD:*:*) amiga:NetBSD:*:*)
echo m68k-cbm-netbsd${UNAME_RELEASE} echo m68k-cbm-netbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
amiga:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
*:[Aa]miga[Oo][Ss]:*:*)
echo ${UNAME_MACHINE}-unknown-amigaos
exit 0 ;;
arc64:OpenBSD:*:*)
echo mips64el-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
hkmips:OpenBSD:*:*)
echo mips-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
pmax:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sgi:OpenBSD:*:*)
echo mips-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
wgrisc:OpenBSD:*:*)
echo mipsel-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*) arm:RISC*:1.[012]*:*|arm:riscix:1.[012]*:*)
echo arm-acorn-riscix${UNAME_RELEASE} echo arm-acorn-riscix${UNAME_RELEASE}
exit 0;; exit 0;;
Pyramid*:OSx*:*:*) arm32:NetBSD:*:*)
echo arm-unknown-netbsd`echo ${UNAME_RELEASE}|sed -e 's/[-_].*/\./'`
exit 0 ;;
SR2?01:HI-UX/MPP:*:*)
echo hppa1.1-hitachi-hiuxmpp
exit 0;;
Pyramid*:OSx*:*:*|MIS*:OSx*:*:*|MIS*:SMP_DC-OSx*:*:*)
# akee@wpdis03.wpafb.af.mil (Earle F. Ake) contributed MIS and NILE.
if test "`(/bin/universe) 2>/dev/null`" = att ; then if test "`(/bin/universe) 2>/dev/null`" = att ; then
echo pyramid-pyramid-sysv3 echo pyramid-pyramid-sysv3
else else
echo pyramid-pyramid-bsd echo pyramid-pyramid-bsd
fi fi
exit 0 ;; exit 0 ;;
sun4*:SunOS:5.*:*) NILE:*:*:dcosx)
echo pyramid-pyramid-svr4
exit 0 ;;
sun4H:SunOS:5.*:*)
echo sparc-hal-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
sun4*:SunOS:5.*:* | tadpole*:SunOS:5.*:*)
echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` echo sparc-sun-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;; exit 0 ;;
i86pc:SunOS:5.*:*) i86pc:SunOS:5.*:*)
@ -112,25 +191,84 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun3*:SunOS:*:*) sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE} echo m68k-sun-sunos${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
sun*:*:4.2BSD:*)
UNAME_RELEASE=`(head -1 /etc/motd | awk '{print substr($5,1,3)}') 2>/dev/null`
test "x${UNAME_RELEASE}" = "x" && UNAME_RELEASE=3
case "`/bin/arch`" in
sun3)
echo m68k-sun-sunos${UNAME_RELEASE}
;;
sun4)
echo sparc-sun-sunos${UNAME_RELEASE}
;;
esac
exit 0 ;;
aushp:SunOS:*:*)
echo sparc-auspex-sunos${UNAME_RELEASE}
exit 0 ;;
atari*:NetBSD:*:*) atari*:NetBSD:*:*)
echo m68k-atari-netbsd${UNAME_RELEASE} echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
atari*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:NetBSD:*:*) sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE} echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
sun3*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:NetBSD:*:*) mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE} echo m68k-apple-netbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
mac68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme68k:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mvme88k:OpenBSD:*:*)
echo m88k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
powerpc:machten:*:*)
echo powerpc-apple-machten${UNAME_RELEASE}
exit 0 ;;
macppc:NetBSD:*:*)
echo powerpc-apple-netbsd${UNAME_RELEASE}
exit 0 ;;
RISC*:Mach:*:*)
echo mips-dec-mach_bsd4.3
exit 0 ;;
RISC*:ULTRIX:*:*) RISC*:ULTRIX:*:*)
echo mips-dec-ultrix${UNAME_RELEASE} echo mips-dec-ultrix${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
VAX*:ULTRIX*:*:*) VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE} echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
mips:*:4*:UMIPS) 2020:CLIX:*:*)
echo mips-mips-riscos4sysv echo clipper-intergraph-clix${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
mips:*:5*:RISCos) mips:*:*:UMIPS | mips:*:*:RISCos)
sed 's/^ //' << EOF >dummy.c
int main (argc, argv) int argc; char **argv; {
#if defined (host_mips) && defined (MIPSEB)
#if defined (SYSTYPE_SYSV)
printf ("mips-mips-riscos%ssysv\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_SVR4)
printf ("mips-mips-riscos%ssvr4\n", argv[1]); exit (0);
#endif
#if defined (SYSTYPE_BSD43) || defined(SYSTYPE_BSD)
printf ("mips-mips-riscos%sbsd\n", argv[1]); exit (0);
#endif
#endif
exit (-1);
}
EOF
${CC-cc} dummy.c -o dummy \
&& ./dummy `echo "${UNAME_RELEASE}" | sed -n 's/\([0-9]*\).*/\1/p'` \
&& rm dummy.c dummy && exit 0
rm -f dummy.c dummy
echo mips-mips-riscos${UNAME_RELEASE} echo mips-mips-riscos${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
Night_Hawk:Power_UNIX:*:*) Night_Hawk:Power_UNIX:*:*)
@ -174,10 +312,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:IRIX*:*:*) *:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'` echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
exit 0 ;; exit 0 ;;
????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX. ????????:AIX?:[12].1:2) # AIX 2.2.1 or AIX 2.1.1 is RT/PC AIX.
echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id echo romp-ibm-aix # uname -m gives an 8 hex-code CPU id
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX ' exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i[34]86:AIX:*:*) i?86:AIX:*:*)
echo i386-ibm-aix echo i386-ibm-aix
exit 0 ;; exit 0 ;;
*:AIX:2:3) *:AIX:2:3)
@ -203,7 +341,8 @@ EOF
fi fi
exit 0 ;; exit 0 ;;
*:AIX:*:4) *:AIX:*:4)
if /usr/sbin/lsattr -EHl proc0 | grep POWER >/dev/null 2>&1; then IBM_CPU_ID=`/usr/sbin/lsdev -C -c processor -S available | head -1 | awk '{ print $1 }'`
if /usr/sbin/lsattr -EHl ${IBM_CPU_ID} | grep POWER >/dev/null 2>&1; then
IBM_ARCH=rs6000 IBM_ARCH=rs6000
else else
IBM_ARCH=powerpc IBM_ARCH=powerpc
@ -236,12 +375,44 @@ EOF
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*) hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4 echo m68k-hp-bsd4.4
exit 0 ;; exit 0 ;;
9000/[3478]??:HP-UX:*:*) 9000/[34678]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;; 9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;; 9000/[34]?? ) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;; 9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 )
9000/8?? ) HP_ARCH=hppa1.0 ;; sed 's/^ //' << EOF >dummy.c
#include <stdlib.h>
#include <unistd.h>
int main ()
{
#if defined(_SC_KERNEL_BITS)
long bits = sysconf(_SC_KERNEL_BITS);
#endif
long cpu = sysconf (_SC_CPU_VERSION);
switch (cpu)
{
case CPU_PA_RISC1_0: puts ("hppa1.0"); break;
case CPU_PA_RISC1_1: puts ("hppa1.1"); break;
case CPU_PA_RISC2_0:
#if defined(_SC_KERNEL_BITS)
switch (bits)
{
case 64: puts ("hppa2.0w"); break;
case 32: puts ("hppa2.0n"); break;
default: puts ("hppa2.0"); break;
} break;
#else /* !defined(_SC_KERNEL_BITS) */
puts ("hppa2.0"); break;
#endif
default: puts ("hppa1.0"); break;
}
exit (0);
}
EOF
(${CC-cc} dummy.c -o dummy 2>/dev/null ) && HP_ARCH=`./dummy`
rm -f dummy.c dummy
esac esac
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'` HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ${HP_ARCH}-hp-hpux${HPUX_REV} echo ${HP_ARCH}-hp-hpux${HPUX_REV}
@ -288,6 +459,13 @@ EOF
hp8??:OSF1:*:*) hp8??:OSF1:*:*)
echo hppa1.0-hp-osf echo hppa1.0-hp-osf
exit 0 ;; exit 0 ;;
i?86:OSF1:*:*)
if [ -x /usr/sbin/sysversion ] ; then
echo ${UNAME_MACHINE}-unknown-osf1mk
else
echo ${UNAME_MACHINE}-unknown-osf1
fi
exit 0 ;;
parisc*:Lites*:*:*) parisc*:Lites*:*:*)
echo hppa1.1-hp-lites echo hppa1.1-hp-lites
exit 0 ;; exit 0 ;;
@ -315,18 +493,40 @@ EOF
CRAY*Y-MP:*:*:*) CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE} echo ymp-cray-unicos${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
CRAY*C90:*:*:*) CRAY*[A-Z]90:*:*:*)
echo c90-cray-unicos${UNAME_RELEASE} echo ${UNAME_MACHINE}-cray-unicos${UNAME_RELEASE} \
| sed -e 's/CRAY.*\([A-Z]90\)/\1/' \
-e y/ABCDEFGHIJKLMNOPQRSTUVWXYZ/abcdefghijklmnopqrstuvwxyz/
exit 0 ;;
CRAY*TS:*:*:*)
echo t90-cray-unicos${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
CRAY-2:*:*:*) CRAY-2:*:*:*)
echo cray2-cray-unicos echo cray2-cray-unicos
exit 0 ;; exit 0 ;;
F300:UNIX_System_V:*:*)
FUJITSU_SYS=`uname -p | tr [A-Z] [a-z] | sed -e 's/\///'`
FUJITSU_REL=`echo ${UNAME_RELEASE} | sed -e 's/ /_/'`
echo "f300-fujitsu-${FUJITSU_SYS}${FUJITSU_REL}"
exit 0 ;;
F301:UNIX_System_V:*:*)
echo f301-fujitsu-uxpv`echo $UNAME_RELEASE | sed 's/ .*//'`
exit 0 ;;
hp3[0-9][05]:NetBSD:*:*) hp3[0-9][05]:NetBSD:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE} echo m68k-hp-netbsd${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
i[34]86:BSD/386:*:* | *:BSD/OS:*:*) hp300:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sparc*:BSD/OS:*:*)
echo sparc-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
i?86:BSD/386:*:* | i?86:BSD/OS:*:*)
echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE} echo ${UNAME_MACHINE}-pc-bsdi${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*) *:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'` echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;; exit 0 ;;
@ -340,33 +540,142 @@ EOF
echo i386-pc-bow echo i386-pc-bow
exit 0 ;; exit 0 ;;
i*:CYGWIN*:*) i*:CYGWIN*:*)
echo i386-pc-cygwin32 echo ${UNAME_MACHINE}-pc-cygwin
exit 0 ;;
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit 0 ;; exit 0 ;;
p*:CYGWIN*:*) p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin32 echo powerpcle-unknown-cygwin
exit 0 ;; exit 0 ;;
prep*:SunOS:5.*:*) prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'` echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;; exit 0 ;;
*:GNU:*:*) *:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'` echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;; exit 0 ;;
*:Linux:*:*) *:Linux:*:*)
echo ${UNAME_MACHINE}-pc-linux # uname on the ARM produces all sorts of strangeness, and we need to
exit 0 ;; # filter it out.
case "$UNAME_MACHINE" in
arm* | sa110*) UNAME_MACHINE="arm" ;;
esac
# The BFD linker knows what the default object file format is, so
# first see if it will tell us.
ld_help_string=`ld --help 2>&1`
ld_supported_emulations=`echo $ld_help_string \
| sed -ne '/supported emulations:/!d
s/[ ][ ]*/ /g
s/.*supported emulations: *//
s/ .*//
p'`
case "$ld_supported_emulations" in
i?86linux) echo "${UNAME_MACHINE}-pc-linux-aout" ; exit 0 ;;
i?86coff) echo "${UNAME_MACHINE}-pc-linux-coff" ; exit 0 ;;
sparclinux) echo "${UNAME_MACHINE}-unknown-linux-aout" ; exit 0 ;;
m68klinux) echo "${UNAME_MACHINE}-unknown-linux-aout" ; exit 0 ;;
elf32ppc) echo "powerpc-unknown-linux" ; exit 0 ;;
esac
if test "${UNAME_MACHINE}" = "alpha" ; then
sed 's/^ //' <<EOF >dummy.s
.globl main
.ent main
main:
.frame \$30,0,\$26,0
.prologue 0
.long 0x47e03d80 # implver $0
lda \$2,259
.long 0x47e20c21 # amask $2,$1
srl \$1,8,\$2
sll \$2,2,\$2
sll \$0,3,\$0
addl \$1,\$0,\$0
addl \$2,\$0,\$0
ret \$31,(\$26),1
.end main
EOF
LIBC=""
${CC-cc} dummy.s -o dummy 2>/dev/null
if test "$?" = 0 ; then
./dummy
case "$?" in
7)
UNAME_MACHINE="alpha"
;;
15)
UNAME_MACHINE="alphaev5"
;;
14)
UNAME_MACHINE="alphaev56"
;;
10)
UNAME_MACHINE="alphapca56"
;;
16)
UNAME_MACHINE="alphaev6"
;;
esac
objdump --private-headers dummy | \
grep ld.so.1 > /dev/null
if test "$?" = 0 ; then
LIBC="libc1"
fi
fi
rm -f dummy.s dummy
echo ${UNAME_MACHINE}-unknown-linux-gnu${LIBC} ; exit 0
elif test "${UNAME_MACHINE}" = "mips" ; then
cat >dummy.c <<EOF
main(argc, argv)
int argc;
char *argv[];
{
#ifdef __MIPSEB__
printf ("%s-unknown-linux\n", argv[1]);
#endif
#ifdef __MIPSEL__
printf ("%sel-unknown-linux\n", argv[1]);
#endif
return 0;
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy "${UNAME_MACHINE}" && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
else
case "${UNAME_MACHINE}" in
i?86)
VENDOR=pc;
;;
*)
VENDOR=unknown;
;;
esac
echo ${UNAME_MACHINE}-${VENDOR}-linux
exit 0
fi ;;
# ptx 4.0 does uname -s correctly, with DYNIX/ptx in there. earlier versions # 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. # are messed up and put the nodename in both sysname and nodename.
i[34]86:DYNIX/ptx:4*:*) i?86:DYNIX/ptx:4*:*)
echo i386-sequent-sysv4 echo i386-sequent-sysv4
exit 0 ;; exit 0 ;;
i[34]86:*:4.*:* | i[34]86:SYSTEM_V:4.*:*) i?86:UNIX_SV:4.2MP:2.*)
# Unixware is an offshoot of SVR4, but it has its own version
# number series starting with 2...
# I am not positive that other SVR4 systems won't match this,
# I just have to hope. -- rms.
# Use sysv4.2uw... so that sysv4* matches it.
echo ${UNAME_MACHINE}-pc-sysv4.2uw${UNAME_VERSION}
exit 0 ;;
i?86:*:4.*:* | i?86:SYSTEM_V:4.*:*)
if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then if grep Novell /usr/include/link.h >/dev/null 2>/dev/null; then
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE} echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
else else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE} echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi fi
exit 0 ;; exit 0 ;;
i[34]86:*:3.2:*) i?86:*:3.2:*)
if test -f /usr/options/cb.name; then if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name` UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
@ -380,6 +689,18 @@ EOF
echo ${UNAME_MACHINE}-pc-sysv32 echo ${UNAME_MACHINE}-pc-sysv32
fi fi
exit 0 ;; exit 0 ;;
i?86:UnixWare:*:*)
if /bin/uname -X 2>/dev/null >/dev/null ; then
(/bin/uname -X|egrep '^Machine.*Pentium' >/dev/null) \
&& UNAME_MACHINE=i586
fi
echo ${UNAME_MACHINE}-unixware-${UNAME_RELEASE}-${UNAME_VERSION}
exit 0 ;;
pc:*:*:*)
# uname -m prints for DJGPP always 'pc', but it prints nothing about
# the processor, so we play safe by assuming i386.
echo i386-pc-msdosdjgpp
exit 0 ;;
Intel:Mach:3*:*) Intel:Mach:3*:*)
echo i386-pc-mach3 echo i386-pc-mach3
exit 0 ;; exit 0 ;;
@ -397,28 +718,36 @@ EOF
# "miniframe" # "miniframe"
echo m68010-convergent-sysv echo m68010-convergent-sysv
exit 0 ;; exit 0 ;;
M680[234]0:*:R3V[567]*:*) M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;; test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0) 3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
uname -p 2>/dev/null | grep 86 >/dev/null \ OS_REL=''
&& echo i486-ncr-sysv4.3 && exit 0 ;; test -r /etc/.relid \
&& OS_REL=.`sed -n 's/[^ ]* [^ ]* \([0-9][0-9]\).*/\1/p' < /etc/.relid`
/bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4.3${OS_REL} && exit 0
/bin/uname -p 2>/dev/null | /bin/grep entium >/dev/null \
&& echo i586-ncr-sysv4.3${OS_REL} && exit 0 ;;
3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*) 3[34]??:*:4.0:* | 3[34]??,*:*:4.0:*)
uname -p 2>/dev/null | grep 86 >/dev/null \ /bin/uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4 && exit 0 ;; && echo i486-ncr-sysv4 && exit 0 ;;
m680[234]0:LynxOS:2.[23]*:*) m68*:LynxOS:2.*:*)
echo m68k-lynx-lynxos${UNAME_RELEASE} echo m68k-unknown-lynxos${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
mc68030:UNIX_System_V:4.*:*) mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4 echo m68k-atari-sysv4
exit 0 ;; exit 0 ;;
i[34]86:LynxOS:2.[23]*:*) i?86:LynxOS:2.*:*)
echo i386-lynx-lynxos${UNAME_RELEASE} echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
TSUNAMI:LynxOS:2.[23]*:*) TSUNAMI:LynxOS:2.*:*)
echo sparc-lynx-lynxos${UNAME_RELEASE} echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
rs6000:LynxOS:2.[23]*:*) rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
echo rs6000-lynx-lynxos${UNAME_RELEASE} echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
RM*:SINIX-*:*:*) RM*:SINIX-*:*:*)
echo mips-sni-sysv4 echo mips-sni-sysv4
@ -431,42 +760,58 @@ EOF
echo ns32k-sni-sysv echo ns32k-sni-sysv
fi fi
exit 0 ;; exit 0 ;;
PENTIUM:CPunix:4.0*:*) # Unisys `ClearPath HMP IX 4000' SVR4/MP effort
# says <Richard.M.Bartel@ccMail.Census.GOV>
echo i586-unisys-sysv4
exit 0 ;;
*:UNIX_System_V:4*:FTX*)
# From Gerald Hewes <hewes@openmarket.com>.
# How about differentiating between stratus architectures? -djm
echo hppa1.1-stratus-sysv4
exit 0 ;;
*:*:*:FTX*)
# From seanf@swdc.stratus.com.
echo i860-stratus-sysv4
exit 0 ;;
mc68*:A/UX:*:*) mc68*:A/UX:*:*)
echo m68k-apple-aux${UNAME_RELEASE} echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;; exit 0 ;;
X680[02346]0:Human68k:*:*) news*:NEWS-OS:*:6*)
echo m68k-sharp-human echo mips-sony-newsos6
exit 0 ;; exit 0 ;;
R[34]000:*System_V*:*:*) R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*)
if [ -d /usr/nec ]; then if [ -d /usr/nec ]; then
echo mips-nec-sysv${UNAME_RELEASE} echo mips-nec-sysv`echo ${UNAME_RELEASE} | sed -n 's/\([.0-9]*\).*/\1/p'`
else else
echo mips-unknown-sysv${UNAME_RELEASE} echo mips-unknown-sysv${UNAME_RELEASE}
fi fi
exit 0 ;; exit 0 ;;
R[34]???:UNIX_SV:4.?MP:*)
if [ -x /sbin/uversion ]; then
UVERSION_RELEASE=`(/sbin/uversion -r) 2>/dev/null` \
|| UVERSION_RELEASE=unknown
UVERSION_SYSTEM=`(/sbin/uversion -s) 2>/dev/null` \
|| UVERSION_SYSTEM=unknown
case "${UVERSION_RELEASE}:${UVERSION_SYSTEM}" in
Release*:EWS4800/*)
suffix=`echo ${UNAME_RELEASE} | tr '[A-Z]' '[a-z]'`
suffix=${suffix}r`echo ${UVERSION_RELEASE} | \
sed -e 's/Release//' -e 's/ Rev.*$//'`
echo mips-nec-sysv${suffix}
exit 0 ;;
esac
fi;;
*:machten:*:*)
echo ${UNAME_MACHINE}-apple-machten
exit 0 ;;
powerpc:JCC_BSD+:*:*)
echo powerpc-jcc-bsd4.4
exit 0 ;;
DS/90*:*:*:V20*) DS/90*:*:*:V20*)
echo sparc-fujitsu-uxpds echo sparc-fujitsu-uxpds
exit 0 ;;
BeBox:BeOS:*:*) # BeOS running on hardware made by Be, PPC only.
echo powerpc-be-beos
exit 0 ;;
BeMac:BeOS:*:*) # BeOS running on Mac or Mac clone, PPC only.
echo powerpc-apple-beos
exit 0 ;;
BePC:BeOS:*:*) # BeOS running on Intel PC compatible.
echo i586-pc-beos
exit 0 ;;
*:Rhapsody:*:*)
arch=`/usr/bin/arch`
case "$arch" in
ppc)
echo powerpc-apple-rhapsody${UNAME_RELEASE}
;;
i[3456]86)
echo i386-apple-rhapsody${UNAME_RELEASE}
;;
*)
echo $arch-apple-rhapsody${UNAME_RELEASE}
;;
esac
exit 0 ;; exit 0 ;;
esac esac
@ -511,7 +856,11 @@ main ()
#endif #endif
int version; int version;
version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`; version=`(hostinfo | sed -n 's/.*NeXT Mach \([0-9]*\).*/\1/p') 2>/dev/null`;
printf ("%s-next-nextstep%s\n", __ARCHITECTURE__, version==2 ? "2" : "3"); if (version < 4)
printf ("%s-next-nextstep%d\n", __ARCHITECTURE__, version);
else
printf ("%s-next-openstep%d\n", __ARCHITECTURE__, version);
exit (0); exit (0);
#endif #endif
@ -567,16 +916,12 @@ main ()
printf ("i860-alliant-bsd\n"); exit (0); printf ("i860-alliant-bsd\n"); exit (0);
#endif #endif
#if defined (__human68k__) || defined (HUMAN68K)
printf ("m68k-sharp-human\n"); exit (0);
#endif
exit (1); exit (1);
} }
EOF EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm -f dummy.c dummy.x dummy && exit 0 ${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy.x dummy rm -f dummy.c dummy
# Apollos put the system type in the environment. # Apollos put the system type in the environment.

156
config.sub vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh #! /bin/sh
# Configuration validation subroutine script, version 1.1. # Configuration validation subroutine script, version 1.1.
# Copyright (C) 1991, 92, 93, 94, 95, 1996 Free Software Foundation, Inc. # Copyright (C) 1991, 92-97, 1998 Free Software Foundation, Inc.
# This file is (in principle) common to ALL GNU software. # This file is (in principle) common to ALL GNU software.
# The presence of a machine in this file suggests that SOME 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.
@ -149,35 +149,43 @@ esac
case $basic_machine in case $basic_machine in
# Recognize the basic CPU types without company name. # Recognize the basic CPU types without company name.
# Some are omitted here because they have special meanings below. # Some are omitted here because they have special meanings below.
tahoe | i860 | m68k | m68000 | m88k | ns32k | arm \ tahoe | i860 | m32r | m68k | m68000 | m88k | ns32k | arc | arm \
| arme[lb] | pyramid \ | arme[lb] | pyramid | mn10200 | mn10300 | tron | a29k \
| tron | a29k | 580 | i960 | h8300 | hppa1.0 | hppa1.1 \ | 580 | i960 | h8300 | hppa | hppa1.0 | hppa1.1 | hppa2.0 \
| alpha | we32k | ns16k | clipper | i370 | sh \ | alpha | alphaev5 | alphaev56 | we32k | ns16k | clipper \
| powerpc | powerpcle | 1750a | dsp16xx | mips64 | mipsel \ | i370 | sh | powerpc | powerpcle | 1750a | dsp16xx | pdp11 \
| pdp11 | mips64el | mips64orion | mips64orionel \ | mips64 | mipsel | mips64el | mips64orion | mips64orionel \
| sparc | sparclet | sparclite | sparc64) | mipstx39 | mipstx39el \
basic_machine=$basic_machine-unknown | sparc | sparclet | sparclite | sparc64 | v850)
;; basic_machine=$basic_machine-unknown
;;
# We use `pc' rather than `unknown' # We use `pc' rather than `unknown'
# because (1) that's what they normally are, and # because (1) that's what they normally are, and
# (2) the word "unknown" tends to confuse beginning users. # (2) the word "unknown" tends to confuse beginning users.
i[3456]86) i[34567]86)
basic_machine=$basic_machine-pc basic_machine=$basic_machine-pc
;; ;;
i[3456]86-TOWNS*)
basic_machine=`echo $basic_machine | sed -e 's/-TOWNS.*/-TOWNS/'`
;;
# Object if more than one company name word. # Object if more than one company name word.
*-*-*) *-*-*)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1 exit 1
;; ;;
# Recognize the basic CPU types with company name. # Recognize the basic CPU types with company name.
vax-* | tahoe-* | i[3456]86-* | i860-* | m68k-* | m68000-* | m88k-* \ vax-* | tahoe-* | i[34567]86-* | i860-* | m32r-* | m68k-* | m68000-* \
| sparc-* | ns32k-* | fx80-* | arm-* | c[123]* \ | m88k-* | sparc-* | ns32k-* | fx80-* | arc-* | arm-* | c[123]* \
| mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* | power-* \ | mips-* | pyramid-* | tron-* | a29k-* | romp-* | rs6000-* \
| none-* | 580-* | cray2-* | h8300-* | i960-* | xmp-* | ymp-* \ | power-* | none-* | 580-* | cray2-* | h8300-* | i960-* \
| hppa1.0-* | hppa1.1-* | alpha-* | we32k-* | cydra-* | ns16k-* \ | xmp-* | ymp-* | hppa-* | hppa1.0-* | hppa1.1-* | hppa2.0-* \
| pn-* | np1-* | xps100-* | clipper-* | orion-* | sparclite-* \ | alpha-* | alphaev5-* | alphaev56-* | we32k-* | cydra-* \
| pdp11-* | sh-* | powerpc-* | powerpcle-* | sparc64-* | mips64-* | mipsel-* \ | ns16k-* | pn-* | np1-* | xps100-* | clipper-* | orion-* \
| mips64el-* | mips64orion-* | mips64orionel-*) | sparclite-* | pdp11-* | sh-* | powerpc-* | powerpcle-* \
| sparc64-* | mips64-* | mipsel-* \
| mips64el-* | mips64orion-* | mips64orionel-* \
| mipstx39-* | mipstx39el-* \
| f301-*)
;; ;;
# Recognize the various machine names and aliases which stand # Recognize the various machine names and aliases which stand
# for a CPU type and a company and sometimes even an OS. # for a CPU type and a company and sometimes even an OS.
@ -204,9 +212,9 @@ case $basic_machine in
amiga | amiga-*) amiga | amiga-*)
basic_machine=m68k-cbm basic_machine=m68k-cbm
;; ;;
amigados) amigaos | amigados)
basic_machine=m68k-cbm basic_machine=m68k-cbm
os=-amigados os=-amigaos
;; ;;
amigaunix | amix) amigaunix | amix)
basic_machine=m68k-cbm basic_machine=m68k-cbm
@ -292,10 +300,6 @@ case $basic_machine in
encore | umax | mmax) encore | umax | mmax)
basic_machine=ns32k-encore basic_machine=ns32k-encore
;; ;;
ews4800)
basic_machine=mips-nec
os=-sysv4
;;
fx2800) fx2800)
basic_machine=i860-alliant basic_machine=i860-alliant
;; ;;
@ -341,24 +345,27 @@ case $basic_machine in
hp9k8[0-9][0-9] | hp8[0-9][0-9]) hp9k8[0-9][0-9] | hp8[0-9][0-9])
basic_machine=hppa1.0-hp basic_machine=hppa1.0-hp
;; ;;
hppa-next)
os=-nextstep3
;;
i370-ibm* | ibm*) i370-ibm* | ibm*)
basic_machine=i370-ibm basic_machine=i370-ibm
os=-mvs os=-mvs
;; ;;
# I'm not sure what "Sysv32" means. Should this be sysv3.2? # I'm not sure what "Sysv32" means. Should this be sysv3.2?
i[3456]86v32) i[34567]86v32)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv32 os=-sysv32
;; ;;
i[3456]86v4*) i[34567]86v4*)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv4 os=-sysv4
;; ;;
i[3456]86v) i[34567]86v)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-sysv os=-sysv
;; ;;
i[3456]86sol2) i[34567]86sol2)
basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'` basic_machine=`echo $1 | sed -e 's/86.*/86-pc/'`
os=-solaris2 os=-solaris2
;; ;;
@ -390,6 +397,14 @@ case $basic_machine in
miniframe) miniframe)
basic_machine=m68000-convergent basic_machine=m68000-convergent
;; ;;
mipsel*-linux*)
basic_machine=mipsel-unknown
os=-linux
;;
mips*-linux*)
basic_machine=mips-unknown
os=-linux
;;
mips3*-*) mips3*-*)
basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'` basic_machine=`echo $basic_machine | sed -e 's/mips3/mips64/'`
;; ;;
@ -457,25 +472,23 @@ case $basic_machine in
pc532 | pc532-*) pc532 | pc532-*)
basic_machine=ns32k-pc532 basic_machine=ns32k-pc532
;; ;;
pentium | p5) pentium | p5 | k5 | nexen)
basic_machine=i586-intel basic_machine=i586-pc
;; ;;
pentiumpro | p6) pentiumpro | p6 | k6 | 6x86)
basic_machine=i686-intel basic_machine=i686-pc
;; ;;
pentium-* | p5-*) pentiumii | pentium2)
basic_machine=i786-pc
;;
pentium-* | p5-* | k5-* | nexen-*)
basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i586-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
pentiumpro-* | p6-*) pentiumpro-* | p6-* | k6-* | 6x86-*)
basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'` basic_machine=i686-`echo $basic_machine | sed 's/^[^-]*-//'`
;; ;;
k5) pentiumii-* | pentium2-*)
# We don't have specific support for AMD's K5 yet, so just call it a Pentium basic_machine=i786-`echo $basic_machine | sed 's/^[^-]*-//'`
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) pn)
basic_machine=pn-gould basic_machine=pn-gould
@ -559,6 +572,12 @@ case $basic_machine in
basic_machine=i386-sequent basic_machine=i386-sequent
os=-dynix os=-dynix
;; ;;
tx39)
basic_machine=mipstx39-unknown
;;
tx39el)
basic_machine=mipstx39el-unknown
;;
tower | tower-32) tower | tower-32)
basic_machine=m68k-ncr basic_machine=m68k-ncr
;; ;;
@ -578,6 +597,9 @@ case $basic_machine in
basic_machine=vax-dec basic_machine=vax-dec
os=-vms os=-vms
;; ;;
vpp*|vx|vx-*)
basic_machine=f301-fujitsu
;;
vxworks960) vxworks960)
basic_machine=i960-wrs basic_machine=i960-wrs
os=-vxworks os=-vxworks
@ -605,7 +627,11 @@ case $basic_machine in
# Here we handle the default manufacturer of certain CPU types. It is in # Here we handle the default manufacturer of certain CPU types. It is in
# some cases the only manufacturer, in others, it is the most popular. # some cases the only manufacturer, in others, it is the most popular.
mips) mips)
basic_machine=mips-mips if [ x$os = x-linux ]; then
basic_machine=mips-unknown
else
basic_machine=mips-mips
fi
;; ;;
romp) romp)
basic_machine=romp-ibm basic_machine=romp-ibm
@ -634,10 +660,6 @@ case $basic_machine in
orion105) orion105)
basic_machine=clipper-highlevel basic_machine=clipper-highlevel
;; ;;
human)
basic_machine=m68k-sharp
os=-human
;;
*) *)
echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2 echo Invalid configuration \`$1\': machine \`$basic_machine\' not recognized 1>&2
exit 1 exit 1
@ -652,6 +674,10 @@ case $basic_machine in
*-commodore*) *-commodore*)
basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'` basic_machine=`echo $basic_machine | sed 's/commodore.*/cbm/'`
;; ;;
human)
basic_machine=m68k-sharp
os=-human
;;
*) *)
;; ;;
esac esac
@ -670,9 +696,12 @@ case $os in
-solaris) -solaris)
os=-solaris2 os=-solaris2
;; ;;
-unixware* | svr4*) -svr4*)
os=-sysv4 os=-sysv4
;; ;;
-unixware*)
os=-sysv4.2uw
;;
-gnu/linux*) -gnu/linux*)
os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'` os=`echo $os | sed -e 's|gnu/linux|linux-gnu|'`
;; ;;
@ -683,15 +712,16 @@ case $os in
-gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \ -gnu* | -bsd* | -mach* | -minix* | -genix* | -ultrix* | -irix* \
| -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\ | -*vms* | -sco* | -esix* | -isc* | -aix* | -sunos | -sunos[34]*\
| -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \ | -hpux* | -unos* | -osf* | -luna* | -dgux* | -solaris* | -sym* \
| -amigados* | -msdos* | -newsos* | -unicos* | -aof* | -aos* \ | -amigaos* | -amigados* | -msdos* | -newsos* | -unicos* | -aof* \
| -nindy* | -vxworks* | -ebmon* | -hms* | -mvs* | -clix* \ | -aos* \
| -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \ | -nindy* | -vxsim* | -vxworks* | -ebmon* | -hms* | -mvs* \
| -clix* | -riscos* | -uniplus* | -iris* | -rtu* | -xenix* \
| -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \ | -hiux* | -386bsd* | -netbsd* | -openbsd* | -freebsd* | -riscix* \
| -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \ | -lynxos* | -bosx* | -nextstep* | -cxux* | -aout* | -elf* \
| -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \ | -ptx* | -coff* | -ecoff* | -winnt* | -domain* | -vsta* \
| -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \ | -udi* | -eabi* | -lites* | -ieee* | -go32* | -aux* \
| -cygwin32* | -pe* | -psos* | -moss* | -proelf* \ | -cygwin* | -pe* | -psos* | -moss* | -proelf* | -rtems* \
| -linux* | -bow*) | -mingw32* | -linux* | -uxpv* | -beos*)
# Remember, each alternative MUST END IN *, to match a version number. # Remember, each alternative MUST END IN *, to match a version number.
;; ;;
-sunos5*) -sunos5*)
@ -754,6 +784,9 @@ case $os in
;; ;;
-human) -human)
;; ;;
-beos)
os=-beos
;;
-none) -none)
;; ;;
*) *)
@ -806,6 +839,9 @@ case $basic_machine in
sparc-* | *-sun) sparc-* | *-sun)
os=-sunos4.1.1 os=-sunos4.1.1
;; ;;
*-be)
os=-beos
;;
*-ibm) *-ibm)
os=-aix os=-aix
;; ;;
@ -819,7 +855,7 @@ case $basic_machine in
os=-sysv os=-sysv
;; ;;
*-cbm) *-cbm)
os=-amigados os=-amigaos
;; ;;
*-dg) *-dg)
os=-dgux os=-dgux
@ -869,6 +905,9 @@ case $basic_machine in
*-masscomp) *-masscomp)
os=-rtu os=-rtu
;; ;;
f301-fujitsu)
os=-uxpv
;;
*) *)
os=-none os=-none
;; ;;
@ -887,9 +926,6 @@ case $basic_machine in
-sunos*) -sunos*)
vendor=sun vendor=sun
;; ;;
-lynxos*)
vendor=lynx
;;
-aix*) -aix*)
vendor=ibm vendor=ibm
;; ;;
@ -917,7 +953,7 @@ case $basic_machine in
-ptx*) -ptx*)
vendor=sequent vendor=sequent
;; ;;
-vxworks*) -vxsim* | -vxworks*)
vendor=wrs vendor=wrs
;; ;;
-aux*) -aux*)

1325
configure vendored

File diff suppressed because it is too large Load diff

View file

@ -2,4 +2,5 @@
sed -f top.sed Makefile.in >Makefile sed -f top.sed Makefile.in >Makefile
sed -f top.sed ext/extmk.rb.in > ext\extmk.rb sed -f top.sed ext/extmk.rb.in > ext\extmk.rb
copy ext\Setup.dj ext\Setup copy ext\Setup.dj ext\Setup
copy config.dj config.h copy config_h.dj config.h
copy config_s.dj config.status

View file

@ -24,28 +24,47 @@ AC_ARG_ENABLE(thread, [--disable-thread never use user-level thread], [
rb_thread=$enableval rb_thread=$enableval
]) ])
if test $rb_thread = yes; then if test $rb_thread = yes; then
AC_DEFINE(THREAD) AC_DEFINE(USE_THREAD)
fi fi
AC_CANONICAL_HOST AC_CANONICAL_HOST
dnl checks for fat-binary dnl checks for fat-binary
fat_binary=no fat_binary=no
AC_ARG_ENABLE( fat-binary, AC_ARG_ENABLE( fat-binary,
[--enable-fat-binary build a NeXT Multi Architecture Binary. ], [--enable-fat-binary build a NeXT/Apple Multi Architecture Binary. ],
[ fat_binary=$enableval ] ) [ fat_binary=$enableval ] )
if test "$fat_binary" = yes ; then if test "$fat_binary" = yes ; then
AC_MSG_CHECKING( target architecture ) AC_MSG_CHECKING( target architecture )
if test "$TARGET_ARCHS" = "" ; then case "$host_os" in
if test `/usr/bin/arch` = "m68k" ; then rhapsody*)
TARGET_ARCHS="m68k i486" echo -n "MacOS X Server: "
if test "$TARGET_ARCHS" = "" ; then
TARGET_ARCHS="ppc i386"
fi
;;
nextstep*|openstep*)
echo -n "NeXTSTEP/OPENSTEP: "
if test "$host_os" = "rhapsody" ; then
echo -n "Rhapsody: "
if test "$TARGET_ARCHS" = "" ; then
TARGET_ARCHS="ppc i486"
fi
else else
TARGET_ARCHS="m68k `/usr/bin/arch`" echo -n "NeXTSTEP/OPENSTEP: "
if test "$TARGET_ARCHS" = "" ; then
if test `/usr/bin/arch` = "m68k" ; then
TARGET_ARCHS="m68k i486"
else # Black and Native one
TARGET_ARCHS="m68k `/usr/bin/arch`"
fi
fi
fi fi
fi ;;
esac
# /usr/lib/arch_tool -archify_list $TARGET_ARCHS # /usr/lib/arch_tool -archify_list $TARGET_ARCHS
for archs in $TARGET_ARCHS for archs in $TARGET_ARCHS
do do
@ -56,7 +75,6 @@ if test "$fat_binary" = yes ; then
echo "." echo "."
fi fi
AC_ARG_PROGRAM AC_ARG_PROGRAM
dnl Checks for programs. dnl Checks for programs.
@ -72,22 +90,70 @@ AC_PROG_MAKE_SET
# checks for UNIX variants that set C preprocessor variables # checks for UNIX variants that set C preprocessor variables
AC_MINIX AC_MINIX
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(void*)
AC_MSG_CHECKING(for prototypes)
AC_CACHE_VAL(rb_cv_have_prototypes,
[AC_TRY_COMPILE([int foo(int x) { return 0; }], [return foo(10);],
rb_cv_have_prototypes=yes,
rb_cv_have_prototypes=no)])
AC_MSG_RESULT($rb_cv_have_prototypes)
if test "$rb_cv_have_prototypes" = yes; then
AC_DEFINE(HAVE_PROTOTYPES)
fi
AC_MSG_CHECKING(for variable length prototypes and stdarg.h)
AC_CACHE_VAL(rb_cv_stdarg,
[AC_TRY_COMPILE([
#include <stdarg.h>
int foo(int x, ...) {
va_list va;
va_start(va, x);
va_arg(va, int);
va_arg(va, char *);
va_arg(va, double);
return 0;
}
], [return foo(10, "", 3.14);],
rb_cv_stdarg=yes,
rb_cv_stdarg=no)])
AC_MSG_RESULT($rb_cv_stdarg)
if test "$rb_cv_stdarg" = yes; then
AC_DEFINE(HAVE_STDARG_PROTOTYPES)
fi
AC_MSG_CHECKING(for gcc attribute noreturn)
AC_CACHE_VAL(rb_cv_have_attr_noreturn,
[AC_TRY_COMPILE([void exit(int x) __attribute__ ((noreturn));], [],
rb_cv_have_attr_noreturn=yes,
rb_cv_have_attr_noreturn=no)])
AC_MSG_RESULT($rb_cv_have_attr_noreturn)
if test "$rb_cv_have_attr_noreturn" = yes; then
AC_DEFINE(HAVE_ATTR_NORETURN)
fi
dnl Checks for libraries. dnl Checks for libraries.
case "$host_os" in case "$host_os" in
nextstep*) ;; nextstep*) ;;
openstep*) ;;
rhapsody*) ;;
human*) ;; human*) ;;
beos*) ;;
*) LIBS="-lm $LIBS";; *) LIBS="-lm $LIBS";;
esac esac
AC_CHECK_LIB(crypt, crypt) 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 AC_CHECK_LIB(dld, shl_load) # Dynamic linking for HP-UX
AC_CHECK_LIB(xpg4, setlocale) # FreeBSD needs this
dnl Checks for header files. dnl Checks for header files.
AC_HEADER_DIRENT AC_HEADER_DIRENT
AC_HEADER_STDC AC_HEADER_STDC
AC_CHECK_HEADERS(stdlib.h unistd.h limits.h sys/file.h sys/ioctl.h pwd.h \ AC_CHECK_HEADERS(stdlib.h unistd.h limits.h sys/file.h sys/ioctl.h pwd.h \
sys/select.h sys/time.h sys/times.h sys/param.h sys/wait.h\ 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) syscall.h a.out.h string.h utime.h memory.h direct.h)
dnl Checks for typedefs, structures, and compiler characteristics. dnl Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T AC_TYPE_UID_T
@ -98,23 +164,19 @@ AC_STRUCT_ST_BLOCKS
LIBOBJS="$save_LIBOBJS" LIBOBJS="$save_LIBOBJS"
AC_STRUCT_ST_RDEV AC_STRUCT_ST_RDEV
AC_CHECK_SIZEOF(short)
AC_CHECK_SIZEOF(int)
AC_CHECK_SIZEOF(long)
AC_CHECK_SIZEOF(void*)
dnl Checks for library functions. dnl Checks for library functions.
AC_TYPE_GETGROUPS AC_TYPE_GETGROUPS
AC_TYPE_SIGNAL AC_TYPE_SIGNAL
AC_FUNC_ALLOCA AC_FUNC_ALLOCA
AC_FUNC_VFORK AC_FUNC_VFORK
AC_REPLACE_FUNCS(dup2 setenv memmove mkdir strcasecmp strerror strftime\ AC_FUNC_MEMCMP
strstr strtoul strdup crypt flock) AC_REPLACE_FUNCS(dup2 memmove mkdir strcasecmp strerror strftime\
AC_CHECK_FUNCS(fmod killpg random wait4 waitpid syscall getcwd\ strchr strstr strtoul strdup crypt flock vsnprintf)
AC_CHECK_FUNCS(fmod killpg drand48 random wait4 waitpid syscall getcwd\
truncate chsize times utimes fcntl lockf setitimer\ truncate chsize times utimes fcntl lockf setitimer\
setruid seteuid setreuid setrgid setegid setregid\ setruid seteuid setreuid setrgid setegid setregid\
setpgrp2 getpgid getgroups getpriority\ setpgrp2 getpgid setpgid getgroups getpriority\
dlopen sigprocmask sigaction _setjmp) dlopen sigprocmask sigaction _setjmp setpgrp setsid)
if test "$ac_cv_func_strftime" = no; then if test "$ac_cv_func_strftime" = no; then
AC_STRUCT_TIMEZONE AC_STRUCT_TIMEZONE
AC_TRY_LINK([], AC_TRY_LINK([],
@ -181,6 +243,26 @@ fi
AC_C_BIGENDIAN AC_C_BIGENDIAN
AC_CHAR_UNSIGNED AC_CHAR_UNSIGNED
AC_MSG_CHECKING(whether right shift preserve sign bit)
AC_CACHE_VAL(rb_cv_rshift_sign,
[AC_TRY_RUN([
int
main()
{
if (-1==(-1>>1))
return 0;
return 1;
}
],
rb_cv_rshift_sign=yes,
rb_cv_rshift_sign=no)])
AC_MSG_RESULT($rb_cv_rshift_sign)
if test "$rb_cv_rshift_sign" = yes; then
AC_DEFINE(RSHIFT(x,y), ((x)>>y))
else
AC_DEFINE(RSHIFT(x,y), (((x)<0) ? ~((~(x))>>y) : (x)>>y))
fi
AC_MSG_CHECKING([count field in FILE structures]) AC_MSG_CHECKING([count field in FILE structures])
AC_CACHE_VAL(rb_cv_fcnt, AC_CACHE_VAL(rb_cv_fcnt,
[AC_TRY_COMPILE([#include <stdio.h>], [AC_TRY_COMPILE([#include <stdio.h>],
@ -205,17 +287,6 @@ else
AC_DEFINE_UNQUOTED(FILE_COUNT, $rb_cv_fcnt) AC_DEFINE_UNQUOTED(FILE_COUNT, $rb_cv_fcnt)
fi fi
if test "$ac_cv_func_getpwent" = yes; then
AC_MSG_CHECKING(struct passwd)
AC_EGREP_HEADER(pw_change, pwd.h, AC_DEFINE(PW_CHANGE))
AC_EGREP_HEADER(pw_quota, pwd.h, AC_DEFINE(PW_QUOTA))
AC_EGREP_HEADER(pw_age, pwd.h, AC_DEFINE(PW_AGE))
AC_EGREP_HEADER(pw_class, pwd.h, AC_DEFINE(PW_CLASS))
AC_EGREP_HEADER(pw_comment, pwd.h, AC_DEFINE(PW_COMMENT))
AC_EGREP_HEADER(pw_expire, pwd.h, AC_DEFINE(PW_EXPIRE))
AC_MSG_RESULT(done)
fi
dnl wheather use dln_a_out ot not 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 case $withval in
@ -271,7 +342,10 @@ if test "$with_dln_a_out" != yes; then
if test "$GCC" = yes; then if test "$GCC" = yes; then
case "$host_os" in case "$host_os" in
nextstep*) ;; nextstep*) ;;
openstep*) ;;
rhapsody*) ;;
human*) ;; human*) ;;
cygwin*) CCDLFLAGS=-DDLLIMPORT;;
*) CCDLFLAGS=-fpic;; *) CCDLFLAGS=-fpic;;
esac esac
else else
@ -301,21 +375,44 @@ if test "$with_dln_a_out" != yes; then
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
linux*) LDSHARED="gcc -shared" linux*) LDSHARED="gcc -shared"
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
freebsd3*) LDSHARED="ld -Bshareable"
LDFLAGS="-rdynamic"
rb_cv_dlopen=yes ;;
freebsd*) LDSHARED="ld -Bshareable" freebsd*) LDSHARED="ld -Bshareable"
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
netbsd*) LDSHARED="ld -Bshareable" netbsd*) LDSHARED="ld -Bshareable"
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
openbsd*) LDSHARED="ld -Bshareable" openbsd*) LDSHARED="ld -Bforcearchive -Bshareable"
CCDLFLAGS=-fPIC
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
nextstep*) LDSHARED='cc -r' nextstep*) LDSHARED='cc -r'
LDFLAGS="-u libsys_s" LDFLAGS="-u libsys_s"
DLDFLAGS="$ARCH_FLAG" DLDFLAGS="$ARCH_FLAG"
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
openstep*) LDSHARED='cc -dynamic -bundle -undefined suppress'
LDFLAGS=""
DLDFLAGS="$ARCH_FLAG"
rb_cv_dlopen=yes ;;
rhapsody*) LDSHARED='cc -dynamic -bundle -undefined suppress'
LDFLAGS=""
DLDFLAGS="$ARCH_FLAG"
rb_cv_dlopen=yes ;;
aix*) LDSHARED='../../miniruby ../aix_ld.rb $(TARGET)' aix*) LDSHARED='../../miniruby ../aix_ld.rb $(TARGET)'
rb_cv_dlopen=yes ;; rb_cv_dlopen=yes ;;
human*) DLDFLAGS='' human*) DLDFLAGS=''
LDSHARED='' LDSHARED=''
LDFLAGS='' ;; LDFLAGS='' ;;
beos*) LDSHARED="ld -xms"
case "$host_cpu" in
powerpc*)
DLDFLAGS="-f ruby.exp -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
;;
*)
DLDFLAGS="ruby.def -lbe -lroot glue-noinit.a init_term_dyn.o start_dyn.o"
;;
esac
rb_cv_dlopen=yes ;;
cygwin*) LDSHARED='../../miniruby ../cygwin32_ld.rb' ;;
*) LDSHARED='ld' ;; *) LDSHARED='ld' ;;
esac esac
AC_MSG_RESULT($rb_cv_dlopen) AC_MSG_RESULT($rb_cv_dlopen)
@ -357,6 +454,12 @@ else
AC_DEFINE(DLEXT, ".sl");; AC_DEFINE(DLEXT, ".sl");;
nextstep*) DLEXT=o nextstep*) DLEXT=o
AC_DEFINE(DLEXT, ".o");; AC_DEFINE(DLEXT, ".o");;
openstep*) DLEXT=bundle
AC_DEFINE(DLEXT, ".bundle");;
rhapsody*) DLEXT=bundle
AC_DEFINE(DLEXT, ".bundle");;
cygwin*) DLEXT=dll
AC_DEFINE(DLEXT, ".dll");;
*) DLEXT=so *) DLEXT=so
AC_DEFINE(DLEXT, ".so");; AC_DEFINE(DLEXT, ".so");;
esac esac
@ -374,6 +477,10 @@ case "$host_os" in
STRIP='strip -S -x';; STRIP='strip -S -x';;
nextstep*) nextstep*)
STRIP='strip -A -n';; STRIP='strip -A -n';;
openstep*)
STRIP='strip -A -n';;
rhapsody*)
STRIP='strip -A -n';;
esac esac
EXTSTATIC= EXTSTATIC=
@ -435,11 +542,18 @@ rb_cv_missing_fconvert=yes, rb_cv_missing_fconvert=no)])
binsuffix=.x binsuffix=.x
setup=Setup.x68 setup=Setup.x68
;; ;;
cygwin*)
binsuffix=.exe
setup=Setup
;;
*) *)
binsuffix= binsuffix=
setup=Setup setup=Setup
;; ;;
esac esac
AC_SUBST(binsuffix) AC_SUBST(binsuffix)
AC_SUBST(setup) AC_SUBST(setup)
@ -448,23 +562,82 @@ if test "$prefix" = NONE; then
fi fi
if test "$fat_binary" = yes ; then if test "$fat_binary" = yes ; then
CFLAGS="$CFLAGS -pipe $ARCH_FLAG" CFLAGS="$CFLAGS $ARCH_FLAG"
fi fi
AC_DEFINE_UNQUOTED(RUBY_LIB, "${prefix}/lib/ruby") LIBRUBY='libruby.a'
LIBRUBYARG='libruby.a'
SOLIBS=
if test "$host_os" = "beos"; then
CFLAGS="$CFLAGS -relax_pointers"
LIBRUBY='libruby.so'
LIBRUBYARG='-lruby'
SOLIBS='-lnet'
echo creating ruby.def
case "$host_cpu" in
powerpc*)
cp beos/ruby.def.in ruby.exp
;;
*)
echo EXPORTS > ruby.def
cat beos/ruby.def.in >> ruby.def
;;
esac
fi
if test "$enable_shared" = 'yes'; then
LIBRUBY='libruby.so'
LIBRUBYARG='-L./ -lruby'
fi
case "$host_os" in
nextstep*)
CFLAGS="$CFLAGS -pipe"
;;
openstep*)
CFLAGS="$CFLAGS -pipe"
;;
rhasody*)
CFLAGS="$CFLAGS -pipe -no-precomp"
;;
*)
;;
esac
AC_SUBST(LIBRUBY)
AC_SUBST(LIBRUBYARG)
AC_SUBST(SOLIBS)
ri_prefix=
test "$program_prefix" != NONE &&
ri_prefix=$program_prefix
ri_suffix=
test "$program_suffix" != NONE &&
ri_suffix=$program_suffix
RUBY_INSTALL_NAME="${ri_prefix}ruby${ri_suffix}"
AC_DEFINE_UNQUOTED(RUBY_LIB, "${prefix}/lib/${RUBY_INSTALL_NAME}")
AC_DEFINE_UNQUOTED(RUBY_SITE_LIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby")
AC_SUBST(arch)dnl AC_SUBST(arch)dnl
if test "$fat_binary" = yes ; then if test "$fat_binary" = yes ; then
arch="fat-${host_os}" arch="fat-${host_os}"
AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB, AC_DEFINE_UNQUOTED(RUBY_THIN_ARCHLIB,
"${prefix}/lib/ruby/" __ARCHITECTURE__ "-${host_os}" ) "${prefix}/lib/${RUBY_INSTALL_NAME}/" __ARCHITECTURE__ "-${host_os}" )
AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${prefix}/lib/ruby/${arch}") AC_DEFINE_UNQUOTED(RUBY_SITE_THIN_ARCHLIB,
"${prefix}/lib/${RUBY_INSTALL_NAME}/" __ARCHITECTURE__ "-${host_os}" )
AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/${arch}")
AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby/${arch}")
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, __ARCHITECTURE__ "-${host_os}" ) AC_DEFINE_UNQUOTED(RUBY_PLATFORM, __ARCHITECTURE__ "-${host_os}" )
else else
arch="${host_cpu}-${host_os}" arch="${host_cpu}-${host_os}"
AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${prefix}/lib/ruby/${arch}") AC_DEFINE_UNQUOTED(RUBY_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/${arch}")
AC_DEFINE_UNQUOTED(RUBY_SITE_ARCHLIB, "${prefix}/lib/${RUBY_INSTALL_NAME}/site_ruby/${arch}")
AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "${arch}") AC_DEFINE_UNQUOTED(RUBY_PLATFORM, "${arch}")
fi fi

View file

@ -12,18 +12,20 @@
#define RUBY #define RUBY
/* define EUC/SJIS for default kanji-code */ /* define RUBY_USE_EUC/SJIS for default kanji-code */
#if defined(MSDOS) || defined(__CYGWIN32__) || defined(__human68k__) #if defined(MSDOS) || defined(__CYGWIN32__) || defined(__human68k__) || defined(__MACOS__)
#undef EUC #undef RUBY_USE_EUC
#define SJIS #define RUBY_USE_SJIS
#else #else
#define EUC #define RUBY_USE_EUC
#undef SJIS #undef RUBY_USE_SJIS
#endif #endif
#ifdef NeXT #ifdef NeXT
#define DYNAMIC_ENDIAN /* determine endian at runtime */ #define DYNAMIC_ENDIAN /* determine endian at runtime */
#ifndef __APPLE__
#define S_IXUSR _S_IXUSR /* execute/search permission, owner */ #define S_IXUSR _S_IXUSR /* execute/search permission, owner */
#endif
#define S_IXGRP 0000010 /* execute/search permission, group */ #define S_IXGRP 0000010 /* execute/search permission, group */
#define S_IXOTH 0000001 /* execute/search permission, other */ #define S_IXOTH 0000001 /* execute/search permission, other */
#endif /* NeXT */ #endif /* NeXT */
@ -32,12 +34,22 @@
#include "missing/nt.h" #include "missing/nt.h"
#endif #endif
#ifndef EXTERN
#define EXTERN extern
#endif
#ifdef sparc #ifdef sparc
#define FLUSH_REGISTER_WINDOWS asm("ta 3") #define FLUSH_REGISTER_WINDOWS asm("ta 3")
#else #else
#define FLUSH_REGISTER_WINDOWS /* empty */ #define FLUSH_REGISTER_WINDOWS /* empty */
#endif #endif
#if defined(MSDOS) || defined(NT) || defined(__human68k__) || defined(__MACOS__)
#define RUBY_PATH_SEP ";"
#else
#define RUBY_PATH_SEP ":"
#endif
#if defined(__human68k__) || defined(__CYGWIN32__) #if defined(__human68k__) || defined(__CYGWIN32__)
#undef HAVE_RANDOM #undef HAVE_RANDOM
#undef HAVE_SETITIMER #undef HAVE_SETITIMER

145
dir.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Wed Jan 5 09:51:01 JST 1994 created at: Wed Jan 5 09:51:01 JST 1994
Copyright (C) 1993-1996 Yukihiro Matsumoto Copyright (C) 1993-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
@ -27,6 +27,9 @@
#if HAVE_DIRENT_H #if HAVE_DIRENT_H
# include <dirent.h> # include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name) # define NAMLEN(dirent) strlen((dirent)->d_name)
#elif HAVE_DIRECT_H
# include <direct.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else #else
# define dirent direct # define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen # define NAMLEN(dirent) (dirent)->d_namlen
@ -39,7 +42,7 @@
# if HAVE_NDIR_H # if HAVE_NDIR_H
# include <ndir.h> # include <ndir.h>
# endif # endif
# ifdef NT # if defined(NT) && defined(_MSC_VER)
# include "missing/dir.h" # include "missing/dir.h"
# endif # endif
#endif #endif
@ -50,7 +53,11 @@
char *getenv(); char *getenv();
#endif #endif
static VALUE cDir; #ifdef USE_CWGUSI
# include <sys/errno.h>
#endif
VALUE rb_cDir;
static void static void
free_dir(dir) free_dir(dir)
@ -59,6 +66,8 @@ free_dir(dir)
if (dir) closedir(dir); if (dir) closedir(dir);
} }
static VALUE dir_close _((VALUE));
static VALUE static VALUE
dir_s_open(dir_class, dirname) dir_s_open(dir_class, dirname)
VALUE dir_class, dirname; VALUE dir_class, dirname;
@ -71,7 +80,7 @@ dir_s_open(dir_class, dirname)
dirp = opendir(RSTRING(dirname)->ptr); dirp = opendir(RSTRING(dirname)->ptr);
if (dirp == NULL) { if (dirp == NULL) {
if (errno == EMFILE || errno == ENFILE) { if (errno == EMFILE || errno == ENFILE) {
gc_gc(); rb_gc();
dirp = opendir(RSTRING(dirname)->ptr); dirp = opendir(RSTRING(dirname)->ptr);
} }
if (dirp == NULL) { if (dirp == NULL) {
@ -81,13 +90,17 @@ dir_s_open(dir_class, dirname)
obj = Data_Wrap_Struct(dir_class, 0, free_dir, dirp); obj = Data_Wrap_Struct(dir_class, 0, free_dir, dirp);
if (rb_iterator_p()) {
return rb_ensure(rb_yield, obj, dir_close, obj);
}
return obj; return obj;
} }
static void static void
dir_closed() dir_closed()
{ {
Fail("closed directory"); rb_raise(rb_eIOError, "closed directory");
} }
#define GetDIR(obj, dirp) {\ #define GetDIR(obj, dirp) {\
@ -95,6 +108,27 @@ dir_closed()
if (dirp == NULL) dir_closed();\ if (dirp == NULL) dir_closed();\
} }
static VALUE
dir_read(dir)
VALUE dir;
{
DIR *dirp;
struct dirent *dp;
GetDIR(dir, dirp);
errno = 0;
dp = readdir(dirp);
if (dp)
return rb_tainted_str_new(dp->d_name, NAMLEN(dp));
else if (errno == 0) { /* end of stream */
return Qnil;
}
else {
rb_sys_fail(0);
}
return Qnil; /* not reached */
}
static VALUE static VALUE
dir_each(dir) dir_each(dir)
VALUE dir; VALUE dir;
@ -105,7 +139,7 @@ dir_each(dir)
GetDIR(dir, dirp); GetDIR(dir, dirp);
for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) { for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
file = str_taint(str_new(dp->d_name, NAMLEN(dp))); file = rb_tainted_str_new(dp->d_name, NAMLEN(dp));
rb_yield(file); rb_yield(file);
} }
return dir; return dir;
@ -118,10 +152,10 @@ dir_tell(dir)
DIR *dirp; DIR *dirp;
int pos; int pos;
#if !defined(__CYGWIN32__) #if !defined(__CYGWIN32__) && !defined(__BEOS__)
GetDIR(dir, dirp); GetDIR(dir, dirp);
pos = telldir(dirp); pos = telldir(dirp);
return int2inum(pos); return rb_int2inum(pos);
#else #else
rb_notimplement(); rb_notimplement();
#endif #endif
@ -133,7 +167,7 @@ dir_seek(dir, pos)
{ {
DIR *dirp; DIR *dirp;
#if !defined(__CYGWIN32__) #if !defined(__CYGWIN32__) && !defined(__BEOS__)
GetDIR(dir, dirp); GetDIR(dir, dirp);
seekdir(dirp, NUM2INT(pos)); seekdir(dirp, NUM2INT(pos));
return dir; return dir;
@ -177,8 +211,7 @@ dir_s_chdir(argc, argv, obj)
char *dist = ""; char *dist = "";
rb_secure(2); rb_secure(2);
rb_scan_args(argc, argv, "01", &path); if (rb_scan_args(argc, argv, "01", &path) == 1) {
if (!NIL_P(path)) {
Check_SafeStr(path); Check_SafeStr(path);
dist = RSTRING(path)->ptr; dist = RSTRING(path)->ptr;
} }
@ -190,7 +223,7 @@ dir_s_chdir(argc, argv, obj)
} }
if (chdir(dist) < 0) if (chdir(dist) < 0)
rb_sys_fail(0); rb_sys_fail(dist);
return INT2FIX(0); return INT2FIX(0);
} }
@ -199,32 +232,33 @@ static VALUE
dir_s_getwd(dir) dir_s_getwd(dir)
VALUE dir; VALUE dir;
{ {
extern char *getwd();
char path[MAXPATHLEN]; char path[MAXPATHLEN];
#ifdef HAVE_GETCWD #ifdef HAVE_GETCWD
if (getcwd(path, sizeof(path)) == 0) rb_sys_fail(path); if (getcwd(path, sizeof(path)) == 0) rb_sys_fail(path);
#else #else
extern char *getwd();
if (getwd(path) == 0) rb_sys_fail(path); if (getwd(path) == 0) rb_sys_fail(path);
#endif #endif
return str_taint(str_new2(path)); return rb_tainted_str_new2(path);
} }
static VALUE static VALUE
dir_s_chroot(dir, path) dir_s_chroot(dir, path)
VALUE dir, path; VALUE dir, path;
{ {
#if !defined(DJGPP) && !defined(__CYGWIN32__) && !defined(NT) && !defined(__human68k__) #if !defined(DJGPP) && !defined(NT) && !defined(__human68k__) && !defined(USE_CWGUSI) && !defined(__BEOS__)
rb_secure(2); rb_secure(2);
Check_SafeStr(path); Check_SafeStr(path);
if (chroot(RSTRING(path)->ptr) == -1) if (chroot(RSTRING(path)->ptr) == -1)
rb_sys_fail(0); rb_sys_fail(RSTRING(path)->ptr);
return INT2FIX(0); return INT2FIX(0);
#else #else
rb_notimplement(); rb_notimplement();
return Qnil; /* not reached */
#endif #endif
} }
@ -246,7 +280,7 @@ dir_s_mkdir(argc, argv, obj)
} }
Check_SafeStr(path); Check_SafeStr(path);
#ifndef NT #if !defined(NT) && !defined(USE_CWGUSI)
if (mkdir(RSTRING(path)->ptr, mode) == -1) if (mkdir(RSTRING(path)->ptr, mode) == -1)
rb_sys_fail(RSTRING(path)->ptr); rb_sys_fail(RSTRING(path)->ptr);
#else #else
@ -266,7 +300,7 @@ dir_s_rmdir(obj, dir)
if (rmdir(RSTRING(dir)->ptr) < 0) if (rmdir(RSTRING(dir)->ptr) < 0)
rb_sys_fail(RSTRING(dir)->ptr); rb_sys_fail(RSTRING(dir)->ptr);
return TRUE; return Qtrue;
} }
#define isdelim(c) ((c)==' '||(c)=='\t'||(c)=='\n'||(c)=='\0') #define isdelim(c) ((c)==' '||(c)=='\t'||(c)=='\n'||(c)=='\0')
@ -285,7 +319,7 @@ push_globs(ary, s)
if (fnames == (char**)-1) rb_sys_fail(s); if (fnames == (char**)-1) rb_sys_fail(s);
ff = fnames; ff = fnames;
while (*ff) { while (*ff) {
ary_push(ary, str_taint(str_new2(*ff))); rb_ary_push(ary, rb_tainted_str_new2(*ff));
free(*ff); free(*ff);
ff++; ff++;
} }
@ -341,22 +375,24 @@ push_braces(ary, s)
} }
static VALUE static VALUE
dir_s_glob(dir, vstr) dir_s_glob(dir, str)
VALUE dir, vstr; VALUE dir, str;
{ {
char *p, *pend; char *p, *pend;
char buf[MAXPATHLEN]; char buf[MAXPATHLEN];
char *t, *t0; char *t, *t0;
int nest; int nest;
VALUE ary; VALUE ary;
struct RString *str;
Check_SafeStr(vstr); Check_SafeStr(str);
str = RSTRING(vstr); if (RSTRING(str)->len > MAXPATHLEN) {
ary = ary_new(); rb_raise(rb_eArgError, "pathname too long (%d bytes)",
RSTRING(str)->len);
}
ary = rb_ary_new();
p = str->ptr; p = RSTRING(str)->ptr;
pend = p + str->len; pend = p + RSTRING(str)->len;
while (p < pend) { while (p < pend) {
t = buf; t = buf;
@ -389,37 +425,48 @@ dir_foreach(io, dirname)
{ {
VALUE dir; VALUE dir;
dir = dir_s_open(cDir, dirname); dir = rb_funcall(rb_cDir, rb_intern("open"), 1, dirname);
return rb_ensure(dir_each, dir, dir_close, dir); return rb_ensure(dir_each, dir, dir_close, dir);
} }
static VALUE
dir_entries(io, dirname)
VALUE io, dirname;
{
VALUE dir;
dir = rb_funcall(rb_cDir, rb_intern("open"), 1, dirname);
return rb_ensure(rb_Array, dir, dir_close, dir);
}
void void
Init_Dir() Init_Dir()
{ {
extern VALUE mEnumerable; rb_cDir = rb_define_class("Dir", rb_cObject);
cDir = rb_define_class("Dir", cObject); rb_include_module(rb_cDir, rb_mEnumerable);
rb_include_module(cDir, mEnumerable); rb_define_singleton_method(rb_cDir, "new", dir_s_open, 1);
rb_define_singleton_method(rb_cDir, "open", dir_s_open, 1);
rb_define_singleton_method(rb_cDir, "foreach", dir_foreach, 1);
rb_define_singleton_method(rb_cDir, "entries", dir_entries, 1);
rb_define_singleton_method(cDir, "open", dir_s_open, 1); rb_define_method(rb_cDir,"read", dir_read, 0);
rb_define_singleton_method(cDir, "foreach", dir_foreach, 1); rb_define_method(rb_cDir,"each", dir_each, 0);
rb_define_method(rb_cDir,"rewind", dir_rewind, 0);
rb_define_method(rb_cDir,"tell", dir_tell, 0);
rb_define_method(rb_cDir,"seek", dir_seek, 1);
rb_define_method(rb_cDir,"close", dir_close, 0);
rb_define_method(cDir,"each", dir_each, 0); rb_define_singleton_method(rb_cDir,"chdir", dir_s_chdir, -1);
rb_define_method(cDir,"rewind", dir_rewind, 0); rb_define_singleton_method(rb_cDir,"getwd", dir_s_getwd, 0);
rb_define_method(cDir,"tell", dir_tell, 0); rb_define_singleton_method(rb_cDir,"pwd", dir_s_getwd, 0);
rb_define_method(cDir,"seek", dir_seek, 1); rb_define_singleton_method(rb_cDir,"chroot", dir_s_chroot, 1);
rb_define_method(cDir,"close", dir_close, 0); rb_define_singleton_method(rb_cDir,"mkdir", dir_s_mkdir, -1);
rb_define_singleton_method(rb_cDir,"rmdir", dir_s_rmdir, 1);
rb_define_singleton_method(rb_cDir,"delete", dir_s_rmdir, 1);
rb_define_singleton_method(rb_cDir,"unlink", dir_s_rmdir, 1);
rb_define_singleton_method(cDir,"chdir", dir_s_chdir, -1); rb_define_singleton_method(rb_cDir,"glob", dir_s_glob, 1);
rb_define_singleton_method(cDir,"getwd", dir_s_getwd, 0); rb_define_singleton_method(rb_cDir,"[]", dir_s_glob, 1);
rb_define_singleton_method(cDir,"pwd", dir_s_getwd, 0);
rb_define_singleton_method(cDir,"chroot", dir_s_chroot, 1);
rb_define_singleton_method(cDir,"mkdir", dir_s_mkdir, -1);
rb_define_singleton_method(cDir,"rmdir", dir_s_rmdir, 1);
rb_define_singleton_method(cDir,"delete", dir_s_rmdir, 1);
rb_define_singleton_method(cDir,"unlink", dir_s_rmdir, 1);
rb_define_singleton_method(cDir,"glob", dir_s_glob, 1);
rb_define_singleton_method(cDir,"[]", dir_s_glob, 1);
} }

298
dln.c
View file

@ -6,20 +6,20 @@
$Date$ $Date$
created at: Tue Jan 18 17:05:06 JST 1994 created at: Tue Jan 18 17:05:06 JST 1994
Copyright (C) 1993-1996 Yukihiro Matsumoto Copyright (C) 1993-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
#ifdef _AIX
#pragma alloca
#endif
#include "config.h" #include "config.h"
#include "defines.h" #include "defines.h"
#include "dln.h" #include "dln.h"
char *dln_argv0; char *dln_argv0;
#ifdef _AIX
#pragma alloca
#endif
#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__) #if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
#include <alloca.h> #include <alloca.h>
#endif #endif
@ -36,7 +36,9 @@ void *xrealloc();
#include <stdio.h> #include <stdio.h>
#ifndef NT #ifndef NT
#include <sys/file.h> # ifndef USE_CWGUSI
# include <sys/file.h>
# endif
#else #else
#include "missing/file.h" #include "missing/file.h"
#endif #endif
@ -58,15 +60,25 @@ char *strdup();
char *getenv(); char *getenv();
#endif #endif
#ifdef __MACOS__
# include <TextUtils.h>
# include <CodeFragments.h>
# include <Aliases.h>
#endif
#ifdef __BEOS__
# include <image.h>
#endif
int eaccess(); int eaccess();
#if defined(HAVE_DLOPEN) && !defined(USE_DLN_A_OUT) #if defined(HAVE_DLOPEN) && !defined(USE_DLN_A_OUT) && !defined(__CYGWIN32__) && !defined(_AIX)
/* dynamic load with dlopen() */ /* dynamic load with dlopen() */
# define USE_DLN_DLOPEN # define USE_DLN_DLOPEN
#endif #endif
#ifndef FUNCNAME_PATTERN #ifndef FUNCNAME_PATTERN
# if defined(__hp9000s300) || defined(__NetBSD__) || defined(__BORLANDC__) || defined(__FreeBSD__) || defined(NeXT) # if defined(__hp9000s300) || defined(__NetBSD__) || defined(__BORLANDC__) || (defined(__FreeBSD__) && __FreeBSD__ < 3) || defined(NeXT) || defined(__WATCOMC__)
# define FUNCNAME_PATTERN "_Init_%.200s" # define FUNCNAME_PATTERN "_Init_%.200s"
# else # else
# define FUNCNAME_PATTERN "Init_%.200s" # define FUNCNAME_PATTERN "Init_%.200s"
@ -81,7 +93,11 @@ init_funcname(buf, file)
/* Load the file as an object one */ /* Load the file as an object one */
for (p = file, slash = p-1; *p; p++) /* Find position of last '/' */ for (p = file, slash = p-1; *p; p++) /* Find position of last '/' */
#ifdef __MACOS__
if (*p == ':') slash = p;
#else
if (*p == '/') slash = p; if (*p == '/') slash = p;
#endif
sprintf(buf, FUNCNAME_PATTERN, slash + 1); sprintf(buf, FUNCNAME_PATTERN, slash + 1);
for (p = buf; *p; p++) { /* Delete suffix it it exists */ for (p = buf; *p; p++) { /* Delete suffix it it exists */
@ -407,7 +423,7 @@ load_text_data(fd, hdrp, bss, disp)
} }
static int static int
undef_print(key, value) underb_f_print(key, value)
char *key, *value; char *key, *value;
{ {
fprintf(stderr, " %s\n", key); fprintf(stderr, " %s\n", key);
@ -418,7 +434,7 @@ static void
dln_print_undef() dln_print_undef()
{ {
fprintf(stderr, " Undefined symbols:\n"); fprintf(stderr, " Undefined symbols:\n");
st_foreach(undef_tbl, undef_print, NULL); st_foreach(undef_tbl, underb_f_print, NULL);
} }
static void static void
@ -814,7 +830,7 @@ load_1(fd, disp, need_init)
for (sym = syms; sym<end; sym++) { for (sym = syms; sym<end; sym++) {
char *name = sym->n_un.n_name; char *name = sym->n_un.n_name;
if (name[0] == '_' && sym->n_value >= block) { if (name[0] == '_' && sym->n_value >= block) {
if (strcmp(name+1, "libs_to_be_linked") == 0) { if (strcmp(name+1, "dln_libs_to_be_linked") == 0) {
libs_to_be_linked = (char**)sym->n_value; libs_to_be_linked = (char**)sym->n_value;
} }
else if (strcmp(name+1, buf) == 0) { else if (strcmp(name+1, buf) == 0) {
@ -869,11 +885,11 @@ search_undef(key, value, lib_tbl)
} }
struct symdef { struct symdef {
int str_index; int rb_str_index;
int lib_offset; int lib_offset;
}; };
char *dln_library_path = DLN_DEFAULT_LIB_PATH; char *dln_librrb_ary_path = DLN_DEFAULT_LIB_PATH;
static int static int
load_lib(lib) load_lib(lib)
@ -904,10 +920,10 @@ load_lib(lib)
/* library search path: */ /* library search path: */
/* look for environment variable DLN_LIBRARY_PATH first. */ /* look for environment variable DLN_LIBRARY_PATH first. */
/* then variable dln_library_path. */ /* then variable dln_librrb_ary_path. */
/* if path is still NULL, use "." for path. */ /* if path is still NULL, use "." for path. */
path = getenv("DLN_LIBRARY_PATH"); path = getenv("DLN_LIBRARY_PATH");
if (path == NULL) path = dln_library_path; if (path == NULL) path = dln_librrb_ary_path;
file = dln_find_file(lib, path); file = dln_find_file(lib, path);
fd = open(file, O_RDONLY); fd = open(file, O_RDONLY);
@ -936,7 +952,7 @@ load_lib(lib)
base = (struct symdef*)(data + 1); base = (struct symdef*)(data + 1);
name_base = (char*)(base + nsym) + sizeof(int); name_base = (char*)(base + nsym) + sizeof(int);
while (nsym > 0) { while (nsym > 0) {
char *name = name_base + base->str_index; char *name = name_base + base->rb_str_index;
st_insert(lib_tbl, name, base->lib_offset + sizeof(ahdr)); st_insert(lib_tbl, name, base->lib_offset + sizeof(ahdr));
nsym--; nsym--;
@ -1065,14 +1081,18 @@ dln_sym(name)
#include "dl.h" #include "dl.h"
#endif #endif
#ifdef _AIX #if defined(_AIX)
#include <ctype.h> /* for isdigit() */ #include <ctype.h> /* for isdigit() */
#include <errno.h> /* for global errno */ #include <errno.h> /* for global errno */
#include <sys/ldr.h> #include <sys/ldr.h>
#endif #endif
#ifdef NeXT #ifdef NeXT
/*#include <mach-o/rld.h>*/ #if NS_TARGET_MAJOR < 4
#include <mach-o/rld.h>
#else
#include <mach-o/dyld.h>
#endif
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
@ -1109,21 +1129,28 @@ dln_strerror()
#ifdef _WIN32 #ifdef _WIN32
static char message[1024]; static char message[1024];
int error = GetLastError();
char *p = message;
p += sprintf(message, "%d: ", error);
FormatMessage( FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM, FORMAT_MESSAGE_FROM_SYSTEM,
NULL, NULL,
GetLastError(), error,
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
message, p,
sizeof message, sizeof message - strlen(message),
NULL); NULL);
for (p = message; *p; p++) {
if (*p == '\n' || *p == '\r')
*p = ' ';
}
return message; return message;
#endif #endif
} }
#ifdef _AIX #if defined(_AIX)
static void static void
aix_loaderror(char *pathname) aix_loaderror(char *pathname)
{ {
@ -1166,7 +1193,7 @@ aix_loaderror(char *pathname)
ERRBUF_APPEND("\n"); ERRBUF_APPEND("\n");
} }
errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */ errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
LoadError(errbuf); rb_loaderror(errbuf);
return; return;
} }
#endif #endif
@ -1193,7 +1220,7 @@ dln_load(file)
/* Load file */ /* Load file */
if ((handle = if ((handle =
LoadLibraryExA(winfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) { LoadLibraryExA(winfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) {
printf("LoadLibraryExA\n"); printf("LoadLibraryExA: %s\n", winfile);
goto failed; goto failed;
} }
@ -1229,15 +1256,15 @@ dln_load(file)
void *handle; void *handle;
void (*init_fct)(); void (*init_fct)();
# ifndef RTLD_LAZY #ifndef RTLD_LAZY
# define RTLD_LAZY 1 # define RTLD_LAZY 1
# endif #endif
# ifndef RTLD_GLOBAL #ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0 # define RTLD_GLOBAL 0
# endif #endif
/* Load file */ /* Load file */
if ((handle = dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) { if ((handle = (void*)dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {
goto failed; goto failed;
} }
@ -1260,15 +1287,15 @@ dln_load(file)
flags = BIND_DEFERRED; flags = BIND_DEFERRED;
lib = shl_load(file, flags, 0); lib = shl_load(file, flags, 0);
if (lib == NULL) { if (lib == NULL) {
rb_sys_fail(file); extern int errno;
rb_loaderror("%s - %s", strerror(errno), file);
} }
shl_findsym(&lib, buf, TYPE_PROCEDURE, (void*)&init_fct); shl_findsym(&lib, buf, TYPE_PROCEDURE, (void*)&init_fct);
if (init_fct == NULL) { if (init_fct == NULL) {
shl_findsym(&lib, buf, TYPE_UNDEFINED, (void*)&init_fct); shl_findsym(&lib, buf, TYPE_UNDEFINED, (void*)&init_fct);
if (init_fct == NULL) { if (init_fct == NULL) {
extern int errno;
errno = ENOSYM; errno = ENOSYM;
rb_sys_fail(file); rb_loaderror("%s - %s", strerror(ENOSYM), file);
} }
} }
(*init_fct)(); (*init_fct)();
@ -1276,7 +1303,7 @@ dln_load(file)
} }
#endif /* hpux */ #endif /* hpux */
#ifdef _AIX #if defined(_AIX)
#define DLN_DEFINED #define DLN_DEFINED
{ {
void (*init_fct)(); void (*init_fct)();
@ -1300,6 +1327,7 @@ dln_load(file)
Mi hisho@tasihara.nest.or.jp, Mi hisho@tasihara.nest.or.jp,
and... Miss ARAI Akino(^^;) and... Miss ARAI Akino(^^;)
----------------------------------------------------*/ ----------------------------------------------------*/
#if NS_TARGET_MAJOR < 4 /* NeXTSTEP rld functions */
{ {
unsigned long init_address; unsigned long init_address;
char *object_files[2] = {NULL, NULL}; char *object_files[2] = {NULL, NULL};
@ -1310,12 +1338,12 @@ dln_load(file)
/* Load object file, if return value ==0 , load failed*/ /* Load object file, if return value ==0 , load failed*/
if(rld_load(NULL, NULL, object_files, NULL) == 0) { if(rld_load(NULL, NULL, object_files, NULL) == 0) {
LoadError("Failed to load %.200s", file); rb_loaderror("Failed to load %.200s", file);
} }
/* lookup the initial function */ /* lookup the initial function */
if(rld_lookup(NULL, buf, &init_address) == 0) { if(rld_lookup(NULL, buf, &init_address) == 0) {
LoadError("Failed to lookup Init function %.200s",file); rb_loaderror("Failed to lookup Init function %.200s", file);
} }
/* Cannot call *init_address directory, so copy this value to /* Cannot call *init_address directory, so copy this value to
@ -1325,8 +1353,133 @@ dln_load(file)
(*init_fct)(); (*init_fct)();
return ; return ;
} }
#else/* OPENSTEP dyld functions */
{
int dyld_result ;
NSObjectFileImage obj_file ; /* handle, but not use it */
/* "file" is module file name .
"buf" is initial function name with "_" . */
void (*init_fct)();
dyld_result = NSCreateObjectFileImageFromFile( file, &obj_file );
if (dyld_result != NSObjectFileImageSuccess) {
rb_loaderror("Failed to load %.200s", file);
}
NSLinkModule(obj_file, file, TRUE);
/* lookup the initial function */
/*NSIsSymbolNameDefined require function name without "_" */
if( NSIsSymbolNameDefined( buf + 1 ) ) {
rb_loaderror("Failed to lookup Init function %.200s",file);
}
/* NSLookupAndBindSymbol require function name with "_" !! */
init_fct = NSAddressOfSymbol( NSLookupAndBindSymbol( buf ) );
(*init_fct)();
return ;
}
#endif /* rld or dyld */
#endif #endif
#ifdef __BEOS__
# define DLN_DEFINED
{
status_t err_stat; /* BeOS error status code */
image_id img_id; /* extention module unique id */
void (*init_fct)(); /* initialize function for extention module */
/* load extention module */
img_id = load_add_on(file);
if (img_id <= 0) {
rb_loaderror("Failed to load %.200s", file);
}
/* find symbol for module initialize function. */
/* The Be Book KernelKit Images section described to use
B_SYMBOL_TYPE_TEXT for symbol of function, not
B_SYMBOL_TYPE_CODE. Why ? */
/* strcat(init_fct_symname, "__Fv"); */ /* parameter nothing. */
/* "__Fv" dont need! The Be Book Bug ? */
err_stat = get_image_symbol(img_id, buf,
B_SYMBOL_TYPE_TEXT, &init_fct);
if (err_stat != B_NO_ERROR) {
char real_name[1024];
strcpy(real_name, buf);
strcat(real_name, "__Fv");
err_stat = get_image_symbol(img_id, real_name,
B_SYMBOL_TYPE_TEXT, &init_fct);
}
if ((B_BAD_IMAGE_ID == err_stat) || (B_BAD_INDEX == err_stat)) {
unload_add_on(img_id);
rb_loaderror("Failed to lookup Init function %.200s", file);
}
else if (B_NO_ERROR != err_stat) {
char errmsg[] = "Internal of BeOS version. %.200s (symbol_name = %s)";
unload_add_on(img_id);
rb_loaderror(errmsg, strerror(err_stat), buf);
}
/* call module initialize function. */
(*init_fct)();
return;
}
#endif /* __BEOS__*/
#ifdef __MACOS__
# define DLN_DEFINED
{
OSErr err;
FSSpec libspec;
CFragConnectionID connID;
Ptr mainAddr;
char errMessage[1024];
Boolean isfolder, didsomething;
Str63 fragname;
Ptr symAddr;
CFragSymbolClass class;
void (*init_fct)();
char fullpath[MAXPATHLEN];
strcpy(fullpath, file);
/* resolve any aliases to find the real file */
c2pstr(fullpath);
(void)FSMakeFSSpec(0, 0, fullpath, &libspec);
err = ResolveAliasFile(&libspec, 1, &isfolder, &didsomething);
if ( err ) {
rb_loaderror("Unresolved Alias - %s", file);
}
/* Load the fragment (or return the connID if it is already loaded */
fragname[0] = 0;
err = GetDiskFragment(&libspec, 0, 0, fragname,
kLoadCFrag, &connID, &mainAddr,
errMessage);
if ( err ) {
p2cstr(errMessage);
rb_loaderror("%s - %s",errMessage , file);
}
/* Locate the address of the correct init function */
c2pstr(buf);
err = FindSymbol(connID, buf, &symAddr, &class);
if ( err ) {
rb_loaderror("Unresolved symbols - %s" , file);
}
init_fct = (void (*)())symAddr;
(*init_fct)();
return;
}
#endif /* __MACOS__ */
#ifndef DLN_DEFINED #ifndef DLN_DEFINED
rb_notimplement("dynamic link not supported"); rb_notimplement("dynamic link not supported");
#endif #endif
@ -1335,7 +1488,7 @@ dln_load(file)
#endif #endif
#if !defined(_AIX) && !defined(NeXT) #if !defined(_AIX) && !defined(NeXT)
failed: failed:
LoadError("%s - %s", dln_strerror(), file); rb_loaderror("%s - %s", dln_strerror(), file);
#endif #endif
} }
@ -1346,15 +1499,21 @@ dln_find_exe(fname, path)
char *fname; char *fname;
char *path; char *path;
{ {
if (!path) {
#if defined(__human68k__) #if defined(__human68k__)
if (!path)
path = getenv("path"); path = getenv("path");
if (!path)
path = "/usr/local/bin;/usr/usb;/usr/bin;/bin;.";
#else #else
if (!path) path = getenv("PATH"); path = getenv("PATH");
if (!path) path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:.";
#endif #endif
}
if (!path) {
#if defined(MSDOS) || defined(NT) || defined(__human68k__) || defined(__MACOS__)
path = "/usr/local/bin;/usr/ucb;/usr/bin;/bin;.";
#else
path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:.";
#endif
}
return dln_find_1(fname, path, 1); return dln_find_1(fname, path, 1);
} }
@ -1367,6 +1526,30 @@ dln_find_file(fname, path)
return dln_find_1(fname, path, 0); return dln_find_1(fname, path, 0);
} }
#if defined(__CYGWIN32__)
char *
conv_to_posix_path(win32, posix)
char *win32;
char *posix;
{
char *first = win32;
char *p = win32;
char *dst = posix;
for (p = win32; *p; p++)
if (*p == ';') {
*p = 0;
cygwin32_conv_to_posix_path(first, posix);
posix += strlen(posix);
*posix++ = ':';
first = p + 1;
*p = ';';
}
cygwin32_conv_to_posix_path(first, posix);
return dst;
}
#endif
static char fbuf[MAXPATHLEN]; static char fbuf[MAXPATHLEN];
static char * static char *
@ -1380,15 +1563,24 @@ dln_find_1(fname, path, exe_flag)
register char *bp; register char *bp;
struct stat st; struct stat st;
#if defined(__CYGWIN32__)
char rubypath[MAXPATHLEN];
conv_to_posix_path(path, rubypath);
path = rubypath;
#endif
#ifndef __MACOS__
if (fname[0] == '/') return fname; if (fname[0] == '/') return fname;
if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0) if (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0)
return fname; return fname;
if (exe_flag && strchr(fname, '/')) return fname;
#if defined(MSDOS) || defined(NT) || defined(__human68k__) #if defined(MSDOS) || defined(NT) || defined(__human68k__)
if (fname[0] == '\\') return fname; if (fname[0] == '\\') return fname;
if (fname[1] == ':') return fname; if (strlen(fname) > 2 && fname[1] == ':') return fname;
if (strncmp(".\\", fname, 2) == 0 || strncmp("..\\", fname, 3) == 0) if (strncmp(".\\", fname, 2) == 0 || strncmp("..\\", fname, 3) == 0)
return fname; return fname;
if (exe_flag && strchr(fname, '\\')) return fname;
#endif #endif
#endif /* __MACOS__ */
for (dp = path;; dp = ++ep) { for (dp = path;; dp = ++ep) {
register int l; register int l;
@ -1396,11 +1588,7 @@ dln_find_1(fname, path, exe_flag)
int fspace; int fspace;
/* extract a component */ /* extract a component */
#if !defined(MSDOS) && !defined(NT) && !defined(__human68k__) ep = strchr(dp, RUBY_PATH_SEP[0]);
ep = strchr(dp, ':');
#else
ep = strchr(dp, ';');
#endif
if (ep == NULL) if (ep == NULL)
ep = dp+strlen(dp); ep = dp+strlen(dp);
@ -1417,7 +1605,11 @@ dln_find_1(fname, path, exe_flag)
** take the path literally. ** take the path literally.
*/ */
if (*dp == '~' && (l == 1 || dp[1] == '/')) { if (*dp == '~' && (l == 1 ||
#if defined(MSDOS) || defined(NT) || defined(__human68k__)
dp[1] == '\\' ||
#endif
dp[1] == '/')) {
char *home; char *home;
home = getenv("HOME"); home = getenv("HOME");
@ -1440,7 +1632,11 @@ dln_find_1(fname, path, exe_flag)
/* add a "/" between directory and filename */ /* add a "/" between directory and filename */
if (ep[-1] != '/') if (ep[-1] != '/')
#ifdef __MACOS__
*bp++ = ':';
#else
*bp++ = '/'; *bp++ = '/';
#endif
} }
/* now append the file name */ /* now append the file name */

14
dln.h
View file

@ -11,12 +11,20 @@
#ifndef DLN_H #ifndef DLN_H
#define DLN_H #define DLN_H
char *dln_find_exe(); #ifndef _
char *dln_find_file(); #ifndef __STDC__
# define _(args) ()
#else
# define _(args) args
#endif
#endif
char *dln_find_exe _((char*,char*));
char *dln_find_file _((char*,char*));
#ifdef USE_DLN_A_OUT #ifdef USE_DLN_A_OUT
extern char *dln_argv0; extern char *dln_argv0;
#endif #endif
void dln_load(); void dln_load _((char*));
#endif #endif

137
enum.c
View file

@ -6,13 +6,13 @@
$Date$ $Date$
created at: Fri Oct 1 15:15:19 JST 1993 created at: Fri Oct 1 15:15:19 JST 1993
Copyright (C) 1993-1996 Yukihiro Matsumoto Copyright (C) 1993-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
#include "ruby.h" #include "ruby.h"
VALUE mEnumerable; VALUE rb_mEnumerable;
static ID id_each, id_eqq, id_cmp; static ID id_each, id_eqq, id_cmp;
VALUE VALUE
@ -27,7 +27,7 @@ grep_i(i, arg)
VALUE i, *arg; VALUE i, *arg;
{ {
if (RTEST(rb_funcall(arg[0], id_eqq, 1, i))) { if (RTEST(rb_funcall(arg[0], id_eqq, 1, i))) {
ary_push(arg[1], i); rb_ary_push(arg[1], i);
} }
return Qnil; return Qnil;
} }
@ -46,14 +46,14 @@ static VALUE
enum_grep(obj, pat) enum_grep(obj, pat)
VALUE obj, pat; VALUE obj, pat;
{ {
if (iterator_p()) { if (rb_iterator_p()) {
rb_iterate(rb_each, obj, grep_iter_i, pat); rb_iterate(rb_each, obj, grep_iter_i, pat);
return obj; return obj;
} }
else { else {
VALUE tmp, arg[2]; VALUE tmp, arg[2];
arg[0] = pat; arg[1] = tmp = ary_new(); arg[0] = pat; arg[1] = tmp = rb_ary_new();
rb_iterate(rb_each, obj, grep_i, (VALUE)arg); rb_iterate(rb_each, obj, grep_i, (VALUE)arg);
return tmp; return tmp;
@ -71,7 +71,7 @@ find_i(i, arg)
struct find_arg *arg; struct find_arg *arg;
{ {
if (RTEST(rb_yield(i))) { if (RTEST(rb_yield(i))) {
arg->found = TRUE; arg->found = Qtrue;
arg->val = i; arg->val = i;
rb_iter_break(); rb_iter_break();
} }
@ -88,7 +88,7 @@ enum_find(argc, argv, obj)
VALUE if_none; VALUE if_none;
rb_scan_args(argc, argv, "01", &if_none); rb_scan_args(argc, argv, "01", &if_none);
arg.found = FALSE; arg.found = Qfalse;
rb_iterate(rb_each, obj, find_i, (VALUE)&arg); rb_iterate(rb_each, obj, find_i, (VALUE)&arg);
if (arg.found) { if (arg.found) {
return arg.val; return arg.val;
@ -104,7 +104,7 @@ find_all_i(i, tmp)
VALUE i, tmp; VALUE i, tmp;
{ {
if (RTEST(rb_yield(i))) { if (RTEST(rb_yield(i))) {
ary_push(tmp, i); rb_ary_push(tmp, i);
} }
return Qnil; return Qnil;
} }
@ -115,7 +115,7 @@ enum_find_all(obj)
{ {
VALUE tmp; VALUE tmp;
tmp = ary_new(); tmp = rb_ary_new();
rb_iterate(rb_each, obj, find_all_i, tmp); rb_iterate(rb_each, obj, find_all_i, tmp);
return tmp; return tmp;
@ -125,12 +125,7 @@ static VALUE
collect_i(i, tmp) collect_i(i, tmp)
VALUE i, tmp; VALUE i, tmp;
{ {
VALUE retval; rb_ary_push(tmp, rb_yield(i));
retval = rb_yield(i);
if (RTEST(retval)) {
ary_push(tmp, retval);
}
return Qnil; return Qnil;
} }
@ -140,37 +135,17 @@ enum_collect(obj)
{ {
VALUE tmp; VALUE tmp;
tmp = ary_new(); tmp = rb_ary_new();
rb_iterate(rb_each, obj, collect_i, tmp); rb_iterate(rb_each, obj, collect_i, tmp);
return tmp; return tmp;
} }
static VALUE
reverse_i(i, tmp)
VALUE i, tmp;
{
ary_unshift(tmp, i);
return Qnil;
}
static VALUE
enum_reverse(obj)
VALUE obj;
{
VALUE tmp;
tmp = ary_new();
rb_iterate(rb_each, obj, reverse_i, tmp);
return tmp;
}
static VALUE static VALUE
enum_all(i, ary) enum_all(i, ary)
VALUE i, ary; VALUE i, ary;
{ {
ary_push(ary, i); rb_ary_push(ary, i);
return Qnil; return Qnil;
} }
@ -180,7 +155,7 @@ enum_to_a(obj)
{ {
VALUE ary; VALUE ary;
ary = ary_new(); ary = rb_ary_new();
rb_iterate(rb_each, obj, enum_all, ary); rb_iterate(rb_each, obj, enum_all, ary);
return ary; return ary;
@ -190,7 +165,7 @@ static VALUE
enum_sort(obj) enum_sort(obj)
VALUE obj; VALUE obj;
{ {
return ary_sort(enum_to_a(obj)); return rb_ary_sort(enum_to_a(obj));
} }
static VALUE static VALUE
@ -203,7 +178,7 @@ min_i(i, min)
*min = i; *min = i;
else { else {
cmp = rb_funcall(i, id_cmp, 1, *min); cmp = rb_funcall(i, id_cmp, 1, *min);
if (FIX2INT(cmp) < 0) if (FIX2LONG(cmp) < 0)
*min = i; *min = i;
} }
return Qnil; return Qnil;
@ -218,8 +193,8 @@ min_ii(i, min)
if (NIL_P(*min)) if (NIL_P(*min))
*min = i; *min = i;
else { else {
cmp = rb_yield(assoc_new(i, *min)); cmp = rb_yield(rb_assoc_new(i, *min));
if (FIX2INT(cmp) < 0) if (FIX2LONG(cmp) < 0)
*min = i; *min = i;
} }
return Qnil; return Qnil;
@ -231,7 +206,7 @@ enum_min(obj)
{ {
VALUE min = Qnil; VALUE min = Qnil;
rb_iterate(rb_each, obj, iterator_p()?min_ii:min_i, (VALUE)&min); rb_iterate(rb_each, obj, rb_iterator_p()?min_ii:min_i, (VALUE)&min);
return min; return min;
} }
@ -245,7 +220,7 @@ max_i(i, max)
*max = i; *max = i;
else { else {
cmp = rb_funcall(i, id_cmp, 1, *max); cmp = rb_funcall(i, id_cmp, 1, *max);
if (FIX2INT(cmp) > 0) if (FIX2LONG(cmp) > 0)
*max = i; *max = i;
} }
return Qnil; return Qnil;
@ -260,8 +235,8 @@ max_ii(i, max)
if (NIL_P(*max)) if (NIL_P(*max))
*max = i; *max = i;
else { else {
cmp = rb_yield(assoc_new(i, *max)); cmp = rb_yield(rb_assoc_new(i, *max));
if (FIX2INT(cmp) > 0) if (FIX2LONG(cmp) > 0)
*max = i; *max = i;
} }
return Qnil; return Qnil;
@ -273,7 +248,7 @@ enum_max(obj)
{ {
VALUE max = Qnil; VALUE max = Qnil;
rb_iterate(rb_each, obj, iterator_p()?max_ii:max_i, (VALUE)&max); rb_iterate(rb_each, obj, rb_iterator_p()?max_ii:max_i, (VALUE)&max);
return max; return max;
} }
@ -333,8 +308,8 @@ enum_member(obj, val)
iv.i = 0; iv.i = 0;
iv.v = val; iv.v = val;
rb_iterate(rb_each, obj, member_i, (VALUE)&iv); rb_iterate(rb_each, obj, member_i, (VALUE)&iv);
if (iv.i) return TRUE; if (iv.i) return Qtrue;
return FALSE; return Qfalse;
} }
static VALUE static VALUE
@ -346,7 +321,7 @@ length_i(i, length)
return Qnil; return Qnil;
} }
VALUE static VALUE
enum_length(obj) enum_length(obj)
VALUE obj; VALUE obj;
{ {
@ -356,26 +331,58 @@ enum_length(obj)
return INT2FIX(length); return INT2FIX(length);
} }
VALUE
rb_enum_length(obj)
VALUE obj;
{
return enum_length(obj);
}
static VALUE
each_with_index_i(val, indexp)
VALUE val;
int *indexp;
{
#if 1
rb_yield(rb_assoc_new(val, INT2FIX(*indexp)));
#else
rb_yield(rb_ary_concat(rb_Array(val), INT2FIX(*indexp)));
#endif
(*indexp)++;
return Qnil;
}
static VALUE
enum_each_with_index(obj)
VALUE obj;
{
int index = 0;
rb_iterate(rb_each, obj, each_with_index_i, (VALUE)&index);
return Qnil;
}
void void
Init_Enumerable() Init_Enumerable()
{ {
mEnumerable = rb_define_module("Enumerable"); rb_mEnumerable = rb_define_module("Enumerable");
rb_define_method(mEnumerable,"to_a", enum_to_a, 0); rb_define_method(rb_mEnumerable,"to_a", enum_to_a, 0);
rb_define_method(rb_mEnumerable,"entries", enum_to_a, 0);
rb_define_method(mEnumerable,"sort", enum_sort, 0); rb_define_method(rb_mEnumerable,"sort", enum_sort, 0);
rb_define_method(mEnumerable,"grep", enum_grep, 1); rb_define_method(rb_mEnumerable,"grep", enum_grep, 1);
rb_define_method(mEnumerable,"find", enum_find, -1); rb_define_method(rb_mEnumerable,"find", enum_find, -1);
rb_define_method(mEnumerable,"find_all", enum_find_all, 0); rb_define_method(rb_mEnumerable,"find_all", enum_find_all, 0);
rb_define_method(mEnumerable,"collect", enum_collect, 0); rb_define_method(rb_mEnumerable,"collect", enum_collect, 0);
rb_define_method(mEnumerable,"reverse", enum_reverse, 0); rb_define_method(rb_mEnumerable,"min", enum_min, 0);
rb_define_method(mEnumerable,"min", enum_min, 0); rb_define_method(rb_mEnumerable,"max", enum_max, 0);
rb_define_method(mEnumerable,"max", enum_max, 0); rb_define_method(rb_mEnumerable,"index", enum_index, 1);
rb_define_method(mEnumerable,"index", enum_index, 1); rb_define_method(rb_mEnumerable,"member?", enum_member, 1);
rb_define_method(mEnumerable,"member?", enum_member, 1); rb_define_method(rb_mEnumerable,"include?", enum_member, 1);
rb_define_method(mEnumerable,"include?", enum_member, 1); rb_define_method(rb_mEnumerable,"length", enum_length, 0);
rb_define_method(mEnumerable,"length", enum_length, 0); rb_define_method(rb_mEnumerable,"size", enum_length, 0);
rb_define_method(mEnumerable,"size", enum_length, 0); rb_define_method(rb_mEnumerable,"each_with_index", enum_each_with_index, 0);
id_eqq = rb_intern("==="); id_eqq = rb_intern("===");
id_each = rb_intern("each"); id_each = rb_intern("each");

11
env.h
View file

@ -12,6 +12,7 @@
#define ENV_H #define ENV_H
extern struct FRAME { extern struct FRAME {
VALUE self;
int argc; int argc;
VALUE *argv; VALUE *argv;
ID last_func; ID last_func;
@ -21,16 +22,16 @@ extern struct FRAME {
char *file; char *file;
int line; int line;
int iter; int iter;
} *the_frame; } *ruby_frame;
void gc_mark_frame _((struct FRAME *)); void rb_gc_mark_frame _((struct FRAME *));
extern struct SCOPE { extern struct SCOPE {
struct RBasic super; struct RBasic super;
ID *local_tbl; ID *local_tbl;
VALUE *local_vars; VALUE *local_vars;
int flag; int flag;
} *the_scope; } *ruby_scope;
#define SCOPE_ALLOCA 0 #define SCOPE_ALLOCA 0
#define SCOPE_MALLOC 1 #define SCOPE_MALLOC 1
@ -38,7 +39,7 @@ extern struct SCOPE {
extern int rb_in_eval; extern int rb_in_eval;
extern VALUE the_class; extern VALUE ruby_class;
struct RVarmap { struct RVarmap {
struct RBasic super; struct RBasic super;
@ -46,6 +47,6 @@ struct RVarmap {
VALUE val; VALUE val;
struct RVarmap *next; struct RVarmap *next;
}; };
extern struct RVarmap *the_dyna_vars; extern struct RVarmap *ruby_dyna_vars;
#endif /* ENV_H */ #endif /* ENV_H */

648
error.c
View file

@ -6,56 +6,46 @@
$Date$ $Date$
created at: Mon Aug 9 16:11:34 JST 1993 created at: Mon Aug 9 16:11:34 JST 1993
Copyright (C) 1993-1996 Yukihiro Matsumoto Copyright (C) 1993-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
#include "ruby.h" #include "ruby.h"
#include "env.h" #include "env.h"
#include <stdio.h> #include <stdio.h>
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
#include <varargs.h> #include <varargs.h>
#define va_init_list(a,b) va_start(a)
#endif
extern char *sourcefile; #ifdef USE_CWGUSI
extern int sourceline; #include <sys/errno.h>
int sys_nerr = 256;
#endif
int nerrs; int ruby_nerrs;
static void static void
err_sprintf(buf, fmt, args) err_snprintf(buf, len, fmt, args)
char *buf, *fmt; char *buf, *fmt;
int len;
va_list args; va_list args;
{ {
if (!sourcefile) { if (!ruby_sourcefile) {
vsprintf(buf, fmt, args); vsnprintf(buf, len, fmt, args);
} }
else { else {
sprintf(buf, "%s:%d: ", sourcefile, sourceline); int n = snprintf(buf, len, "%s:%d: ", ruby_sourcefile, ruby_sourceline);
vsprintf((char*)buf+strlen(buf), fmt, args); if (len > n) {
} vsnprintf((char*)buf+n, len-n, fmt, args);
} }
static void
err_append(s)
char *s;
{
extern VALUE errinfo;
if (rb_in_eval) {
if (NIL_P(errinfo)) {
errinfo = str_new2(s);
}
else {
str_cat(errinfo, "\n", 1);
str_cat(errinfo, s, strlen(s));
}
}
else {
fputs(s, stderr);
fputs("\n", stderr);
fflush(stderr);
} }
} }
static void err_append _((char*));
static void static void
err_print(fmt, args) err_print(fmt, args)
char *fmt; char *fmt;
@ -63,66 +53,102 @@ err_print(fmt, args)
{ {
char buf[BUFSIZ]; char buf[BUFSIZ];
err_sprintf(buf, fmt, args); err_snprintf(buf, BUFSIZ, fmt, args);
err_append(buf); err_append(buf);
} }
void void
Error(fmt, va_alist) #ifdef HAVE_STDARG_PROTOTYPES
rb_compile_error(char *fmt, ...)
#else
rb_compile_error(fmt, va_alist)
char *fmt; char *fmt;
va_dcl va_dcl
#endif
{ {
va_list args; va_list args;
va_start(args); va_init_list(args, fmt);
err_print(fmt, args); err_print(fmt, args);
va_end(args); va_end(args);
nerrs++; ruby_nerrs++;
} }
void void
Error_Append(fmt, va_alist) #ifdef HAVE_STDARG_PROTOTYPES
rb_compile_error_append(char *fmt, ...)
#else
rb_compile_error_append(fmt, va_alist)
char *fmt; char *fmt;
va_dcl va_dcl
#endif
{ {
va_list args; va_list args;
char buf[BUFSIZ]; char buf[BUFSIZ];
va_start(args); va_init_list(args, fmt);
vsprintf(buf, fmt, args); vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args); va_end(args);
err_append(buf); err_append(buf);
} }
void void
Warning(fmt, va_alist) #ifdef HAVE_STDARG_PROTOTYPES
rb_warn(char *fmt, ...)
#else
rb_warn(fmt, va_alist)
char *fmt; char *fmt;
va_dcl va_dcl
#endif
{ {
char buf[BUFSIZ]; char buf[BUFSIZ];
va_list args; va_list args;
if (!RTEST(verbose)) return; snprintf(buf, BUFSIZ, "warning: %s", fmt);
sprintf(buf, "warning: %s", fmt); va_init_list(args, fmt);
err_print(buf, args);
va_end(args);
}
va_start(args); /* rb_warning() reports only in verbose mode */
void
#ifdef HAVE_STDARG_PROTOTYPES
rb_warning(char *fmt, ...)
#else
rb_warning(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
char buf[BUFSIZ];
va_list args;
if (!RTEST(rb_verbose)) return;
snprintf(buf, BUFSIZ, "warning: %s", fmt);
va_init_list(args, fmt);
err_print(buf, args); err_print(buf, args);
va_end(args); va_end(args);
} }
void void
Bug(fmt, va_alist) #ifdef HAVE_STDARG_PROTOTYPES
rb_bug(char *fmt, ...)
#else
rb_bug(fmt, va_alist)
char *fmt; char *fmt;
va_dcl va_dcl
#endif
{ {
char buf[BUFSIZ]; char buf[BUFSIZ];
va_list args; va_list args;
sprintf(buf, "[BUG] %s", fmt); snprintf(buf, BUFSIZ, "[BUG] %s", fmt);
rb_in_eval = 0; rb_in_eval = 0;
va_start(args); va_init_list(args, fmt);
err_print(buf, args); err_print(buf, args);
va_end(args); va_end(args);
abort(); abort();
@ -156,94 +182,133 @@ static struct types {
-1, 0, -1, 0,
}; };
extern void TypeError();
void void
rb_check_type(x, t) rb_check_type(x, t)
VALUE x; VALUE x;
int t; int t;
{ {
struct types *type = builtin_types; struct types *type = builtin_types;
int tt = TYPE(x);
if (TYPE(x)!=(t)) { if (tt != t) {
while (type->type >= 0) { while (type->type >= 0) {
if (type->type == t) { if (type->type == t) {
TypeError("wrong argument type %s (expected %s)", char *etype;
rb_class2name(CLASS_OF(x)), type->name);
if (NIL_P(x)) {
etype = "nil";
}
else if (FIXNUM_P(x)) {
etype = "Fixnum";
}
else if (rb_special_const_p(x)) {
etype = RSTRING(rb_obj_as_string(x))->ptr;
}
else {
etype = rb_class2name(CLASS_OF(x));
}
rb_raise(rb_eTypeError, "wrong argument type %s (expected %s)",
etype, type->name);
} }
type++; type++;
} }
Bug("unknown type 0x%x", t); rb_bug("unknown type 0x%x", t);
} }
} }
/* exception classes */ /* exception classes */
#include "errno.h" #include <errno.h>
extern VALUE cString; VALUE rb_eException;
VALUE eGlobalExit, eException; VALUE rb_eSystemExit, rb_eInterrupt, rb_eFatal;
VALUE eSystemExit, eInterrupt, eFatal; VALUE rb_eStandardError;
VALUE eRuntimeError; VALUE rb_eRuntimeError;
VALUE eSyntaxError; VALUE rb_eSyntaxError;
VALUE eTypeError; VALUE rb_eTypeError;
VALUE eArgError; VALUE rb_eArgError;
VALUE eNameError; VALUE rb_eNameError;
VALUE eIndexError; VALUE rb_eIndexError;
VALUE eNotImpError; VALUE rb_eLoadError;
VALUE eLoadError; VALUE rb_eSecurityError;
VALUE eSecurityError; VALUE rb_eNotImpError;
VALUE eSystemCallError; VALUE rb_eSystemCallError;
VALUE mErrno; VALUE rb_mErrno;
VALUE VALUE
exc_new(etype, ptr, len) rb_exc_new(etype, ptr, len)
VALUE etype; VALUE etype;
char *ptr; char *ptr;
UINT len; int len;
{ {
NEWOBJ(exc, struct RString); VALUE exc = rb_obj_alloc(etype);
OBJSETUP(exc, etype, T_STRING);
exc->len = len; rb_iv_set(exc, "mesg", rb_str_new(ptr, len));
exc->orig = 0; return exc;
exc->ptr = ALLOC_N(char,len+1);
if (ptr) {
memcpy(exc->ptr, ptr, len);
}
exc->ptr[len] = '\0';
return (VALUE)exc;
} }
VALUE VALUE
exc_new2(etype, s) rb_exc_new2(etype, s)
VALUE etype; VALUE etype;
char *s; char *s;
{ {
return exc_new(etype, s, strlen(s)); return rb_exc_new(etype, s, strlen(s));
} }
VALUE VALUE
exc_new3(etype, str) rb_exc_new3(etype, str)
VALUE etype, str; VALUE etype, str;
{ {
Check_Type(str, T_STRING); char *s;
return exc_new(etype, RSTRING(str)->ptr, RSTRING(str)->len); int len;
s = str2cstr(str, &len);
return rb_exc_new(etype, s, len);
} }
static VALUE static VALUE
exc_s_new(argc, argv, etype) exc_initialize(argc, argv, exc)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE etype; VALUE exc;
{ {
VALUE arg; VALUE mesg;
if (rb_scan_args(argc, argv, "01", &arg) == 0) { if (rb_scan_args(argc, argv, "01", &mesg) == 1) {
return exc_new(etype, 0, 0); STR2CSTR(mesg); /* ensure mesg can be converted to String */
} }
Check_Type(arg, T_STRING); rb_iv_set(exc, "mesg", mesg);
return exc_new3(etype, arg);
return exc;
}
static VALUE
exc_new(argc, argv, self)
int argc;
VALUE *argv;
VALUE self;
{
VALUE etype, exc;
if (argc == 1 && self == argv[0]) return self;
etype = CLASS_OF(self);
while (FL_TEST(etype, FL_SINGLETON)) {
etype = RCLASS(etype)->super;
}
exc = rb_obj_alloc(etype);
rb_obj_call_init(exc);
return exc;
}
static VALUE
exc_to_s(exc)
VALUE exc;
{
VALUE mesg = rb_iv_get(exc, "mesg");
if (NIL_P(mesg)) return rb_class_path(CLASS_OF(exc));
return mesg;
} }
static VALUE static VALUE
@ -253,185 +318,314 @@ exc_inspect(exc)
VALUE str, klass; VALUE str, klass;
klass = CLASS_OF(exc); klass = CLASS_OF(exc);
exc = rb_obj_as_string(exc);
if (RSTRING(exc)->len == 0) { if (RSTRING(exc)->len == 0) {
return rb_class_path(klass); return rb_str_dup(rb_class_path(klass));
} }
str = str_new2("#<"); str = rb_str_new2("#<");
klass = rb_class_path(klass); klass = rb_class_path(klass);
str_cat(str, RSTRING(klass)->ptr, RSTRING(klass)->len); rb_str_concat(str, klass);
str_cat(str, ":", 1); rb_str_cat(str, ":", 1);
str_cat(str, RSTRING(exc)->ptr, RSTRING(exc)->len); rb_str_concat(str, exc);
str_cat(str, ">", 1); rb_str_cat(str, ">", 1);
return str; return str;
} }
static VALUE
exc_backtrace(exc)
VALUE exc;
{
return rb_iv_get(exc, "bt");
}
static VALUE
check_backtrace(bt)
VALUE bt;
{
int i;
static char *err = "backtrace must be Array of String";
if (!NIL_P(bt)) {
int t = TYPE(bt);
if (t == T_STRING) return rb_ary_new3(1, bt);
if (t != T_ARRAY) {
rb_raise(rb_eTypeError, err);
}
for (i=0;i<RARRAY(bt)->len;i++) {
if (TYPE(RARRAY(bt)->ptr[i]) != T_STRING) {
rb_raise(rb_eTypeError, err);
}
}
}
return bt;
}
static VALUE
exc_set_backtrace(exc, bt)
VALUE exc;
{
return rb_iv_set(exc, "bt", check_backtrace(bt));
}
static VALUE static VALUE
exception(argc, argv) exception(argc, argv)
int argc; int argc;
VALUE *argv; VALUE *argv;
{ {
void ArgError();
VALUE v = Qnil; VALUE v = Qnil;
VALUE etype = rb_eStandardError;
int i; int i;
ID id; ID id;
if (argc == 0) { if (argc == 0) {
ArgError("wrong # of arguments"); rb_raise(rb_eArgError, "wrong # of arguments");
}
rb_warn("Exception() is now obsolete");
if (TYPE(argv[argc-1]) == T_CLASS) {
etype = argv[argc-1];
argc--;
if (!rb_funcall(etype, '<', 1, rb_eException)) {
rb_raise(rb_eTypeError, "exception should be subclass of Exception");
}
} }
for (i=0; i<argc; i++) { /* argument check */ for (i=0; i<argc; i++) { /* argument check */
id = rb_to_id(argv[i]); id = rb_to_id(argv[i]);
if (!rb_id2name(id)) { if (!rb_id2name(id)) {
ArgError("argument needs to be symbol or string"); rb_raise(rb_eArgError, "argument needs to be symbol or string");
} }
if (!rb_is_const_id(id)) { if (!rb_is_const_id(id)) {
ArgError("identifier %s needs to be constant", rb_id2name(id)); rb_raise(rb_eArgError, "identifier `%s' needs to be constant",
rb_id2name(id));
} }
} }
for (i=0; i<argc; i++) { for (i=0; i<argc; i++) {
v = rb_define_class_under(the_class, rb_id2name(rb_to_id(argv[i])), eException); v = rb_define_class_under(ruby_class,
rb_id2name(rb_to_id(argv[i])),
rb_eStandardError);
} }
return v; return v;
} }
#ifdef __BEOS__
typedef struct {
VALUE *list;
size_t n;
} syserr_list_entry;
typedef struct {
int ix;
size_t n;
} syserr_index_entry;
static VALUE syserr_list_b_general[16+1];
static VALUE syserr_list_b_os0[2+1];
static VALUE syserr_list_b_os1[5+1];
static VALUE syserr_list_b_os2[2+1];
static VALUE syserr_list_b_os3[3+1];
static VALUE syserr_list_b_os4[1+1];
static VALUE syserr_list_b_app[15+1];
static VALUE syserr_list_b_interface[0+1];
static VALUE syserr_list_b_media[8+1];
static VALUE syserr_list_b_midi[0+1];
static VALUE syserr_list_b_storage[15+1];
static VALUE syserr_list_b_posix[38+1];
static VALUE syserr_list_b_mail[8+1];
static VALUE syserr_list_b_print[1+1];
static VALUE syserr_list_b_device[14+1];
# define SYSERR_LIST_B(n) {(n), sizeof(n)/sizeof(VALUE)}
static const syserr_list_entry syserr_list[] = {
SYSERR_LIST_B(syserr_list_b_general),
SYSERR_LIST_B(syserr_list_b_os0),
SYSERR_LIST_B(syserr_list_b_os1),
SYSERR_LIST_B(syserr_list_b_os2),
SYSERR_LIST_B(syserr_list_b_os3),
SYSERR_LIST_B(syserr_list_b_os4),
SYSERR_LIST_B(syserr_list_b_app),
SYSERR_LIST_B(syserr_list_b_interface),
SYSERR_LIST_B(syserr_list_b_media),
SYSERR_LIST_B(syserr_list_b_midi),
SYSERR_LIST_B(syserr_list_b_storage),
SYSERR_LIST_B(syserr_list_b_posix),
SYSERR_LIST_B(syserr_list_b_mail),
SYSERR_LIST_B(syserr_list_b_print),
SYSERR_LIST_B(syserr_list_b_device),
};
# undef SYSERR_LIST_B
static const syserr_index_entry syserr_index[]= {
{0, 1}, {1, 5}, {6, 1}, {7, 1}, {8, 1}, {9, 1}, {10, 1}, {11, 1},
{12, 1}, {13, 1}, {14, 1}, {0, 0},
};
#else
static VALUE *syserr_list; static VALUE *syserr_list;
#endif
#ifndef NT #ifndef NT
extern int sys_nerr; extern int sys_nerr;
#endif #endif
static void static VALUE
set_syserr(i, name) set_syserr(i, name)
int i; int i;
char *name; char *name;
{ {
#ifdef __BEOS__
VALUE *list;
int ix, offset;
#endif
VALUE error = rb_define_class_under(rb_mErrno, name, rb_eSystemCallError);
rb_define_const(error, "Errno", INT2FIX(i));
#ifdef __BEOS__
i -= B_GENERAL_ERROR_BASE;
ix = (i >> 12) & 0xf;
offset = (i >> 8) & 0xf;
if (offset < syserr_index[ix].n) {
ix = syserr_index[ix].ix;
if ((i & 0xff) < syserr_list[ix + offset].n) {
list = syserr_list[ix + offset].list;
list[i & 0xff] = error;
rb_global_variable(&list[i & 0xff]);
}
}
#else
if (i <= sys_nerr) { if (i <= sys_nerr) {
syserr_list[i] = rb_define_class_under(mErrno, name, eSystemCallError); syserr_list[i] = error;
rb_global_variable(&syserr_list[i]);
} }
#endif
return error;
} }
static void init_syserr(); static VALUE
syserr_errno(self)
VALUE self;
{
return rb_iv_get(self, "errno");
}
#ifdef __BEOS__
static VALUE
get_syserr(int i)
{
VALUE *list;
int ix, offset;
i -= B_GENERAL_ERROR_BASE;
ix = (i >> 12) & 0xf;
offset = (i >> 8) & 0xf;
if (offset < syserr_index[ix].n) {
ix = syserr_index[ix].ix;
if ((i & 0xff) < syserr_list[ix + offset].n) {
list = syserr_list[ix + offset].list;
return list[i & 0xff];
}
}
return 0;
}
#endif /* __BEOS__ */
static void init_syserr _((void));
void void
Init_Exception() Init_Exception()
{ {
eGlobalExit = rb_define_class("GlobalExit", cString); rb_eException = rb_define_class("Exception", rb_cObject);
rb_define_singleton_method(eGlobalExit, "new", exc_s_new, -1); rb_define_method(rb_eException, "new", exc_new, -1);
rb_define_method(eGlobalExit, "inspect", exc_inspect, 0); rb_define_method(rb_eException, "initialize", exc_initialize, -1);
rb_define_method(rb_eException, "to_s", exc_to_s, 0);
rb_define_method(rb_eException, "to_str", exc_to_s, 0);
rb_define_method(rb_eException, "message", exc_to_s, 0);
rb_define_method(rb_eException, "inspect", exc_inspect, 0);
rb_define_method(rb_eException, "backtrace", exc_backtrace, 0);
rb_define_method(rb_eException, "set_backtrace", exc_set_backtrace, 1);
eSystemExit = rb_define_class("SystemExit", eGlobalExit); rb_eSystemExit = rb_define_class("SystemExit", rb_eException);
eFatal = rb_define_class("fatal", eGlobalExit); rb_eFatal = rb_define_class("fatal", rb_eException);
eInterrupt = rb_define_class("Interrupt", eGlobalExit); rb_eInterrupt = rb_define_class("Interrupt", rb_eException);
eException = rb_define_class("Exception", eGlobalExit); rb_eStandardError = rb_define_class("StandardError", rb_eException);
eSyntaxError = rb_define_class("SyntaxError", eException); rb_eSyntaxError = rb_define_class("SyntaxError", rb_eStandardError);
eTypeError = rb_define_class("TypeError", eException); rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
eArgError = rb_define_class("ArgumentError", eException); rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
eNameError = rb_define_class("NameError", eException); rb_eNameError = rb_define_class("NameError", rb_eStandardError);
eIndexError = rb_define_class("IndexError", eException); rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
eNotImpError = rb_define_class("NotImplementError", eException); rb_eLoadError = rb_define_class("LoadError", rb_eStandardError);
eLoadError = rb_define_class("LoadError", eException);
eRuntimeError = rb_define_class("RuntimeError", eException); rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
eSecurityError = rb_define_class("SecurityError", eException); rb_eSecurityError = rb_define_class("SecurityError", rb_eStandardError);
rb_eNotImpError = rb_define_class("NotImplementError", rb_eException);
init_syserr(); init_syserr();
rb_define_global_function("Exception", exception, -1); rb_define_global_function("Exception", exception, -1);
} }
#define RAISE_ERROR(class) {\
va_list args;\
char buf[BUFSIZ];\
\
va_start(args);\
vsprintf(buf, fmt, args);\
va_end(args);\
\
rb_raise(exc_new2(class, buf));\
}
void void
Raise(exc, fmt, va_alist) #ifdef HAVE_STDARG_PROTOTYPES
rb_raise(VALUE exc, char *fmt, ...)
#else
rb_raise(exc, fmt, va_alist)
VALUE exc; VALUE exc;
char *fmt; char *fmt;
va_dcl va_dcl
#endif
{ {
RAISE_ERROR(exc); va_list args;
char buf[BUFSIZ];
va_init_list(args,fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args);
rb_exc_raise(rb_exc_new2(exc, buf));
} }
void void
TypeError(fmt, va_alist) #ifdef HAVE_STDARG_PROTOTYPES
rb_loaderror(char *fmt, ...)
#else
rb_loaderror(fmt, va_alist)
char *fmt; char *fmt;
va_dcl va_dcl
#endif
{ {
RAISE_ERROR(eTypeError); va_list args;
} char buf[BUFSIZ];
void va_init_list(args, fmt);
ArgError(fmt, va_alist) vsnprintf(buf, BUFSIZ, fmt, args);
char *fmt; va_end(args);
va_dcl rb_exc_raise(rb_exc_new2(rb_eLoadError, buf));
{
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
Fail(fmt, va_alist)
char *fmt;
va_dcl
{
RAISE_ERROR(eRuntimeError);
} }
void void
rb_notimplement() rb_notimplement()
{ {
Raise(eNotImpError, rb_raise(rb_eNotImpError,
"The %s() function is unimplemented on this machine", "The %s() function is unimplemented on this machine",
rb_id2name(the_frame->last_func)); rb_id2name(ruby_frame->last_func));
} }
void void
LoadError(fmt, va_alist) #ifdef HAVE_STDARG_PROTOTYPES
char *fmt; rb_fatal(char *fmt, ...)
va_dcl #else
{ rb_fatal(fmt, va_alist)
RAISE_ERROR(eLoadError);
}
void
Fatal(fmt, va_alist)
char *fmt; char *fmt;
va_dcl va_dcl
#endif
{ {
va_list args; va_list args;
char buf[BUFSIZ]; char buf[BUFSIZ];
va_start(args); va_init_list(args, fmt);
vsprintf(buf, fmt, args); vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args); va_end(args);
rb_in_eval = 0; rb_in_eval = 0;
rb_fatal(exc_new2(eFatal, buf)); rb_exc_fatal(rb_exc_new2(rb_eFatal, buf));
} }
void void
@ -441,32 +635,79 @@ rb_sys_fail(mesg)
#ifndef NT #ifndef NT
char *strerror(); char *strerror();
#endif #endif
char buf[BUFSIZ]; char *err;
char *buf;
extern int errno; extern int errno;
int n = errno; int n = errno;
VALUE ee;
if (RTEST(mesg)) err = strerror(errno);
sprintf(buf, "%s - %s", strerror(errno), mesg); if (mesg) {
else buf = ALLOCA_N(char, strlen(err)+strlen(mesg)+4);
sprintf(buf, "%s", strerror(errno)); sprintf(buf, "%s - %s", err, mesg);
}
else {
buf = ALLOCA_N(char, strlen(err)+1);
strcpy(buf, err);
}
errno = 0; errno = 0;
#ifdef __BEOS__
ee = get_syserr(n);
if (!ee) {
char name[6];
sprintf(name, "E%03d", n);
ee = set_syserr(n, name);
}
#else
# ifdef USE_CWGUSI
if (n < 0) {
int macoserr_index = sys_nerr - 1;
if (!syserr_list[macoserr_index]) {
char name[6];
sprintf(name, "E%03d", macoserr_index);
ee = set_syserr(macoserr_index, name);
}
}
else
#endif /* USE_CWGUSI */
if (n > sys_nerr || !syserr_list[n]) { if (n > sys_nerr || !syserr_list[n]) {
char name[6]; char name[6];
sprintf(name, "E%03d", n); sprintf(name, "E%03d", n);
set_syserr(n, name); ee = set_syserr(n, name);
} }
rb_raise(exc_new2(syserr_list[n], buf)); else {
ee = syserr_list[n];
}
ee = rb_exc_new2(ee, buf);
#endif
rb_iv_set(ee, "errno", INT2FIX(n));
rb_exc_raise(ee);
} }
static void static void
init_syserr() init_syserr()
{ {
eSystemCallError = rb_define_class("SystemCallError", eException); #ifdef __BEOS__
mErrno = rb_define_module("Errno"); int i, ix, offset;
#endif
rb_eSystemCallError = rb_define_class("SystemCallError", rb_eStandardError);
rb_define_method(rb_eSystemCallError, "errno", syserr_errno, 0);
rb_mErrno = rb_define_module("Errno");
#ifdef __BEOS__
for (i = 0; syserr_index[i].n != 0; i++) {
ix = syserr_index[i].ix;
for (offset = 0; offset < syserr_index[i].n; offset++) {
MEMZERO(syserr_list[ix + offset].list, VALUE, syserr_list[ix + offset].n);
}
}
#else
syserr_list = ALLOC_N(VALUE, sys_nerr+1); syserr_list = ALLOC_N(VALUE, sys_nerr+1);
MEMZERO(syserr_list, VALUE, sys_nerr+1); MEMZERO(syserr_list, VALUE, sys_nerr+1);
#endif
#ifdef EPERM #ifdef EPERM
set_syserr(EPERM, "EPERM"); set_syserr(EPERM, "EPERM");
@ -835,3 +1076,28 @@ init_syserr()
set_syserr(EDQUOT, "EDQUOT"); set_syserr(EDQUOT, "EDQUOT");
#endif #endif
} }
static void
err_append(s)
char *s;
{
extern VALUE rb_errinfo;
if (rb_in_eval) {
if (NIL_P(rb_errinfo)) {
rb_errinfo = rb_exc_new2(rb_eSyntaxError, s);
}
else {
VALUE str = rb_str_to_str(rb_errinfo);
rb_str_cat(str, "\n", 1);
rb_str_cat(str, s, strlen(s));
rb_errinfo = rb_exc_new3(rb_eSyntaxError, str);
}
}
else {
fputs(s, stderr);
fputs("\n", stderr);
fflush(stderr);
}
}

4810
eval.c

File diff suppressed because it is too large Load diff

View file

@ -10,3 +10,4 @@
#socket #socket
#tkutil #tkutil
#tcltklib #tcltklib
#gtk

View file

@ -43,7 +43,7 @@ def extract(nm, out)
else else
next next
end end
}.sort! }.compact!.sort!
uniq(data) uniq(data)
exp = open(out, "w") exp = open(out, "w")
for line in data for line in data

View file

@ -2,7 +2,7 @@
* ext/curses/curses.c * ext/curses/curses.c
* *
* by MAEDA Shugo (ender@pic-internet.or.jp) * by MAEDA Shugo (ender@pic-internet.or.jp)
* modified by Yukihiro Matsumoto (matz@ruby.club.or.jp) * modified by Yukihiro Matsumoto (matz@netlab.co.jp)
*/ */
#ifdef HAVE_NCURSES_H #ifdef HAVE_NCURSES_H
@ -12,12 +12,18 @@
# include <ncurses/curses.h> # include <ncurses/curses.h>
# else # else
# include <curses.h> # include <curses.h>
# if defined(__NetBSD__) && !defined(_maxx) # if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_maxx)
# define _maxx maxx # define _maxx maxx
# endif # endif
# if defined(__NetBSD__) && !defined(_maxy) # if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_maxy)
# define _maxy maxy # define _maxy maxy
# endif # endif
# if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_begx)
# define _begx begx
# endif
# if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_begy)
# define _begy begy
# endif
# endif # endif
#endif #endif
@ -32,14 +38,10 @@ struct windata {
WINDOW *window; WINDOW *window;
}; };
#define NUM2CHAR(x) ((TYPE(x) == T_STRING)&&(RSTRING(x)->len>=1))?\
RSTRING(x)->ptr[0]:(char)NUM2INT(x)
#define CHAR2FIX(x) INT2FIX((int)x)
static void static void
no_window() no_window()
{ {
Fail("already closed window"); rb_raise(rb_eRuntimeError, "already closed window");
} }
#define GetWINDOW(obj, winp) {\ #define GetWINDOW(obj, winp) {\
@ -55,6 +57,7 @@ free_window(winp)
{ {
if (winp->window && winp->window != stdscr) delwin(winp->window); if (winp->window && winp->window != stdscr) delwin(winp->window);
winp->window = 0; winp->window = 0;
free(winp);
} }
static VALUE static VALUE
@ -66,7 +69,7 @@ prep_window(class, window)
struct windata *winp; struct windata *winp;
if (window == NULL) { if (window == NULL) {
Fail("failed to create window"); rb_raise(rb_eRuntimeError, "failed to create window");
} }
obj = Data_Make_Struct(class, struct windata, 0, free_window, winp); obj = Data_Make_Struct(class, struct windata, 0, free_window, winp);
@ -83,7 +86,7 @@ curses_init_screen()
{ {
initscr(); initscr();
if (stdscr == 0) { if (stdscr == 0) {
Fail("cannot initialize curses"); rb_raise(rb_eRuntimeError, "cannot initialize curses");
} }
clear(); clear();
rb_stdscr = prep_window(cWindow, stdscr); rb_stdscr = prep_window(cWindow, stdscr);
@ -102,19 +105,33 @@ curses_stdscr()
static VALUE static VALUE
curses_close_screen() curses_close_screen()
{ {
endwin(); #ifdef HAVE_ISENDWIN
if (!isendwin())
#endif
endwin();
return Qnil; return Qnil;
} }
static void
curses_finalize()
{
if (stdscr
#ifdef HAVE_ISENDWIN
&& !isendwin()
#endif
)
endwin();
}
/* def closed? */ /* def closed? */
static VALUE static VALUE
curses_closed() curses_closed()
{ {
#ifdef HAVE_ENDWIN #ifdef HAVE_ISENDWIN
if (isendwin()) { if (isendwin()) {
return TRUE; return Qtrue;
} }
return FALSE; return Qfalse;
#else #else
rb_notimplement(); rb_notimplement();
#endif #endif
@ -138,12 +155,16 @@ curses_refresh(obj)
return Qnil; return Qnil;
} }
/* def refresh */ /* def doupdate */
static VALUE static VALUE
curses_doupdate(obj) curses_doupdate(obj)
VALUE obj; VALUE obj;
{ {
#ifdef HAVE_DOUPDATE
doupdate(); doupdate();
#else
refresh();
#endif
return Qnil; return Qnil;
} }
@ -235,7 +256,9 @@ static VALUE
curses_flash(obj) curses_flash(obj)
VALUE obj; VALUE obj;
{ {
#ifdef HAVE_FLASH
flash(); flash();
#endif
return Qnil; return Qnil;
} }
@ -287,7 +310,7 @@ static VALUE
curses_inch(obj) curses_inch(obj)
VALUE obj; VALUE obj;
{ {
return CHAR2FIX(inch()); return CHR2FIX(inch());
} }
/* def addch(ch) */ /* def addch(ch) */
@ -296,7 +319,7 @@ curses_addch(obj, ch)
VALUE obj; VALUE obj;
VALUE ch; VALUE ch;
{ {
addch(NUM2CHAR(ch)); addch(NUM2CHR(ch));
return Qnil; return Qnil;
} }
@ -306,7 +329,7 @@ curses_insch(obj, ch)
VALUE obj; VALUE obj;
VALUE ch; VALUE ch;
{ {
insch(NUM2CHAR(ch)); insch(NUM2CHR(ch));
return Qnil; return Qnil;
} }
@ -316,7 +339,9 @@ curses_addstr(obj, str)
VALUE obj; VALUE obj;
VALUE str; VALUE str;
{ {
addstr(RSTRING(str)->ptr); if (!NIL_P(str)) {
addstr(STR2CSTR(str));
}
return Qnil; return Qnil;
} }
@ -325,7 +350,7 @@ static VALUE
curses_getch(obj) curses_getch(obj)
VALUE obj; VALUE obj;
{ {
return CHAR2FIX(getch()); return CHR2FIX(getch());
} }
/* def getstr */ /* def getstr */
@ -335,7 +360,7 @@ curses_getstr(obj)
{ {
char rtn[1024]; /* This should be big enough.. I hope */ char rtn[1024]; /* This should be big enough.. I hope */
getstr(rtn); getstr(rtn);
return str_taint(str_new2(rtn)); return rb_tainted_str_new2(rtn);
} }
/* def delch */ /* def delch */
@ -352,7 +377,9 @@ static VALUE
curses_deleteln(obj) curses_deleteln(obj)
VALUE obj; VALUE obj;
{ {
#ifdef HAVE_DELETELN
deleteln(); deleteln();
#endif
return Qnil; return Qnil;
} }
@ -379,11 +406,15 @@ window_s_new(class, lines, cols, top, left)
VALUE top; VALUE top;
VALUE left; VALUE left;
{ {
VALUE w;
WINDOW *window; WINDOW *window;
window = newwin(NUM2INT(lines), NUM2INT(cols), NUM2INT(top), NUM2INT(left)); window = newwin(NUM2INT(lines), NUM2INT(cols), NUM2INT(top), NUM2INT(left));
wclear(window); wclear(window);
return prep_window(class, window); w = prep_window(class, window);
rb_obj_call_init(w);
return w;
} }
/* def subwin(lines, cols, top, left) */ /* def subwin(lines, cols, top, left) */
@ -412,7 +443,8 @@ window_close(obj)
struct windata *winp; struct windata *winp;
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
free_window(winp); delwin(winp->window);
winp->window = 0;
return Qnil; return Qnil;
} }
@ -453,7 +485,7 @@ window_box(obj, vert, hor)
struct windata *winp; struct windata *winp;
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
box(winp->window, NUM2CHAR(vert), NUM2CHAR(hor)); box(winp->window, NUM2CHR(vert), NUM2CHR(hor));
return Qnil; return Qnil;
} }
@ -622,7 +654,7 @@ window_inch(obj)
struct windata *winp; struct windata *winp;
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
return CHAR2FIX(winch(winp->window)); return CHR2FIX(winch(winp->window));
} }
/* def addch(ch) */ /* def addch(ch) */
@ -634,7 +666,7 @@ window_addch(obj, ch)
struct windata *winp; struct windata *winp;
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
waddch(winp->window, NUM2CHAR(ch)); waddch(winp->window, NUM2CHR(ch));
return Qnil; return Qnil;
} }
@ -648,7 +680,7 @@ window_insch(obj, ch)
struct windata *winp; struct windata *winp;
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
winsch(winp->window, NUM2CHAR(ch)); winsch(winp->window, NUM2CHR(ch));
return Qnil; return Qnil;
} }
@ -659,11 +691,12 @@ window_addstr(obj, str)
VALUE obj; VALUE obj;
VALUE str; VALUE str;
{ {
struct windata *winp; if (!NIL_P(str)) {
struct windata *winp;
GetWINDOW(obj, winp);
waddstr(winp->window, RSTRING(str)->ptr); GetWINDOW(obj, winp);
waddstr(winp->window, STR2CSTR(str));
}
return Qnil; return Qnil;
} }
@ -685,7 +718,7 @@ window_getch(obj)
struct windata *winp; struct windata *winp;
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
return CHAR2FIX(wgetch(winp->window)); return CHR2FIX(wgetch(winp->window));
} }
/* def getstr */ /* def getstr */
@ -698,7 +731,7 @@ window_getstr(obj)
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
wgetstr(winp->window, rtn); wgetstr(winp->window, rtn);
return str_taint(str_new2(rtn)); return rb_tainted_str_new2(rtn);
} }
/* def delch */ /* def delch */
@ -718,10 +751,12 @@ static VALUE
window_deleteln(obj) window_deleteln(obj)
VALUE obj; VALUE obj;
{ {
#ifdef HAVE_WDELETELN
struct windata *winp; struct windata *winp;
GetWINDOW(obj, winp); GetWINDOW(obj, winp);
wdeleteln(winp->window); wdeleteln(winp->window);
#endif
return Qnil; return Qnil;
} }
@ -764,7 +799,7 @@ Init_curses()
rb_define_module_function(mCurses, "lines", curses_lines, 0); rb_define_module_function(mCurses, "lines", curses_lines, 0);
rb_define_module_function(mCurses, "cols", curses_cols, 0); rb_define_module_function(mCurses, "cols", curses_cols, 0);
cWindow = rb_define_class_under(mCurses, "Window", cObject); cWindow = rb_define_class_under(mCurses, "Window", rb_cObject);
rb_define_singleton_method(cWindow, "new", window_s_new, 4); rb_define_singleton_method(cWindow, "new", window_s_new, 4);
rb_define_method(cWindow, "subwin", window_subwin, 4); rb_define_method(cWindow, "subwin", window_subwin, 4);
rb_define_method(cWindow, "close", window_close, 0); rb_define_method(cWindow, "close", window_close, 0);
@ -790,4 +825,6 @@ Init_curses()
rb_define_method(cWindow, "getstr", window_getstr, 0); rb_define_method(cWindow, "getstr", window_getstr, 0);
rb_define_method(cWindow, "delch", window_delch, 0); rb_define_method(cWindow, "delch", window_delch, 0);
rb_define_method(cWindow, "deleteln", window_deleteln, 0); rb_define_method(cWindow, "deleteln", window_deleteln, 0);
rb_set_end_proc(curses_finalize, 0);
} }

View file

@ -1,6 +1,9 @@
require 'mkmf'
$CFLAGS="-I/usr/include/ncurses -I/usr/local/include/ncurses" $CFLAGS="-I/usr/include/ncurses -I/usr/local/include/ncurses"
$LDFLAGS="-L/usr/local/lib" $LDFLAGS="-L/usr/local/lib"
make=FALSE make=FALSE
have_library("mytinfo", "tgetent") if /bow/ =~ PLATFORM
if have_header("ncurses.h") and have_library("ncurses", "initscr") if have_header("ncurses.h") and have_library("ncurses", "initscr")
make=TRUE make=TRUE
elsif have_header("ncurses/curses.h") and have_library("ncurses", "initscr") elsif have_header("ncurses/curses.h") and have_library("ncurses", "initscr")
@ -14,7 +17,7 @@ else
end end
if make then if make then
for f in ["isendwin", "ungetch", "beep"] for f in %w(isendwin ungetch beep doupdate flash deleteln wdeleteln)
have_func(f) have_func(f)
end end
create_makefile("curses") create_makefile("curses")

View file

@ -10,6 +10,7 @@ def show_message(message)
win.box(?|, ?=) win.box(?|, ?=)
win.setpos(2, 3) win.setpos(2, 3)
win.addstr(message) win.addstr(message)
win.refresh
win.getch win.getch
win.close win.close
end end
@ -18,8 +19,9 @@ init_screen
begin begin
crmode crmode
# show_message("Hit any key") # show_message("Hit any key")
setpos (lines - 5) / 2, (cols - 10) / 2 setpos((lines - 5) / 2, (cols - 10) / 2)
addstr("Hit any key") addstr("Hit any key")
refresh
getch getch
show_message("Hello, World!") show_message("Hello, World!")
refresh refresh

View file

@ -43,6 +43,7 @@ while TRUE
addstr(data_lines[lptr + i]) #if data_lines[lptr + i] addstr(data_lines[lptr + i]) #if data_lines[lptr + i]
i += 1 i += 1
end end
refresh
explicit = FALSE explicit = FALSE
n = 0 n = 0

View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Mon Jan 24 15:59:52 JST 1994 created at: Mon Jan 24 15:59:52 JST 1994
Copyright (C) 1995 Yukihiro Matsumoto Copyright (C) 1995-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
@ -15,11 +15,12 @@
#include <ndbm.h> #include <ndbm.h>
#include <fcntl.h> #include <fcntl.h>
#include <errno.h> #include <errno.h>
#ifdef USE_CWGUSI
# include <sys/errno.h>
#endif
VALUE cDBM; VALUE cDBM;
extern VALUE mEnumerable;
struct dbmdata { struct dbmdata {
int di_size; int di_size;
DBM *di_dbm; DBM *di_dbm;
@ -28,7 +29,7 @@ struct dbmdata {
static void static void
closed_dbm() closed_dbm()
{ {
Fail("closed DBM file"); rb_raise(rb_eRuntimeError, "closed DBM file");
} }
#define GetDBM(obj, dbmp) {\ #define GetDBM(obj, dbmp) {\
@ -41,13 +42,14 @@ free_dbm(dbmp)
struct dbmdata *dbmp; struct dbmdata *dbmp;
{ {
if (dbmp->di_dbm) dbm_close(dbmp->di_dbm); if (dbmp->di_dbm) dbm_close(dbmp->di_dbm);
free(dbmp);
} }
static VALUE static VALUE
fdbm_s_open(argc, argv, class) fdbm_s_open(argc, argv, klass)
int argc; int argc;
VALUE *argv; VALUE *argv;
VALUE class; VALUE klass;
{ {
VALUE file, vmode; VALUE file, vmode;
DBM *dbm; DBM *dbm;
@ -79,9 +81,10 @@ fdbm_s_open(argc, argv, class)
rb_sys_fail(RSTRING(file)->ptr); rb_sys_fail(RSTRING(file)->ptr);
} }
obj = Data_Make_Struct(class,struct dbmdata,0,free_dbm,dbmp); obj = Data_Make_Struct(klass,struct dbmdata,0,free_dbm,dbmp);
dbmp->di_dbm = dbm; dbmp->di_dbm = dbm;
dbmp->di_size = -1; dbmp->di_size = -1;
rb_obj_call_init(obj);
return obj; return obj;
} }
@ -118,23 +121,23 @@ fdbm_fetch(obj, keystr)
if (value.dptr == 0) { if (value.dptr == 0) {
return Qnil; return Qnil;
} }
return str_taint(str_new(value.dptr, value.dsize)); return rb_tainted_str_new(value.dptr, value.dsize);
} }
static VALUE static VALUE
fdbm_indexes(obj, ag) fdbm_indexes(argc, argv, obj)
VALUE obj, ag; int argc;
VALUE *argv;
VALUE obj;
{ {
VALUE *p, *pend;
VALUE new; VALUE new;
int i = 0; int i;
struct RArray *args = RARRAY(rb_Array(ag));
new = ary_new2(args->len); new = rb_ary_new2(argc);
p = args->ptr; pend = p + args->len; for (i=0; i<argc; i++) {
while (p < pend) { rb_ary_push(new, fdbm_fetch(obj, argv[i]));
ary_push(new, fdbm_fetch(obj, *p++));
} }
return new; return new;
} }
@ -156,13 +159,13 @@ fdbm_delete(obj, keystr)
value = dbm_fetch(dbm, key); value = dbm_fetch(dbm, key);
if (value.dptr == 0) { if (value.dptr == 0) {
if (iterator_p()) rb_yield(keystr); if (rb_iterator_p()) rb_yield(keystr);
return Qnil; return Qnil;
} }
if (dbm_delete(dbm, key)) { if (dbm_delete(dbm, key)) {
dbmp->di_size = -1; dbmp->di_size = -1;
Fail("dbm_delete failed"); rb_raise(rb_eRuntimeError, "dbm_delete failed");
} }
else if (dbmp->di_size >= 0) { else if (dbmp->di_size >= 0) {
dbmp->di_size--; dbmp->di_size--;
@ -188,9 +191,9 @@ fdbm_shift(obj)
val = dbm_fetch(dbm, key); val = dbm_fetch(dbm, key);
dbm_delete(dbm, key); dbm_delete(dbm, key);
keystr = str_taint(str_new(key.dptr, key.dsize)); keystr = rb_tainted_str_new(key.dptr, key.dsize);
valstr = str_taint(str_new(val.dptr, val.dsize)); valstr = rb_tainted_str_new(val.dptr, val.dsize);
return assoc_new(keystr, valstr); return rb_assoc_new(keystr, valstr);
} }
static VALUE static VALUE
@ -207,11 +210,11 @@ fdbm_delete_if(obj)
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key); val = dbm_fetch(dbm, key);
keystr = str_taint(str_new(key.dptr, key.dsize)); keystr = rb_tainted_str_new(key.dptr, key.dsize);
valstr = str_taint(str_new(val.dptr, val.dsize)); valstr = rb_tainted_str_new(val.dptr, val.dsize);
if (RTEST(rb_yield(assoc_new(keystr, valstr)))) { if (RTEST(rb_yield(rb_assoc_new(keystr, valstr)))) {
if (dbm_delete(dbm, key)) { if (dbm_delete(dbm, key)) {
Fail("dbm_delete failed"); rb_raise(rb_eRuntimeError, "dbm_delete failed");
} }
} }
} }
@ -232,12 +235,71 @@ fdbm_clear(obj)
dbmp->di_size = -1; dbmp->di_size = -1;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
if (dbm_delete(dbm, key)) { if (dbm_delete(dbm, key)) {
Fail("dbm_delete failed"); rb_raise(rb_eRuntimeError, "dbm_delete failed");
} }
} }
return obj; return obj;
} }
static VALUE
fdbm_invert(obj)
VALUE obj;
{
datum key, val;
struct dbmdata *dbmp;
DBM *dbm;
VALUE keystr, valstr;
VALUE hash = rb_hash_new();
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
keystr = rb_tainted_str_new(key.dptr, key.dsize);
valstr = rb_tainted_str_new(val.dptr, val.dsize);
rb_hash_aset(hash, valstr, keystr);
}
return obj;
}
static VALUE
each_pair(obj)
VALUE obj;
{
return rb_funcall(obj, rb_intern("each_pair"), 0, 0);
}
static VALUE fdbm_store _((VALUE,VALUE,VALUE));
static VALUE
update_i(pair, dbm)
VALUE pair, dbm;
{
Check_Type(pair, T_ARRAY);
if (RARRAY(pair)->len < 2) {
rb_raise(rb_eArgError, "pair must be [key, value]");
}
fdbm_store(dbm, RARRAY(pair)->ptr[0], RARRAY(pair)->ptr[1]);
return Qnil;
}
static VALUE
fdbm_update(obj, other)
VALUE obj, other;
{
rb_iterate(each_pair, other, update_i, obj);
return obj;
}
static VALUE
fdbm_replace(obj, other)
VALUE obj, other;
{
fdbm_clear(obj);
rb_iterate(each_pair, other, update_i, obj);
return obj;
}
static VALUE static VALUE
fdbm_store(obj, keystr, valstr) fdbm_store(obj, keystr, valstr)
VALUE obj, keystr, valstr; VALUE obj, keystr, valstr;
@ -252,14 +314,14 @@ fdbm_store(obj, keystr, valstr)
} }
rb_secure(4); rb_secure(4);
keystr = obj_as_string(keystr); keystr = rb_obj_as_string(keystr);
key.dptr = RSTRING(keystr)->ptr; key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len; key.dsize = RSTRING(keystr)->len;
if (NIL_P(valstr)) return fdbm_delete(obj, keystr); if (NIL_P(valstr)) return fdbm_delete(obj, keystr);
valstr = obj_as_string(valstr); valstr = rb_obj_as_string(valstr);
val.dptr = RSTRING(valstr)->ptr; val.dptr = RSTRING(valstr)->ptr;
val.dsize = RSTRING(valstr)->len; val.dsize = RSTRING(valstr)->len;
@ -267,9 +329,11 @@ fdbm_store(obj, keystr, valstr)
dbmp->di_size = -1; dbmp->di_size = -1;
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
if (dbm_store(dbm, key, val, DBM_REPLACE)) { if (dbm_store(dbm, key, val, DBM_REPLACE)) {
#ifdef HAVE_DBM_CLAERERR
dbm_clearerr(dbm); dbm_clearerr(dbm);
if (errno == EPERM) rb_sys_fail(Qnil); #endif
Fail("dbm_store failed"); if (errno == EPERM) rb_sys_fail(0);
rb_raise(rb_eRuntimeError, "dbm_store failed");
} }
return valstr; return valstr;
@ -316,8 +380,8 @@ fdbm_empty_p(obj)
else { else {
i = dbmp->di_size; i = dbmp->di_size;
} }
if (i == 0) return TRUE; if (i == 0) return Qtrue;
return FALSE; return Qfalse;
} }
static VALUE static VALUE
@ -332,7 +396,7 @@ fdbm_each_value(obj)
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key); val = dbm_fetch(dbm, key);
rb_yield(str_taint(str_new(val.dptr, val.dsize))); rb_yield(rb_tainted_str_new(val.dptr, val.dsize));
} }
return obj; return obj;
} }
@ -348,7 +412,7 @@ fdbm_each_key(obj)
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
rb_yield(str_taint(str_new(key.dptr, key.dsize))); rb_yield(rb_tainted_str_new(key.dptr, key.dsize));
} }
return obj; return obj;
} }
@ -367,9 +431,9 @@ fdbm_each_pair(obj)
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key); val = dbm_fetch(dbm, key);
keystr = str_taint(str_new(key.dptr, key.dsize)); keystr = rb_tainted_str_new(key.dptr, key.dsize);
valstr = str_taint(str_new(val.dptr, val.dsize)); valstr = rb_tainted_str_new(val.dptr, val.dsize);
rb_yield(assoc_new(keystr, valstr)); rb_yield(rb_assoc_new(keystr, valstr));
} }
return obj; return obj;
@ -387,9 +451,9 @@ fdbm_keys(obj)
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
ary = ary_new(); ary = rb_ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
ary_push(ary, str_taint(str_new(key.dptr, key.dsize))); rb_ary_push(ary, rb_tainted_str_new(key.dptr, key.dsize));
} }
return ary; return ary;
@ -407,10 +471,10 @@ fdbm_values(obj)
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
ary = ary_new(); ary = rb_ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key); val = dbm_fetch(dbm, key);
ary_push(ary, str_taint(str_new(val.dptr, val.dsize))); rb_ary_push(ary, rb_tainted_str_new(val.dptr, val.dsize));
} }
return ary; return ary;
@ -431,8 +495,8 @@ fdbm_has_key(obj, keystr)
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
val = dbm_fetch(dbm, key); val = dbm_fetch(dbm, key);
if (val.dptr) return TRUE; if (val.dptr) return Qtrue;
return FALSE; return Qfalse;
} }
static VALUE static VALUE
@ -453,9 +517,9 @@ fdbm_has_value(obj, valstr)
val = dbm_fetch(dbm, key); val = dbm_fetch(dbm, key);
if (val.dsize == RSTRING(valstr)->len && if (val.dsize == RSTRING(valstr)->len &&
memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0) memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)
return TRUE; return Qtrue;
} }
return FALSE; return Qfalse;
} }
static VALUE static VALUE
@ -470,26 +534,29 @@ fdbm_to_a(obj)
GetDBM(obj, dbmp); GetDBM(obj, dbmp);
dbm = dbmp->di_dbm; dbm = dbmp->di_dbm;
ary = ary_new(); ary = rb_ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) { for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key); val = dbm_fetch(dbm, key);
ary_push(ary, assoc_new(str_taint(str_new(key.dptr, key.dsize)), rb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
str_taint(str_new(val.dptr, val.dsize)))); rb_tainted_str_new(val.dptr, val.dsize)));
} }
return ary; return ary;
} }
void
Init_dbm() Init_dbm()
{ {
cDBM = rb_define_class("DBM", cObject); cDBM = rb_define_class("DBM", rb_cObject);
rb_include_module(cDBM, mEnumerable); rb_include_module(cDBM, rb_mEnumerable);
rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1); rb_define_singleton_method(cDBM, "open", fdbm_s_open, -1);
rb_define_singleton_method(cDBM, "new", fdbm_s_open, -1);
rb_define_method(cDBM, "close", fdbm_close, 0); rb_define_method(cDBM, "close", fdbm_close, 0);
rb_define_method(cDBM, "[]", fdbm_fetch, 1); rb_define_method(cDBM, "[]", fdbm_fetch, 1);
rb_define_method(cDBM, "[]=", fdbm_store, 2); rb_define_method(cDBM, "[]=", fdbm_store, 2);
rb_define_method(cDBM, "indexes", fdbm_indexes, -2); rb_define_method(cDBM, "indexes", fdbm_indexes, -1);
rb_define_method(cDBM, "indices", fdbm_indexes, -1);
rb_define_method(cDBM, "length", fdbm_length, 0); rb_define_method(cDBM, "length", fdbm_length, 0);
rb_define_alias(cDBM, "size", "length"); rb_define_alias(cDBM, "size", "length");
rb_define_method(cDBM, "empty?", fdbm_empty_p, 0); rb_define_method(cDBM, "empty?", fdbm_empty_p, 0);
@ -503,6 +570,10 @@ Init_dbm()
rb_define_method(cDBM, "delete", fdbm_delete, 1); rb_define_method(cDBM, "delete", fdbm_delete, 1);
rb_define_method(cDBM, "delete_if", fdbm_delete_if, 0); rb_define_method(cDBM, "delete_if", fdbm_delete_if, 0);
rb_define_method(cDBM, "clear", fdbm_clear, 0); rb_define_method(cDBM, "clear", fdbm_clear, 0);
rb_define_method(cDBM,"invert", fdbm_invert, 0);
rb_define_method(cDBM,"update", fdbm_update, 1);
rb_define_method(cDBM,"replace", fdbm_replace, 1);
rb_define_method(cDBM, "include?", fdbm_has_key, 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_key?", fdbm_has_key, 1);
rb_define_method(cDBM, "has_value?", fdbm_has_value, 1); rb_define_method(cDBM, "has_value?", fdbm_has_value, 1);

View file

@ -1,5 +1,9 @@
require 'mkmf'
$LDFLAGS = "-L/usr/local/lib" $LDFLAGS = "-L/usr/local/lib"
have_library("gdbm", "dbm_open") or have_library("dbm", "dbm_open") have_library("gdbm", "dbm_open") or
have_library("db", "dbm_open") or
have_library("dbm", "dbm_open")
if have_func("dbm_open") if have_func("dbm_open")
have_func("dbm_clearerr")
create_makefile("dbm") create_makefile("dbm")
end end

View file

@ -37,7 +37,7 @@ etc_getlogin(obj)
#endif #endif
if (login) if (login)
return str_new2(login); return rb_tainted_str_new2(login);
return Qnil; return Qnil;
} }
@ -47,34 +47,36 @@ setup_passwd(pwd)
struct passwd *pwd; struct passwd *pwd;
{ {
if (pwd == 0) rb_sys_fail("/etc/passwd"); if (pwd == 0) rb_sys_fail("/etc/passwd");
return struct_new(sPasswd, return rb_struct_new(sPasswd,
str_new2(pwd->pw_name), rb_tainted_str_new2(pwd->pw_name),
str_new2(pwd->pw_passwd), rb_tainted_str_new2(pwd->pw_passwd),
INT2FIX(pwd->pw_uid), INT2FIX(pwd->pw_uid),
INT2FIX(pwd->pw_gid), INT2FIX(pwd->pw_gid),
str_new2(pwd->pw_gecos), #ifdef PW_GECOS
str_new2(pwd->pw_dir), rb_tainted_str_new2(pwd->pw_gecos),
str_new2(pwd->pw_shell), #endif
rb_tainted_str_new2(pwd->pw_dir),
rb_tainted_str_new2(pwd->pw_shell),
#ifdef PW_CHANGE #ifdef PW_CHANGE
INT2FIX(pwd->pw_change), INT2FIX(pwd->pw_change),
#endif #endif
#ifdef PW_QUOTA #ifdef PW_QUOTA
INT2FIX(pwd->pw_quota), INT2FIX(pwd->pw_quota),
#endif #endif
#ifdef PW_AGE #ifdef PW_AGE
INT2FIX(pwd->pw_age), INT2FIX(pwd->pw_age),
#endif #endif
#ifdef PW_CLASS #ifdef PW_CLASS
str_new2(pwd->pw_class), rb_tainted_str_new2(pwd->pw_class),
#endif #endif
#ifdef PW_COMMENT #ifdef PW_COMMENT
str_new2(pwd->pw_comment), rb_tainted_str_new2(pwd->pw_comment),
#endif #endif
#ifdef PW_EXPIRE #ifdef PW_EXPIRE
INT2FIX(pwd->pw_expire), INT2FIX(pwd->pw_expire),
#endif #endif
0 /*dummy*/ 0 /*dummy*/
); );
} }
#endif #endif
@ -96,7 +98,7 @@ etc_getpwuid(argc, argv, obj)
uid = getuid(); uid = getuid();
} }
pwd = getpwuid(uid); pwd = getpwuid(uid);
if (pwd == 0) Fail("can't find user for %d", uid); if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %d", uid);
return setup_passwd(pwd); return setup_passwd(pwd);
#else #else
return Qnil; return Qnil;
@ -112,7 +114,7 @@ etc_getpwnam(obj, nam)
Check_Type(nam, T_STRING); Check_Type(nam, T_STRING);
pwd = getpwnam(RSTRING(nam)->ptr); pwd = getpwnam(RSTRING(nam)->ptr);
if (pwd == 0) Fail("can't find user for %s", RSTRING(nam)->ptr); if (pwd == 0) rb_raise(rb_eArgError, "can't find user for %s", RSTRING(nam)->ptr);
return setup_passwd(pwd); return setup_passwd(pwd);
#else #else
return Qnil; return Qnil;
@ -123,10 +125,10 @@ static VALUE
etc_passwd(obj) etc_passwd(obj)
VALUE obj; VALUE obj;
{ {
#if defined(HAVE_GETPWENT) && !defined(__CYGWIN32__) #if defined(HAVE_GETPWENT)
struct passwd *pw; struct passwd *pw;
if (iterator_p()) { if (rb_iterator_p()) {
setpwent(); setpwent();
while (pw = getpwent()) { while (pw = getpwent()) {
rb_yield(setup_passwd(pw)); rb_yield(setup_passwd(pw));
@ -135,7 +137,7 @@ etc_passwd(obj)
return obj; return obj;
} }
pw = getpwent(); pw = getpwent();
if (pw == 0) Fail("can't fetch next -- /etc/passwd"); if (pw == 0) rb_raise(rb_eRuntimeError, "can't fetch next -- /etc/passwd");
return setup_passwd(pw); return setup_passwd(pw);
#else #else
return Qnil; return Qnil;
@ -150,17 +152,17 @@ setup_group(grp)
VALUE mem; VALUE mem;
char **tbl; char **tbl;
mem = ary_new(); mem = rb_ary_new();
tbl = grp->gr_mem; tbl = grp->gr_mem;
while (*tbl) { while (*tbl) {
ary_push(mem, str_new2(*tbl)); rb_ary_push(mem, rb_tainted_str_new2(*tbl));
tbl++; tbl++;
} }
return struct_new(sGroup, return rb_struct_new(sGroup,
str_new2(grp->gr_name), rb_tainted_str_new2(grp->gr_name),
str_new2(grp->gr_passwd), rb_tainted_str_new2(grp->gr_passwd),
INT2FIX(grp->gr_gid), INT2FIX(grp->gr_gid),
mem); mem);
} }
#endif #endif
@ -174,7 +176,7 @@ etc_getgrgid(obj, id)
gid = NUM2INT(id); gid = NUM2INT(id);
grp = getgrgid(gid); grp = getgrgid(gid);
if (grp == 0) Fail("can't find group for %d", gid); if (grp == 0) rb_raise(rb_eArgError, "can't find group for %d", gid);
return setup_group(grp); return setup_group(grp);
#else #else
return Qnil; return Qnil;
@ -190,7 +192,7 @@ etc_getgrnam(obj, nam)
Check_Type(nam, T_STRING); Check_Type(nam, T_STRING);
grp = getgrnam(RSTRING(nam)->ptr); grp = getgrnam(RSTRING(nam)->ptr);
if (grp == 0) Fail("can't find group for %s", RSTRING(nam)->ptr); if (grp == 0) rb_raise(rb_eArgError, "can't find group for %s", RSTRING(nam)->ptr);
return setup_group(grp); return setup_group(grp);
#else #else
return Qnil; return Qnil;
@ -204,7 +206,7 @@ etc_group(obj)
#ifdef HAVE_GETGRENT #ifdef HAVE_GETGRENT
struct group *grp; struct group *grp;
if (iterator_p()) { if (rb_iterator_p()) {
setgrent(); setgrent();
while (grp = getgrent()) { while (grp = getgrent()) {
rb_yield(setup_group(grp)); rb_yield(setup_group(grp));
@ -235,32 +237,35 @@ Init_etc()
rb_define_module_function(mEtc, "getgrnam", etc_getgrnam, 1); rb_define_module_function(mEtc, "getgrnam", etc_getgrnam, 1);
rb_define_module_function(mEtc, "group", etc_group, 0); rb_define_module_function(mEtc, "group", etc_group, 0);
sPasswd = struct_define("Passwd", sPasswd = rb_struct_define("Passwd",
"name", "passwd", "uid", "gid", "name", "passwd", "uid", "gid",
"gecos", "dir", "shell", #ifdef PW_GECOS
"gecos",
#endif
"dir", "shell",
#ifdef PW_CHANGE #ifdef PW_CHANGE
"change", "change",
#endif #endif
#ifdef PW_QUOTA #ifdef PW_QUOTA
"quota", "quota",
#endif #endif
#ifdef PW_AGE #ifdef PW_AGE
"age", "age",
#endif #endif
#ifdef PW_CLASS #ifdef PW_CLASS
"class", "class",
#endif #endif
#ifdef PW_COMMENT #ifdef PW_COMMENT
"comment", "comment",
#endif #endif
#ifdef PW_EXPIRE #ifdef PW_EXPIRE
"expire", "expire",
#endif #endif
0); 0);
rb_global_variable(&sPasswd); rb_global_variable(&sPasswd);
#ifdef HAVE_GETGRENT #ifdef HAVE_GETGRENT
sGroup = struct_define("Group", "name", "passwd", "gid", "mem", 0); sGroup = rb_struct_define("Group", "name", "passwd", "gid", "mem", 0);
rb_global_variable(&sGroup); rb_global_variable(&sGroup);
#endif #endif
} }

View file

@ -1,7 +1,31 @@
require 'mkmf'
def etc_grep_header(field)
f = open("conftest.c", "w")
f.print <<EOF
#include <pwd.h>
EOF
f.close
begin
if xsystem("#{CPP} | egrep #{field}")
$defs.push(format("-D%s", field.upcase))
end
ensure
system "rm -f conftest.c"
end
end
have_library("sun", "getpwnam") # NIS (== YP) interface for IRIX 4 have_library("sun", "getpwnam") # NIS (== YP) interface for IRIX 4
a = have_func("getlogin") a = have_func("getlogin")
b = have_func("getpwent") b = have_func("getpwent")
c = have_func("getgrent") c = have_func("getgrent")
if a or b or c if a or b or c
etc_grep_header("pw_gecos")
etc_grep_header("pw_change")
etc_grep_header("pw_quota")
etc_grep_header("pw_age")
etc_grep_header("pw_class")
etc_grep_header("pw_comment")
etc_grep_header("pw_expire")
create_makefile("etc") create_makefile("etc")
end end

View file

@ -1,12 +1,14 @@
#! /usr/local/bin/ruby #! /usr/local/bin/ruby
$".push 'mkmf.rb' $".push 'mkmf.rb' #"
load '@top_srcdir@/lib/find.rb'
if ARGV[0] == 'static' if ARGV[0] == 'static'
$force_static = TRUE $force_static = TRUE
ARGV.shift ARGV.shift
elsif ARGV[0] == 'install' elsif ARGV[0] == 'install'
$install = TRUE $install = TRUE
$destdir = ARGV[1] || ''
ARGV.shift ARGV.shift
elsif ARGV[0] == 'clean' elsif ARGV[0] == 'clean'
$clean = TRUE $clean = TRUE
@ -19,8 +21,16 @@ $cache_mod = FALSE;
$lib_cache = {} $lib_cache = {}
$func_cache = {} $func_cache = {}
$hdr_cache = {} $hdr_cache = {}
$topdir = "@top_srcdir@" $top_srcdir = "@top_srcdir@"
if $topdir !~ "^/" if $top_srcdir !~ "^/"
# get absolute path
save = Dir.pwd
Dir.chdir $top_srcdir
$top_srcdir = Dir.pwd
Dir.chdir save
end
$topdir = ".."
if $topdir !~ "^/"
# get absolute path # get absolute path
save = Dir.pwd save = Dir.pwd
Dir.chdir $topdir Dir.chdir $topdir
@ -59,23 +69,59 @@ end
if PLATFORM == "m68k-human" if PLATFORM == "m68k-human"
CFLAGS = "@CFLAGS@".gsub(/-c..-stack=[0-9]+ */, '') CFLAGS = "@CFLAGS@".gsub(/-c..-stack=[0-9]+ */, '')
LINK = "@CC@ -o conftest -I#{$topdir} " + CFLAGS + " %s @LDFLAGS@ %s conftest.c @LIBS@ %s > nul 2>&1"
CPP = "@CPP@ @CPPFLAGS@ -I#{$topdir} " + CFLAGS + " %s conftest.c > nul 2>&1"
else else
CFLAGS = "@CFLAGS@" CFLAGS = "@CFLAGS@"
LINK = "@CC@ -o conftest -I#{$topdir} " + CFLAGS + " %s @LDFLAGS@ %s conftest.c %s > /dev/null 2>&1" end
CPP = "@CPP@ @CPPFLAGS@ -I#{$topdir} " + CFLAGS + " %s conftest.c > /dev/null 2>&1" LINK = "@CC@ -o conftest -I#$topdir -I#$top_srcdir -I@includedir@ #{CFLAGS} %s @LDFLAGS@ %s conftest.c @LIBS@ %s"
CPP = "@CPP@ @CPPFLAGS@ -I#$topdir -I#$top_srcdir -I@includedir@ #{CFLAGS} %s conftest.c"
if /cygwin|mswin32|djgpp|mingw32|m68k-human/i =~ PLATFORM
$null = open("nul", "w")
else
$null = open("/dev/null", "w")
end
$orgerr = $stderr.dup
$orgout = $stdout.dup
def xsystem command
if $DEBUG
return system(command)
end
$stderr.reopen($null)
$stdout.reopen($null)
r = system(command)
$stderr.reopen($orgerr)
$stdout.reopen($orgout)
return r
end end
def try_link(libs) def try_link(libs)
system(format(LINK, $CFLAGS, $LDFLAGS, libs)) xsystem(format(LINK, $CFLAGS, $LDFLAGS, libs))
end end
def try_cpp def try_cpp
system(format(CPP, $CFLAGS)) xsystem(format(CPP, $CFLAGS))
end end
def have_library(lib, func) def install_rb(mfile)
path = []
dir = []
Find.find("lib") do |f|
next unless /\.rb$/ =~ f
f = f[4..-1]
path.push f
dir |= File.dirname(f)
end
for f in dir
next if f == "."
mfile.printf "\t@test -d $(DESTDIR)$(pkglibdir)/%s || mkdir $(DESTDIR)$(pkglibdir)/%s\n", f, f
end
for f in path
mfile.printf "\t$(INSTALL_DATA) lib/%s $(DESTDIR)$(pkglibdir)/%s\n", f, f
end
end
def have_library(lib, func="main")
if $lib_cache[lib] if $lib_cache[lib]
if $lib_cache[lib] == "yes" if $lib_cache[lib] == "yes"
if $libs if $libs
@ -89,26 +135,34 @@ def have_library(lib, func)
end end
end end
cfile = open("conftest.c", "w") if func && func != ""
cfile.printf "\ cfile = open("conftest.c", "w")
cfile.printf "\
int main() { return 0; } int main() { return 0; }
int t() { %s(); return 0; } int t() { %s(); return 0; }
", func ", func
cfile.close cfile.close
begin begin
if $libs
libs = "-l" + lib + " " + $libs
else
libs = "-l" + lib
end
unless try_link(libs)
$lib_cache[lib] = 'no'
$cache_mod = TRUE
return FALSE
end
ensure
system "rm -f conftest*"
end
else
if $libs if $libs
libs = "-l" + lib + " " + $libs libs = "-l" + lib + " " + $libs
else else
libs = "-l" + lib libs = "-l" + lib
end end
unless try_link(libs)
$lib_cache[lib] = 'no'
$cache_mod = TRUE
return FALSE
end
ensure
system "rm -f conftest*"
end end
$libs = libs $libs = libs
@ -206,9 +260,19 @@ def create_makefile(target)
end end
$defs.push(format("-DEXTLIB='%s'", libs.join(","))) $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
end end
$libs = "" unless $libs
$srcdir = $topdir + "/ext/" + target $DLDFLAGS = '@DLDFLAGS@'
if PLATFORM =~ /beos/
if $libs
$libs = $libs + " -lruby"
else
$libs = "-lruby"
end
$DLDFLAGS = $DLDFLAGS + " -L" + $topdir
end
$srcdir = $top_srcdir + "/ext/" + target
mfile = open("Makefile", "w") mfile = open("Makefile", "w")
mfile.printf "\ mfile.printf "\
SHELL = /bin/sh SHELL = /bin/sh
@ -222,10 +286,11 @@ hdrdir = #{$topdir}
CC = @CC@ CC = @CC@
CFLAGS = %s -I#{$topdir} %s #$CFLAGS %s prefix = @prefix@
DLDFLAGS = @DLDFLAGS@ #$LDFLAGS CFLAGS = %s -I#{$topdir} -I#{$top_srcdir} -I@includedir@ #{CFLAGS} #$CFLAGS %s
DLDFLAGS = #$DLDFLAGS @LDFLAGS@ #$LDFLAGS
LDSHARED = @LDSHARED@ LDSHARED = @LDSHARED@
", if $static then "" else "@CCDLFLAGS@" end, CFLAGS, $defs.join(" ") ", if $static then "" else "@CCDLFLAGS@" end, $defs.join(" ")
mfile.printf "\ mfile.printf "\
@ -234,18 +299,20 @@ RUBY_INSTALL_NAME = `t='$(program_transform_name)'; echo ruby | sed $$t`
prefix = @prefix@ prefix = @prefix@
exec_prefix = @exec_prefix@ exec_prefix = @exec_prefix@
libdir = @libdir@/$(RUBY_INSTALL_NAME)/@arch@ libdir = @libdir@
pkglibdir = $(libdir)/$(RUBY_INSTALL_NAME)
archdir = $(pkglibdir)/@arch@
@SET_MAKE@ @SET_MAKE@
#### End of system configuration section. #### #### End of system configuration section. ####
" "
mfile.printf "LOCAL_LIBS = %s\n", $local_libs if $local_libs mfile.printf "LOCAL_LIBS = %s\n", $local_libs unless $local_libs == ""
mfile.printf "LIBS = %s\n", $libs mfile.printf "LIBS = %s\n", $libs
mfile.printf "OBJS = " mfile.printf "OBJS = "
if !$objs then if !$objs then
$objs = [] $objs = []
for f in Dir["#{$topdir}/ext/#{target}/*.{c,cc}"] for f in Dir["#{$top_srcdir}/ext/#{$mdir}/*.{c,cc}"]
f = File.basename(f) f = File.basename(f)
f.sub!(/\.(c|cc)$/, ".o") f.sub!(/\.(c|cc)$/, ".o")
$objs.push f $objs.push f
@ -254,42 +321,48 @@ libdir = @libdir@/$(RUBY_INSTALL_NAME)/@arch@
mfile.printf $objs.join(" ") mfile.printf $objs.join(" ")
mfile.printf "\n" mfile.printf "\n"
mfile.printf "\ mfile.printf <<EOS
TARGET = %s.%s TARGET = #{target}.#{$static ? "a" : "@DLEXT@"}
INSTALL = %s@INSTALL@ INSTALL = #{$dots}@INSTALL@
INSTALL_DATA = @INSTALL_DATA@
binsuffix = @binsuffix@ binsuffix = @binsuffix@
all: $(TARGET) all: $(TARGET)
clean:; @rm -f *.o *.so *.sl clean:; @rm -f *.o *.a *.so *.sl
@rm -f Makefile extconf.h conftest.* @rm -f Makefile extconf.h conftest.*
@rm -f core ruby$(binsuffix) *~ @rm -f core ruby$(binsuffix) *~
realclean: clean realclean: clean
", target, EOS
if $static then "o" else "@DLEXT@" end, $dots
mfile.printf "\ mfile.printf <<EOS
install: install:
" @test -d $(DESTDIR)$(libdir) || mkdir $(DESTDIR)$(libdir)
@test -d $(DESTDIR)$(pkglibdir) || mkdir $(DESTDIR)$(pkglibdir)
@test -d $(DESTDIR)$(archdir) || mkdir $(DESTDIR)$(archdir)
EOS
if !$static if !$static
mfile.printf " mfile.printf "\
@test -d $(libdir) || mkdir $(libdir) $(INSTALL) $(TARGET) $(DESTDIR)$(archdir)/$(TARGET)
$(INSTALL) $(TARGET) $(libdir)/$(TARGET)
" "
end end
for rb in Dir["lib/*.rb"] install_rb(mfile)
mfile.printf "\t$(INSTALL) %s @libdir@/$(RUBY_INSTALL_NAME)\n", rb
end
mfile.printf "\n" mfile.printf "\n"
if !$static && "@DLEXT@" != "o" if $static
mfile.printf "\
$(TARGET): $(OBJS)
@AR@ cru $(TARGET) $(OBJS)
@-@RANLIB@ $(TARGET) 2> /dev/null || true
"
elsif "@DLEXT@" != "o"
mfile.printf "\ mfile.printf "\
$(TARGET): $(OBJS) $(TARGET): $(OBJS)
$(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LOCAL_LIBS) $(LIBS) $(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) $(LOCAL_LIBS)
" "
elsif not File.exist?(target + ".c") and not File.exist?(target + ".cc") elsif not File.exist?(target + ".c") and not File.exist?(target + ".cc")
if PLATFORM == "m68k-human" if PLATFORM == "m68k-human"
@ -297,15 +370,10 @@ $(TARGET): $(OBJS)
$(TARGET): $(OBJS) $(TARGET): $(OBJS)
ar cru $(TARGET) $(OBJS) ar cru $(TARGET) $(OBJS)
" "
elsif PLATFORM =~ "-nextstep" elsif PLATFORM =~ "-nextstep" || PLATFORM =~ "-openstep" || PLATFORM =~ "-rhapsody"
mfile.printf "\ mfile.printf "\
$(TARGET): $(OBJS) $(TARGET): $(OBJS)
cc -r $(CFLAGS) -o $(TARGET) $(OBJS) cc -r $(CFLAGS) -o $(TARGET) $(OBJS)
"
elsif $static
mfile.printf "\
$(TARGET): $(OBJS)
ld -r -o $(TARGET) $(OBJS)
" "
else else
mfile.printf "\ mfile.printf "\
@ -324,6 +392,19 @@ $(TARGET): $(OBJS)
dfile.close dfile.close
end end
mfile.close mfile.close
if PLATFORM =~ /beos/
if PLATFORM =~ /^powerpc/ then
deffilename = "ruby.exp"
else
deffilename = "ruby.def"
end
print "creating ruby.def\n"
open(deffilename, "w") do |file|
file.print("EXPORTS\n") if PLATFORM =~ /^i/
file.print("Init_#{target}\n")
end
end
end end
def extmake(target) def extmake(target)
@ -335,24 +416,25 @@ def extmake(target)
return if $nodynamic and not $static return if $nodynamic and not $static
$local_libs = nil
$libs = nil
$objs = nil $objs = nil
$CFLAGS = nil $libs = PLATFORM =~ /cygwin|beos|openstep|nextstep|rhapsody/ ? nil : "-lc"
$LDFLAGS = nil $local_libs = "" # to be assigned in extconf.rb
$CFLAGS = ""
$LDFLAGS = ""
begin begin
system "mkdir " + target unless File.directory?(target) system "mkdir", target unless File.directory?(target)
Dir.chdir target Dir.chdir target
$mdir = target
if $static_ext.size > 0 || if $static_ext.size > 0 ||
!File.exist?("./Makefile") || !File.exist?("./Makefile") ||
older("./Makefile", "#{$topdir}/ext/@setup@") || older("./Makefile", "#{$top_srcdir}/ext/@setup@") ||
older("./Makefile", "../extmk.rb") || older("./Makefile", "../extmk.rb") ||
older("./Makefile", "#{$topdir}/ext/#{target}/extconf.rb") older("./Makefile", "#{$top_srcdir}/ext/#{target}/extconf.rb")
then then
$defs = [] $defs = []
if File.exist?("#{$topdir}/ext/#{target}/extconf.rb") if File.exist?("#{$top_srcdir}/ext/#{target}/extconf.rb")
load "#{$topdir}/ext/#{target}/extconf.rb" load "#{$top_srcdir}/ext/#{target}/extconf.rb"
else else
create_makefile(target); create_makefile(target);
end end
@ -362,7 +444,7 @@ def extmake(target)
$extlist.push [$static,target] $extlist.push [$static,target]
end end
if $install if $install
system "make install" system "make install DESTDIR=#{$destdir}"
elsif $clean elsif $clean
system "make clean" system "make clean"
else else
@ -370,9 +452,10 @@ def extmake(target)
end end
end end
if $static if $static
$extlibs += " " + $LDFLAGS if $LDFLAGS $extlibs ||= ""
$extlibs += " " + $local_libs if $local_libs $extlibs += " " + $LDFLAGS unless $LDFLAGS == ""
$extlibs += " " + $libs if $libs $extlibs += " " + $libs if $libs
$extlibs += " " + $local_libs unless $local_libs == ""
end end
ensure ensure
Dir.chdir ".." Dir.chdir ".."
@ -381,11 +464,11 @@ end
# get static-link modules # get static-link modules
$static_ext = {} $static_ext = {}
for setup in ["@setup@", "#{$topdir}/ext/@setup@"] for setup in ["@setup@", "#{$top_srcdir}/ext/@setup@"]
if File.file? setup if File.file? setup
f = open(setup) f = open(setup)
while f.gets() while f.gets()
$_.chop! $_.chomp!
sub!(/#.*$/, '') sub!(/#.*$/, '')
next if /^\s*$/ next if /^\s*$/
if /^option +nodynamic/ if /^option +nodynamic/
@ -399,7 +482,7 @@ for setup in ["@setup@", "#{$topdir}/ext/@setup@"]
end end
end end
for d in Dir["#{$topdir}/ext/*"] for d in Dir["#{$top_srcdir}/ext/*"]
File.directory?(d) || next File.directory?(d) || next
File.file?(d + "/MANIFEST") || next File.file?(d + "/MANIFEST") || next
@ -429,15 +512,16 @@ if $cache_mod
end end
exit if $install or $clean exit if $install or $clean
$extinit += "" $extinit = "" unless $extinit
if $extlist.size > 0 if $extlist.size > 0
for s,t in $extlist for s,t in $extlist
f = format("%s/%s.o", s, t) f = format("%s/%s.a", s, t)
if File.exist?(f) if File.exist?(f)
$extinit += format("\ $extinit += format("\
\tInit_%s();\n\ \tInit_%s();\n\
\trb_provide(\"%s.o\");\n\ \trb_provide(\"%s.o\");\n\
", t, t) ", t, t)
$extobjs = "" unless $extobjs
$extobjs += "ext/" $extobjs += "ext/"
$extobjs += f $extobjs += f
$extobjs += " " $extobjs += " "
@ -446,7 +530,7 @@ if $extlist.size > 0
end end
end end
if older("extinit.c", "#{$topdir}/ext/@setup@") if older("extinit.c", "#{$top_srcdir}/ext/@setup@")
f = open("extinit.c", "w") f = open("extinit.c", "w")
f.printf "void Init_ext() {\n" f.printf "void Init_ext() {\n"
f.printf $extinit f.printf $extinit
@ -461,17 +545,24 @@ if $extlist.size > 0
Dir.chdir ".." Dir.chdir ".."
if older("ruby@binsuffix@", "#{$topdir}/ext/@setup@") or older("ruby@binsuffix@", "miniruby@binsuffix@") if older("ruby@binsuffix@", "#{$top_srcdir}/ext/@setup@") or older("ruby@binsuffix@", "miniruby@binsuffix@")
`rm -f ruby@binsuffix@` `rm -f ruby@binsuffix@`
end end
$extobjs = "ext/extinit.o " + $extobjs if $extobjs
$extobjs = "ext/extinit.o " + $extobjs
else
$extobjs = "ext/extinit.o "
end
if PLATFORM =~ /m68k-human|beos/
$extlibs.gsub!("-L/usr/local/lib", "") if $extlibs
end
system format('make ruby@binsuffix@ EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs) system format('make ruby@binsuffix@ EXTOBJS="%s" EXTLIBS="%s"', $extobjs, $extlibs)
else else
Dir.chdir ".." Dir.chdir ".."
if older("ruby@binsuffix@", "miniruby@binsuffix@") if older("ruby@binsuffix@", "miniruby@binsuffix@")
`rm -f ruby@binsuffix@` `rm -f ruby@binsuffix@`
`cp miniruby@binsuffix@ ruby@binsuffix@` system("make ruby@binsuffix@")
end end
end end

View file

@ -1,5 +1,7 @@
#! /usr/local/bin/ruby #! /usr/local/bin/ruby
$".push 'mkmf.rb' #"
if ARGV[0] == 'static' if ARGV[0] == 'static'
$force_static = TRUE $force_static = TRUE
ARGV.shift ARGV.shift
@ -379,7 +381,7 @@ def extmake(target)
end end
end end
if $static if $static
#$extlibs = " " $extlibs = " "
$extlibs += " " + $LDFLAGS if $LDFLAGS $extlibs += " " + $LDFLAGS if $LDFLAGS
$extlibs += " " + $local_libs if $local_libs $extlibs += " " + $local_libs if $local_libs
$extlibs += " " + $libs if $libs $extlibs += " " + $libs if $libs
@ -438,6 +440,8 @@ if $cache_mod
end end
exit if $install or $clean exit if $install or $clean
$extinit = " " unless $extinit
$extobjs = ""
if $extlist.size > 0 if $extlist.size > 0
for s,t in $extlist for s,t in $extlist
#for s,t in $static_ext #for s,t in $static_ext

View file

@ -5,7 +5,7 @@
$Author$ $Author$
created at: Mon Apr 7 18:53:05 JST 1997 created at: Mon Apr 7 18:53:05 JST 1997
Copyright (C) 1997 Yukihiro Matsumoto Copyright (C) 1997-1998 Yukihiro Matsumoto
************************************************/ ************************************************/

View file

@ -1780,12 +1780,30 @@ kconv_kconv(argc, argv)
VALUE src, dst; VALUE src, dst;
VALUE in, out; VALUE in, out;
int in_code, out_code; int in_code, out_code;
char *codename = 0;
rb_scan_args(argc, argv, "12", &src, &out, &in); rb_scan_args(argc, argv, "12", &src, &out, &in);
Check_Type(src, T_STRING); Check_Type(src, T_STRING);
if (NIL_P(out)) { if (NIL_P(out)) {
out_code = _JIS; codename = rb_get_kcode();
goto codeselect;
}
else if (TYPE(out) == T_STRING) {
codename = RSTRING(out)->ptr;
codeselect:
switch (codename[0]) {
case 'E': case 'e':
out_code = _EUC;
break;
case 'S': case 's':
out_code = _SJIS;
break;
case 'J': case 'j':
default:
out_code = _JIS;
break;
}
} }
else { else {
out_code = NUM2INT(out); out_code = NUM2INT(out);
@ -1794,12 +1812,28 @@ kconv_kconv(argc, argv)
if (NIL_P(in)) { if (NIL_P(in)) {
in_code = _AUTO; in_code = _AUTO;
} }
else if (TYPE(in) == T_STRING) {
switch (RSTRING(in)->ptr[0]) {
case 'E': case 'e':
in_code = _EUC;
break;
case 'S': case 's':
in_code = _SJIS;
break;
case 'J': case 'j':
in_code = _JIS;
break;
default:
in_code = _AUTO;
break;
}
}
else { else {
in_code = NUM2INT(in); in_code = NUM2INT(in);
if (in_code == _NOCONV) return (VALUE)src; if (in_code == _NOCONV) return (VALUE)src;
} }
dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */ dst = rb_str_new(0, RSTRING(src)->len*3+10); /* large enough? */
RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, out_code, in_code); RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, out_code, in_code);
return dst; return dst;
@ -1813,7 +1847,7 @@ kconv_tojis(obj, src)
Check_Type(src, T_STRING); Check_Type(src, T_STRING);
dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */ dst = rb_str_new(0, RSTRING(src)->len*3+10); /* large enough? */
RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _JIS, _AUTO); RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _JIS, _AUTO);
return dst; return dst;
@ -1827,7 +1861,7 @@ kconv_toeuc(obj, src)
Check_Type(src, T_STRING); Check_Type(src, T_STRING);
dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */ dst = rb_str_new(0, RSTRING(src)->len*3+10); /* large enough? */
RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _EUC, _AUTO); RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _EUC, _AUTO);
return (VALUE)dst; return (VALUE)dst;
@ -1841,7 +1875,7 @@ kconv_tosjis(obj, src)
Check_Type(src, T_STRING); Check_Type(src, T_STRING);
dst = str_new(0, RSTRING(src)->len*3+10); /* large enough? */ dst = rb_str_new(0, RSTRING(src)->len*3+10); /* large enough? */
RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _SJIS, _AUTO); RSTRING(dst)->len = do_kconv(RSTRING(src)->ptr, RSTRING(dst)->ptr, RSTRING(dst)->len, _SJIS, _AUTO);
return dst; return dst;
@ -1857,10 +1891,29 @@ static VALUE
kconv_guess(obj, src) kconv_guess(obj, src)
VALUE obj, src; VALUE obj, src;
{ {
unsigned char *p = RSTRING(src)->ptr; unsigned char *p;
unsigned char *pend = p + RSTRING(src)->len; unsigned char *pend;
int sequence_counter = 0;
#define INCR {p++;if (p==pend) return INT2FIX(_UNKNOWN);} Check_Type(src, T_STRING);
p = RSTRING(src)->ptr;
pend = p + RSTRING(src)->len;
#define INCR do {\
p++;\
if (p==pend) return INT2FIX(_UNKNOWN);\
sequence_counter++;\
if (sequence_counter % 2 == 1 && *p != 0xa4)\
sequence_counter = 0;\
if (6 <= sequence_counter) {\
sequence_counter = 0;\
return INT2FIX(_EUC);\
}\
} while (0)
if (*p == 0xa4)
sequence_counter = 1;
while (p<pend) { while (p<pend) {
if (*p == '\033') { if (*p == '\033') {
@ -1874,37 +1927,41 @@ kconv_guess(obj, src)
if (0x81 <= *p && *p <= 0x8d) { if (0x81 <= *p && *p <= 0x8d) {
return INT2FIX(_SJIS); return INT2FIX(_SJIS);
} }
if (*p == 0x8e) { if (0x8f <= *p && *p <= 0x9f) {
return INT2FIX(_SJIS);
}
if (*p == 0x8e) { /* SS2 */
INCR; INCR;
if ((0x40 <= *p && *p <= 0x7e) || if ((0x40 <= *p && *p <= 0x7e) ||
(0x80 <= *p && *p <= 0xa0) || (0x80 <= *p && *p <= 0xa0) ||
(0xe0 <= *p && *p <= 0xfc)) (0xe0 <= *p && *p <= 0xfc))
return INT2FIX(_SJIS); return INT2FIX(_SJIS);
} }
if (0xa1 <= *p && *p <= 0xdf) { else if (0xa1 <= *p && *p <= 0xdf) {
INCR; INCR;
if (0xf0 <= *p && *p <= 0xfe) if (0xf0 <= *p && *p <= 0xfe)
return INT2FIX(_EUC); return INT2FIX(_EUC);
if (0xe0 <= *p && *p <= 0xef) { if (0xe0 <= *p && *p <= 0xef) {
while (*p >= 0x40) { while (p < pend && *p >= 0x40) {
if (*p >= 0x81) { if (*p >= 0x81) {
if (0x8d <= *p || (0x8f <= *p && *p <= 0x9f)) { if (*p <= 0x8d || (0x8f <= *p && *p <= 0x9f)) {
return INT2FIX(_SJIS); return INT2FIX(_SJIS);
} }
else if (0xfd <= *p && *p <= 0xfe) { else if (0xfd <= *p && *p <= 0xfe) {
return INT2FIX(_EUC); return INT2FIX(_EUC);
} }
} }
INCR;
} }
} }
if (*p <= 0x9f) { else if (*p <= 0x9f) {
return INT2FIX(_SJIS); return INT2FIX(_SJIS);
} }
} }
if (0xf0 <= *p && *p <= 0xfe) { else if (0xf0 <= *p && *p <= 0xfe) {
return INT2FIX(_EUC); return INT2FIX(_EUC);
} }
if (0xe0 <= *p && *p <= 0xef) { else if (0xe0 <= *p && *p <= 0xef) {
INCR; INCR;
if ((0x40 <= *p && *p <= 0x7e) || if ((0x40 <= *p && *p <= 0x7e) ||
(0x80 <= *p && *p <= 0xa0)) { (0x80 <= *p && *p <= 0xa0)) {
@ -1914,7 +1971,7 @@ kconv_guess(obj, src)
return INT2FIX(_EUC); return INT2FIX(_EUC);
} }
} }
p++; INCR;
} }
return INT2FIX(_UNKNOWN); return INT2FIX(_UNKNOWN);
} }

View file

@ -5,7 +5,7 @@
$Author$ $Author$
created at: Fri Aug 2 09:24:12 JST 1996 created at: Fri Aug 2 09:24:12 JST 1996
Copyright (C) 1995 Yukihiro Matsumoto Copyright (C) 1995-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
/* This module provides an interface to the RSA Data Security, /* This module provides an interface to the RSA Data Security,
@ -42,7 +42,7 @@ md5_digest(obj)
ctx = *md5; ctx = *md5;
MD5Final(digest, &ctx); MD5Final(digest, &ctx);
return str_new(digest, 16); return rb_str_new(digest, 16);
} }
static VALUE static VALUE
@ -53,7 +53,7 @@ md5_clone(obj)
MD5_CTX *md5, *md5_new; MD5_CTX *md5, *md5_new;
Data_Get_Struct(obj, MD5_CTX, md5); Data_Get_Struct(obj, MD5_CTX, md5);
obj = Data_Make_Struct(CLASS_OF(obj), MD5_CTX, 0, 0, md5_new); obj = Data_Make_Struct(CLASS_OF(obj), MD5_CTX, 0, free, md5_new);
*md5_new = *md5; *md5_new = *md5;
return obj; return obj;
@ -61,6 +61,9 @@ md5_clone(obj)
static VALUE static VALUE
md5_new(argc, argv, class) md5_new(argc, argv, class)
int argc;
VALUE* argv;
VALUE class;
{ {
int i; int i;
VALUE arg, obj; VALUE arg, obj;
@ -69,18 +72,19 @@ md5_new(argc, argv, class)
rb_scan_args(argc, argv, "01", &arg); rb_scan_args(argc, argv, "01", &arg);
if (!NIL_P(arg)) Check_Type(arg, T_STRING); if (!NIL_P(arg)) Check_Type(arg, T_STRING);
obj = Data_Make_Struct(class, MD5_CTX, 0, 0, md5); obj = Data_Make_Struct(class, MD5_CTX, 0, free, md5);
MD5Init(md5); MD5Init(md5);
if (!NIL_P(arg)) { if (!NIL_P(arg)) {
md5_update(obj, arg); md5_update(obj, arg);
} }
rb_obj_call_init(obj);
return obj; return obj;
} }
Init_md5() Init_md5()
{ {
cMD5 = rb_define_class("MD5", cObject); cMD5 = rb_define_class("MD5", rb_cObject);
rb_define_singleton_method(cMD5, "new", md5_new, -1); rb_define_singleton_method(cMD5, "new", md5_new, -1);

View file

@ -1 +1 @@
socket.o : socket.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h $(hdrdir)/io.h $(hdrdir)/sig.h socket.o : socket.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h $(hdrdir)/rubyio.h $(hdrdir)/rubysig.h

View file

@ -1,18 +1,22 @@
$LDFLAGS = "-L/usr/local/lib" require 'mkmf'
$LDFLAGS = "-L/usr/local/lib" if File.directory?("/usr/local/lib")
case PLATFORM case PLATFORM
when /mswin32/ when /mswin32/
test_func = "WSACleanup" test_func = "WSACleanup"
have_library("wsock32", "WSACleanup") have_library("wsock32", "WSACleanup")
when /cygwin32/ when /cygwin32/
test_func = "cygwin32_socket" test_func = "socket"
when /beos/
test_func = "socket"
have_library("net", "socket")
else else
test_func = "socket" test_func = "socket"
have_library("nsl", "t_open")
have_library("socket", "socket") have_library("socket", "socket")
have_library("inet", "gethostbyname")
have_library("nsl", "gethostbyname")
end end
have_header("sys/un.h") have_header("sys/un.h")
if have_func(test_func) if have_func(test_func)
have_func("inet_aton")
have_func("hsterror") have_func("hsterror")
unless have_func("gethostname") unless have_func("gethostname")
have_func("uname") have_func("uname")

File diff suppressed because it is too large Load diff

View file

@ -1,19 +1,27 @@
# extconf.rb for tcltklib # extconf.rb for tcltklib
have_library("socket", "socket") require 'mkmf'
have_library("nsl", "gethostbyname")
def search_file(var, include, *path) have_library("nsl", "t_open")
have_library("socket", "socket")
have_library("dl", "dlopen")
have_library("m", "log")
$includes = []
def search_header(include, *path)
pwd = Dir.getwd pwd = Dir.getwd
begin begin
for i in path.reverse! for i in path.sort!.reverse!
dir = Dir[i] dir = Dir[i]
for path in dir for path in dir.sort!.reverse!
next unless File.directory? path
Dir.chdir path Dir.chdir path
files = Dir[include] files = Dir[include]
if files.size > 0 if files.size > 0
var << path unless $includes.include? path
return files.pop $includes << path
end
return
end end
end end
end end
@ -22,58 +30,56 @@ def search_file(var, include, *path)
end end
end end
$includes = [] search_header("tcl.h",
search_file($includes, "/usr/include/tcl{,8*,7*}",
"tcl.h", "/usr/include",
"/usr/include/tcl*", "/usr/local/include/tcl{,8*,7*}",
"/usr/include", "/usr/local/include")
"/usr/local/include/tcl*", search_header("tk.h",
"/usr/local/include") "/usr/include/tk{,8*,4*}",
search_file($includes, "/usr/include",
"tk.h", "/usr/local/include/tk{,8*,4*}",
"/usr/include/tk*", "/usr/local/include")
"/usr/include", search_header("X11/Xlib.h",
"/usr/local/include/tk*", "/usr/include/X11*",
"/usr/local/include") "/usr/include",
search_file($includes, "/usr/openwin/include",
"X11/Xlib.h", "/usr/X11*/include")
"/usr/include",
"/usr/X11*/include",
"/usr/include",
"/usr/X11*/include")
$CFLAGS = "-Wall " + $includes.collect{|path| "-I" + path}.join(" ") $CFLAGS = $includes.collect{|path| "-I" + path}.join(" ")
$libraries = [] $libraries = []
tcllibfile = search_file($libraries, def search_lib(file, func, *path)
"libtcl{,7*,8*}.{a,so}", for i in path.reverse!
"/usr/lib", dir = Dir[i]
"/usr/local/lib") for path in dir.sort!.reverse!
if tcllibfile $LDFLAGS = $libraries.collect{|p| "-L" + p}.join(" ") + " -L" + path
tcllibfile.sub!(/^lib/, '') files = Dir[path+"/"+file]
tcllibfile.sub!(/\.(a|so)$/, '') if files.size > 0
for lib in files.sort!.reverse!
lib = File::basename(lib)
lib.sub!(/^lib/, '')
lib.sub!(/\.(a|so)$/, '')
if have_library(lib, func)
unless $libraries.include? path
$libraries << path
end
return true
end
end
end
end
end
return false;
end end
tklibfile = search_file($libraries,
"libtk{,4*,8*}.{a,so}",
"/usr/lib",
"/usr/local/lib")
if tklibfile
tklibfile.sub!(/^lib/, '')
tklibfile.sub!(/\.(a|so)$/, '')
end
search_file($libraries,
"libX11.{a,so}",
"/usr/lib",
"/usr/X11*/lib")
$LDFLAGS = $libraries.collect{|path| "-L" + path}.join(" ") if have_header("tcl.h") && have_header("tk.h") &&
search_lib("libX11.{so,a}", "XOpenDisplay",
have_library("dl", "dlopen") "/usr/lib", "/usr/openwin/lib", "/usr/X11*/lib") &&
if have_header("tcl.h") && search_lib("libtcl{8*,7*,}.{so,a}", "Tcl_FindExecutable",
have_header("tk.h") && "/usr/lib", "/usr/local/lib") &&
have_library("X11", "XOpenDisplay") && search_lib("libtk{8*,4*,}.{so,a}", "Tk_Init",
have_library("m", "log") && "/usr/lib", "/usr/local/lib")
have_library(tcllibfile, "Tcl_FindExecutable") && $LDFLAGS = $libraries.collect{|path| "-L" + path}.join(" ")
have_library(tklibfile, "Tk_Init")
create_makefile("tcltklib") create_makefile("tcltklib")
end end

View file

@ -1,48 +1,44 @@
# tof # tof
#### tcltk ライブラリ #### tcltk library, more direct manipulation of tcl/tk
#### Sep. 5, 1997 Y. Shigehiro #### Sep. 5, 1997 Y. Shigehiro
require "tcltklib" require "tcltklib"
################ ################
# module TclTk: tcl/tk のライブラリ全体で必要になるものを集めたもの # module TclTk: collection of tcl/tk utilities (supplies namespace.)
# (主に, 名前空間の点から module にする使う.)
module TclTk module TclTk
# 単にここに書けば最初に 1 度実行されるのか?? # initialize Hash to hold unique symbols and such
# 生成した一意な名前を保持しておく連想配列を初期化する.
@namecnt = {} @namecnt = {}
# コールバックを保持しておく連想配列を初期化する. # initialize Hash to hold callbacks
@callback = {} @callback = {}
end end
# TclTk.mainloop(): TclTkLib.mainloop() を呼ぶ. # TclTk.mainloop(): call TclTkLib.mainloop()
def TclTk.mainloop() def TclTk.mainloop()
print("mainloop: start\n") if $DEBUG print("mainloop: start\n") if $DEBUG
TclTkLib.mainloop() TclTkLib.mainloop()
print("mainloop: end\n") if $DEBUG print("mainloop: end\n") if $DEBUG
end end
# TclTk.deletecallbackkey(ca): コールバックを TclTk module から取り除く. # TclTk.deletecallbackkey(ca): remove callback from TclTk module
# tcl/tk インタプリタにおいてコールバックが取り消されるわけではない. # this does not remove callbacks from tcl/tk interpreter
# これをしないと, 最後に TclTkInterpreter が GC できない. # without calling this method, TclTkInterpreter will not be GCed
# (GC したくなければ, 別に, これをしなくても良い.) # ca: callback(TclTkCallback)
# ca: コールバック(TclTkCallback)
def TclTk.deletecallbackkey(ca) def TclTk.deletecallbackkey(ca)
print("deletecallbackkey: ", ca.to_s(), "\n") if $DEBUG print("deletecallbackkey: ", ca.to_s(), "\n") if $DEBUG
@callback.delete(ca.to_s) @callback.delete(ca.to_s)
end end
# TclTk.dcb(ca, wid, W): 配列に入っている複数のコールバックに対して # TclTk.dcb(ca, wid, W): call TclTk.deletecallbackkey() for each callbacks
# TclTk.deletecallbackkey() を呼ぶ. # in an array.
# トップレベルの <Destroy> イベントのコールバックとして呼ぶためのもの. # this is for callback for top-level <Destroy>
# ca: コールバック(TclTkCallback) の Array # ca: array of callbacks(TclTkCallback)
# wid: トップレベルのウィジェット(TclTkWidget) # wid: top-level widget(TclTkWidget)
# w: コールバックに %W で与えられる, ウインドウに関するパラメータ(String) # w: information about window given by %W(String)
def TclTk.dcb(ca, wid, w) def TclTk.dcb(ca, wid, w)
if wid.to_s() == w if wid.to_s() == w
ca.each{|i| ca.each{|i|
@ -51,33 +47,33 @@ def TclTk.dcb(ca, wid, w)
end end
end end
# TclTk._addcallback(ca): コールバックを登録する. # TclTk._addcallback(ca): register callback
# ca: コールバック(TclTkCallback) # ca: callback(TclTkCallback)
def TclTk._addcallback(ca) def TclTk._addcallback(ca)
print("_addcallback: ", ca.to_s(), "\n") if $DEBUG print("_addcallback: ", ca.to_s(), "\n") if $DEBUG
@callback[ca.to_s()] = ca @callback[ca.to_s()] = ca
end end
# TclTk._callcallback(key, arg): 登録したコールバックを呼び出す. # TclTk._callcallback(key, arg): invoke registered callback
# key: コールバックを選択するキー (TclTkCallback が to_s() で返す値) # key: key to select callback (to_s value of the TclTkCallback)
# arg: tcl/tk インタプリタからのパラメータ # arg: parameter from tcl/tk interpreter
def TclTk._callcallback(key, arg) def TclTk._callcallback(key, arg)
print("_callcallback: ", @callback[key].inspect, "\n") if $DEBUG print("_callcallback: ", @callback[key].inspect, "\n") if $DEBUG
@callback[key]._call(arg) @callback[key]._call(arg)
# コールバックからの返り値はどうせ捨てられる. # throw out callback value
# String を返さないと, rb_eval_string() がエラーになる. # should return String to satisfy rb_eval_string()
return "" return ""
end end
# TclTk._newname(prefix): 一意な名前(String)を生成して返す. # TclTk._newname(prefix): generate unique name(String)
# prefix: 名前の接頭語 # prefix: prefix of the unique name
def TclTk._newname(prefix) def TclTk._newname(prefix)
# 生成した名前のカウンタは @namecnt に入っているので, 調べる. # generated name counter is stored in @namecnt
if !@namecnt.key?(prefix) if !@namecnt.key?(prefix)
# 初めて使う接頭語なので初期化する. # first appearing prefix, initialize
@namecnt[prefix] = 1 @namecnt[prefix] = 1
else else
# 使ったことのある接頭語なので, 次の名前にする. # already appeared prefix, generate next name
@namecnt[prefix] += 1 @namecnt[prefix] += 1
end end
return "#{prefix}#{@namecnt[prefix]}" return "#{prefix}#{@namecnt[prefix]}"
@ -85,51 +81,48 @@ end
################ ################
# class TclTkInterpreter: tcl/tk のインタプリタ # class TclTkInterpreter: tcl/tk interpreter
class TclTkInterpreter class TclTkInterpreter
# initialize(): 初期化. # initialize():
def initialize() def initialize()
# インタプリタを生成する. # generate interpreter object
@ip = TclTkIp.new() @ip = TclTkIp.new()
# インタプリタに ruby_fmt コマンドを追加する. # add ruby_fmt command to tcl interpreter
# ruby_fmt コマンドとは, 後ろの引数を format コマンドで処理して # ruby_fmt command format arguments by `format' and call `ruby' command
# ruby コマンドに渡すものである. # (notice ruby command receives only one argument)
# (なお, ruby コマンドは, 引数を 1 つしかとれない.)
if $DEBUG if $DEBUG
@ip._eval("proc ruby_fmt {fmt args} { puts \"ruby_fmt: $fmt $args\" ; ruby [format $fmt $args] }") @ip._eval("proc ruby_fmt {fmt args} { puts \"ruby_fmt: $fmt $args\" ; ruby [format $fmt $args] }")
else else
@ip._eval("proc ruby_fmt {fmt args} { ruby [format $fmt $args] }") @ip._eval("proc ruby_fmt {fmt args} { ruby [format $fmt $args] }")
end end
# @ip._get_eval_string(*args): tcl/tk インタプリタで評価する # @ip._get_eval_string(*args): generate string to evaluate in tcl interpreter
# 文字列(String)を生成して返す. # *args: script which is going to be evaluated under tcl/tk
# *args: tcl/tk で評価するスクリプト(に対応するオブジェクト列)
def @ip._get_eval_string(*args) def @ip._get_eval_string(*args)
argstr = "" argstr = ""
args.each{|arg| args.each{|arg|
argstr += " " if argstr != "" argstr += " " if argstr != ""
# もし to_eval() メソッドが # call to_eval if it is defined
if (arg.respond_to?(:to_eval)) if (arg.respond_to?(:to_eval))
# 定義されていればそれを呼ぶ.
argstr += arg.to_eval() argstr += arg.to_eval()
else else
# 定義されていなければ to_s() を呼ぶ. # call to_s unless defined
argstr += arg.to_s() argstr += arg.to_s()
end end
} }
return argstr return argstr
end end
# @ip._eval_args(*args): tcl/tk インタプリタで評価し, # @ip._eval_args(*args): evaluate string under tcl/tk interpreter
# その結果(String)を返す. # returns result string.
# *args: tcl/tk で評価するスクリプト(に対応するオブジェクト列) # *args: script which is going to be evaluated under tcl/tk
def @ip._eval_args(*args) def @ip._eval_args(*args)
# インタプリタで評価する文字列を求める. # calculate the string to eval in the interpreter
argstr = _get_eval_string(*args) argstr = _get_eval_string(*args)
# インタプリタで評価する. # evaluate under the interpreter
print("_eval: \"", argstr, "\"") if $DEBUG print("_eval: \"", argstr, "\"") if $DEBUG
res = _eval(argstr) res = _eval(argstr)
if $DEBUG if $DEBUG
@ -137,219 +130,205 @@ class TclTkInterpreter
elsif _return_value() != 0 elsif _return_value() != 0
print(res, "\n") print(res, "\n")
end end
fail(%Q/can't eval "#{argstr}"/) if _return_value() != 0 fail(%Q/can't eval "#{argstr}"/) if _return_value() != 0 #'
return res return res
end end
# tcl/tk のコマンドに対応するオブジェクトを生成し, 連想配列に入れておく. # generate tcl/tk command object and register in the hash
@commands = {} @commands = {}
# tcl/tk インタプリタに登録されているすべてのコマンドに対して, # for all commands registered in tcl/tk interpreter:
@ip._eval("info command").split(/ /).each{|comname| @ip._eval("info command").split(/ /).each{|comname|
if comname =~ /^[.]/ if comname =~ /^[.]/
# コマンドがウィジェット(のパス名)の場合は # if command is a widget (path), generate TclTkWidget,
# TclTkWidget のインスタンスを作って連想配列に入れる. # and register it in the hash
@commands[comname] = TclTkWidget.new(@ip, comname) @commands[comname] = TclTkWidget.new(@ip, comname)
else else
# そうでない場合は # otherwise, generate TclTkCommand
# TclTkCommand のインスタンスを作って連想配列に入れる.
@commands[comname] = TclTkCommand.new(@ip, comname) @commands[comname] = TclTkCommand.new(@ip, comname)
end end
} }
end end
# commands(): tcl/tk のコマンドに対応するオブジェクトを Hash に # commands(): returns hash of the tcl/tk commands
# 入れたものを返す.
def commands() def commands()
return @commands return @commands
end end
# rootwidget(): ルートウィジェット(TclTkWidget)を返す. # rootwidget(): returns root widget(TclTkWidget)
def rootwidget() def rootwidget()
return @commands["."] return @commands["."]
end end
# _tcltkip(): @ip(TclTkIp) を返す. # _tcltkip(): returns @ip(TclTkIp)
def _tcltkip() def _tcltkip()
return @ip return @ip
end end
# method_missing(id, *args): 未定義のメソッドは tcl/tk のコマンドとみなして # method_missing(id, *args): execute undefined method as tcl/tk command
# 実行し, その結果(String)を返す. # id: method symbol
# id: メソッドのシンボル # *args: method arguments
# *args: コマンドの引数
def method_missing(id, *args) def method_missing(id, *args)
# もし, メソッドの tcl/tk コマンドが # if command named by id registered, then execute it
if @commands.key?(id.id2name) if @commands.key?(id.id2name)
# あれば, 実行して結果を返す.
return @commands[id.id2name].e(*args) return @commands[id.id2name].e(*args)
else else
# 無ければもともとの処理. # otherwise, exception
super super
end end
end end
end end
# class TclTkObject: tcl/tk のオブジェクト # class TclTkObject: base class of the tcl/tk objects
# (基底クラスとして使う.
# tcltk ライブラリを使う人が TclTkObject.new() することはないはず.)
class TclTkObject class TclTkObject
# initialize(ip, exp): 初期化. # initialize(ip, exp):
# ip: インタプリタ(TclTkIp) # ip: interpreter(TclTkIp)
# exp: tcl/tk での表現形 # exp: tcl/tk representation
def initialize(ip, exp) def initialize(ip, exp)
fail("type is not TclTkIp") if !ip.kind_of?(TclTkIp) fail("type is not TclTkIp") if !ip.kind_of?(TclTkIp)
@ip = ip @ip = ip
@exp = exp @exp = exp
end end
# to_s(): tcl/tk での表現形(String)を返す. # to_s(): returns tcl/tk representation
def to_s() def to_s()
return @exp return @exp
end end
end end
# class TclTkCommand: tcl/tk のコマンド # class TclTkCommand: tcl/tk commands
# (tcltk ライブラリを使う人が TclTkCommand.new() することはないはず. # you should not call TclTkCommand.new()
# TclTkInterpreter:initialize() から new() される.) # commands are created by TclTkInterpreter:initialize()
class TclTkCommand < TclTkObject class TclTkCommand < TclTkObject
# e(*args): コマンドを実行し, その結果(String)を返す. # e(*args): execute command. returns String (e is for exec or eval)
# (e は exec または eval の e.) # *args: command arguments
# *args: コマンドの引数
def e(*args) def e(*args)
return @ip._eval_args(to_s(), *args) return @ip._eval_args(to_s(), *args)
end end
end end
# class TclTkLibCommand: tcl/tk のコマンド # class TclTkLibCommand: tcl/tk commands in the library
# (ライブラリにより実現されるコマンドで, tcl/tk インタプリタに最初から
# 存在しないものは, インタプリタの commands() では生成できない.
# そのようなものに対し, コマンドの名前から TclTkCommand オブジェクトを
# 生成する.
class TclTkLibCommand < TclTkCommand class TclTkLibCommand < TclTkCommand
# initialize(ip, name): 初期化 # initialize(ip, name):
# ip: インタプリタ(TclTkInterpreter) # ip: interpreter(TclTkInterpreter)
# name: コマンド名 (String) # name: command name (String)
def initialize(ip, name) def initialize(ip, name)
super(ip._tcltkip, name) super(ip._tcltkip, name)
end end
end end
# class TclTkVariable: tcl/tk の変数 # class TclTkVariable: tcl/tk variable
class TclTkVariable < TclTkObject class TclTkVariable < TclTkObject
# initialize(interp, dat): 初期化. # initialize(interp, dat):
# interp: インタプリタ(TclTkInterpreter) # interp: interpreter(TclTkInterpreter)
# dat: 設定する値(String) # dat: the value to set(String)
# nil なら, 設定しない. # if nil, not initialize variable
def initialize(interp, dat) def initialize(interp, dat)
# tcl/tk での表現形(変数名)を自動生成する. # auto-generate tcl/tk representation (variable name)
exp = TclTk._newname("v_") exp = TclTk._newname("v_")
# TclTkObject を初期化する. # initialize TclTkObject
super(interp._tcltkip(), exp) super(interp._tcltkip(), exp)
# set コマンドを使うのでとっておく. # safe this for `set' command
@set = interp.commands()["set"] @set = interp.commands()["set"]
# 値を設定する. # set value
set(dat) if dat set(dat) if dat
end end
# tcl/tk の set を使えば, 値の設定/参照はできるが, # although you can set/refer variable by using set in tcl/tk,
# それだけではなんなので, 一応, メソッドをかぶせたものも用意しておく. # we provide the method for accessing variables
# set(data): tcl/tk の変数に set を用いて値を設定する. # set(data): set tcl/tk variable using `set'
# data: 設定する値 # data: new value
def set(data) def set(data)
@set.e(to_s(), data.to_s()) @set.e(to_s(), data.to_s())
end end
# get(): tcl/tk の変数の値(String)を set を用いて読みだし返す. # get(): read tcl/tk variable(String) using `set'
def get() def get()
return @set.e(to_s()) return @set.e(to_s())
end end
end end
# class TclTkWidget: tcl/tk のウィジェット # class TclTkWidget: tcl/tk widget
class TclTkWidget < TclTkCommand class TclTkWidget < TclTkCommand
# initialize(*args): 初期化. # initialize(*args):
# *args: パラメータ # *args: parameters
def initialize(*args) def initialize(*args)
if args[0].kind_of?(TclTkIp) if args[0].kind_of?(TclTkIp)
# 最初の引数が TclTkIp の場合: # in case the 1st argument is TclTkIp:
# 既に tcl/tk に定義されているウィジェットに TclTkWidget の構造を # Wrap tcl/tk widget by TclTkWidget
# かぶせる. (TclTkInterpreter:initialize() から使われる.) # (used in TclTkInterpreter#initialize())
# パラメータ数が 2 でなければエラー. # need two arguments
fail("illegal # of parameter") if args.size != 2 fail("illegal # of parameter") if args.size != 2
# ip: インタプリタ(TclTkIp) # ip: interpreter(TclTkIp)
# exp: tcl/tk での表現形 # exp: tcl/tk representation
ip, exp = args ip, exp = args
# TclTkObject を初期化する. # initialize TclTkObject
super(ip, exp) super(ip, exp)
elsif args[0].kind_of?(TclTkInterpreter) elsif args[0].kind_of?(TclTkInterpreter)
# 最初の引数が TclTkInterpreter の場合: # in case 1st parameter is TclTkInterpreter:
# 親ウィジェットから新たなウィジェトを生成する. # generate new widget from parent widget
# interp: インタプリタ(TclTkInterpreter) # interp: interpreter(TclTkInterpreter)
# parent: 親ウィジェット # parent: parent widget
# command: ウィジェットを生成するコマンド(label 等) # command: widget generating tk command(label Åù)
# *args: command に渡す引数 # *args: argument to the command
interp, parent, command, *args = args interp, parent, command, *args = args
# ウィジェットの名前を作る. # generate widget name
exp = parent.to_s() exp = parent.to_s()
exp += "." if exp !~ /[.]$/ exp += "." if exp !~ /[.]$/
exp += TclTk._newname("w_") exp += TclTk._newname("w_")
# TclTkObject を初期化する. # initialize TclTkObject
super(interp._tcltkip(), exp) super(interp._tcltkip(), exp)
# ウィジェットを生成する. # generate widget
res = @ip._eval_args(command, exp, *args) res = @ip._eval_args(command, exp, *args)
# fail("can't create Widget") if res != exp # fail("can't create Widget") if res != exp
# tk_optionMenu では, ボタン名を exp で指定すると # for tk_optionMenu, it is legal res != exp
# res にメニュー名を返すので res != exp となる.
else else
fail("first parameter is not TclTkInterpreter") fail("first parameter is not TclTkInterpreter")
end end
end end
end end
# class TclTkCallback: tcl/tk のコールバック # class TclTkCallback: tcl/tk callbacks
class TclTkCallback < TclTkObject class TclTkCallback < TclTkObject
# initialize(interp, pr, arg): 初期化. # initialize(interp, pr, arg):
# interp: インタプリタ(TclTkInterpreter) # interp: interpreter(TclTkInterpreter)
# pr: コールバック手続き(Proc) # pr: callback procedure(Proc)
# arg: pr のイテレータ変数に渡す文字列 # arg: string to pass as block parameters of pr
# tcl/tk の bind コマンドではパラメータを受け取るために % 置換を # bind command of tcl/tk uses % replacement for parameters
# 用いるが, pr の内部で % を書いてもうまくいかない. # pr can receive replaced data using block parameter
# arg に文字列を書いておくと, その置換結果を, pr で # its format is specified by arg string
# イテレータ変数を通して受け取ることができる. # You should not specify arg for the command like
# scrollbar コマンドの -command オプションのように # scrollbar with -command option, which receives parameters
# 何も指定しなくてもパラメータが付くコマンドに対しては, # without specifying any replacement
# arg を指定してはならない.
def initialize(interp, pr, arg = nil) def initialize(interp, pr, arg = nil)
# tcl/tk での表現形(変数名)を自動生成する. # auto-generate tcl/tk representation (variable name)
exp = TclTk._newname("c_") exp = TclTk._newname("c_")
# TclTkObject を初期化する. # initialize TclTkObject
super(interp._tcltkip(), exp) super(interp._tcltkip(), exp)
# パラメータをとっておく. # save parameters
@pr = pr @pr = pr
@arg = arg @arg = arg
# モジュールに登録しておく. # register in the module
TclTk._addcallback(self) TclTk._addcallback(self)
end end
# to_eval(): @ip._eval_args で評価するときの表現形(String)を返す. # to_eval(): retuens string representation for @ip._eval_args
def to_eval() def to_eval()
if @arg if @arg
# %s は ruby_fmt より前に bind により置換されてしまうので # bind replaces %s before calling ruby_fmt, so %%s is used
# %%s としてある. したがって, これは bind 専用.
s = %Q/{ruby_fmt {TclTk._callcallback("#{to_s()}", "%%s")} #{@arg}}/ s = %Q/{ruby_fmt {TclTk._callcallback("#{to_s()}", "%%s")} #{@arg}}/
else else
s = %Q/{ruby_fmt {TclTk._callcallback("#{to_s()}", "%s")}}/ s = %Q/{ruby_fmt {TclTk._callcallback("#{to_s()}", "%s")}}/
@ -358,28 +337,28 @@ class TclTkCallback < TclTkObject
return s return s
end end
# _call(arg): コールバックを呼び出す. # _call(arg): invoke callback
# arg: コールバックに渡されるパラメータ # arg: callback parameter
def _call(arg) def _call(arg)
@pr.call(arg) @pr.call(arg)
end end
end end
# class TclTkImage: tcl/tk のイメージ # class TclTkImage: tcl/tk images
class TclTkImage < TclTkCommand class TclTkImage < TclTkCommand
# initialize(interp, t, *args): 初期化. # initialize(interp, t, *args):
# イメージの生成は TclTkImage.new() で行うが, # generating image is done by TclTkImage.new()
# 破壊は image delete で行う. (いまいちだけど仕方が無い.) # destrying is done by image delete (inconsistent, sigh)
# interp: インタプリタ(TclTkInterpreter) # interp: interpreter(TclTkInterpreter)
# t: イメージのタイプ (photo, bitmap, etc.) # t: image type (photo, bitmap, etc.)
# *args: コマンドの引数 # *args: command argument
def initialize(interp, t, *args) def initialize(interp, t, *args)
# tcl/tk での表現形(変数名)を自動生成する. # auto-generate tcl/tk representation
exp = TclTk._newname("i_") exp = TclTk._newname("i_")
# TclTkObject を初期化する. # initialize TclTkObject
super(interp._tcltkip(), exp) super(interp._tcltkip(), exp)
# イメージを生成する. # generate image
res = @ip._eval_args("image create", t, exp, *args) res = @ip._eval_args("image create", t, exp, *args)
fail("can't create Image") if res != exp fail("can't create Image") if res != exp
end end

View file

@ -5,22 +5,31 @@
*/ */
#include "ruby.h" #include "ruby.h"
#include "sig.h" #include "rubysig.h"
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
#include <tcl.h> #include <tcl.h>
#include <tk.h> #include <tk.h>
/* for debug */ #ifdef __MACOS__
# include <tkMac.h>
# include <Quickdraw.h>
#endif
#define DUMP1(ARG1) if (debug) { fprintf(stderr, "tcltklib: %s\n", ARG1);} /* for rb_debug */
#define DUMP2(ARG1, ARG2) if (debug) { fprintf(stderr, "tcltklib: ");\
#define DUMP1(ARG1) if (rb_debug) { fprintf(stderr, "tcltklib: %s\n", ARG1);}
#define DUMP2(ARG1, ARG2) if (rb_debug) { fprintf(stderr, "tcltklib: ");\
fprintf(stderr, ARG1, ARG2); fprintf(stderr, "\n"); } fprintf(stderr, ARG1, ARG2); fprintf(stderr, "\n"); }
/* /*
#define DUMP1(ARG1) #define DUMP1(ARG1)
#define DUMP2(ARG1, ARG2) #define DUMP2(ARG1, ARG2)
*/ */
/* for callback break & continue */
VALUE eTkCallbackBreak;
VALUE eTkCallbackContinue;
/* from tkAppInit.c */ /* from tkAppInit.c */
/* /*
@ -33,26 +42,52 @@ int *tclDummyMathPtr = (int *) matherr;
/*---- module TclTkLib ----*/ /*---- module TclTkLib ----*/
static VALUE thread_safe = Qnil; /* Tk_ThreadTimer */
typedef struct {
Tcl_TimerToken token;
int flag;
} Tk_TimerData;
/* timer callback */
void _timer_for_tcl (ClientData clientData)
{
Tk_TimerData *timer = (Tk_TimerData*)clientData;
timer->flag = 0;
CHECK_INTS;
#ifdef USE_THREAD
if (!rb_thread_critical) rb_thread_schedule();
#endif
timer->token = Tk_CreateTimerHandler(200, _timer_for_tcl,
(ClientData)timer);
timer->flag = 1;
}
/* execute Tk_MainLoop */ /* execute Tk_MainLoop */
static VALUE static VALUE
lib_mainloop(VALUE self) lib_mainloop(VALUE self)
{ {
int old_trapflg; Tk_TimerData *timer;
int flags = RTEST(thread_safe)?TCL_DONT_WAIT:0;
timer = (Tk_TimerData *) ckalloc(sizeof(Tk_TimerData));
timer->flag = 0;
timer->token = Tk_CreateTimerHandler(200, _timer_for_tcl,
(ClientData)timer);
timer->flag = 1;
DUMP1("start Tk_Mainloop"); DUMP1("start Tk_Mainloop");
while (Tk_GetNumMainWindows() > 0) { while (Tk_GetNumMainWindows() > 0) {
old_trapflg = trap_immediate; Tcl_DoOneEvent(0);
trap_immediate = 1;
Tcl_DoOneEvent(flags);
trap_immediate = old_trapflg;
CHECK_INTS;
flags = (thread_safe == 0 || thread_safe == Qnil)?0:TCL_DONT_WAIT;
} }
DUMP1("stop Tk_Mainloop"); DUMP1("stop Tk_Mainloop");
#ifdef USE_THREAD
if (timer->flag) {
Tk_DeleteTimerHandler(timer->token);
}
#endif
return Qnil; return Qnil;
} }
@ -71,27 +106,49 @@ ip_eval_rescue(VALUE *failed, VALUE einfo)
} }
static int static int
#if TCL_MAJOR_VERSION >= 8
ip_ruby(ClientData clientData, Tcl_Interp *interp,
int argc, Tcl_Obj *CONST argv[])
#else
ip_ruby(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[]) ip_ruby(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
#endif
{ {
VALUE res; VALUE res;
int old_trapflg; int old_trapflg;
VALUE failed = 0; VALUE failed = 0;
char *arg;
int dummy;
/* ruby command has 1 arg. */ /* ruby command has 1 arg. */
if (argc != 2) { if (argc != 2) {
ArgError("wrong # of arguments (%d for 1)", argc); rb_raise(rb_eArgError, "wrong # of arguments (%d for 1)", argc);
} }
/* evaluate the argument string by ruby */ /* get C string from Tcl object */
DUMP2("rb_eval_string(%s)", argv[1]); #if TCL_MAJOR_VERSION >= 8
old_trapflg = trap_immediate; arg = Tcl_GetStringFromObj(argv[1], &dummy);
trap_immediate = 0; #else
res = rb_rescue(rb_eval_string, argv[1], ip_eval_rescue, &failed); arg = argv[1];
trap_immediate = old_trapflg; #endif
/* evaluate the argument string by ruby */
DUMP2("rb_eval_string(%s)", arg);
old_trapflg = rb_trap_immediate;
rb_trap_immediate = 0;
res = rb_rescue(rb_eval_string, (VALUE)arg, ip_eval_rescue, (VALUE)&failed);
rb_trap_immediate = old_trapflg;
Tcl_ResetResult(interp);
if (failed) { if (failed) {
Tcl_AppendResult(interp, RSTRING(failed)->ptr, (char*)NULL); VALUE eclass = CLASS_OF(failed);
return TCL_ERROR; Tcl_AppendResult(interp, STR2CSTR(failed), (char*)NULL);
if (eclass == eTkCallbackBreak) {
return TCL_BREAK;
} else if (eclass == eTkCallbackContinue) {
return TCL_CONTINUE;
} else {
return TCL_ERROR;
}
} }
/* result must be string or nil */ /* result must be string or nil */
@ -99,12 +156,11 @@ ip_ruby(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
DUMP1("(rb_eval_string result) nil"); DUMP1("(rb_eval_string result) nil");
return TCL_OK; return TCL_OK;
} }
Check_Type(res, T_STRING);
/* copy result to the tcl interpreter */ /* copy result to the tcl interpreter */
DUMP2("(rb_eval_string result) %s", RSTRING(res)->ptr); DUMP2("(rb_eval_string result) %s", STR2CSTR(res));
DUMP1("Tcl_AppendResult"); DUMP1("Tcl_AppendResult");
Tcl_AppendResult(interp, RSTRING(res)->ptr, (char *)NULL); Tcl_AppendResult(interp, STR2CSTR(res), (char *)NULL);
return TCL_OK; return TCL_OK;
} }
@ -115,6 +171,7 @@ ip_free(struct tcltkip *ptr)
{ {
DUMP1("Tcl_DeleteInterp"); DUMP1("Tcl_DeleteInterp");
Tcl_DeleteInterp(ptr->ip); Tcl_DeleteInterp(ptr->ip);
free(ptr);
} }
/* create and initialize interpreter */ /* create and initialize interpreter */
@ -135,20 +192,26 @@ ip_new(VALUE self)
/* from Tcl_AppInit() */ /* from Tcl_AppInit() */
DUMP1("Tcl_Init"); DUMP1("Tcl_Init");
if (Tcl_Init(ptr->ip) == TCL_ERROR) { if (Tcl_Init(ptr->ip) == TCL_ERROR) {
Fail("Tcl_Init"); rb_raise(rb_eRuntimeError, "Tcl_Init");
} }
DUMP1("Tk_Init"); DUMP1("Tk_Init");
if (Tk_Init(ptr->ip) == TCL_ERROR) { if (Tk_Init(ptr->ip) == TCL_ERROR) {
Fail("Tk_Init"); rb_raise(rb_eRuntimeError, "Tk_Init");
} }
DUMP1("Tcl_StaticPackage(\"Tk\")"); DUMP1("Tcl_StaticPackage(\"Tk\")");
Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init, Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init,
(Tcl_PackageInitProc *) NULL); (Tcl_PackageInitProc *) NULL);
/* add ruby command to the interpreter */ /* add ruby command to the interpreter */
#if TCL_MAJOR_VERSION >= 8
DUMP1("Tcl_CreateObjCommand(\"ruby\")");
Tcl_CreateObjCommand(ptr->ip, "ruby", ip_ruby, (ClientData *)NULL,
(Tcl_CmdDeleteProc *)NULL);
#else
DUMP1("Tcl_CreateCommand(\"ruby\")"); DUMP1("Tcl_CreateCommand(\"ruby\")");
Tcl_CreateCommand(ptr->ip, "ruby", ip_ruby, (ClientData *)NULL, Tcl_CreateCommand(ptr->ip, "ruby", ip_ruby, (ClientData *)NULL,
(Tcl_CmdDeleteProc *)NULL); (Tcl_CmdDeleteProc *)NULL);
#endif
return obj; return obj;
} }
@ -157,6 +220,7 @@ ip_new(VALUE self)
static VALUE static VALUE
ip_eval(VALUE self, VALUE str) ip_eval(VALUE self, VALUE str)
{ {
char *s;
char *buf; /* Tcl_Eval requires re-writable string region */ char *buf; /* Tcl_Eval requires re-writable string region */
struct tcltkip *ptr; /* tcltkip data struct */ struct tcltkip *ptr; /* tcltkip data struct */
@ -164,18 +228,162 @@ ip_eval(VALUE self, VALUE str)
Data_Get_Struct(self, struct tcltkip, ptr); Data_Get_Struct(self, struct tcltkip, ptr);
/* call Tcl_Eval() */ /* call Tcl_Eval() */
Check_Type(str, T_STRING); s = STR2CSTR(str);
buf = ALLOCA_N(char,RSTRING(str)->len+1); buf = ALLOCA_N(char, strlen(s)+1);
strcpy(buf, RSTRING(str)->ptr); strcpy(buf, s);
DUMP2("Tcl_Eval(%s)", buf); DUMP2("Tcl_Eval(%s)", buf);
ptr->return_value = Tcl_Eval(ptr->ip, buf); ptr->return_value = Tcl_Eval(ptr->ip, buf);
if (ptr->return_value == TCL_ERROR) { if (ptr->return_value == TCL_ERROR) {
Fail(ptr->ip->result); rb_raise(rb_eRuntimeError, ptr->ip->result);
} }
DUMP2("(TCL_Eval result) %d", ptr->return_value); DUMP2("(TCL_Eval result) %d", ptr->return_value);
/* pass back the result (as string) */ /* pass back the result (as string) */
return(str_new2(ptr->ip->result)); return(rb_str_new2(ptr->ip->result));
}
static VALUE
ip_toUTF8(VALUE self, VALUE str, VALUE encodename)
{
#ifndef TCL_UTF_MAX
return str;
#else
Tcl_Interp *interp;
Tcl_Encoding encoding;
Tcl_DString dstr;
struct tcltkip *ptr;
char *buff1,*buff2;
Data_Get_Struct(self,struct tcltkip, ptr);
interp = ptr->ip;
encoding = Tcl_GetEncoding(interp,STR2CSTR(encodename));
buff1 = ALLOCA_N(char,strlen(STR2CSTR(str))+1);
strcpy(buff1,STR2CSTR(str));
Tcl_DStringInit(&dstr);
Tcl_DStringFree(&dstr);
Tcl_ExternalToUtfDString(encoding,buff1,strlen(buff1),&dstr);
buff2 = ALLOCA_N(char,Tcl_DStringLength(&dstr)+1);
strcpy(buff2,Tcl_DStringValue(&dstr));
Tcl_FreeEncoding(encoding);
Tcl_DStringFree(&dstr);
return rb_str_new2(buff2);
#endif
}
static VALUE
ip_fromUTF8(VALUE self, VALUE str, VALUE encodename)
{
#ifndef TCL_UTF_MAX
return str;
#else
Tcl_Interp *interp;
Tcl_Encoding encoding;
Tcl_DString dstr;
struct tcltkip *ptr;
char *buff1,*buff2;
Data_Get_Struct(self,struct tcltkip, ptr);
interp = ptr->ip;
encoding = Tcl_GetEncoding(interp,STR2CSTR(encodename));
buff1 = ALLOCA_N(char,strlen(STR2CSTR(str))+1);
strcpy(buff1,STR2CSTR(str));
Tcl_DStringInit(&dstr);
Tcl_DStringFree(&dstr);
Tcl_UtfToExternalDString(encoding,buff1,strlen(buff1),&dstr);
buff2 = ALLOCA_N(char,Tcl_DStringLength(&dstr)+1);
strcpy(buff2,Tcl_DStringValue(&dstr));
Tcl_FreeEncoding(encoding);
Tcl_DStringFree(&dstr);
return rb_str_new2(buff2);
#endif
}
static VALUE
ip_invoke(int argc, VALUE *argv, VALUE obj)
{
struct tcltkip *ptr; /* tcltkip data struct */
int i;
int object = 0;
Tcl_CmdInfo info;
char *cmd;
char **av = (char **)NULL;
#if TCL_MAJOR_VERSION >= 8
Tcl_Obj **ov = (Tcl_Obj **)NULL;
Tcl_Obj *resultPtr;
#endif
/* get the data struct */
Data_Get_Struct(obj, struct tcltkip, ptr);
/* get the command name string */
cmd = STR2CSTR(argv[0]);
/* map from the command name to a C procedure */
if (!Tcl_GetCommandInfo(ptr->ip, cmd, &info)) {
rb_raise(rb_eNameError, "invalid command name `%s'", cmd);
}
#if TCL_MAJOR_VERSION >= 8
object = info.isNativeObjectProc;
#endif
/* memory allocation for arguments of this command */
if (object) {
#if TCL_MAJOR_VERSION >= 8
/* object interface */
ov = (Tcl_Obj **)ALLOCA_N(Tcl_Obj *, argc+1);
for (i = 0; i < argc; ++i) {
char *s = STR2CSTR(argv[i]);
ov[i] = Tcl_NewStringObj(s, strlen(s));
}
ov[argc] = (Tcl_Obj *)NULL;
#endif
} else {
/* string interface */
av = (char **)ALLOCA_N(char *, argc+1);
for (i = 0; i < argc; ++i) {
char *s = STR2CSTR(argv[i]);
av[i] = ALLOCA_N(char, strlen(s)+1);
strcpy(av[i], s);
}
av[argc] = (char *)NULL;
}
Tcl_ResetResult(ptr->ip);
/* Invoke the C procedure */
if (object) {
#if TCL_MAJOR_VERSION >= 8
int dummy;
ptr->return_value = (*info.objProc)(info.objClientData,
ptr->ip, argc, ov);
/* get the string value from the result object */
resultPtr = Tcl_GetObjResult(ptr->ip);
Tcl_SetResult(ptr->ip, Tcl_GetStringFromObj(resultPtr, &dummy),
TCL_VOLATILE);
#endif
} else {
ptr->return_value = (*info.proc)(info.clientData,
ptr->ip, argc, av);
}
if (ptr->return_value == TCL_ERROR) {
rb_raise(rb_eRuntimeError, ptr->ip->result);
}
/* pass back the result (as string) */
return(rb_str_new2(ptr->ip->result));
} }
/* get return code from Tcl_Eval() */ /* get return code from Tcl_Eval() */
@ -190,27 +398,44 @@ ip_retval(VALUE self)
return (INT2FIX(ptr->return_value)); return (INT2FIX(ptr->return_value));
} }
#ifdef __MACOS__
static void
_macinit()
{
tcl_macQdPtr = &qd; /* setup QuickDraw globals */
Tcl_MacSetEventProc(TkMacConvertEvent); /* setup event handler */
}
#endif
/*---- initialization ----*/ /*---- initialization ----*/
void Init_tcltklib() void Init_tcltklib()
{ {
extern VALUE rb_argv0; /* the argv[0] */ extern VALUE rb_argv0; /* the argv[0] */
VALUE lib = rb_define_module("TclTkLib"); VALUE lib = rb_define_module("TclTkLib");
VALUE ip = rb_define_class("TclTkIp", cObject); VALUE ip = rb_define_class("TclTkIp", rb_cObject);
eTkCallbackBreak = rb_define_class("TkCallbackBreak", rb_eStandardError);
eTkCallbackContinue = rb_define_class("TkCallbackContinue",rb_eStandardError);
rb_define_module_function(lib, "mainloop", lib_mainloop, 0); rb_define_module_function(lib, "mainloop", lib_mainloop, 0);
rb_define_singleton_method(ip, "new", ip_new, 0); rb_define_singleton_method(ip, "new", ip_new, 0);
rb_define_method(ip, "_eval", ip_eval, 1); rb_define_method(ip, "_eval", ip_eval, 1);
rb_define_method(ip, "_toUTF8",ip_toUTF8,2);
rb_define_method(ip, "_fromUTF8",ip_fromUTF8,2);
rb_define_method(ip, "_invoke", ip_invoke, -1);
rb_define_method(ip, "_return_value", ip_retval, 0); rb_define_method(ip, "_return_value", ip_retval, 0);
rb_define_method(ip, "mainloop", lib_mainloop, 0); rb_define_method(ip, "mainloop", lib_mainloop, 0);
#ifdef __MACOS__
_macinit();
#endif
/*---- initialize tcl/tk libraries ----*/ /*---- initialize tcl/tk libraries ----*/
/* from Tk_Main() */ /* from Tk_Main() */
DUMP1("Tcl_FindExecutable"); DUMP1("Tcl_FindExecutable");
Tcl_FindExecutable(RSTRING(rb_argv0)->ptr); Tcl_FindExecutable(RSTRING(rb_argv0)->ptr);
rb_define_variable("$tk_thread_safe", &thread_safe);
} }
/* eof */ /* eof */

861
file.c

File diff suppressed because it is too large Load diff

View file

@ -20,6 +20,10 @@ Cambridge, MA 02139, USA. */
#include <errno.h> #include <errno.h>
#include "fnmatch.h" #include "fnmatch.h"
#ifdef USE_CWGUSI
#include <sys/errno.h>
#endif
#if !defined (__GNU_LIBRARY__) && !defined (STDC_HEADERS) #if !defined (__GNU_LIBRARY__) && !defined (STDC_HEADERS)
# if !defined (errno) # if !defined (errno)
extern int errno; extern int errno;
@ -51,15 +55,23 @@ fnmatch (pattern, string, flags)
if (*n == '\0') if (*n == '\0')
return (FNM_NOMATCH); return (FNM_NOMATCH);
else if ((flags & FNM_PATHNAME) && *n == '/') else if ((flags & FNM_PATHNAME) && *n == '/')
/* If we are matching a pathname, `?' can never match a `/'. */
return (FNM_NOMATCH); return (FNM_NOMATCH);
else if ((flags & FNM_PERIOD) && *n == '.' && else if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
/* `?' cannot match a `.' if it is the first character of the
string or if it is the first character following a slash and
we are matching a pathname. */
return (FNM_NOMATCH); return (FNM_NOMATCH);
break; break;
case '\\': case '\\':
if (!(flags & FNM_NOESCAPE)) if (!(flags & FNM_NOESCAPE))
c = *p++; {
c = *p++;
if (c == '\0')
return (FNM_NOMATCH);
}
if (*n != c) if (*n != c)
return (FNM_NOMATCH); return (FNM_NOMATCH);
break; break;
@ -67,19 +79,38 @@ fnmatch (pattern, string, flags)
case '*': case '*':
if ((flags & FNM_PERIOD) && *n == '.' && if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
/* `*' cannot match a `.' if it is the first character of the
string or if it is the first character following a slash and
we are matching a pathname. */
return (FNM_NOMATCH); return (FNM_NOMATCH);
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n) /* Collapse multiple consecutive, `*' and `?', but make sure that
if (((flags & FNM_PATHNAME) && *n == '/') || one character of the string is consumed for each `?'. */
(c == '?' && *n == '\0')) for (c = *p++; c == '?' || c == '*'; c = *p++)
return (FNM_NOMATCH); {
if ((flags & FNM_PATHNAME) && *n == '/')
/* A slash does not match a wildcard under FNM_PATHNAME. */
return (FNM_NOMATCH);
else if (c == '?')
{
if (*n == '\0')
return (FNM_NOMATCH);
/* One character of the string is consumed in matching
this ? wildcard, so *??? won't match if there are
fewer than three characters. */
n++;
}
}
if (c == '\0') if (c == '\0')
return (0); return (0);
/* General case, use recursion. */
{ {
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c; char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
for (--p; *n != '\0'; ++n) for (--p; *n != '\0'; ++n)
/* Only call fnmatch if the first character indicates a
possible match. */
if ((c == '[' || *n == c1) && if ((c == '[' || *n == c1) &&
fnmatch (p, n, flags & ~FNM_PERIOD) == 0) fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
return (0); return (0);
@ -94,22 +125,30 @@ fnmatch (pattern, string, flags)
if (*n == '\0') if (*n == '\0')
return (FNM_NOMATCH); return (FNM_NOMATCH);
/* A character class cannot match a `.' if it is the first
character of the string or if it is the first character
following a slash and we are matching a pathname. */
if ((flags & FNM_PERIOD) && *n == '.' && if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/'))) (n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
return (FNM_NOMATCH); return (FNM_NOMATCH);
/* Make sure there is a closing `]'. If there isn't, the `[' /* POSIX.2 2.8.3.1.2 says: `An expression containing a `[' that
is just a character to be matched. */ is not preceded by a backslash and is not part of a bracket
expression produces undefined results.' This implementation
treats the `[' as just a character to be matched if there is
not a closing `]'. This code will have to be changed when
POSIX.2 character classes are implemented. */
{ {
register char *np; register char *np;
for (np = p; np && *np && *np != ']'; np++); for (np = p; np && *np && *np != ']'; np++)
;
if (np && !*np) if (np && !*np)
{ {
if (*n != '[') if (*n != '[')
return (FNM_NOMATCH); return (FNM_NOMATCH);
goto next_char; break;
} }
} }
@ -120,10 +159,18 @@ fnmatch (pattern, string, flags)
c = *p++; c = *p++;
for (;;) for (;;)
{ {
register char cstart = c, cend = c; register char cstart, cend;
/* Initialize cstart and cend in case `-' is the last
character of the pattern. */
cstart = cend = c;
if (!(flags & FNM_NOESCAPE) && c == '\\') if (!(flags & FNM_NOESCAPE) && c == '\\')
cstart = cend = *p++; {
if (*p == '\0')
return FNM_NOMATCH;
cstart = cend = *p++;
}
if (c == '\0') if (c == '\0')
/* [ (unterminated) loses. */ /* [ (unterminated) loses. */
@ -135,6 +182,9 @@ fnmatch (pattern, string, flags)
/* [/] can never match. */ /* [/] can never match. */
return (FNM_NOMATCH); return (FNM_NOMATCH);
/* This introduces a range, unless the `-' is the last
character of the class. Find the end of the range
and move past it. */
if (c == '-' && *p != ']') if (c == '-' && *p != ']')
{ {
cend = *p++; cend = *p++;
@ -142,6 +192,7 @@ fnmatch (pattern, string, flags)
cend = *p++; cend = *p++;
if (cend == '\0') if (cend == '\0')
return (FNM_NOMATCH); return (FNM_NOMATCH);
c = *p++; c = *p++;
} }
@ -153,8 +204,6 @@ fnmatch (pattern, string, flags)
} }
if (!not) if (!not)
return (FNM_NOMATCH); return (FNM_NOMATCH);
next_char:
break; break;
matched: matched:
@ -167,8 +216,12 @@ fnmatch (pattern, string, flags)
c = *p++; c = *p++;
if (!(flags & FNM_NOESCAPE) && c == '\\') if (!(flags & FNM_NOESCAPE) && c == '\\')
/* 1003.2d11 is unclear if this is right. %%% */ {
++p; if (*p == '\0')
return FNM_NOMATCH;
/* XXX 1003.2d11 is unclear if this is right. */
++p;
}
} }
if (not) if (not)
return (FNM_NOMATCH); return (FNM_NOMATCH);

492
gc.c

File diff suppressed because it is too large Load diff

119
glob.c
View file

@ -14,83 +14,79 @@
You should have received a copy of the GNU General Public License You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* To whomever it may concern: I have never seen the code which most /* To whomever it may concern: I have never seen the code which most
Unix programs use to perform this function. I wrote this from scratch Unix programs use to perform this function. I wrote this from scratch
based on specifications for the pattern matching. --RMS. */ based on specifications for the pattern matching. --RMS. */
#include "config.h" #include "config.h"
#include <sys/types.h> #if !defined (__GNUC__) && !defined (HAVE_ALLOCA_H) && defined (_AIX)
#pragma alloca
#endif /* _AIX && RISC6000 && !__GNUC__ */
#if !defined (SHELL) && (defined (_POSIX_VERSION) || defined (USGr3)) #if defined (HAVE_ALLOCA_H)
# if !defined (HAVE_DIRENT_H) # include <alloca.h>
# define HAVE_DIRENT_H #endif
# endif /* !HAVE_DIRENT_H */
#endif /* !SHELL && (_POSIX_VERSION || USGr3) */ #if defined (HAVE_UNISTD_H)
# include <unistd.h>
#endif
#if defined (HAVE_STDLIB_H)
# include <stdlib.h>
#else
# if defined (SHELL)
# include "ansi_stdlib.h"
# endif /* SHELL */
#endif
#include <sys/types.h>
#if defined (HAVE_DIRENT_H) #if defined (HAVE_DIRENT_H)
# include <dirent.h> # include <dirent.h>
# if !defined (direct) # define D_NAMLEN(d) strlen ((d)->d_name)
# define direct dirent #elif HAVE_DIRECT_H
# endif /* !direct */ # include <direct.h>
# define D_NAMLEN(d) strlen ((d)->d_name) # define D_NAMLEN(d) strlen ((d)->d_name)
#else /* !HAVE_DIRENT_H */ #else /* !HAVE_DIRENT_H */
# define D_NAMLEN(d) ((d)->d_namlen) # define D_NAMLEN(d) ((d)->d_namlen)
# if defined (USG) # if defined (HAVE_SYS_NDIR_H)
# if defined (Xenix) # include <sys/ndir.h>
# include <sys/ndir.h> # endif
# else /* !Xenix (but USG...) */ # if defined (HAVE_SYS_DIR_H)
# include "ndir.h"
# endif /* !Xenix */
# else /* !USG */
# if defined(NT)
# include "missing/dir.h"
# else
# include <sys/dir.h> # include <sys/dir.h>
# endif /* !NT */ # endif /* HAVE_SYS_DIR_H */
# endif /* !USG */ # if defined (HAVE_NDIR_H)
# include <ndir.h>
# endif
# if !defined (dirent)
# define dirent direct
# endif
#endif /* !HAVE_DIRENT_H */ #endif /* !HAVE_DIRENT_H */
#if defined (_POSIX_SOURCE) || defined(DJGPP) #if defined (_POSIX_SOURCE) || defined(DJGPP) || defined(USE_CWGUSI)
/* Posix does not require that the d_ino field be present, and some /* Posix does not require that the d_ino field be present, and some
systems do not provide it. */ systems do not provide it. */
# define REAL_DIR_ENTRY(dp) 1 # define REAL_DIR_ENTRY(dp) 1
#elif defined (__BORLANDC__)
# define REAL_DIR_ENTRY(dp) 1
#else #else
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0) # define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
#endif /* _POSIX_SOURCE */ #endif /* _POSIX_SOURCE */
#if defined (USG) || defined (NeXT)
# if !defined (HAVE_STRING_H)
# define HAVE_STRING_H
# endif /* !HAVE_STRING_H */
#endif /* USG || NeXT */
#if defined (HAVE_STRING_H) #if defined (HAVE_STRING_H)
# include <string.h> # include <string.h>
#else /* !HAVE_STRING_H */ #else /* !HAVE_STRING_H */
# include <strings.h> # include <strings.h>
#endif /* !HAVE_STRING_H */ #endif /* !HAVE_STRING_H */
#ifndef bcopy #if !defined (HAVE_BCOPY) && !defined (bcopy)
# define bcopy(s, d, n) (memcpy ((d), (s), (n))) # define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
#endif #endif /* !HAVE_BCOPY */
#ifdef _AIX
#pragma alloca
#else
#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
#include <alloca.h>
#else
char *alloca ();
#endif
#endif
#include "fnmatch.h"
/* If the opendir () on your system lets you open non-directory files, /* If the opendir () on your system lets you open non-directory files,
then we consider that not robust. Define OPENDIR_NOT_ROBUST in the then we consider that not robust. */
SYSDEP_CFLAGS for your machines entry in machines.h. */
#if defined (OPENDIR_NOT_ROBUST) #if defined (OPENDIR_NOT_ROBUST)
# if defined (SHELL) # if defined (SHELL)
# include "posixstat.h" # include "posixstat.h"
@ -99,6 +95,8 @@ char *alloca ();
# endif /* !SHELL */ # endif /* !SHELL */
#endif /* OPENDIR_NOT_ROBUST */ #endif /* OPENDIR_NOT_ROBUST */
#include "fnmatch.h"
extern void *xmalloc (), *xrealloc (); extern void *xmalloc (), *xrealloc ();
#if !defined (HAVE_STDLIB_H) #if !defined (HAVE_STDLIB_H)
extern void free (); extern void free ();
@ -113,9 +111,15 @@ extern void free ();
#endif /* !NULL */ #endif /* !NULL */
#if defined (SHELL) #if defined (SHELL)
extern void throw_to_top_level ();
extern int interrupt_state; extern int interrupt_state;
#endif /* SHELL */ #endif /* SHELL */
#if defined(NT) && defined(_MSC_VER)
#include "missing/dir.h"
#endif
/* Global variable which controls whether or not * matches .*. /* Global variable which controls whether or not * matches .*.
Non-zero means don't match .*. */ Non-zero means don't match .*. */
int noglob_dot_filenames = 1; int noglob_dot_filenames = 1;
@ -123,7 +127,6 @@ int noglob_dot_filenames = 1;
/* Global variable to return to signify an error in globbing. */ /* Global variable to return to signify an error in globbing. */
char *glob_error_return; char *glob_error_return;
/* Return nonzero if PATTERN has any special globbing chars in it. */ /* Return nonzero if PATTERN has any special globbing chars in it. */
int int
glob_pattern_p (pattern) glob_pattern_p (pattern)
@ -205,7 +208,7 @@ glob_vector (pat, dir)
}; };
DIR *d; DIR *d;
register struct direct *dp; register struct dirent *dp;
struct globval *lastlink; struct globval *lastlink;
register struct globval *nextlink; register struct globval *nextlink;
register char *nextname; register char *nextname;
@ -276,7 +279,8 @@ glob_vector (pat, dir)
continue; continue;
/* If a dot must be explicity matched, check to see if they do. */ /* If a dot must be explicity matched, check to see if they do. */
if (noglob_dot_filenames && dp->d_name[0] == '.' && pat[0] != '.') if (noglob_dot_filenames && dp->d_name[0] == '.' && pat[0] != '.' &&
(pat[0] != '\\' || pat[1] != '.'))
continue; continue;
flags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME; flags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
@ -306,7 +310,9 @@ glob_vector (pat, dir)
} }
/* Have we run out of memory? */ /* Have we run out of memory? */
#if defined (SHELL)
lost: lost:
#endif
if (lose) if (lose)
{ {
/* Here free the strings we have got. */ /* Here free the strings we have got. */
@ -365,7 +371,14 @@ glob_dir_to_array (dir, array)
+ strlen (array[i]) + 1); + strlen (array[i]) + 1);
if (result[i] == NULL) if (result[i] == NULL)
return (NULL); return (NULL);
sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]); #if 1
strcpy (result[i], dir);
if (add_slash)
result[i][l] = '/';
strcpy (result[i] + l + add_slash, array[i]);
#else
(void)sprintf (result[i], "%s%s%s", dir, add_slash ? "/" : "", array[i]);
#endif
} }
result[i] = NULL; result[i] = NULL;
@ -435,10 +448,14 @@ glob_filename (pathname)
if (directories == NULL) if (directories == NULL)
goto memory_error; goto memory_error;
else if (directories == (char **)&glob_error_return) else if (directories == (char **)&glob_error_return)
return ((char **) &glob_error_return); {
free ((char *) result);
return ((char **) &glob_error_return);
}
else if (*directories == NULL) else if (*directories == NULL)
{ {
free ((char *) directories); free ((char *) directories);
free ((char *) result);
return ((char **) &glob_error_return); return ((char **) &glob_error_return);
} }

899
hash.c

File diff suppressed because it is too large Load diff

10
inits.c
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Tue Dec 28 16:01:58 JST 1993 created at: Tue Dec 28 16:01:58 JST 1993
Copyright (C) 1993-1996 Yukihiro Matsumoto Copyright (C) 1993-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
@ -49,14 +49,14 @@ rb_call_inits()
Init_sym(); Init_sym();
Init_var_tables(); Init_var_tables();
Init_Object(); Init_Object();
Init_Exception();
#ifdef THREAD
Init_Thread();
#endif
Init_Comparable(); Init_Comparable();
Init_Enumerable(); Init_Enumerable();
Init_eval(); Init_eval();
Init_String(); Init_String();
Init_Exception();
#ifdef USE_THREAD
Init_Thread();
#endif
Init_Numeric(); Init_Numeric();
Init_Bignum(); Init_Bignum();
Init_Array(); Init_Array();

View file

@ -1,7 +1,10 @@
#!./miniruby #!./miniruby -I.
require "rbconfig.rb" require "rbconfig.rb"
include Config include Config
destdir = ARGV[0] || ''
$:.unshift CONFIG["srcdir"]+"/lib" $:.unshift CONFIG["srcdir"]+"/lib"
require "ftools" require "ftools"
@ -12,26 +15,43 @@ else
prefix = CONFIG["prefix"] prefix = CONFIG["prefix"]
end end
ruby_install_name = CONFIG["ruby_install_name"] ruby_install_name = CONFIG["ruby_install_name"]
bindir = prefix + "/bin" bindir = CONFIG["bindir"]
libdir = prefix + "/lib/" + ruby_install_name libdir = CONFIG["libdir"]
archdir = libdir+"/"+CONFIG["arch"] pkglibdir = libdir + "/" + ruby_install_name
archdir = pkglibdir + "/" + CONFIG["arch"]
mandir = CONFIG["mandir"] + "/man1" mandir = CONFIG["mandir"] + "/man1"
wdir = Dir.getwd
File.makedirs "#{destdir}#{bindir}", true
File.install "ruby#{binsuffix}", File.install "ruby#{binsuffix}",
"#{bindir}/#{ruby_install_name}#{binsuffix}", 0755, TRUE "#{destdir}#{bindir}/#{ruby_install_name}#{binsuffix}", 0755, true
File.makedirs libdir, TRUE for dll in Dir['*.dll']
Dir.chdir "ext" File.install dll, "#{destdir}#{bindir}/#{dll}", 0755, true
system "../miniruby#{binsuffix} extmk.rb install"
Dir.chdir CONFIG["srcdir"]
IO.foreach 'MANIFEST' do |$_|
$_.chop!
if /^lib/
File.install $_, libdir, 0644, TRUE
elsif /^[a-z]+\.h$/
File.install $_, archdir, 0644, TRUE
end
File.install "config.h", archdir, 0644, TRUE
end end
File.install "rbconfig.rb", archdir, 0644, TRUE File.makedirs "#{destdir}#{libdir}", true
File.install "ruby.1", mandir, 0644, TRUE for lib in ["libruby.so", "libruby.so.LIB"]
if File.exist? lib
File.install lib, "#{destdir}#{libdir}", 0644, true
end
end
File.makedirs "#{destdir}#{pkglibdir}", true
File.makedirs "#{destdir}#{archdir}", true
Dir.chdir "ext"
system "../miniruby#{binsuffix} extmk.rb install #{destdir}"
Dir.chdir CONFIG["srcdir"]
for f in Dir["lib/*.rb"]
File.install f, "#{destdir}#{pkglibdir}", 0644, true
end
File.makedirs(archdir,true)
for f in Dir["*.h"]
File.install f, "#{destdir}#{archdir}", 0644, true
end
File.install "libruby.a", "#{destdir}#{archdir}", 0644, true
File.makedirs "#{destdir}#{mandir}", true
File.install "ruby.1", "#{destdir}#{mandir}", 0644, true
Dir.chdir wdir
File.install "config.h", "#{destdir}#{archdir}", 0644, true
File.install "rbconfig.rb", "#{destdir}#{archdir}", 0644, true
# vi:set sw=2: # vi:set sw=2:

484
intern.h
View file

@ -3,289 +3,321 @@
*/ */
/* array.c */ /* array.c */
void memclear _((register VALUE *, register int)); void rb_mem_clear _((register VALUE*, register size_t));
VALUE assoc_new _((VALUE, VALUE)); VALUE rb_assoc_new _((VALUE, VALUE));
VALUE ary_new _((void)); VALUE rb_ary_new _((void));
VALUE ary_new2 _((int)); VALUE rb_ary_new2 _((size_t));
VALUE ary_new3(); VALUE rb_ary_new3 __((size_t,...));
VALUE ary_new4 _((int, VALUE *)); VALUE rb_ary_new4 _((size_t, VALUE *));
VALUE ary_freeze _((VALUE)); VALUE rb_ary_freeze _((VALUE));
void ary_store _((VALUE, int, VALUE)); VALUE rb_ary_aref _((int, VALUE*, VALUE));
VALUE ary_push _((VALUE, VALUE)); void rb_ary_store _((VALUE, size_t, VALUE));
VALUE ary_pop _((VALUE)); VALUE rb_ary_to_s _((VALUE));
VALUE ary_shift _((VALUE)); VALUE rb_ary_push _((VALUE, VALUE));
VALUE ary_unshift _((VALUE, VALUE)); VALUE rb_ary_pop _((VALUE));
VALUE ary_entry _((VALUE, int)); VALUE rb_ary_shift _((VALUE));
VALUE ary_each _((VALUE)); VALUE rb_ary_unshift _((VALUE, VALUE));
VALUE ary_join _((VALUE, VALUE)); VALUE rb_ary_entry _((VALUE, size_t));
VALUE ary_to_s _((VALUE)); VALUE rb_ary_each _((VALUE));
VALUE ary_print_on _((VALUE, VALUE)); VALUE rb_ary_join _((VALUE, VALUE));
VALUE ary_reverse _((VALUE)); VALUE rb_ary_print_on _((VALUE, VALUE));
VALUE ary_sort_bang _((VALUE)); VALUE rb_ary_reverse _((VALUE));
VALUE ary_sort _((VALUE)); VALUE rb_ary_sort _((VALUE));
VALUE ary_delete _((VALUE, VALUE)); VALUE rb_ary_sort_bang _((VALUE));
VALUE ary_delete_at _((VALUE, VALUE)); VALUE rb_ary_delete _((VALUE, VALUE));
VALUE ary_plus _((VALUE, VALUE)); VALUE rb_ary_delete_at _((VALUE, VALUE));
VALUE ary_concat _((VALUE, VALUE)); VALUE rb_ary_plus _((VALUE, VALUE));
VALUE ary_assoc _((VALUE, VALUE)); VALUE rb_ary_concat _((VALUE, VALUE));
VALUE ary_rassoc _((VALUE, VALUE)); VALUE rb_ary_assoc _((VALUE, VALUE));
VALUE ary_includes _((VALUE, VALUE)); VALUE rb_ary_rassoc _((VALUE, VALUE));
VALUE rb_ary_includes _((VALUE, VALUE));
VALUE rb_protect_inspect _((VALUE(*)(),VALUE,VALUE));
VALUE rb_inspecting_p _((VALUE));
/* bignum.c */ /* bignum.c */
VALUE big_clone _((VALUE)); VALUE rb_big_clone _((VALUE));
void big_2comp _((VALUE)); void rb_big_2comp _((VALUE));
VALUE big_norm _((VALUE)); VALUE rb_big_norm _((VALUE));
VALUE uint2big _((UINT)); VALUE rb_uint2big _((unsigned long));
VALUE int2big _((INT)); VALUE rb_int2big _((long));
VALUE uint2inum _((UINT)); VALUE rb_uint2inum _((unsigned long));
VALUE int2inum _((INT)); VALUE rb_int2inum _((long));
VALUE str2inum _((UCHAR *, int)); VALUE rb_str2inum _((char*, int));
VALUE big2str _((VALUE, int)); VALUE rb_big2str _((VALUE, int));
INT big2int _((VALUE)); long rb_big2long _((VALUE));
VALUE big_to_i _((VALUE)); #define rb_big2int(x) rb_big2long(x)
VALUE dbl2big _((double)); unsigned long rb_big2ulong _((VALUE));
double big2dbl _((VALUE)); #define rb_big2uint(x) rb_big2ulong(x)
VALUE big_to_f _((VALUE)); VALUE rb_dbl2big _((double));
VALUE big_plus _((VALUE, VALUE)); double rb_big2dbl _((VALUE));
VALUE big_minus _((VALUE, VALUE)); VALUE rb_big_plus _((VALUE, VALUE));
VALUE big_mul _((VALUE, VALUE)); VALUE rb_big_minus _((VALUE, VALUE));
VALUE big_pow _((VALUE, VALUE)); VALUE rb_big_mul _((VALUE, VALUE));
VALUE big_and _((VALUE, VALUE)); VALUE rb_big_pow _((VALUE, VALUE));
VALUE big_or _((VALUE, VALUE)); VALUE rb_big_and _((VALUE, VALUE));
VALUE big_xor _((VALUE, VALUE)); VALUE rb_big_or _((VALUE, VALUE));
VALUE big_lshift _((VALUE, VALUE)); VALUE rb_big_xor _((VALUE, VALUE));
VALUE big_rand _((VALUE)); VALUE rb_big_lshift _((VALUE, VALUE));
VALUE rb_big_rand _((VALUE));
/* class.c */ /* class.c */
VALUE class_new _((VALUE)); VALUE rb_class_new _((VALUE));
VALUE singleton_class_new _((VALUE)); VALUE rb_singleton_class_new _((VALUE));
VALUE singleton_class_clone _((VALUE)); VALUE rb_singleton_class_clone _((VALUE));
void singleton_class_attached _((VALUE,VALUE)); void rb_singleton_class_attached _((VALUE,VALUE));
VALUE rb_define_class_id _((ID, VALUE)); VALUE rb_define_class_id _((ID, VALUE));
VALUE module_new _((void)); VALUE rb_module_new _((void));
VALUE rb_define_module_id _((ID)); VALUE rb_define_module_id _((ID));
VALUE mod_included_modules _((VALUE)); VALUE rb_mod_included_modules _((VALUE));
VALUE mod_ancestors _((VALUE)); VALUE rb_mod_ancestors _((VALUE));
VALUE class_instance_methods _((int, VALUE *, VALUE)); VALUE rb_class_instance_methods _((int, VALUE*, VALUE));
VALUE class_private_instance_methods _((int, VALUE *, VALUE)); VALUE rb_class_protected_instance_methods _((int, VALUE*, VALUE));
VALUE obj_singleton_methods _((VALUE)); VALUE rb_class_private_instance_methods _((int, VALUE*, VALUE));
VALUE rb_obj_singleton_methods _((VALUE));
void rb_define_method_id _((VALUE, ID, VALUE (*)(), int)); void rb_define_method_id _((VALUE, ID, VALUE (*)(), int));
void rb_undef_method _((VALUE, char *)); void rb_undef_method _((VALUE, char*));
void rb_define_private_method _((VALUE, char *, VALUE (*)(), int)); void rb_define_protected_method _((VALUE, char*, VALUE (*)(), int));
void rb_define_private_method _((VALUE, char*, VALUE (*)(), int));
void rb_define_singleton_method _((VALUE,char*,VALUE(*)(),int)); void rb_define_singleton_method _((VALUE,char*,VALUE(*)(),int));
void rb_define_private_method _((VALUE,char*,VALUE(*)(),int)); void rb_define_private_method _((VALUE,char*,VALUE(*)(),int));
VALUE rb_singleton_class _((VALUE)); VALUE rb_singleton_class _((VALUE));
/* enum.c */ /* enum.c */
VALUE enum_length _((VALUE)); VALUE rb_enum_length _((VALUE));
/* error.c */ /* error.c */
VALUE exc_new _((VALUE, char *, UINT)); extern int ruby_nerrs;
VALUE exc_new2 _((VALUE, char *)); VALUE rb_exc_new _((VALUE, char*, int));
VALUE exc_new3 _((VALUE, VALUE)); VALUE rb_exc_new2 _((VALUE, char*));
#ifdef __GNUC__ VALUE rb_exc_new3 _((VALUE, VALUE));
volatile voidfn TypeError; void rb_loaderror __((char*, ...)) NORETURN;
volatile voidfn ArgError; void rb_compile_error __((char*, ...));
volatile voidfn NameError; void rb_compile_error_append __((char*, ...));
volatile voidfn IndexError;
volatile voidfn LoadError;
#else
void TypeError();
void ArgError();
void NameError();
void IndexError();
void LoadError();
#endif
/* eval.c */ /* eval.c */
void rb_exc_raise _((VALUE)) NORETURN;
void rb_exc_fatal _((VALUE)) NORETURN;
void rb_remove_method _((VALUE, char*));
void rb_disable_super _((VALUE, char*));
void rb_enable_super _((VALUE, char*));
void rb_clear_cache _((void)); void rb_clear_cache _((void));
void rb_alias _((VALUE, ID, ID)); void rb_alias _((VALUE, ID, ID));
void rb_attr _((VALUE,ID,int,int,int));
int rb_method_boundp _((VALUE, ID, int)); int rb_method_boundp _((VALUE, ID, int));
VALUE dyna_var_defined _((ID)); VALUE rb_dvar_defined _((ID));
VALUE dyna_var_ref _((ID)); VALUE rb_dvar_ref _((ID));
VALUE dyna_var_asgn _((ID, VALUE)); void rb_dvar_asgn _((ID, VALUE));
void ruby_init _((void)); void rb_dvar_push _((ID, VALUE));
void ruby_options _((int, char **)); VALUE rb_eval_cmd _((VALUE, VALUE));
void ruby_run _((void)); VALUE rb_trap_eval _((VALUE, int));
void rb_eval_cmd _((VALUE, VALUE));
void rb_trap_eval _((VALUE, int));
int rb_respond_to _((VALUE, ID)); int rb_respond_to _((VALUE, ID));
void rb_raise _((VALUE));
void rb_fatal _((VALUE));
void rb_interrupt _((void)); void rb_interrupt _((void));
int iterator_p _((void));
VALUE rb_yield_0 _((VALUE, volatile VALUE));
VALUE rb_apply _((VALUE, ID, VALUE)); VALUE rb_apply _((VALUE, ID, VALUE));
VALUE rb_funcall2 _((VALUE, ID, int, VALUE *)); VALUE rb_funcall2 _((VALUE, ID, int, VALUE*));
void rb_backtrace _((void)); void rb_backtrace _((void));
ID rb_frame_last_func _((void)); ID rb_frame_last_func _((void));
VALUE f_load _((VALUE, VALUE)); VALUE rb_obj_instance_eval _((int, VALUE*, VALUE));
void rb_provide _((char *)); void rb_load _((VALUE, int));
VALUE f_require _((VALUE, VALUE)); void rb_load_protect _((VALUE, int, int*));
VALUE class_new_instance _((int, VALUE *, VALUE)); void rb_jump_tag _((int)) NORETURN;
VALUE f_lambda _((void)); void rb_provide _((char*));
void rb_set_end_proc _((void (*)(),VALUE)); VALUE rb_f_require _((VALUE, VALUE));
void gc_mark_threads _((void)); void rb_obj_call_init _((VALUE));
void thread_schedule _((void)); VALUE rb_class_new_instance _((int, VALUE*, VALUE));
void thread_wait_fd _((int)); VALUE rb_f_lambda _((void));
void thread_fd_writable _((int)); VALUE rb_protect _((VALUE (*)(), VALUE, int*));
int thread_alone _((void)); void rb_set_end_proc _((void (*)(), VALUE));
void thread_sleep _((int)); void rb_gc_mark_threads _((void));
void thread_sleep_forever _((void)); void rb_thread_start_timer _((void));
VALUE thread_create _((VALUE (*)(), void *)); void rb_thread_stop_timer _((void));
void thread_interrupt _((void)); void rb_thread_schedule _((void));
void rb_thread_wait_fd _((int));
void rb_thread_fd_writable _((int));
int rb_thread_alone _((void));
void rb_thread_sleep _((int));
void rb_thread_sleep_forever _((void));
VALUE rb_thread_create _((VALUE (*)(), void*));
int rb_thread_scope_shared_p _((void));
void rb_thread_interrupt _((void));
void rb_thread_trap_eval _((VALUE, int));
int rb_thread_select();
void rb_thread_wait_for();
VALUE rb_thread_current _((void));
VALUE rb_thread_main _((void));
VALUE rb_thread_local_aref _((VALUE, ID));
VALUE rb_thread_local_aset _((VALUE, ID, VALUE));
/* file.c */ /* file.c */
VALUE file_open _((char *, char *)); VALUE rb_file_open _((char*, char*));
int eaccess _((char *, int)); int eaccess _((char*, int));
VALUE file_s_expand_path _((VALUE, VALUE)); VALUE rb_file_s_expand_path _((int, VALUE *));
/* gc.c */ /* gc.c */
void rb_global_variable _((VALUE *)); void rb_global_variable _((VALUE*));
void gc_mark_locations _((VALUE *, VALUE *)); void rb_gc_mark_locations _((VALUE*, VALUE*));
void gc_mark_maybe(); void rb_mark_tbl _((struct st_table*));
void gc_mark(); void rb_mark_hash _((struct st_table*));
void gc_force_recycle(); void rb_gc_mark_maybe();
void gc_gc _((void)); void rb_gc_mark();
void init_stack _((void)); void rb_gc_force_recycle _((VALUE));
void init_heap _((void)); void rb_gc _((void));
void rb_gc_call_finalizer_at_exit _((void));
/* hash.c */ /* hash.c */
VALUE hash_freeze _((VALUE));
VALUE rb_hash _((VALUE)); VALUE rb_hash _((VALUE));
VALUE hash_new _((void)); VALUE rb_hash_new _((void));
VALUE hash_aref _((VALUE, VALUE)); VALUE rb_hash_freeze _((VALUE));
VALUE hash_aset _((VALUE, VALUE, VALUE)); VALUE rb_hash_aref _((VALUE, VALUE));
VALUE rb_hash_aset _((VALUE, VALUE, VALUE));
int rb_path_check _((char *));
int rb_env_path_tainted _((void));
/* io.c */ /* io.c */
void eof_error _((void)); extern VALUE rb_fs;
VALUE io_write _((VALUE, VALUE)); extern VALUE rb_output_fs;
VALUE io_gets_method _((int, VALUE*, VALUE)); extern VALUE rb_rs;
VALUE io_gets _((VALUE)); extern VALUE rb_default_rs;
VALUE io_getc _((VALUE)); extern VALUE rb_output_rs;
VALUE io_ungetc _((VALUE, VALUE)); VALUE rb_io_write _((VALUE, VALUE));
VALUE io_close _((VALUE)); VALUE rb_io_gets _((VALUE));
VALUE io_binmode _((VALUE)); VALUE rb_io_getc _((VALUE));
int io_mode_flags _((char *)); VALUE rb_io_ungetc _((VALUE, VALUE));
VALUE io_reopen _((VALUE, VALUE)); VALUE rb_io_close _((VALUE));
VALUE f_gets _((void)); VALUE rb_io_eof _((VALUE));
void rb_str_setter _((VALUE, ID, VALUE *)); VALUE rb_io_binmode _((VALUE));
int rb_io_mode_flags _((char*));
VALUE rb_io_reopen _((VALUE, VALUE));
VALUE rb_gets _((void));
void rb_str_setter _((VALUE, ID, VALUE*));
/* numeric.c */ /* numeric.c */
void num_zerodiv _((void)); void rb_num_zerodiv _((void));
VALUE num_coerce_bin _((VALUE, VALUE)); VALUE rb_num_coerce_bin _((VALUE, VALUE));
VALUE float_new _((double)); VALUE rb_float_new _((double));
VALUE flo_pow _((VALUE, VALUE)); VALUE rb_num2fix _((VALUE));
VALUE num2fix _((VALUE)); VALUE rb_fix2str _((VALUE, int));
VALUE fix2str _((VALUE, int)); VALUE rb_fix_upto _((VALUE, VALUE));
VALUE fix_to_s _((VALUE));
VALUE num_upto _((VALUE, VALUE));
VALUE fix_upto _((VALUE, VALUE));
/* object.c */ /* object.c */
VALUE rb_equal _((VALUE, VALUE));
int rb_eql _((VALUE, VALUE)); int rb_eql _((VALUE, VALUE));
VALUE obj_equal _((VALUE, VALUE)); VALUE rb_any_to_s _((VALUE));
VALUE any_to_s _((VALUE));
VALUE rb_inspect _((VALUE)); VALUE rb_inspect _((VALUE));
VALUE obj_is_instance_of _((VALUE, VALUE)); VALUE rb_obj_is_instance_of _((VALUE, VALUE));
VALUE obj_is_kind_of _((VALUE, VALUE)); VALUE rb_obj_is_kind_of _((VALUE, VALUE));
VALUE obj_alloc _((VALUE)); VALUE rb_obj_alloc _((VALUE));
VALUE rb_obj_clone _((VALUE));
VALUE rb_obj_taint _((VALUE));
VALUE rb_obj_tainted _((VALUE));
VALUE rb_obj_untaint _((VALUE));
VALUE rb_obj_id _((VALUE));
VALUE rb_convert_type _((VALUE,int,char*,char*));
VALUE rb_Integer _((VALUE)); VALUE rb_Integer _((VALUE));
VALUE rb_Float _((VALUE)); VALUE rb_Float _((VALUE));
VALUE rb_String _((VALUE)); VALUE rb_String _((VALUE));
VALUE rb_Array _((VALUE)); VALUE rb_Array _((VALUE));
double num2dbl _((VALUE));
/* parse.y */ /* parse.y */
extern int ruby_sourceline;
extern char *ruby_sourcefile;
int yyparse _((void)); int yyparse _((void));
void pushback _((int)); ID rb_id_attrset _((ID));
ID id_attrset _((ID)); void rb_parser_append_print _((void));
void yyappend_print _((void)); void rb_parser_while_loop _((int, int));
void yywhile_loop _((int, int));
int rb_is_const_id _((ID)); int rb_is_const_id _((ID));
int rb_is_instance_id _((ID)); int rb_is_instance_id _((ID));
void local_var_append _((ID)); VALUE rb_backref_get _((void));
VALUE backref_get _((void)); void rb_backref_set _((VALUE));
void backref_set _((VALUE)); VALUE rb_lastline_get _((void));
VALUE lastline_get _((void)); void rb_lastline_set _((VALUE));
void lastline_set _((VALUE));
/* process.c */ /* process.c */
int rb_proc_exec _((char *)); int rb_proc_exec _((char*));
void rb_syswait _((int)); void rb_syswait _((int));
/* range.c */ /* range.c */
VALUE range_new _((VALUE, VALUE)); VALUE rb_range_new _((VALUE, VALUE));
VALUE range_beg_end _((VALUE, int *, int *)); VALUE rb_range_beg_end _((VALUE, int*, int*));
/* re.c */ /* re.c */
VALUE reg_nth_defined _((int, VALUE)); VALUE rb_reg_nth_defined _((int, VALUE));
VALUE reg_nth_match _((int, VALUE)); VALUE rb_reg_nth_match _((int, VALUE));
VALUE reg_last_match _((VALUE)); VALUE rb_reg_last_match _((VALUE));
VALUE reg_match_pre _((VALUE)); VALUE rb_reg_match_pre _((VALUE));
VALUE reg_match_post _((VALUE)); VALUE rb_reg_match_post _((VALUE));
VALUE reg_match_last _((VALUE)); VALUE rb_reg_match_last _((VALUE));
VALUE reg_new _((char *, int, int)); VALUE rb_reg_new _((char*, size_t, int));
VALUE reg_match _((VALUE, VALUE)); VALUE rb_reg_match _((VALUE, VALUE));
VALUE reg_match2 _((VALUE)); VALUE rb_reg_match2 _((VALUE));
void rb_set_kcode _((char *)); int rb_reg_options _((VALUE));
char*rb_get_kcode _((void));
void rb_set_kcode _((char*));
int rb_ignorecase_p _((void));
/* ruby.c */ /* ruby.c */
void rb_require_modules _((void)); void rb_load_file _((char*));
void rb_load_file _((char *)); void ruby_script _((char*));
void ruby_script _((char *));
void ruby_prog_init _((void)); void ruby_prog_init _((void));
void ruby_set_argv _((int, char **)); void ruby_set_argv _((int, char**));
void ruby_process_options _((int, char **)); void ruby_process_options _((int, char**));
void ruby_require_modules _((void));
void ruby_load_script _((void));
/* signal.c */ /* signal.c */
VALUE f_kill _((int, VALUE *)); VALUE rb_f_kill _((int, VALUE*));
void gc_mark_trap_list _((void)); void rb_gc_mark_trap_list _((void));
#ifdef POSIX_SIGNAL
#define posix_signal ruby_posix_signal
void posix_signal _((int, void (*)())); void posix_signal _((int, void (*)()));
#endif
void rb_trap_exit _((void)); void rb_trap_exit _((void));
void rb_trap_exec _((void)); void rb_trap_exec _((void));
/* sprintf.c */ /* sprintf.c */
VALUE f_sprintf _((int, VALUE *)); VALUE rb_f_sprintf _((int, VALUE*));
/* string.c */ /* string.c */
VALUE str_new _((UCHAR *, UINT)); VALUE rb_str_new _((char*, size_t));
VALUE str_new2 _((UCHAR *)); VALUE rb_str_new2 _((char*));
VALUE str_new3 _((VALUE)); VALUE rb_str_new3 _((VALUE));
VALUE str_new4 _((VALUE)); VALUE rb_str_new4 _((VALUE));
VALUE obj_as_string _((VALUE)); VALUE rb_tainted_str_new _((char*, size_t));
VALUE str_dup _((VALUE)); VALUE rb_tainted_str_new2 _((char*));
VALUE str_plus _((VALUE, VALUE)); VALUE rb_obj_as_string _((VALUE));
VALUE str_times _((VALUE, VALUE)); VALUE rb_str_to_str _((VALUE));
VALUE str_substr _((VALUE, int, int)); VALUE rb_str_dup _((VALUE));
void str_modify _((VALUE)); VALUE rb_str_plus _((VALUE, VALUE));
VALUE str_freeze _((VALUE)); VALUE rb_str_times _((VALUE, VALUE));
VALUE str_dup_freezed _((VALUE)); VALUE rb_str_substr _((VALUE, size_t, size_t));
VALUE str_taint _((VALUE)); void rb_str_modify _((VALUE));
VALUE str_tainted _((VALUE)); VALUE rb_str_freeze _((VALUE));
VALUE str_resize _((VALUE, int)); VALUE rb_str_dup_frozen _((VALUE));
VALUE str_cat _((VALUE, UCHAR *, UINT)); VALUE rb_str_resize _((VALUE, size_t));
int str_hash _((VALUE)); VALUE rb_str_cat _((VALUE, char*, size_t));
int str_cmp _((VALUE, VALUE)); VALUE rb_str_concat _((VALUE, VALUE));
VALUE str_upto _((VALUE, VALUE)); int rb_str_hash _((VALUE));
VALUE str_inspect _((VALUE)); int rb_str_cmp _((VALUE, VALUE));
VALUE str_split _((VALUE, char *)); VALUE rb_str_upto _((VALUE, VALUE));
VALUE rb_str_inspect _((VALUE));
VALUE rb_str_split _((VALUE, char*));
/* struct.c */ /* struct.c */
VALUE struct_new(); VALUE rb_struct_new __((VALUE, ...));
VALUE struct_define(); VALUE rb_struct_define __((char*, ...));
VALUE struct_alloc _((VALUE, VALUE)); VALUE rb_struct_alloc _((VALUE, VALUE));
VALUE struct_aref _((VALUE, VALUE)); VALUE rb_struct_aref _((VALUE, VALUE));
VALUE struct_aset _((VALUE, VALUE, VALUE)); VALUE rb_struct_aset _((VALUE, VALUE, VALUE));
VALUE struct_getmember _((VALUE, ID)); VALUE rb_struct_getmember _((VALUE, ID));
/* time.c */ /* time.c */
VALUE time_new _((int, int)); VALUE rb_time_new _((int, int));
/* util.c */
void add_suffix _((VALUE, char *));
unsigned long scan_oct _((char *, int, int *));
unsigned long scan_hex _((char *, int, int *));
/* variable.c */ /* variable.c */
VALUE mod_name _((VALUE)); VALUE rb_mod_name _((VALUE));
VALUE rb_class_path _((VALUE)); VALUE rb_class_path _((VALUE));
void rb_set_class_path _((VALUE, VALUE, char *)); void rb_set_class_path _((VALUE, VALUE, char*));
VALUE rb_path2class _((char *)); VALUE rb_path2class _((char*));
void rb_name_class _((VALUE, ID)); void rb_name_class _((VALUE, ID));
void rb_autoload _((char *, char *)); void rb_autoload _((char*, char*));
VALUE f_autoload _((VALUE, VALUE, VALUE)); VALUE rb_f_autoload _((VALUE, VALUE, VALUE));
void gc_mark_global_tbl _((void)); void rb_gc_mark_global_tbl _((void));
VALUE f_trace_var _((int, VALUE *)); VALUE rb_f_trace_var _((int, VALUE*));
VALUE f_untrace_var _((int, VALUE *)); VALUE rb_f_untrace_var _((int, VALUE*));
VALUE rb_gvar_set2 _((char *, VALUE)); VALUE rb_gvar_set2 _((char*, VALUE));
VALUE f_global_variables _((void)); VALUE rb_f_global_variables _((void));
void rb_alias_variable _((ID, ID)); void rb_alias_variable _((ID, ID));
void rb_mark_generic_ivar _((VALUE));
void rb_mark_generic_ivar_tbl _((void));
void rb_free_generic_ivar _((VALUE));
VALUE rb_ivar_get _((VALUE, ID)); VALUE rb_ivar_get _((VALUE, ID));
VALUE rb_ivar_set _((VALUE, ID, VALUE)); VALUE rb_ivar_set _((VALUE, ID, VALUE));
VALUE rb_ivar_defined _((VALUE, ID)); VALUE rb_ivar_defined _((VALUE, ID));
VALUE obj_instance_variables _((VALUE)); VALUE rb_obj_instance_variables _((VALUE));
VALUE mod_const_at _((VALUE, VALUE)); VALUE rb_obj_remove_instance_variable _((VALUE, VALUE));
VALUE mod_constants _((VALUE)); VALUE rb_mod_const_at _((VALUE, VALUE));
VALUE mod_const_of _((VALUE, VALUE)); VALUE rb_mod_constants _((VALUE));
VALUE rb_mod_const_of _((VALUE, VALUE));
VALUE rb_mod_remove_const _((VALUE, VALUE));
int rb_const_defined_at _((VALUE, ID)); int rb_const_defined_at _((VALUE, ID));
int rb_autoload_defined _((ID)); int rb_autoload_defined _((ID));
int rb_const_defined _((VALUE, ID)); int rb_const_defined _((VALUE, ID));
/* version.c */
void ruby_show_version _((void));
void ruby_show_copyright _((void));

1536
io.c

File diff suppressed because it is too large Load diff

View file

@ -1,5 +1,7 @@
struct kwtable {char *name; int id[2]; enum lex_state state;}; struct kwtable {char *name; int id[2]; enum lex_state state;};
%% %%
__LINE__, k__LINE__, k__LINE__, EXPR_END
__FILE__, k__FILE__, k__FILE__, EXPR_END
BEGIN, klBEGIN, klBEGIN, EXPR_END BEGIN, klBEGIN, klBEGIN, EXPR_END
END, klEND, klEND, EXPR_END END, klEND, klEND, EXPR_END
alias, kALIAS, kALIAS, EXPR_FNAME alias, kALIAS, kALIAS, EXPR_FNAME

44
lex.c
View file

@ -2,12 +2,12 @@
/* Command-line: gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$ keywords */ /* Command-line: gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k1,3,$ keywords */
struct kwtable {char *name; int id[2]; enum lex_state state;}; struct kwtable {char *name; int id[2]; enum lex_state state;};
#define TOTAL_KEYWORDS 38 #define TOTAL_KEYWORDS 40
#define MIN_WORD_LENGTH 2 #define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 8 #define MAX_WORD_LENGTH 8
#define MIN_HASH_VALUE 6 #define MIN_HASH_VALUE 6
#define MAX_HASH_VALUE 52 #define MAX_HASH_VALUE 55
/* maximum key range = 47, duplicates = 0 */ /* maximum key range = 50, duplicates = 0 */
#ifdef __GNUC__ #ifdef __GNUC__
inline inline
@ -19,19 +19,19 @@ hash (str, len)
{ {
static unsigned char asso_values[] = static unsigned char asso_values[] =
{ {
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
53, 53, 53, 11, 53, 53, 34, 53, 1, 35, 56, 56, 56, 11, 56, 56, 36, 56, 1, 37,
53, 1, 53, 53, 53, 53, 53, 53, 1, 53, 31, 1, 56, 56, 56, 56, 29, 56, 1, 56,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
53, 53, 53, 53, 53, 53, 53, 29, 1, 2, 56, 56, 56, 56, 56, 1, 56, 32, 1, 2,
1, 1, 4, 24, 53, 17, 53, 20, 9, 2, 1, 1, 4, 23, 56, 17, 56, 20, 9, 2,
9, 26, 14, 53, 5, 1, 1, 16, 53, 21, 9, 26, 14, 56, 5, 1, 1, 16, 56, 21,
24, 9, 53, 53, 53, 53, 53, 53, 20, 9, 56, 56, 56, 56, 56, 56,
}; };
register int hval = len; register int hval = len;
@ -87,17 +87,19 @@ rb_reserved_word (str, len)
{"until", kUNTIL, kUNTIL_MOD, EXPR_BEG}, {"until", kUNTIL, kUNTIL_MOD, EXPR_BEG},
{"unless", kUNLESS, kUNLESS_MOD, EXPR_BEG}, {"unless", kUNLESS, kUNLESS_MOD, EXPR_BEG},
{"or", kOR, kOR, EXPR_BEG}, {"or", kOR, kOR, EXPR_BEG},
{"and", kAND, kAND, EXPR_BEG}, {"next", kNEXT, kNEXT, EXPR_END},
{"when", kWHEN, kWHEN, EXPR_BEG}, {"when", kWHEN, kWHEN, EXPR_BEG},
{"redo", kREDO, kREDO, EXPR_END}, {"redo", kREDO, kREDO, EXPR_END},
{"class", kCLASS, kCLASS, EXPR_CLASS}, {"and", kAND, kAND, EXPR_BEG},
{"next", kNEXT, kNEXT, EXPR_END},
{"begin", kBEGIN, kBEGIN, EXPR_BEG}, {"begin", kBEGIN, kBEGIN, EXPR_BEG},
{"__LINE__", k__LINE__, k__LINE__, EXPR_END},
{"class", kCLASS, kCLASS, EXPR_CLASS},
{"__FILE__", k__FILE__, k__FILE__, EXPR_END},
{"END", klEND, klEND, EXPR_END}, {"END", klEND, klEND, EXPR_END},
{"BEGIN", klBEGIN, klBEGIN, EXPR_END}, {"BEGIN", klBEGIN, klBEGIN, EXPR_END},
{"",}, {"",},
{"while", kWHILE, kWHILE_MOD, EXPR_BEG}, {"while", kWHILE, kWHILE_MOD, EXPR_BEG},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"",},
{"alias", kALIAS, kALIAS, EXPR_FNAME}, {"alias", kALIAS, kALIAS, EXPR_FNAME},
}; };

View file

@ -1,50 +1,25 @@
def decode64(str) require "kconv"
string = ''
for line in str.split("\n")
line.delete!('^A-Za-z0-9+/') # remove non-base64 chars
line.tr!('A-Za-z0-9+/', ' -_') # convert to uuencoded format
len = ["#{32 + line.length * 3 / 4}"].pack("c")
# compute length byte
string += "#{len}#{line}".unpack("u") # uudecode and concatenate
end
return string
end
def j2e(str) def decode64(str)
while str =~ /\033\$B([^\033]*)\033\(B/ str.unpack("m")[0]
s = $1
pre, post = $`, $'
s.gsub!(/./) { |ch|
(ch[0]|0x80).chr
}
str = pre + s + post
end
# str.gsub!(/\033\$B([^\033]*)\033\(B/) {
# $1.gsub!(/./) { |ch|
# (ch[0]|0x80).chr
# }
# }
str
end end
def decode_b(str) def decode_b(str)
str.gsub!(/=\?ISO-2022-JP\?B\?([!->@-~]+)\?=/i) { str.gsub!(/=\?ISO-2022-JP\?B\?([!->@-~]+)\?=/i) {
decode64($1) decode64($1)
} }
str = Kconv::toeuc(str)
str.gsub!(/=\?SHIFT_JIS\?B\?([!->@-~]+)\?=/i) {
decode64($1)
}
str = Kconv::toeuc(str)
str.gsub!(/\n/, ' ') str.gsub!(/\n/, ' ')
str.gsub!(/\0/, '') str.gsub!(/\0/, '')
j2e(str) str
end end
def encode64(bin) def encode64(bin)
encode = "" [bin].pack("m")
pad = 0
[bin].pack("u").each do |uu|
len = (2 + (uu[0] - 32)* 4) / 3
encode << uu[1, len].tr('` -_', 'AA-Za-z0-9+/')
pad += uu.length - 2 - len
end
encode + "=" * (pad % 3)
end end
def b64encode(bin, len = 60) def b64encode(bin, len = 60)

View file

@ -1,4 +1,3 @@
#!/usr/local/bin/ruby
# #
# Get CGI String # Get CGI String
# #
@ -7,26 +6,26 @@
# foo = CGI.new # foo = CGI.new
# foo['field'] <== value of 'field' # foo['field'] <== value of 'field'
# foo.keys <== array of fields # foo.keys <== array of fields
# foo.inputs <== hash of { <field> => <value> } # and foo has Hash class methods
# if running on Windows(IIS or PWS) then change cwd. # if running on Windows(IIS or PWS) then change cwd.
if ENV['SERVER_SOFTWARE'] =~ /^Microsoft-/ then if ENV['SERVER_SOFTWARE'] =~ /^Microsoft-/ then
Dir.chdir ENV['PATH_TRANSLATED'].sub(/[^\\]+$/, '') Dir.chdir ENV['PATH_TRANSLATED'].sub(/[^\\]+$/, '')
end end
require "shellwords.rb" require "delegate"
class CGI class CGI < SimpleDelegator
include Shellwords
attr("inputs") attr("inputs")
# original is CGI.pm # original is CGI.pm
def read_from_cmdline def read_from_cmdline
words = shellwords(if not ARGV.empty? then require "shellwords.rb"
words = Shellwords.shellwords(if not ARGV.empty? then
ARGV.join(' ') ARGV.join(' ')
else else
print "(offline mode: enter name=value pairs on standard input)\n" STDERR.print "(offline mode: enter name=value pairs on standard input)\n" if STDIN.tty?
readlines.join(' ').gsub(/\n/, '') readlines.join(' ').gsub(/\n/, '')
end.gsub(/\\=/, '%3D').gsub(/\\&/, '%26')) end.gsub(/\\=/, '%3D').gsub(/\\&/, '%26'))
@ -47,32 +46,32 @@ class CGI
end end
module_function :escape, :unescape module_function :escape, :unescape
def initialize def initialize(input = $stdin)
# exception messages should be printed to stdout.
STDERR.reopen(STDOUT)
@inputs = {} @inputs = {}
case ENV['REQUEST_METHOD'] case ENV['REQUEST_METHOD']
when "GET" when "GET"
# exception messages should be printed to stdout.
STDERR.reopen(STDOUT)
ENV['QUERY_STRING'] or "" ENV['QUERY_STRING'] or ""
when "POST" when "POST"
$stdin.read ENV['CONTENT_LENGTH'].to_i # exception messages should be printed to stdout.
STDERR.reopen(STDOUT)
input.read Integer(ENV['CONTENT_LENGTH'])
else else
read_from_cmdline read_from_cmdline
end.split(/&/).each do |x| end.split(/&/).each do |x|
key, val = x.split(/=/,2).collect{|x|unescape(x)} key, val = x.split(/=/,2).collect{|x|unescape(x)}
@inputs[key] += ("\0" if @inputs[key]) + (val or "") if @inputs.include?(key)
@inputs[key] += "\0" + (val or "")
else
@inputs[key] = (val or "")
end
end end
super(@inputs)
end end
def keys
@inputs.keys
end
def [](key)
@inputs[key]
end
def CGI.message(msg, title = "") def CGI.message(msg, title = "")
print "Content-type: text/html\n\n" print "Content-type: text/html\n\n"
print "<html><head><title>" print "<html><head><title>"
@ -84,7 +83,7 @@ class CGI
end end
def CGI.error def CGI.error
m = $!.dup m = $!.to_s.dup
m.gsub!(/&/, '&amp;') m.gsub!(/&/, '&amp;')
m.gsub!(/</, '&lt;') m.gsub!(/</, '&lt;')
m.gsub!(/>/, '&gt;') m.gsub!(/>/, '&gt;')

View file

@ -1,8 +1,8 @@
# #
# complex.rb - # complex.rb -
# $Release Version: 0.5 $ # $Release Version: 0.5 $
# $Revision: 1.1 $ # $Revision: 1.3 $
# $Date: 1996/11/11 04:25:19 $ # $Date: 1998/07/08 10:05:28 $
# by Keiju ISHITSUKA(SHL Japan Inc.) # by Keiju ISHITSUKA(SHL Japan Inc.)
# #
# -- # --
@ -59,6 +59,7 @@ def Complex(a, b = 0)
end end
class Complex < Numeric class Complex < Numeric
@RCS_ID='-$Id: complex.rb,v 1.3 1998/07/08 10:05:28 keiju Exp keiju $-'
def Complex.generic?(other) def Complex.generic?(other)
other.kind_of?(Integer) or other.kind_of?(Integer) or
@ -284,6 +285,11 @@ class Complex < Numeric
@real ^ @image @real ^ @image
end end
def inspect
sprintf("Complex(%s, %s)", @real.inspect, @image.inspect)
end
I = Complex(0,1) I = Complex(0,1)
attr :real attr :real
@ -396,7 +402,7 @@ module Math
cos!(z) cos!(z)
else else
Complex(cos!(z.real)*cosh!(z.image), Complex(cos!(z.real)*cosh!(z.image),
sin!(z.real)*sinh!(z.image)) -sin!(z.real)*sinh!(z.image))
end end
end end
@ -405,7 +411,7 @@ module Math
sin!(z) sin!(z)
else else
Complex(sin!(z.real)*cosh!(z.image), Complex(sin!(z.real)*cosh!(z.image),
-cos!(z.real)*sinh!(z.image)) cos!(z.real)*sinh!(z.image))
end end
end end

View file

@ -1,8 +1,8 @@
# #
# Date.rb - # Date.rb -
# $Release Version: $ # $Release Version: $
# $Revision: 1.2 $ # $Revision: 1.1.1.1.4.5 $
# $Date: 1997/02/14 11:05:29 $ # $Date: 1998/03/03 02:39:34 $
# by Yasuo OHBA(SHL Japan Inc. Technology Dept.) # by Yasuo OHBA(SHL Japan Inc. Technology Dept.)
# #
# -- # --
@ -17,15 +17,34 @@
class Date class Date
include Comparable include Comparable
Weektag = [
"Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"
]
Monthtag = [
"January","February","March","April", "May", "June","July",
"August", "September", "October", "November", "December"
]
Monthtab = {
"jan"=>1, "feb"=>2, "mar"=>3, "apr"=>4, "may"=>5, "jun"=>6,
"jul"=>7, "aug"=>8, "sep"=>9, "oct"=>10, "nov"=>11, "dec"=>12
}
def initialize(y = 1, m = 1, d = 1) def initialize(y = 1, m = 1, d = 1)
if y.kind_of?(String) && y.size == 8 if y.kind_of?(String)
@year = y[0,4].to_i case y
@month = y[4,2].to_i when /(\d\d\d\d)-?(?:(\d\d)-?(\d\d)?)?/
@day = y[6,2].to_i @year = $1.to_i
@month = if $2 then $2.to_i else 1 end
@day = if $3 then $3.to_i else 1 end
else
require 'parsedate'
@year, @month, @day = ParseDate.parsedate(y)
end
else else
if m.kind_of?(String) if m.kind_of?(String)
ml = {"jan"=>1, "feb"=>2, "mar"=>3, "apr"=>4, "may"=>5, "jun"=>6, "jul"=>7, "aug"=>8, "sep"=>9, "oct"=>10, "nov"=>11, "dec"=>12} m = Monthtab[m.downcase]
m = ml[m.downcase]
if m.nil? if m.nil?
raise ArgumentError, "Wrong argument. (month)" raise ArgumentError, "Wrong argument. (month)"
end end
@ -53,25 +72,35 @@ class Date
def period def period
return Date.period!(@year, @month, @day) return Date.period!(@year, @month, @day)
end end
def jd
return period + 1721423
end
def mjd
return jd - 2400000.5
end
def to_s
format("%.3s, %.3s %2d %4d", name_of_week, name_of_month, @day, @year)
end
def inspect
to_s
end
def day_of_week def day_of_week
dl = Date.daylist(@year) return (period + 5) % 7
d = Date.jan1!(@year)
for m in 1..(@month - 1)
d += dl[m]
end
d += @day - 1
if @year == 1752 && @month == 9 && @day >= 14
d -= (14 - 3)
end
return (d % 7)
end end
Weektag = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
def name_of_week def name_of_week
return Weektag[self.day_of_week] return Weektag[self.day_of_week]
end end
def name_of_month
return Monthtag[@month-1]
end
def +(o) def +(o)
if o.kind_of?(Numeric) if o.kind_of?(Numeric)
d = Integer(self.period + o) d = Integer(self.period + o)
@ -80,6 +109,9 @@ class Date
else else
raise TypeError, "Illegal type. (Integer or Date)" raise TypeError, "Illegal type. (Integer or Date)"
end end
if d <= 0
raise ArgumentError, "argument out of range. (self > other)"
end
return Date.at(d) return Date.at(d)
end end
@ -117,14 +149,13 @@ class Date
end end
def leapyear? def leapyear?
if Date.leapyear(@year) == 1 Date.leapyear(@year) != 1
return FALSE
else
return TRUE
end
end end
def _check_date def _check_date
if @year == nil or @month == nil or @day == nil
raise ArgumentError, "argument contains nil"
end
m = Date.daylist(@year) m = Date.daylist(@year)
if @month < 1 || @month > 12 if @month < 1 || @month > 12
raise ArgumentError, "argument(month) out of range." raise ArgumentError, "argument(month) out of range."
@ -151,7 +182,7 @@ end
def Date.at(d) def Date.at(d)
if d.kind_of? Time if d.kind_of? Time
return Date.new(1900+d.year, d.mon+1, d.mday) return Date.new(d.year, d.mon, d.mday)
end end
if d.kind_of? Date if d.kind_of? Date
return Date.at(d.period) return Date.at(d.period)
@ -189,10 +220,10 @@ def Date.period!(y, m, d)
p += dl[mm] p += dl[mm]
end end
p += (y - 1) * 365 + ((y - 1) / 4.0).to_i p += (y - 1) * 365 + ((y - 1) / 4.0).to_i
if (y - 1) > 1752 if y > 1752
p -= ((y - 1 - 1752) / 100.0).to_i p -= ((y - 1) / 100.0).to_i
p += ((y - 1 - 1752) / 400.0).to_i p += ((y - 1) / 400.0).to_i
p -= (14 - 3) p += 2
elsif y == 1752 && m == 9 && d >= 14 && d <= 30 elsif y == 1752 && m == 9 && d >= 14 && d <= 30
p -= (14 - 3) p -= (14 - 3)
end end

View file

@ -11,6 +11,8 @@ class DEBUGGER__
@scripts = {} @scripts = {}
end end
DEBUG_LAST_CMD = []
def interrupt def interrupt
@stop_next = 1 @stop_next = 1
end end
@ -40,6 +42,11 @@ class DEBUGGER__
STDOUT.flush STDOUT.flush
while input = STDIN.gets while input = STDIN.gets
input.chop! input.chop!
if input == ""
input = DEBUG_LAST_CMD[0]
else
DEBUG_LAST_CMD[0] = input
end
case input case input
when /^b(reak)?\s+(([^:\n]+:)?.+)/ when /^b(reak)?\s+(([^:\n]+:)?.+)/
pos = $2 pos = $2
@ -169,7 +176,7 @@ class DEBUGGER__
printf "no sourcefile available for %s\n", file printf "no sourcefile available for %s\n", file
end end
when /^p\s+/ when /^p\s+/
p debug_eval($', binding) p debug_eval($', binding) #'
else else
v = debug_eval(input, binding) v = debug_eval(input, binding)
p v unless v == nil p v unless v == nil
@ -187,10 +194,13 @@ class DEBUGGER__
return "\n" unless line return "\n" unless line
return line return line
end end
save = $DEBUG
begin begin
$DEBUG = FALSE
f = open(file) f = open(file)
lines = @scripts[file] = f.readlines lines = @scripts[file] = f.readlines
rescue rescue
$DEBUG = save
@scripts[file] = TRUE @scripts[file] = TRUE
return "\n" return "\n"
end end

View file

@ -1,26 +1,51 @@
# Delegation class that delegates even methods defined in super class, # Delegation class that delegates even methods defined in super class,
# which can not be covered with normal method_missing hack. # which can not be covered with normal method_missing hack.
# #
# Delegater is the abstract delegation class. Need to redefine # Delegator is the abstract delegation class. Need to redefine
# `__getobj__' method in the subclass. SimpleDelegater is the # `__getobj__' method in the subclass. SimpleDelegator is the
# concrete subclass for simple delegation. # concrete subclass for simple delegation.
# #
# Usage: # Usage:
# foo = Object.new # foo = Object.new
# foo = SimpleDelegater.new(foo) # foo2 = SimpleDelegator.new(foo)
# foo.type # => Object # foo.hash == foo2.hash # => true
#
# Foo = DelegateClass(Array)
#
# class ExtArray<DelegateClass(Array)
# ...
# end
class Delegater class Delegator
def initialize(obj) def initialize(obj)
preserved = ["id", "equal?", "__getobj__"] preserved = ::Kernel.instance_methods
preserved -= ["to_s","to_a","inspect","==","=~","==="]
for t in self.type.ancestors for t in self.type.ancestors
preserved |= t.instance_methods preserved |= t.instance_methods
break if t == Delegater preserved |= t.private_instance_methods
preserved |= t.protected_instance_methods
break if t == Delegator
end end
for method in obj.methods for method in obj.methods
next if preserved.include? method next if preserved.include? method
eval "def self.#{method}(*args); __getobj__.send :#{method}, *args; end" eval <<-EOS
def self.#{method}(*args, &block)
begin
__getobj__.__send__(:#{method}, *args, &block)
rescue Exception
c = -caller(0).size
if /:in `__getobj__'$/ =~ $@[c-1] #`
n = 1
else
c -= 1
n = 2
end
$@[c,n] = nil
raise
end
end
EOS
end end
end end
@ -30,7 +55,7 @@ class Delegater
end end
class SimpleDelegater<Delegater class SimpleDelegator<Delegator
def initialize(obj) def initialize(obj)
super super
@ -41,4 +66,61 @@ class SimpleDelegater<Delegater
@obj @obj
end end
def __setobj__(obj)
@obj = obj
end
end
# backward compatibility ^_^;;;
Delegater = Delegator
SimpleDelegater = SimpleDelegator
#
def DelegateClass(superclass)
klass = Class.new
methods = superclass.instance_methods
methods -= ::Kernel.instance_methods
methods |= ["to_s","to_a","inspect","==","=~","==="]
klass.module_eval <<-EOS
def initialize(obj)
@obj = obj
end
EOS
for method in methods
klass.module_eval <<-EOS
def #{method}(*args, &block)
begin
@obj.__send__(:#{method}, *args, &block)
rescue
$@[0,2] = nil
raise
end
end
EOS
end
return klass;
end
if __FILE__ == $0
class ExtArray<DelegateClass(Array)
def initialize()
super([])
end
end
ary = ExtArray.new
p ary.type
ary.push 25
p ary
foo = Object.new
def foo.test
25
end
def foo.error
raise 'this is OK'
end
foo2 = SimpleDelegator.new(foo)
p foo.test == foo2.test # => true
foo2.error # raise error!
end end

View file

@ -1,11 +1,22 @@
# #
# e2mmap.rb - for ruby 1.1 # e2mmap.rb - for ruby 1.1
# $Release Version: 1.1$ # $Release Version: 1.2$
# $Revision: 1.4 $ # $Revision: 1.8 $
# $Date: 1997/08/18 07:12:12 $ # $Date: 1998/08/19 15:22:22 $
# by Keiju ISHITSUKA # by Keiju ISHITSUKA
# #
# -- # --
# Usage:
#
# class Foo
# extend Exception2MassageMapper
# def_exception :NewExceptionClass, "message..."[, superclass]
# def_e2meggage ExistingExceptionClass, "message..."
# ...
# end
#
# Foo.Fail NewExceptionClass, arg...
# Foo.Fail ExistingExceptionClass, arg...
# #
# #
if VERSION < "1.1" if VERSION < "1.1"
@ -13,40 +24,60 @@ if VERSION < "1.1"
else else
module Exception2MessageMapper module Exception2MessageMapper
RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/e2mmap.rb,v 1.4 1997/08/18 07:12:12 keiju Exp keiju $-' @RCS_ID='-$Id: e2mmap.rb,v 1.8 1998/08/19 15:22:22 keiju Exp keiju $-'
E2MM = Exception2MessageMapper E2MM = Exception2MessageMapper
def E2MM.extend_object(cl) def E2MM.extend_object(cl)
super super
cl.bind(self) cl.bind(self)
end end
# 以前との互換性のために残してある. # backward compatibility
def E2MM.extend_to(b) def E2MM.extend_to(b)
c = eval("self", b) c = eval("self", b)
c.extend(self) c.extend(self)
end end
# public :fail # public :fail
# alias e2mm_fail fail alias fail! fail
def fail(err = nil, *rest) #def fail(err = nil, *rest)
Exception2MessageMapper.fail Exception2MessageMapper::ErrNotRegisteredException, err.to_s # super
#end
def Fail(err = nil, *rest)
Exception2MessageMapper.Fail Exception2MessageMapper::ErrNotRegisteredException, err.inspect
end end
def bind(cl) def bind(cl)
self.module_eval %q^ self.module_eval %q^
E2MM_ErrorMSG = {} E2MM_ErrorMSG = {} unless self.const_defined?(:E2MM_ErrorMSG)
# fail(err, *rest) # fail(err, *rest)
# err: 例外 # err: Exception
# rest: メッセージに渡すパラメータ # rest: Parameter accompanied with the exception
# #
def self.fail(err = nil, *rest) def self.Fail(err = nil, *rest)
$@ = caller(0) if $@.nil?
$@.shift
if form = E2MM_ErrorMSG[err] if form = E2MM_ErrorMSG[err]
$! = err.new(sprintf(form, *rest)) $! = err.new(sprintf(form, *rest))
$@ = caller(0) if $@.nil?
$@.shift
# e2mm_fail()
raise()
# elsif self == Exception2MessageMapper
# fail Exception2MessageMapper::ErrNotRegisteredException, err.to_s
else
# print "super\n"
super
end
end
# ²áµî¤Î¸ß´¹À­¤Î¤¿¤á
def self.fail(err = nil, *rest)
if form = E2MM_ErrorMSG[err]
$! = err.new(sprintf(form, *rest))
$@ = caller(0) if $@.nil?
$@.shift
# e2mm_fail() # e2mm_fail()
raise() raise()
# elsif self == Exception2MessageMapper # elsif self == Exception2MessageMapper
@ -63,7 +94,6 @@ else
# def_exception(c, m) # def_exception(c, m)
# c: exception # c: exception
# m: message_form # m: message_form
# 例外cのメッセージをmとする.
# #
def self.def_e2message(c, m) def self.def_e2message(c, m)
E2MM_ErrorMSG[c] = m E2MM_ErrorMSG[c] = m
@ -72,13 +102,21 @@ else
# def_exception(c, m) # def_exception(c, m)
# n: exception_name # n: exception_name
# m: message_form # m: message_form
# s: 例外スーパークラス(デフォルト: Exception) # s: superclass_of_exception (default: Exception)
# 例外名``c''をもつ例外を定義し, そのメッセージをmとする. # defines excaption named ``c'', whose message is ``m''.
# #
#def def_exception(n, m) #def def_exception(n, m)
def self.def_exception(n, m, s = Exception) def self.def_exception(n, m, s = nil)
n = n.id2name if n.kind_of?(Fixnum) n = n.id2name if n.kind_of?(Fixnum)
unless s
if defined?(StandardError)
s = StandardError
else
s = Exception
end
end
e = Class.new(s) e = Class.new(s)
const_set(n, e) const_set(n, e)
E2MM_ErrorMSG[e] = m E2MM_ErrorMSG[e] = m
# const_get(:E2MM_ErrorMSG)[e] = m # const_get(:E2MM_ErrorMSG)[e] = m
@ -91,4 +129,3 @@ else
def_exception(:ErrNotRegisteredException, "not registerd exception(%s)") def_exception(:ErrNotRegisteredException, "not registerd exception(%s)")
end end
end end

View file

@ -30,10 +30,7 @@ class Regexp
end end
end end
p "abc" =~ /b/|/c/ if __FILE__ == $0
p "abc" =~ /b/&/c/ p "abc" =~ /b/|/c/
p "abc" =~ /b/&/c/
end

View file

@ -1,8 +1,8 @@
# #
# finalizer.rb - # finalizer.rb -
# $Release Version: 0.2$ # $Release Version: 0.3$
# $Revision: 1.3 $ # $Revision: 1.4 $
# $Date: 1998/01/09 08:09:49 $ # $Date: 1998/02/27 05:34:33 $
# by Keiju ISHITSUKA # by Keiju ISHITSUKA
# #
# -- # --
@ -11,44 +11,42 @@
# #
# add(obj, dependant, method = :finalize, *opt) # add(obj, dependant, method = :finalize, *opt)
# add_dependency(obj, dependant, method = :finalize, *opt) # add_dependency(obj, dependant, method = :finalize, *opt)
# 依存関係 R_method(obj, dependant) の追加 # add dependency R_method(obj, dependant)
# #
# delete(obj_or_id, dependant, method = :finalize) # delete(obj_or_id, dependant, method = :finalize)
# delete_dependency(obj_or_id, dependant, method = :finalize) # delete_dependency(obj_or_id, dependant, method = :finalize)
# 依存関係 R_method(obj, dependant) の削除 # delete dependency R_method(obj, dependant)
# delete_all_dependency(obj_or_id, dependant) # delete_all_dependency(obj_or_id, dependant)
# 依存関係 R_*(obj, dependant) の削除 # delete dependency R_*(obj, dependant)
# delete_by_dependant(dependant, method = :finalize) # delete_by_dependant(dependant, method = :finalize)
# 依存関係 R_method(*, dependant) の削除 # delete dependency R_method(*, dependant)
# delete_all_by_dependant(dependant) # delete_all_by_dependant(dependant)
# 依存関係 R_*(*, dependant) の削除 # delete dependency R_*(*, dependant)
# delete_all # delete_all
# 全ての依存関係の削除. # delete all dependency R_*(*, *)
# #
# finalize(obj_or_id, dependant, method = :finalize) # finalize(obj_or_id, dependant, method = :finalize)
# finalize_dependency(obj_or_id, dependant, method = :finalize) # finalize_dependency(obj_or_id, dependant, method = :finalize)
# 依存関連 R_method(obj, dependtant) で結ばれるdependantを # finalize the dependant connected by dependency R_method(obj, dependtant).
# finalizeする.
# finalize_all_dependency(obj_or_id, dependant) # finalize_all_dependency(obj_or_id, dependant)
# 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする. # finalize all dependants connected by dependency R_*(obj, dependtant).
# finalize_by_dependant(dependant, method = :finalize) # finalize_by_dependant(dependant, method = :finalize)
# 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする. # finalize the dependant connected by dependency R_method(*, dependtant).
# fainalize_all_by_dependant(dependant) # fainalize_all_by_dependant(dependant)
# 依存関連 R_*(*, dependtant) で結ばれるdependantをfinalizeする. # finalize all dependants connected by dependency R_*(*, dependant).
# finalize_all # finalize_all
# Finalizerに登録される全てのdependantをfinalizeする # finalize all dependency registered to the Finalizer.
# #
# safe{..} # safe{..}
# gc時にFinalizerが起動するのを止める. # stop invoking Finalizer on GC.
#
# #
module Finalizer module Finalizer
RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/finalize.rb,v 1.3 1998/01/09 08:09:49 keiju Exp keiju $-' RCS_ID='-$Id: finalize.rb,v 1.4 1998/02/27 05:34:33 keiju Exp keiju $-'
# @dependency: {id => [[dependant, method, *opt], ...], ...} # @dependency: {id => [[dependant, method, *opt], ...], ...}
# 依存関係 R_method(obj, dependant) の追加 # add dependency R_method(obj, dependant)
def add_dependency(obj, dependant, method = :finalize, *opt) def add_dependency(obj, dependant, method = :finalize, *opt)
ObjectSpace.call_finalizer(obj) ObjectSpace.call_finalizer(obj)
method = method.intern unless method.kind_of?(Integer) method = method.intern unless method.kind_of?(Integer)
@ -61,7 +59,7 @@ module Finalizer
end end
alias add add_dependency alias add add_dependency
# 依存関係 R_method(obj, dependant) の削除 # delete dependency R_method(obj, dependant)
def delete_dependency(id, dependant, method = :finalize) def delete_dependency(id, dependant, method = :finalize)
id = id.id unless id.kind_of?(Integer) id = id.id unless id.kind_of?(Integer)
method = method.intern unless method.kind_of?(Integer) method = method.intern unless method.kind_of?(Integer)
@ -75,7 +73,7 @@ module Finalizer
end end
alias delete delete_dependency alias delete delete_dependency
# 依存関係 R_*(obj, dependant) の削除 # delete dependency R_*(obj, dependant)
def delete_all_dependency(id, dependant) def delete_all_dependency(id, dependant)
id = id.id unless id.kind_of?(Integer) id = id.id unless id.kind_of?(Integer)
method = method.intern unless method.kind_of?(Integer) method = method.intern unless method.kind_of?(Integer)
@ -88,30 +86,29 @@ module Finalizer
end end
end end
# 依存関係 R_method(*, dependant) の削除 # delete dependency R_method(*, dependant)
def delete_by_dependant(dependant, method = :finalize) def delete_by_dependant(dependant, method = :finalize)
method = method.intern unless method.kind_of?(Integer) method = method.intern unless method.kind_of?(Integer)
for id in Dependency.keys for id in @dependency.keys
delete(id, dependant, method) delete(id, dependant, method)
end end
end end
# 依存関係 R_*(*, dependant) の削除 # delete dependency R_*(*, dependant)
def delete_all_by_dependant(dependant) def delete_all_by_dependant(dependant)
for id in @dependency.keys for id in @dependency.keys
delete_all_dependency(id, dependant) delete_all_dependency(id, dependant)
end end
end end
# 依存関連 R_method(obj, dependtant) で結ばれるdependantをfinalizeす # finalize the depandant connected by dependency R_method(obj, dependtant)
# る.
def finalize_dependency(id, dependant, method = :finalize) def finalize_dependency(id, dependant, method = :finalize)
id = id.id unless id.kind_of?(Integer) id = id.id unless id.kind_of?(Integer)
method = method.intern unless method.kind_of?(Integer) method = method.intern unless method.kind_of?(Integer)
for assocs in @dependency[id] for assocs in @dependency[id]
assocs.delete_if do assocs.delete_if do
|d, m, *o| |d, m, *o|
d.send(m, *o) if ret = d == dependant && m == method d.send(m, id, *o) if ret = d == dependant && m == method
ret ret
end end
@dependency.delete(id) if assoc.empty? @dependency.delete(id) if assoc.empty?
@ -119,20 +116,20 @@ module Finalizer
end end
alias finalize finalize_dependency alias finalize finalize_dependency
# 依存関連 R_*(obj, dependtant) で結ばれるdependantをfinalizeする. # finalize all dependants connected by dependency R_*(obj, dependtant)
def finalize_all_dependency(id, dependant) def finalize_all_dependency(id, dependant)
id = id.id unless id.kind_of?(Integer) id = id.id unless id.kind_of?(Integer)
method = method.intern unless method.kind_of?(Integer) method = method.intern unless method.kind_of?(Integer)
for assoc in @dependency[id] for assoc in @dependency[id]
assoc.delete_if do assoc.delete_if do
|d, m, *o| |d, m, *o|
d.send(m, *o) if ret = d == dependant d.send(m, id, *o) if ret = d == dependant
end end
@dependency.delete(id) if assoc.empty? @dependency.delete(id) if assoc.empty?
end end
end end
# 依存関連 R_method(*, dependtant) で結ばれるdependantをfinalizeする. # finalize the dependant connected by dependency R_method(*, dependtant)
def finalize_by_dependant(dependant, method = :finalize) def finalize_by_dependant(dependant, method = :finalize)
method = method.intern unless method.kind_of?(Integer) method = method.intern unless method.kind_of?(Integer)
for id in @dependency.keys for id in @dependency.keys
@ -140,14 +137,14 @@ module Finalizer
end end
end end
# 依存関連 R_*(*, dependtant) で結ばれるdependantをfinalizeする. # finalize all dependants connected by dependency R_*(*, dependtant)
def fainalize_all_by_dependant(dependant) def fainalize_all_by_dependant(dependant)
for id in @dependency.keys for id in @dependency.keys
finalize_all_dependency(id, dependant) finalize_all_dependency(id, dependant)
end end
end end
# Finalizerに登録されている全てのdependantをfinalizeする # finalize all dependants registered to the Finalizer.
def finalize_all def finalize_all
for id, assocs in @dependency for id, assocs in @dependency
for dependant, method, *opt in assocs for dependant, method, *opt in assocs
@ -157,7 +154,7 @@ module Finalizer
end end
end end
# finalize_* を安全に呼び出すためのイテレータ # method to call finalize_* safely.
def safe def safe
old_status = Thread.critical old_status = Thread.critical
Thread.critical = TRUE Thread.critical = TRUE
@ -167,7 +164,7 @@ module Finalizer
Thread.critical = old_status Thread.critical = old_status
end end
# ObjectSpace#add_finalizerへの登録関数 # registering function to ObjectSpace#add_finalizer
def final_of(id) def final_of(id)
if assocs = @dependency.delete(id) if assocs = @dependency.delete(id)
for dependant, method, *opt in assocs for dependant, method, *opt in assocs
@ -202,4 +199,3 @@ module Finalizer
private_class_method :final_of private_class_method :final_of
end end

View file

@ -1,5 +1,5 @@
# Usage: # Usage:
# require "find.rb" # require "find"
# #
# Find.find('/foo','/bar') {|f| ...} # Find.find('/foo','/bar') {|f| ...}
# or # or
@ -12,7 +12,7 @@ module Find
while file = path.shift while file = path.shift
catch(:prune) { catch(:prune) {
yield file yield file
if File.directory? file and not File.symlink? file then if File.directory? file then
d = Dir.open(file) d = Dir.open(file)
begin begin
for f in d for f in d

View file

@ -30,7 +30,7 @@ class << File
to.binmode to.binmode
begin begin
while TRUE while true
r = from.sysread(fsize) r = from.sysread(fsize)
rsize = r.size rsize = r.size
w = 0 w = 0
@ -40,9 +40,9 @@ class << File
end end
end end
rescue EOFError rescue EOFError
ret = TRUE ret = true
rescue rescue
ret = FALSE ret = false
ensure ensure
to.close to.close
from.close from.close
@ -50,7 +50,7 @@ class << File
ret ret
end end
def copy from, to, verbose = FALSE def copy from, to, verbose = false
$stderr.print from, " -> ", catname(from, to), "\n" if verbose $stderr.print from, " -> ", catname(from, to), "\n" if verbose
syscopy from, to syscopy from, to
end end
@ -59,11 +59,11 @@ class << File
# move file # move file
def move from, to, verbose = FALSE def move from, to, verbose = false
to = catname(from, to) to = catname(from, to)
$stderr.print from, " -> ", to, "\n" if verbose $stderr.print from, " -> ", to, "\n" if verbose
if PLATFORM =~ /djgpp|cygwin32|mswin32/ and FileTest.file? to if PLATFORM =~ /djgpp|cygwin|mswin32/ and FileTest.file? to
unlink to unlink to
end end
begin begin
@ -76,10 +76,10 @@ class << File
alias mv move alias mv move
# compare two files # compare two files
# TRUE: identical # true: identical
# FALSE: not identical # false: not identical
def compare from, to, verbose = FALSE def compare from, to, verbose = false
$stderr.print from, " <=> ", to, "\n" if verbose $stderr.print from, " <=> ", to, "\n" if verbose
fsize = size(from) fsize = size(from)
fsize = 1024 if fsize < 512 fsize = 1024 if fsize < 512
@ -90,7 +90,7 @@ class << File
to = open(to, "r") to = open(to, "r")
to.binmode to.binmode
ret = FALSE ret = false
fr = tr = '' fr = tr = ''
begin begin
@ -103,7 +103,7 @@ class << File
end end
end end
rescue rescue
ret = FALSE ret = false
ensure ensure
to.close to.close
from.close from.close
@ -116,7 +116,7 @@ class << File
# unlink files safely # unlink files safely
def safe_unlink(*files) def safe_unlink(*files)
verbose = if files[-1].is_a? String then FALSE else files.pop end verbose = if files[-1].is_a? String then false else files.pop end
begin begin
$stderr.print files.join(" "), "\n" if verbose $stderr.print files.join(" "), "\n" if verbose
chmod 0777, *files chmod 0777, *files
@ -129,7 +129,7 @@ class << File
alias rm_f safe_unlink alias rm_f safe_unlink
def makedirs(*dirs) def makedirs(*dirs)
verbose = if dirs[-1].is_a? String then FALSE else dirs.pop end verbose = if dirs[-1].is_a? String then false else dirs.pop end
# mode = if dirs[-1].is_a? Fixnum then dirs.pop else 0755 end # mode = if dirs[-1].is_a? Fixnum then dirs.pop else 0755 end
mode = 0755 mode = 0755
for dir in dirs for dir in dirs
@ -146,14 +146,15 @@ class << File
alias o_chmod chmod alias o_chmod chmod
def chmod(mode, *files) def chmod(mode, *files)
verbose = if files[-1].is_a? String then FALSE else files.pop end verbose = if files[-1].is_a? String then false else files.pop end
$stderr.printf "chmod %04o %s\n", mode, files.join(" ") if verbose $stderr.printf "chmod %04o %s\n", mode, files.join(" ") if verbose
o_chmod mode, *files o_chmod mode, *files
end end
def install(from, to, mode, verbose) def install(from, to, mode = nil, verbose = false)
to = catname(from, to) to = catname(from, to)
unless FileTest.exist? to and cmp from, to unless FileTest.exist? to and cmp from, to
unlink to if FileTest.exist? to
cp from, to, verbose cp from, to, verbose
chmod mode, to, verbose if mode chmod mode, to, verbose if mode
end end

File diff suppressed because it is too large Load diff

View file

@ -1,4 +1,3 @@
#!/usr/local/bin/ruby
# #
# getopts.rb - # getopts.rb -
# $Release Version: $ # $Release Version: $
@ -11,7 +10,7 @@
# #
# #
$RCS_ID="$Header$" $RCS_ID=%q$Header$
def isSingle(lopt) def isSingle(lopt)
if lopt.index(":") if lopt.index(":")

View file

@ -21,9 +21,12 @@ for k,v in ENV
EOS EOS
end end
p $TERM if __FILE__ == $0
$TERM = nil p $TERM
p $TERM $TERM = nil
p ENV["TERM"] p $TERM
$TERM = "foo" p ENV["TERM"]
p ENV["TERM"] $TERM = "foo"
p ENV["TERM"]
end

View file

@ -11,13 +11,13 @@ class String
alias original_succ succ alias original_succ succ
private :original_succ private :original_succ
def mbchar?(c) def mbchar?
if $KCODE =~ /^s/i if $KCODE =~ /^s/i
c =~ /[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc]/n self =~ /[\x81-\x9f\xe0-\xef][\x40-\x7e\x80-\xfc]/n
elsif $KCODE =~ /^e/i elsif $KCODE =~ /^e/i
c =~ /[\xa1-\xfe][\xa1-\xfe]/n self =~ /[\xa1-\xfe][\xa1-\xfe]/n
else else
FALSE false
end end
end end
@ -25,12 +25,13 @@ class String
if self[-2] && self[-2] & 0x80 != 0 if self[-2] && self[-2] & 0x80 != 0
s = self.dup s = self.dup
s[-1] += 1 s[-1] += 1
s[-1] += 1 if !mbchar?(s) s[-1] += 1 if !s.mbchar?
return s return s
else else
original_succ original_succ
end end
end end
alias next succ
def upto(to) def upto(to)
return if self > to return if self > to
@ -41,7 +42,7 @@ class String
if self[0..-2] == to[0..-2] if self[0..-2] == to[0..-2]
first = self[-2].chr first = self[-2].chr
for c in self[-1] .. to[-1] for c in self[-1] .. to[-1]
if mbchar?(first+c.chr) if (first+c.chr).mbchar?
yield self[0..-2]+c.chr yield self[0..-2]+c.chr
end end
end end
@ -103,7 +104,7 @@ class String
end end
def tr(from, to) def tr(from, to)
self.dup.tr!(from, to) (str = self.dup).tr!(from, to) or str
end end
def delete!(del) def delete!(del)
@ -126,7 +127,7 @@ class String
end end
def delete(del) def delete(del)
self.dup.delete!(del) (str = self.dup).delete!(del) or str
end end
def squeeze!(del=nil) def squeeze!(del=nil)
@ -154,7 +155,7 @@ class String
end end
def squeeze(del=nil) def squeeze(del=nil)
self.dup.squeeze!(del) (str = self.dup).squeeze!(del) or str
end end
def tr_s!(from, to) def tr_s!(from, to)
@ -187,7 +188,7 @@ class String
end end
def tr_s(from, to) def tr_s(from, to)
self.dup.tr_s!(from,to) (str = self.dup).tr_s!(from,to) or str
end end
alias original_chop! chop! alias original_chop! chop!
@ -201,7 +202,7 @@ class String
end end
def chop def chop
self.dup.chop! (str = self.dup).chop! or str
end end
end end
$VERBOSE = $vsave $VERBOSE = $vsave

View file

@ -1,7 +1,7 @@
class Mail class Mail
def initialize(f) def initialize(f)
unless f.kind_of?(IO) unless defined? f.gets
f = open(f, "r") f = open(f, "r")
opened = true opened = true
end end
@ -15,7 +15,8 @@ class Mail
break if /^$/ # end of header break if /^$/ # end of header
if /^(\S+):\s*(.*)/ if /^(\S+):\s*(.*)/
@header[attr = $1.capitalize!] = $2 (attr = $1).capitalize!
@header[attr] = $2
elsif attr elsif attr
sub!(/^\s*/, '') sub!(/^\s*/, '')
@header[attr] += "\n" + $_ @header[attr] += "\n" + $_

View file

@ -1,8 +1,8 @@
# #
# mathn.rb - # mathn.rb -
# $Release Version: 0.5 $ # $Release Version: 0.5 $
# $Revision: 1.1 $ # $Revision: 1.1.1.1.4.1 $
# $Date: 1997/07/03 04:43:47 $ # $Date: 1998/01/16 12:36:05 $
# by Keiju ISHITSUKA(SHL Japan Inc.) # by Keiju ISHITSUKA(SHL Japan Inc.)
# #
# -- # --
@ -96,6 +96,7 @@ class Prime
@counts.push @seed + @seed @counts.push @seed + @seed
return @seed return @seed
end end
alias next succ
def each def each
loop do loop do

View file

@ -1,9 +1,8 @@
#!/usr/local/bin/ruby
# #
# matrix.rb - # matrix.rb -
# $Release Version: 1.0$ # $Release Version: 1.0$
# $Revision: 1.0 $ # $Revision: 1.6 $
# $Date: 97/05/23 11:35:28 $ # $Date: 1998/07/31 03:39:49 $
# Original Version from Smalltalk-80 version # Original Version from Smalltalk-80 version
# on July 23, 1985 at 8:37:17 am # on July 23, 1985 at 8:37:17 am
# by Keiju ISHITSUKA # by Keiju ISHITSUKA
@ -18,9 +17,158 @@
# : # :
# rown] # rown]
# #
# column: Îó
# row: ¹Ô
# #
# module ExceptionForMatrix::
# Exceptions:
# ErrDimensionMismatch
# number of column/row do not match
# ErrNotRegular
# not a regular matrix
# ErrOperationNotDefined
# specified operator is not defined (yet)
#
# class Matrix
# include ExceptionForMatrix
#
# Methods:
# class methods:
# Matrix.[](*rows)
# creates a matrix where `rows' indicates rows.
# `rows' is an array of arrays,
# e.g, Matrix[[11, 12], [21, 22]]
# Matrix.rows(rows, copy = TRUE)
# creates a matrix where `rows' indicates rows.
# if optional argument `copy' is false, use the array as
# internal structure of the metrix without copying.
# Matrix.columns(columns)
# creates a new matrix using `columns` as set of colums vectors.
# Matrix.diagonal(*values)
# creates a matrix where `columns' indicates columns.
# Matrix.scalar(n, value)
# creates a diagonal matrix such that the diagal compornents is
# given by `values'.
# Matrix.scalar(n, value)
# creates an n-by-n scalar matrix such that the diagal compornent is
# given by `value'.
# Matrix.identity(n)
# Matrix.unit(n)
# Matrix.I(n)
# creates an n-by-n unit matrix.
# Matrix.zero(n)
# creates an n-by-n zero matrix.
# Matrix.row_vector(row)
# creates a 1-by-n matrix such the row vector is `row'.
# `row' is specifed as a Vector or an Array.
# Matrix.column_vector(column)
# creates a 1-by-n matrix such that column vector is `column'.
# `column' is specifed as a Vector or an Array.
# accessing:
# [](i, j)
# returns (i,j) compornent
# row_size
# returns the number of rows
# column_size
# returns the number of columns
# row(i)
# returns the i-th row vector.
# when the block is supplied for the method, the block is iterated
# over all row vectors.
# column(j)
# returns the jth column vector.
# when the block is supplied for the method, the block is iterated
# over all column vectors.
# collect
# map
# creates a matrix which is the result of iteration of given
# block over all compornents.
# minor(*param)
# returns sub matrix. parameter is specified as the following:
# 1. from_row, row_size, from_col, size_col
# 2. from_row..to_row, from_col..to_col
# TESTING:
# regular?
# Is regular?
# singular?
# Is singular? i.e. Is non-regular?
# square?
# Is square?
# ARITHMETIC:
# *(m)
# times
# +(m)
# plus
# -(m)
# minus
# /(m)
# self * m.inv
# inverse
# inv
# inverse
# **
# power
# Matrix functions:
# determinant
# det
# returns the determinant
# rank
# returns the rank
# trace
# tr
# returns the trace
# transpose
# t
# returns the transposed
# CONVERTING:
# coerce(other)
# row_vectors
# array of row vectors
# column_vectors
# array of column vectors
# to_a
# converts each element to Array
# to_f
# converts each element to Float
# to_i
# converts each element to Integer
# to_r
# converts each element to Rational
# PRINTING:
# to_s
# returns string representation
# inspect
#
# class Vector
# include ExceptionForMatrix
#
# INSTANCE CREATION:
# Vector.[](*array)
# Vector.elements(array, copy = TRUE)
# ACCSESSING:
# [](i)
# size
# ENUMRATIONS:
# each2(v)
# collect2(v)
# ARITHMETIC:
# *(x) "is matrix or number"
# +(v)
# -(v)
# VECTOR FUNCTIONS:
# inner_product(v)
# collect
# map
# map2(v)
# r
# CONVERTING:
# covector
# to_a
# to_f
# to_i
# to_r
# coerce(other)
# PRINTING:
# to_s
# inspect
require "e2mmap.rb" require "e2mmap.rb"
@ -36,8 +184,8 @@ module ExceptionForMatrix
end end
class Matrix class Matrix
RCS_ID='-$Header: ruby-mode,v 1.2 91/04/20 17:24:57 keiju Locked $-' @RCS_ID='-$Id: matrix.rb,v 1.6 1998/07/31 03:39:49 keiju Exp keiju $-'
include ExceptionForMatrix include ExceptionForMatrix
# instance creations # instance creations
@ -144,6 +292,7 @@ class Matrix
if iterator? if iterator?
for e in @rows[i] for e in @rows[i]
yield e yield e
end end
else else
Vector.elements(@rows[i]) Vector.elements(@rows[i])
@ -211,6 +360,38 @@ class Matrix
column_size == row_size column_size == row_size
end end
# COMPARING
def ==(other)
return FALSE unless Matrix === other
other.compare_by_row_vectors(@rows)
end
alias eql? ==
def compare_by_row_vectors(rows)
return FALSE unless @rows.size == rows.size
0.upto(@rows.size - 1) do
|i|
return FALSE unless @rows[i] == rows[i]
end
TRUE
end
def clone
Matrix.rows(@rows)
end
def hash
value = 0
for row in @rows
for e in row
value ^= e.hash
end
end
return value
end
# ARITHMETIC # ARITHMETIC
def *(m) #is matrix or vector or number" def *(m) #is matrix or vector or number"
@ -297,6 +478,25 @@ class Matrix
} }
Matrix.rows(rows, FALSE) Matrix.rows(rows, FALSE)
end end
def /(other)
case other
when Numeric
rows = @rows.collect {
|row|
row.collect {
|e|
e / other
}
}
return Matrix.rows(rows, FALSE)
when Matrix
return self * other.inverse
else
x, y = other.coerce(self)
rerurn x / y
end
end
def inverse def inverse
Matrix.fail ErrDimensionMismatch unless square? Matrix.fail ErrDimensionMismatch unless square?
@ -597,13 +797,12 @@ end
#---------------------------------------------------------------------- #----------------------------------------------------------------------
class Vector class Vector
include ExceptionForMatrix include ExceptionForMatrix
#INSTANCE CREATION #INSTANCE CREATION
private_class_method :new private_class_method :new
def Vector.[](*array) def Vector.[](*array)
new(:init_elements, array, copy = FALSE) new(:init_elements, array, FALSE)
end end
def Vector.elements(array, copy = TRUE) def Vector.elements(array, copy = TRUE)
@ -649,6 +848,26 @@ class Vector
end end
end end
# COMPARING
def ==(other)
return FALSE unless Vector === other
other.compare_by(@elements)
end
alias eqn? ==
def compare_by(elements)
@elements == elements
end
def clone
Vector.elements(@elements)
end
def hash
@elements.hash
end
# ARITHMETIC # ARITHMETIC
def *(x) "is matrix or number" def *(x) "is matrix or number"
@ -733,7 +952,7 @@ class Vector
for e in @elements for e in @elements
v += e*e v += e*e
end end
return v.sqrt return Math.sqrt(v)
end end
# CONVERTING # CONVERTING

View file

@ -1,7 +1,8 @@
# module to create Makefile for extention modules # module to create Makefile for extension modules
# invoke like: ruby -r mkmf extconf.rb # invoke like: ruby -r mkmf extconf.rb
require 'rbconfig' require 'rbconfig'
require 'find'
include Config include Config
@ -36,6 +37,7 @@ $install = CONFIG["INSTALL_PROGRAM"]
$install_data = CONFIG["INSTALL_DATA"] $install_data = CONFIG["INSTALL_DATA"]
if $install !~ /^\// then if $install !~ /^\// then
$install = CONFIG["srcdir"]+"/"+$install $install = CONFIG["srcdir"]+"/"+$install
$install_data = CONFIG["srcdir"]+"/"+$install_data
end end
if File.exist? $archdir + "/ruby.h" if File.exist? $archdir + "/ruby.h"
@ -47,28 +49,60 @@ else
exit 1 exit 1
end end
nul = "> /dev/null"
CFLAGS = CONFIG["CFLAGS"] CFLAGS = CONFIG["CFLAGS"]
if PLATFORM == "m68k-human" if PLATFORM == "m68k-human"
nul = "> nul"
CFLAGS.gsub!(/-c..-stack=[0-9]+ */, '') CFLAGS.gsub!(/-c..-stack=[0-9]+ */, '')
end end
if $DEBUG if /win32|djgpp|mingw32|m68k-human/i =~ PLATFORM
nul = "" $null = open("nul", "w")
else
$null = open("/dev/null", "w")
end
LINK = "#{CONFIG['CC']} -o conftest -I#{$srcdir} -I#{CONFIG['includedir']} #{CFLAGS} %s #{CONFIG['LDFLAGS']} %s conftest.c #{CONFIG['LIBS']} %s"
CPP = "#{CONFIG['CPP']} -E -I#{$srcdir} -I#{CONFIG['includedir']} #{CFLAGS} %s conftest.c"
$orgerr = $stderr.dup
$orgout = $stdout.dup
def xsystem command
if $DEBUG
print command, "\n"
return system(command)
end
$stderr.reopen($null)
$stdout.reopen($null)
r = system(command)
$stderr.reopen($orgerr)
$stdout.reopen($orgout)
return r
end end
LINK = CONFIG["CC"]+" -o conftest -I#{$srcdir} " + CFLAGS + " %s " + CONFIG["LDFLAGS"] + " %s conftest.c " + CONFIG["LIBS"] + "%s " + nul + " 2>&1"
CPP = CONFIG["CPP"] + " -E -I#{$srcdir} " + CFLAGS + " %s conftest.c " + nul + " 2>&1"
def try_link(libs) def try_link(libs)
system(format(LINK, $CFLAGS, $LDFLAGS, libs)) xsystem(format(LINK, $CFLAGS, $LDFLAGS, libs))
end end
def try_cpp def try_cpp
system(format(CPP, $CFLAGS)) xsystem(format(CPP, $CFLAGS))
end end
def have_library(lib, func) def install_rb(mfile)
path = []
dir = []
Find.find("lib") do |f|
next unless /\.rb$/ =~ f
f = f[4..-1]
path.push f
dir |= File.dirname(f)
end
for f in dir
next if f == "."
mfile.printf "\t@test -d $(libdir)/%s || mkdir $(libdir)/%s\n", f, f
end
for f in path
mfile.printf "\t$(INSTALL_DATA) lib/%s $(libdir)/%s\n", f, f
end
end
def have_library(lib, func="main")
printf "checking for %s() in -l%s... ", func, lib printf "checking for %s() in -l%s... ", func, lib
STDOUT.flush STDOUT.flush
if $lib_cache[lib] if $lib_cache[lib]
@ -86,32 +120,40 @@ def have_library(lib, func)
end end
end end
cfile = open("conftest.c", "w") if func && func != ""
cfile.printf "\ cfile = open("conftest.c", "w")
cfile.printf "\
int main() { return 0; } int main() { return 0; }
int t() { %s(); return 0; } int t() { %s(); return 0; }
", func ", func
cfile.close cfile.close
begin begin
if $libs
libs = "-l" + lib + " " + $libs
else
libs = "-l" + lib
end
unless try_link(libs)
$lib_cache[lib] = 'no'
$cache_mod = TRUE
print "no\n"
return FALSE
end
ensure
system "rm -f conftest*"
end
else
if $libs if $libs
libs = "-l" + lib + " " + $libs libs = "-l" + lib + " " + $libs
else else
libs = "-l" + lib libs = "-l" + lib
end end
unless try_link(libs)
$lib_found[lib] = 'no'
$found = TRUE
print "no\n"
return FALSE
end
ensure
system "rm -f conftest*"
end end
$libs = libs $libs = libs
$lib_found[lib] = 'yes' $lib_cache[lib] = 'yes'
$found = TRUE $cache_mod = TRUE
print "yes\n" print "yes\n"
return TRUE return TRUE
end end
@ -221,9 +263,15 @@ def create_makefile(target)
$defs.push(format("-DEXTLIB='%s'", libs.join(","))) $defs.push(format("-DEXTLIB='%s'", libs.join(",")))
end end
$libs = "" unless $libs $libs = "" unless $libs
$DLDFLAGS = CONFIG["DLDFLAGS"]
if !$objs then if PLATFORM =~ /beos/
$objs = Dir["*.c"] $libs = $libs + " -lruby"
$DLDFLAGS = $DLDFLAGS + " -L" + CONFIG["prefix"] + "/lib"
end
unless $objs then
$objs = Dir["*.{c,cc}"]
for f in $objs for f in $objs
f.sub!(/\.(c|cc)$/, ".o") f.sub!(/\.(c|cc)$/, ".o")
end end
@ -239,15 +287,18 @@ SHELL = /bin/sh
srcdir = #{$srcdir} srcdir = #{$srcdir}
hdrdir = #{$hdrdir} hdrdir = #{$hdrdir}
CC = gcc CC = #{CONFIG["CC"]}
CFLAGS = #{CONFIG["CCDLFLAGS"]} -I#{$hdrdir} #{CFLAGS} #{$CFLAGS} #{$defs.join(" ")} prefix = #{CONFIG["prefix"]}
DLDFLAGS = #{CONFIG["DLDFLAGS"]} #{$LDFLAGS} CFLAGS = #{CONFIG["CCDLFLAGS"]} -I$(hdrdir) -I#{CONFIG["includedir"]} #{CFLAGS} #{$CFLAGS} #{$defs.join(" ")}
CXXFLAGS = $(CFLAGS)
DLDFLAGS = #{$DLDFLAGS} #{$LDFLAGS}
LDSHARED = #{CONFIG["LDSHARED"]} LDSHARED = #{CONFIG["LDSHARED"]}
prefix = #{CONFIG["prefix"]} prefix = #{CONFIG["prefix"]}
exec_prefix = #{CONFIG["exec_prefix"]} exec_prefix = #{CONFIG["exec_prefix"]}
libdir = #{$archdir} libdir = #{$libdir}
archdir = #{$archdir}
#### End of system configuration section. #### #### End of system configuration section. ####
@ -258,6 +309,7 @@ OBJS = #{$objs}
TARGET = #{target}.#{CONFIG["DLEXT"]} TARGET = #{target}.#{CONFIG["DLEXT"]}
INSTALL = #{$install} INSTALL = #{$install}
INSTALL_DATA = #{$install_data}
binsuffix = #{CONFIG["binsuffix"]} binsuffix = #{CONFIG["binsuffix"]}
@ -269,21 +321,20 @@ clean:; @rm -f *.o *.so *.sl
realclean: clean realclean: clean
install: $(libdir)/$(TARGET) install: $(archdir)/$(TARGET)
$(libdir)/$(TARGET): $(TARGET) $(archdir)/$(TARGET): $(TARGET)
@test -d $(libdir) || mkdir $(libdir) @test -d $(libdir) || mkdir $(libdir)
$(INSTALL) $(TARGET) $(libdir)/$(TARGET) @test -d $(archdir) || mkdir $(archdir)
$(INSTALL) $(TARGET) $(archdir)/$(TARGET)
EOMF EOMF
for rb in Dir["lib/*.rb"] install_rb(mfile)
mfile.printf "\t$(INSTALL) %s %s\n", rb, $libdir
end
mfile.printf "\n" mfile.printf "\n"
if CONFIG["DLEXT"] != "o" if CONFIG["DLEXT"] != "o"
mfile.printf <<EOMF mfile.printf <<EOMF
$(TARGET): $(OBJS) $(TARGET): $(OBJS)
$(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LOCAL_LIBS) $(LIBS) $(LDSHARED) $(DLDFLAGS) -o $(TARGET) $(OBJS) $(LIBS) $(LOCAL_LIBS)
EOMF EOMF
elsif not File.exist?(target + ".c") and not File.exist?(target + ".cc") or elsif not File.exist?(target + ".c") and not File.exist?(target + ".cc") or
mfile.print "$(TARGET): $(OBJS)\n" mfile.print "$(TARGET): $(OBJS)\n"
@ -332,12 +383,19 @@ EOMF
rescue rescue
end end
end end
if PLATFORM =~ /beos/
print "creating ruby.def\n"
open("ruby.def", "w") do |file|
file.print("EXPORTS\n") if PLATFORM =~ /^i/
file.print("Init_#{target}\n")
end
end
end end
$local_libs = nil $libs = PLATFORM =~ /cygwin32|beos/ ? nil : "-lc"
$libs = nil
$objs = nil $objs = nil
$CFLAGS = nil $local_libs = ""
$LDFLAGS = nil $CFLAGS = ""
$LDFLAGS = ""
$defs = [] $defs = []

View file

@ -1,8 +1,8 @@
# #
# mutex_m.rb - # mutex_m.rb -
# $Release Version: 2.0$ # $Release Version: 2.0$
# $Revision: 1.2 $ # $Revision: 1.7 $
# $Date: 1997/07/25 02:43:21 $ # $Date: 1998/02/27 04:28:57 $
# Original from mutex.rb # Original from mutex.rb
# by Keiju ISHITSUKA(SHL Japan Inc.) # by Keiju ISHITSUKA(SHL Japan Inc.)
# #
@ -18,21 +18,50 @@
require "finalize" require "finalize"
module Mutex_m module Mutex_m
def Mutex_m.extend_object(obj) def Mutex_m.extendable_module(obj)
if Fixnum === obj or TRUE === obj or FALSE === obj or nil == obj if Fixnum === obj or TRUE === obj or FALSE === obj or nil == obj
raise TypeError, "Mutex_m can't extend to this class(#{obj.type})" raise TypeError, "Mutex_m can't extend to this class(#{obj.type})"
else else
begin begin
eval "class << obj obj.instance_eval "@mu_locked"
@mu_locked For_general_object
end"
obj.extend(For_primitive_object)
rescue TypeError rescue TypeError
obj.extend(For_general_object) For_primitive_object
end end
end end
end end
def Mutex_m.includable_module(cl)
begin
dummy = cl.new
Mutex_m.extendable_module(dummy)
rescue NameError
# newが定義されていない時は, DATAとみなす.
For_primitive_object
end
end
def Mutex_m.extend_class(cl)
return super if cl.instance_of?(Module)
# モジュールの時は何もしない. クラスの場合, 適切なモジュールの決定
# とaliasを行う.
real = includable_module(cl)
cl.module_eval %q{
include real
alias locked? mu_locked?
alias lock mu_lock
alias unlock mu_unlock
alias try_lock mu_try_lock
alias synchronize mu_synchronize
}
end
def Mutex_m.extend_object(obj)
obj.extend(Mutex_m.extendable_module(obj))
end
def mu_extended def mu_extended
unless (defined? locked? and unless (defined? locked? and
defined? lock and defined? lock and
@ -40,7 +69,7 @@ module Mutex_m
defined? try_lock and defined? try_lock and
defined? synchronize) defined? synchronize)
eval "class << self eval "class << self
alias locked mu_locked? alias locked? mu_locked?
alias lock mu_lock alias lock mu_lock
alias unlock mu_unlock alias unlock mu_unlock
alias try_lock mu_try_lock alias try_lock mu_try_lock
@ -49,6 +78,7 @@ module Mutex_m
end end
end end
# locking
def mu_synchronize def mu_synchronize
begin begin
mu_lock mu_lock
@ -58,6 +88,7 @@ module Mutex_m
end end
end end
# internal class
module For_general_object module For_general_object
include Mutex_m include Mutex_m
@ -118,10 +149,16 @@ module Mutex_m
def For_primitive_object.extend_object(obj) def For_primitive_object.extend_object(obj)
super super
obj.mu_extended obj.mu_extended
Finalizer.add(obj, For_primitive_object, :mu_finalize) Finalizer.add(obj, For_primitive_object, :mu_finalize)
end end
def mu_extended
super
initialize
end
def For_primitive_object.mu_finalize(id) def For_primitive_object.mu_finalize(id)
Thread.critical = TRUE Thread.critical = TRUE
if wait = Mu_Locked.delete(id) if wait = Mu_Locked.delete(id)
@ -146,7 +183,7 @@ module Mutex_m
ret = FALSE ret = FALSE
else else
Mu_Locked[self.id] = [] Mu_Locked[self.id] = []
Finalizer.set(self, For_primitive_object, :mu_delete_Locked) Finalizer.add(self, For_primitive_object, :mu_finalize)
ret = TRUE ret = TRUE
end end
Thread.critical = FALSE Thread.critical = FALSE
@ -159,7 +196,7 @@ module Mutex_m
Thread.stop Thread.stop
end end
Mu_Locked[self.id] = [] Mu_Locked[self.id] = []
Finalizer.add(self, For_primitive_object, :mu_delete_Locked) Finalizer.add(self, For_primitive_object, :mu_finalize)
Thread.critical = FALSE Thread.critical = FALSE
self self
end end
@ -180,4 +217,3 @@ module Mutex_m
end end
end end

View file

@ -30,9 +30,11 @@ module Observable
@observer_state @observer_state
end end
def notify_observers(*arg) def notify_observers(*arg)
if @observer_peers and @observer_state if @observer_state
for i in @observer_peers if @observer_peers
i.update(*arg) for i in @observer_peers
i.update(*arg)
end
end end
@observer_state = FALSE @observer_state = FALSE
end end

View file

@ -1,4 +1,3 @@
#!/usr/local/bin/ruby
# #
# parsearg.rb - parse arguments # parsearg.rb - parse arguments
# $Release Version: $ # $Release Version: $
@ -11,9 +10,9 @@
# #
# #
$RCS_ID="$Header$" $RCS_ID=%q$Header$
load("getopts.rb") require "getopts"
def printUsageAndExit() def printUsageAndExit()
if $USAGE if $USAGE

View file

@ -4,39 +4,68 @@ module ParseDate
'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8, 'may' => 5, 'jun' => 6, 'jul' => 7, 'aug' => 8,
'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12 } 'sep' => 9, 'oct' =>10, 'nov' =>11, 'dec' =>12 }
MONTHPAT = MONTHS.keys.join('|') MONTHPAT = MONTHS.keys.join('|')
DAYPAT = 'mon|tue|wed|thu|fri|sat|sun' DAYS = {
'sun' => 0, 'mon' => 1, 'tue' => 2, 'wed' => 3,
'thu' => 4, 'fri' => 5, 'sat' => 6 }
DAYPAT = DAYS.keys.join('|')
def parsedate(date) def parsedate(date)
if date.sub!(/(#{DAYPAT})/i, ' ') # part of ISO 8601
dayofweek = $1 # yyyy-mm-dd | yyyy-mm | yyyy
# date hh:mm:ss | date Thh:mm:ss
if date =~ /^(\d\d\d\d)-?(?:(\d\d)-?(\d\d)?)? *T?(?:(\d\d):?(\d\d):?(\d\d)?)?$/
return $1.to_i,
if $2 then $2.to_i else 1 end,
if $3 then $3.to_i else 1 end,
if $4 then $4.to_i end,
if $5 then $5.to_i end,
if $6 then $6.to_i end,
nil,
nil
end end
if date.sub!(/\s+(\d+:\d+(:\d+)?)/, ' ') date = date.dup
time = $1 if date.sub!(/(#{DAYPAT})[a-z]*,?/i, ' ')
wday = DAYS[$1.downcase]
end end
if date =~ /19(\d\d)/ if date.sub!(/(\d+):(\d+)(?::(\d+))?\s*(am|pm)?\s*(?:\s+([a-z]{1,4}(?:\s+[a-z]{1,4})?|[-+]\d{4}))?/i, ' ')
year = Integer($1) hour = $1.to_i
min = $2.to_i
if $3
sec = $3.to_i
end
if $4 == 'pm'
hour += 12
end
if $5
zone = $5
end
end end
if date.sub!(/\s*(\d+)\s+(#{MONTHPAT})\S*\s+/i, ' ') if date.sub!(/(\d+)\S*\s+(#{MONTHPAT})\S*(?:\s+(\d+))?/i, ' ')
dayofmonth = $1.to_i mday = $1.to_i
monthname = $2 mon = MONTHS[$2.downcase]
elsif date.sub!(/\s*(#{MONTHPAT})\S*\s+(\d+)\s+/i, ' ') if $3
monthname = $1 year = $3.to_i
dayofmonth = $2.to_i end
elsif date.sub!(/\s*(#{MONTHPAT})\S*\s+(\d+)\D+/i, ' ') elsif date.sub!(/(#{MONTHPAT})\S*\s+(\d+)\S*\s*,?(?:\s+(\d+))?/i, ' ')
monthname = $1 mon = MONTHS[$1.downcase]
dayofmonth = $2.to_i mday = $2.to_i
elsif date.sub!(/\s*(\d\d?)\/(\d\d?)/, ' ') if $3
month = $1 year = $3.to_i
dayofmonth = $2.to_i end
elsif date.sub!(/(\d+)\/(\d+)(?:\/(\d+))/, ' ')
mon = $1.to_i
mday = $2.to_i
if $3
year = $3.to_i
end
end end
if monthname return year, mon, mday, hour, min, sec, zone, wday
month = MONTHS[monthname.downcase]
end
if ! year && date =~ /\d\d/
year = Integer($&)
end
return year, month, dayofmonth
end end
module_function :parsedate module_function :parsedate
end end
if __FILE__ == $0
p Time.now.asctime
p ParseDate.parsedate(Time.now.asctime)
end

View file

@ -26,6 +26,10 @@
# #
# The timeout in seconds. If not specified it will default to 5 seconds. # The timeout in seconds. If not specified it will default to 5 seconds.
# #
# : service
#
# The service port to connect. The default is "echo".
#
#= WARNING #= WARNING
# #
# pingecho() uses user-level thread to implement the timeout, so it may block # pingecho() uses user-level thread to implement the timeout, so it may block
@ -33,23 +37,26 @@
# #
#=end #=end
require 'timeout'
module Ping module Ping
require "socket" require "socket"
def pingecho(host, timeout=5) def pingecho(host, timeout=5, service="echo")
begin begin
x = Thread.current timeout(timeout) do
y = Thread.start { s = TCPsocket.new(host, service)
sleep timeout s.close
x.raise RuntimeError if x.status end
}
s = TCPsocket.new(host, "echo")
s.close
return TRUE
rescue rescue
return FALSE; return false
ensure
Thread.kill y if y.status
end end
return true
end end
module_function "pingecho" module_function :pingecho
end
if $0 == __FILE__
host = ARGV[0]
host ||= "localhost"
printf("%s alive? - %s\n", host, Ping::pingecho(host, 5))
end end

View file

@ -1,5 +1,4 @@
#!/usr/local/bin/ruby #
# How to use: # How to use:
# #
# db = PStore.new("/tmp/foo") # db = PStore.new("/tmp/foo")
@ -16,7 +15,8 @@
require "marshal" require "marshal"
class PStore class PStore
Exception(:Error) class Error < StandardError
end
def initialize(file) def initialize(file)
dir = File::dirname(file) dir = File::dirname(file)
@ -89,33 +89,46 @@ class PStore
catch(:pstore_abort_transaction) do catch(:pstore_abort_transaction) do
value = yield(self) value = yield(self)
end end
rescue Exception
@abort = true
raise
ensure ensure
unless @abort unless @abort
File::rename @filename, @filename+"~" begin
File::rename @filename, @filename+"~"
rescue Errno::ENOENT
no_orig = true
end
begin begin
File::open(@filename, "w") do |file| File::open(@filename, "w") do |file|
Marshal::dump(@table, file) Marshal::dump(@table, file)
end end
rescue rescue
File::rename @filename+"~", @filename File::rename @filename+"~", @filename unless no_orig
end end
end end
@abort = false @abort = false
end end
ensure ensure
@table = nil
@transaction = false @transaction = false
end end
value value
end end
end end
db = PStore.new("/tmp/foo") if __FILE__ == $0
db.transaction do db = PStore.new("/tmp/foo")
p db.roots db.transaction do
ary = db["root"] = [1,2,3,4] p db.roots
ary[0] = [1,1.5] ary = db["root"] = [1,2,3,4]
end ary[1] = [1,1.5]
end
db.transaction do 1000.times do
p db["root"] db.transaction do
db["root"][0] += 1
p db["root"][0]
end
end
end end

View file

@ -1,8 +1,8 @@
# #
# rational.rb - # rational.rb -
# $Release Version: 0.5 $ # $Release Version: 0.5 $
# $Revision: 1.1 $ # $Revision: 1.3 $
# $Date: 1996/11/11 04:25:14 $ # $Date: 1998/03/11 14:09:03 $
# by Keiju ISHITSUKA(SHL Japan Inc.) # by Keiju ISHITSUKA(SHL Japan Inc.)
# #
# -- # --
@ -44,7 +44,11 @@ def Rational(a, b = 1)
end end
class Rational < Numeric class Rational < Numeric
@RCS_ID='-$Id: rational.rb,v 1.3 1998/03/11 14:09:03 keiju Exp keiju $-'
def Rational.reduce(num, den = 1) def Rational.reduce(num, den = 1)
raise ZeroDivisionError, "denometor is 0" if den == 0
if den < 0 if den < 0
num = -num num = -num
den = -den den = -den
@ -128,6 +132,7 @@ class Rational < Numeric
den = @denominator * a.numerator den = @denominator * a.numerator
Rational(num, den) Rational(num, den)
elsif a.kind_of?(Integer) elsif a.kind_of?(Integer)
raise ZeroDivisionError, "devided by 0" if a == 0
self / Rational.new!(a, 1) self / Rational.new!(a, 1)
elsif a.kind_of?(Float) elsif a.kind_of?(Float)
Float(self) / a Float(self) / a

View file

@ -18,21 +18,19 @@ module Shellwords
while line != '' while line != ''
field = '' field = ''
while TRUE while TRUE
if line.sub! /^"(([^"\\]|\\.)*)"/, '' then if line.sub! /^"(([^"\\]|\\.)*)"/, '' then #"
snippet = $1 snippet = $1
snippet.gsub! /\\(.)/, '\1' snippet.gsub! /\\(.)/, '\1'
elsif line =~ /^"/ then elsif line =~ /^"/ then #"
STDOUT.print "Unmatched double quote: $_\n" raise ArgError, "Unmatched double quote: #{line}"
exit elsif line.sub! /^'(([^'\\]|\\.)*)'/, '' then #'
elsif line.sub! /^'(([^'\\]|\\.)*)'/, '' then
snippet = $1 snippet = $1
snippet.gsub! /\\(.)/, '\1' snippet.gsub! /\\(.)/, '\1'
elsif line =~ /^'/ then elsif line =~ /^'/ then #'
STDOUT.print "Unmatched single quote: $_\n" raise ArgError, "Unmatched single quote: #{line}"
exit
elsif line.sub! /^\\(.)/, '' then elsif line.sub! /^\\(.)/, '' then
snippet = $1 snippet = $1
elsif line.sub! /^([^\s\\'"]+)/, '' then elsif line.sub! /^([^\s\\'"]+)/, '' then #'
snippet = $1 snippet = $1
else else
line.sub! /^\s+/, '' line.sub! /^\s+/, ''

View file

@ -4,6 +4,7 @@
# $Revision$ # $Revision$
# $Date$ # $Date$
# by Keiju ISHITSUKA # by Keiju ISHITSUKA
# modified by matz
# #
# -- # --
# Sync_m, Synchronizer_m # Sync_m, Synchronizer_m
@ -43,7 +44,7 @@ unless defined? Thread
fail "Thread not available for this ruby interpreter" fail "Thread not available for this ruby interpreter"
end end
require "finalize" require "final"
module Sync_m module Sync_m
RCS_ID='-$Header$-' RCS_ID='-$Header$-'
@ -54,7 +55,7 @@ module Sync_m
EX = :EX EX = :EX
# Îã³°ÄêµÁ # Îã³°ÄêµÁ
class Err < Exception class Err < StandardError
def Err.Fail(*opt) def Err.Fail(*opt)
fail self, sprintf(self::Message, *opt) fail self, sprintf(self::Message, *opt)
end end
@ -296,8 +297,8 @@ module Sync_m
private :sync_try_lock_sub private :sync_try_lock_sub
def sync_synchronize(mode = EX) def sync_synchronize(mode = EX)
sync_lock(mode)
begin begin
sync_lock(mode)
yield yield
ensure ensure
sync_unlock sync_unlock
@ -321,7 +322,11 @@ module Sync_m
def For_primitive_object.extend_object(obj) def For_primitive_object.extend_object(obj)
super super
obj.sync_extended obj.sync_extended
Finalizer.add(obj, For_primitive_object, :sync_finalize) # Changed to use `final.rb'.
# Finalizer.add(obj, For_primitive_object, :sync_finalize)
ObjectSpace.define_finalizer(obj) do |id|
For_primitive_object.sync_finalize(id)
end
end end
def initialize def initialize

View file

@ -9,14 +9,20 @@ unless defined? Thread
end end
unless defined? ThreadError unless defined? ThreadError
class ThreadError<Exception class ThreadError<StandardError
end end
end end
if $DEBUG
Thread.abort_on_exception = true
end
class Mutex class Mutex
def initialize def initialize
@waiting = [] @waiting = []
@locked = FALSE; @locked = false;
@waiting.taint # enable tainted comunication
self.taint
end end
def locked? def locked?
@ -24,42 +30,39 @@ class Mutex
end end
def try_lock def try_lock
result = FALSE result = false
Thread.critical = TRUE Thread.critical = true
unless @locked unless @locked
@locked = TRUE @locked = true
result = TRUE result = true
end end
Thread.critical = FALSE Thread.critical = false
result result
end end
def lock def lock
while (Thread.critical = TRUE; @locked) while (Thread.critical = true; @locked)
@waiting.push Thread.current @waiting.push Thread.current
Thread.stop Thread.stop
end end
@locked = TRUE @locked = true
Thread.critical = FALSE Thread.critical = false
self self
end end
def unlock def unlock
return unless @locked return unless @locked
Thread.critical = TRUE Thread.critical = TRUE
wait = @waiting t = @waiting.shift
@waiting = []
@locked = FALSE @locked = FALSE
Thread.critical = FALSE Thread.critical = FALSE
for w in wait t.run if t
w.run
end
self self
end end
def synchronize def synchronize
lock
begin begin
lock
yield yield
ensure ensure
unlock unlock
@ -67,37 +70,74 @@ class Mutex
end end
end end
class ConditionVariable
def initialize
@waiters = []
@waiters_mutex = Mutex.new
@waiters.taint # enable tainted comunication
self.taint
end
def wait(mutex)
mutex.unlock
@waiters_mutex.synchronize {
@waiters.push(Thread.current)
}
Thread.stop
mutex.lock
end
def signal
@waiters_mutex.synchronize {
t = @waiters.shift
t.run if t
}
end
def broadcast
@waiters_mutex.synchronize {
for t in @waiters
t.run
end
@waiters.clear
}
end
end
class Queue class Queue
def initialize def initialize
@que = [] @que = []
@waiting = [] @waiting = []
@que.taint # enable tainted comunication
@waiting.taint
self.taint
end end
def push(obj) def push(obj)
Thread.critical = TRUE Thread.critical = true
@que.push obj @que.push obj
t = @waiting.shift t = @waiting.shift
Thread.critical = FALSE Thread.critical = false
t.run if t t.run if t
end end
def pop non_block=FALSE def pop non_block=false
item = nil Thread.critical = true
until item begin
Thread.critical = TRUE loop do
if @que.length == 0 if @que.length == 0
if non_block if non_block
Thread.critical = FALSE raise ThreadError, "queue empty"
raise ThreadError, "queue empty" end
@waiting.push Thread.current
Thread.stop
else
return @que.shift
end end
@waiting.push Thread.current
Thread.stop
else
item = @que.shift
end end
ensure
Thread.critical = false
end end
Thread.critical = FALSE
item
end end
def empty? def empty?
@ -107,4 +147,63 @@ class Queue
def length def length
@que.length @que.length
end end
alias size length
def num_waiting
@waiting.size
end
end
class SizedQueue<Queue
def initialize(max)
@max = max
@queue_wait = []
@queue_wait.taint # enable tainted comunication
super()
end
def max
@max
end
def max=(max)
Thread.critical = TRUE
if @max >= max
@max = max
Thread.critical = FALSE
else
diff = max - @max
@max = max
Thread.critical = FALSE
diff.times do
t = @queue_wait.shift
t.run if t
end
end
max
end
def push(obj)
Thread.critical = true
while @que.length >= @max
@queue_wait.push Thread.current
Thread.stop
Thread.critical = true
end
super
end
def pop(*args)
Thread.critical = true
if @que.length < @max
t = @queue_wait.shift
t.run if t
end
super
end
def num_waiting
@waiting.size + @queue_wait.size
end
end end

View file

@ -1,34 +1,53 @@
# #
# thwait.rb - # thwait.rb - thread synchronization class
# $Release Version: $ # $Release Version: 0.9 $
# $Revision: 1.1 $ # $Revision: 1.3 $
# $Date: 1997/08/18 03:13:14 $ # $Date: 1998/06/26 03:19:34 $
# by Keiju ISHITSUKA(Nippon Rational Inc.) # by Keiju ISHITSUKA(Nihpon Rational Software Co.,Ltd.)
# #
# -- # --
# feature:
# provides synchronization for multiple threads.
# #
# # class methods:
# * ThreadsWait.all_waits(thread1,...)
# waits until all of specified threads are terminated.
# if a block is supplied for the method, evaluates it for
# each thread termination.
# * th = ThreadsWait.new(thread1,...)
# creates synchronization object, specifying thread(s) to wait.
#
# methods:
# * th.threads
# list threads to be synchronized
# * th.empty?
# is there any thread to be synchronized.
# * th.finished?
# is there already terminated thread.
# * th.join(thread1,...)
# wait for specified thread(s).
# * th.join_nowait(threa1,...)
# specifies thread(s) to wait. non-blocking.
# * th.next_wait
# waits until any of specified threads is terminated.
# * th.all_waits
# waits until all of specified threads are terminated.
# if a block is supplied for the method, evaluates it for
# each thread termination.
# #
require "thread.rb" require "thread.rb"
require "e2mmap.rb" require "e2mmap.rb"
class ThreadsWait class ThreadsWait
RCS_ID='-$Header: /home/keiju/var/src/var.lib/ruby/RCS/thwait.rb,v 1.1 1997/08/18 03:13:14 keiju Exp keiju $-' RCS_ID='-$Id: thwait.rb,v 1.3 1998/06/26 03:19:34 keiju Exp keiju $-'
Exception2MessageMapper.extend_to(binding) Exception2MessageMapper.extend_to(binding)
def_exception("ErrWaitThreadsNothing", "Wait threads nothing.") def_exception("ErrNoWaitingThread", "No threads for waiting.")
def_exception("FinshedThreadsNothing", "finished thread nothing.") def_exception("ErrNoFinshedThread", "No finished threads.")
# class mthods
# all_waits
#
# 指定したスレッドが全て終了するまで待つ. イテレータとして呼ばれると
# 指定したスレッドが終了するとイテレータを呼び出す.
#
def ThreadsWait.all_waits(*threads) def ThreadsWait.all_waits(*threads)
tw = ThreadsWait.new(th1, th2, th3, th4, th5) tw = ThreadsWait.new(*threads)
if iterator? if iterator?
tw.all_waits do tw.all_waits do
|th| |th|
@ -39,12 +58,6 @@ class ThreadsWait
end end
end end
# initialize and terminating:
# initialize
#
# 初期化. 待つスレッドの指定ができる.
#
def initialize(*threads) def initialize(*threads)
@threads = [] @threads = []
@wait_queue = Queue.new @wait_queue = Queue.new
@ -52,24 +65,19 @@ class ThreadsWait
end end
# accessing # accessing
# threads # threads - list threads to be synchronized
# 待ちスレッドの一覧を返す.
attr :threads attr :threads
# testing # testing
# empty? # empty?
# finished? # finished?
#
# is there any thread to be synchronized.
#
# 待ちスレッドが存在するかどうかを返す.
def empty? def empty?
@threads.empty? @threads.empty?
end end
# # is there already terminated thread.
# すでに終了したスレッドがあるかどうか返す
def finished? def finished?
!@wait_queue.empty? !@wait_queue.empty?
end end
@ -80,45 +88,40 @@ class ThreadsWait
# next_wait # next_wait
# all_wait # all_wait
# # adds thread(s) to join, waits for any of waiting threads to terminate.
# 待っているスレッドを追加し待ちにはいる.
#
def join(*threads) def join(*threads)
join_nowait(*threads) join_nowait(*threads)
next_wait next_wait
end end
# # adds thread(s) to join, no wait.
# 待っているスレッドを追加する. 待ちには入らない.
#
def join_nowait(*threads) def join_nowait(*threads)
@threads.concat threads @threads.concat threads
for th in threads for th in threads
Thread.start do Thread.start do
th = Thread.join(th) th = th.join
@wait_queue.push th @wait_queue.push th
end end
end end
end end
# # waits for any of waiting threads to terminate
# 次の待ちにはいる. # if there is no thread to wait, raises ErrNoWaitingThread.
# 待つべきスレッドがなければ, 例外ErrWaitThreadsNothing を返す. # if `nonblock' is true, and there is no terminated thread,
# nonnlockが真の時には, nonblockingで調べる. 存在しなければ, 例外 # raises ErrNoFinishedThread.
# FinishedThreadNothingを返す.
#
def next_wait(nonblock = nil) def next_wait(nonblock = nil)
Threads.Wait.fail ErrWaitThreadsNothing if @threads.empty? ThreadsWait.fail ErrNoWaitingThread if @threads.empty?
begin
th = @wait_queue.pop(nonblock) @threads.delete(th = @wait_queue.pop(nonblock))
@threads.delete th th
th rescue ThreadError
ThreadsWait.fail ErrNoFinshedThread
end
end end
# # waits until all of specified threads are terminated.
# 全てのスレッドが終了するまで待つ. イテレータとして呼ばれた時は, ス # if a block is supplied for the method, evaluates it for
# レッドが終了する度に, イテレータを呼び出す. # each thread termination.
#
def all_waits def all_waits
until @threads.empty? until @threads.empty?
th = next_wait th = next_wait
@ -126,3 +129,5 @@ class ThreadsWait
end end
end end
end end
ThWait = ThreadsWait

View file

@ -1,7 +1,28 @@
#
# tracer.rb -
# $Release Version: 0.2$
# $Revision: 1.8 $
# $Date: 1998/05/19 03:42:49 $
# by Keiju ISHITSUKA(Nippon Rational Inc.)
#
# --
#
#
#
#
# tracer main class
#
class Tracer class Tracer
MY_FILE_NAME_PATTERN = /^tracer\.(rb)?/ @RCS_ID='-$Id: tracer.rb,v 1.8 1998/05/19 03:42:49 keiju Exp keiju $-'
Threads = Hash.new
Sources = Hash.new class << self
attr :verbose, TRUE
alias verbose? verbose
end
verbose = TRUE
MY_FILE_NAME = caller(0)[0].scan(/^(.*):[0-9]+$/)[0][0]
EVENT_SYMBOL = { EVENT_SYMBOL = {
"line" => "-", "line" => "-",
@ -10,39 +31,89 @@ class Tracer
"class" => "C", "class" => "C",
"end" => "E"} "end" => "E"}
def initialize
@threads = Hash.new
if defined? Thread.main
@threads[Thread.main.id] = 0
else
@threads[Thread.current.id] = 0
end
@get_line_procs = {}
@sources = {}
@filters = []
end
def on def on
set_trace_func proc{|event, file, line, id, binding| if iterator?
trace_func event, file, line, id, binding on
} begin
print "Trace on\n" yield
ensure
off
end
else
set_trace_func proc{|event, file, line, id, binding|
trace_func event, file, line, id, binding
}
print "Trace on\n" if Tracer.verbose?
end
end end
def off def off
set_trace_func nil set_trace_func nil
print "Trace off\n" print "Trace off\n" if Tracer.verbose?
end end
def get_thread_no def add_filter(p = proc)
unless no = Threads[Thread.current.id] @filters.push p
Threads[Thread.current.id] = no = Threads.size end
end
no def set_get_line_procs(file, p = proc)
@get_line_procs[file] = p
end end
def get_line(file, line) def get_line(file, line)
unless list = Sources[file] if p = @get_line_procs[file]
f =open(file) return p.call line
begin end
Sources[file] = list = f.readlines
ensure unless list = @sources[file]
f.close # print file if $DEBUG
begin
f = open(file)
begin
@sources[file] = list = f.readlines
ensure
f.close
end
rescue
@sources[file] = list = []
end end
end end
list[line - 1] if l = list[line - 1]
l
else
"-\n"
end
end
def get_thread_no
if no = @threads[Thread.current.id]
no
else
@threads[Thread.current.id] = @threads.size
end
end end
def trace_func(event, file, line, id, binding) def trace_func(event, file, line, id, binding)
return if File.basename(file) =~ MY_FILE_NAME_PATTERN return if file == MY_FILE_NAME
#printf "Th: %s\n", Thread.current.inspect
for p in @filters
return unless p.call event, file, line, id, binding
end
Thread.critical = TRUE Thread.critical = TRUE
printf("#%d:%s:%d:%s: %s", printf("#%d:%s:%d:%s: %s",
@ -56,20 +127,36 @@ class Tracer
Single = new Single = new
def Tracer.on def Tracer.on
Single.on if iterator?
Single.on{yield}
else
Single.on
end
end end
def Tracer.off def Tracer.off
Single.off Single.off
end end
def Tracer.set_get_line_procs(file_name, p = proc)
Single.set_get_line_procs(file_name, p)
end
def Tracer.add_filter(p = proc)
Single.add_filter(p)
end
end end
if File.basename($0) =~ Tracer::MY_FILE_NAME_PATTERN if caller(0).size == 1
$0 = ARGV.shift if $0 == Tracer::MY_FILE_NAME
# direct call
Tracer.on
load $0 $0 = ARGV[0]
else ARGV.shift
Tracer.on Tracer.on
require $0
else
Tracer.on
end
end end

View file

@ -10,9 +10,10 @@
require "delegate" require "delegate"
class WeakRef<Delegater class WeakRef<Delegator
Exception :RefError class RefError<StandardError
end
ID_MAP = {} ID_MAP = {}
ID_REV_MAP = {} ID_REV_MAP = {}
@ -31,26 +32,22 @@ class WeakRef<Delegater
def initialize(orig) def initialize(orig)
super super
@id = orig.id @__id = orig.__id__
ObjectSpace.call_finalizer orig ObjectSpace.call_finalizer orig
ID_MAP[@id] = self.id ObjectSpace.call_finalizer self
ID_REV_MAP[self.id] = @id ID_MAP[@__id] = self.__id__
ID_REV_MAP[self.id] = @__id
end end
def __getobj__ def __getobj__
unless ID_MAP[@id] unless ID_MAP[@__id]
$@ = caller(1) raise RefError, "Illegal Reference - probably recycled", caller(2)
$! = RefError.new("Illegal Reference - probably recycled")
raise
end end
ObjectSpace.id2ref(@id) ObjectSpace._id2ref(@__id)
# ObjectSpace.each_object do |obj|
# return obj if obj.id == @id
# end
end end
def weakref_alive? def weakref_alive?
if ID_MAP[@id] if ID_MAP[@__id]
true true
else else
false false
@ -62,9 +59,11 @@ class WeakRef<Delegater
end end
end end
foo = Object.new if __FILE__ == $0
p foo.hash foo = Object.new
foo = WeakRef.new(foo) p foo.hash # original's hash value
p foo.hash foo = WeakRef.new(foo)
ObjectSpace.garbage_collect p foo.hash # should be same hash value
p foo.hash ObjectSpace.garbage_collect
p foo.hash # should raise exception (recycled)
end

1
main.c
View file

@ -30,4 +30,5 @@ main(argc, argv, envp)
ruby_init(); ruby_init();
ruby_options(argc, argv); ruby_options(argc, argv);
ruby_run(); ruby_run();
return 0;
} }

289
marshal.c
View file

@ -3,14 +3,13 @@
marshal.c - marshal.c -
$Author$ $Author$
$Revision$
$Date$ $Date$
created at: Thu Apr 27 16:30:01 JST 1995 created at: Thu Apr 27 16:30:01 JST 1995
************************************************/ ************************************************/
#include "ruby.h" #include "ruby.h"
#include "io.h" #include "rubyio.h"
#include "st.h" #include "st.h"
#define MARSHAL_MAJOR 4 #define MARSHAL_MAJOR 4
@ -38,12 +37,7 @@
#define TYPE_LINK '@' #define TYPE_LINK '@'
extern VALUE cString; VALUE rb_path2class _((char*));
extern VALUE cRegexp;
extern VALUE cArray;
extern VALUE cHash;
VALUE rb_path2class();
static ID s_dump, s_load; static ID s_dump, s_load;
@ -69,7 +63,7 @@ w_byte(c, arg)
struct dump_arg *arg; struct dump_arg *arg;
{ {
if (arg->fp) putc(c, arg->fp); if (arg->fp) putc(c, arg->fp);
else str_cat(arg->str, (UCHAR*)&c, 1); else rb_str_cat(arg->str, &c, 1);
} }
static void static void
@ -83,7 +77,7 @@ w_bytes(s, n, arg)
fwrite(s, 1, n, arg->fp); fwrite(s, 1, n, arg->fp);
} }
else { else {
str_cat(arg->str, s, n); rb_str_cat(arg->str, s, n);
} }
} }
@ -94,7 +88,7 @@ w_short(x, arg)
{ {
int i; int i;
for (i=0; i<sizeof(USHORT); i++) { for (i=0; i<sizeof(short); i++) {
w_byte((x >> (i*8)) & 0xff, arg); w_byte((x >> (i*8)) & 0xff, arg);
} }
} }
@ -155,7 +149,7 @@ w_symbol(id, arg)
else { else {
w_byte(TYPE_SYMBOL, arg); w_byte(TYPE_SYMBOL, arg);
w_bytes(sym, strlen(sym), arg); w_bytes(sym, strlen(sym), arg);
st_insert(arg->symbol, id, arg->symbol->num_entries); st_add_direct(arg->symbol, id, arg->symbol->num_entries);
} }
} }
@ -168,10 +162,9 @@ w_unique(s, arg)
} }
static void w_object _((VALUE,struct dump_arg*,int)); static void w_object _((VALUE,struct dump_arg*,int));
extern VALUE cIO, cBignum, cStruct;
static int static int
hash_each(key, value, arg) rb_hash_each(key, value, arg)
VALUE key, value; VALUE key, value;
struct dump_call_arg *arg; struct dump_call_arg *arg;
{ {
@ -181,7 +174,7 @@ hash_each(key, value, arg)
} }
static int static int
obj_each(id, value, arg) rb_obj_each(id, value, arg)
ID id; ID id;
VALUE value; VALUE value;
struct dump_call_arg *arg; struct dump_call_arg *arg;
@ -192,11 +185,11 @@ obj_each(id, value, arg)
} }
static void static void
w_uclass(obj, class, arg) w_uclass(obj, klass, arg)
VALUE obj, class; VALUE obj, klass;
struct dump_arg *arg; struct dump_arg *arg;
{ {
if (CLASS_OF(obj) != class) { if (CLASS_OF(obj) != klass) {
w_byte(TYPE_UCLASS, arg); w_byte(TYPE_UCLASS, arg);
w_unique(rb_class2name(CLASS_OF(obj)), arg); w_unique(rb_class2name(CLASS_OF(obj)), arg);
} }
@ -208,23 +201,18 @@ w_object(obj, arg, limit)
struct dump_arg *arg; struct dump_arg *arg;
int limit; int limit;
{ {
int n;
struct dump_call_arg c_arg; struct dump_call_arg c_arg;
if (limit == 0) { if (limit == 0) {
Fail("exceed depth limit"); rb_raise(rb_eRuntimeError, "exceed depth limit");
} }
limit--;
c_arg.limit = limit;
c_arg.arg = arg;
if (obj == Qnil) { if (obj == Qnil) {
w_byte(TYPE_NIL, arg); w_byte(TYPE_NIL, arg);
} }
else if (obj == TRUE) { else if (obj == Qtrue) {
w_byte(TYPE_TRUE, arg); w_byte(TYPE_TRUE, arg);
} }
else if (obj == FALSE) { else if (obj == Qfalse) {
w_byte(TYPE_FALSE, arg); w_byte(TYPE_FALSE, arg);
} }
else if (FIXNUM_P(obj)) { else if (FIXNUM_P(obj)) {
@ -232,26 +220,30 @@ w_object(obj, arg, limit)
w_byte(TYPE_FIXNUM, arg); w_byte(TYPE_FIXNUM, arg);
w_long(FIX2INT(obj), arg); w_long(FIX2INT(obj), arg);
#else #else
if (RSHIFT(obj, 32) == 0 || RSHIFT(obj, 32) == -1) { if (RSHIFT((long)obj, 32) == 0 || RSHIFT((long)obj, 32) == -1) {
w_byte(TYPE_FIXNUM, arg); w_byte(TYPE_FIXNUM, arg);
w_long(FIX2INT(obj), arg); w_long(FIX2LONG(obj), arg);
} }
else { else {
obj = int2big(FIX2INT(obj)); w_object(rb_int2big(FIX2LONG(obj)), arg, limit);
goto write_bignum; return;
} }
#endif #endif
} }
else { else {
int num; int num;
limit--;
c_arg.limit = limit;
c_arg.arg = arg;
if (st_lookup(arg->data, obj, &num)) { if (st_lookup(arg->data, obj, &num)) {
w_byte(TYPE_LINK, arg); w_byte(TYPE_LINK, arg);
w_long(num, arg); w_long(num, arg);
return; return;
} }
st_insert(arg->data, obj, arg->data->num_entries); st_add_direct(arg->data, obj, arg->data->num_entries);
if (rb_respond_to(obj, s_dump)) { if (rb_respond_to(obj, s_dump)) {
VALUE v; VALUE v;
@ -259,7 +251,7 @@ w_object(obj, arg, limit)
w_unique(rb_class2name(CLASS_OF(obj)), arg); w_unique(rb_class2name(CLASS_OF(obj)), arg);
v = rb_funcall(obj, s_dump, 1, limit); v = rb_funcall(obj, s_dump, 1, limit);
if (TYPE(v) != T_STRING) { if (TYPE(v) != T_STRING) {
TypeError("_dump_to must return String"); rb_raise(rb_eTypeError, "_dump_to must return String");
} }
w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, arg); w_bytes(RSTRING(v)->ptr, RSTRING(v)->len, arg);
return; return;
@ -281,12 +273,11 @@ w_object(obj, arg, limit)
return; return;
case T_BIGNUM: case T_BIGNUM:
write_bignum:
w_byte(TYPE_BIGNUM, arg); w_byte(TYPE_BIGNUM, arg);
{ {
char sign = RBIGNUM(obj)->sign?'+':'-'; char sign = RBIGNUM(obj)->sign?'+':'-';
int len = RBIGNUM(obj)->len; int len = RBIGNUM(obj)->len;
USHORT *d = RBIGNUM(obj)->digits; unsigned short *d = RBIGNUM(obj)->digits;
w_byte(sign, arg); w_byte(sign, arg);
w_long(len, arg); w_long(len, arg);
@ -298,20 +289,20 @@ w_object(obj, arg, limit)
return; return;
case T_STRING: case T_STRING:
w_uclass(obj, cString, arg); w_uclass(obj, rb_cString, arg);
w_byte(TYPE_STRING, arg); w_byte(TYPE_STRING, arg);
w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg); w_bytes(RSTRING(obj)->ptr, RSTRING(obj)->len, arg);
return; return;
case T_REGEXP: case T_REGEXP:
w_uclass(obj, cRegexp, arg); w_uclass(obj, rb_cRegexp, arg);
w_byte(TYPE_REGEXP, arg); w_byte(TYPE_REGEXP, arg);
w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, arg); w_bytes(RREGEXP(obj)->str, RREGEXP(obj)->len, arg);
w_byte(FL_TEST(obj, FL_USER1), arg); w_byte(rb_reg_options(obj), arg);
return; return;
case T_ARRAY: case T_ARRAY:
w_uclass(obj, cArray, arg); w_uclass(obj, rb_cArray, arg);
w_byte(TYPE_ARRAY, arg); w_byte(TYPE_ARRAY, arg);
{ {
int len = RARRAY(obj)->len; int len = RARRAY(obj)->len;
@ -326,10 +317,10 @@ w_object(obj, arg, limit)
break; break;
case T_HASH: case T_HASH:
w_uclass(obj, cHash, arg); w_uclass(obj, rb_cHash, arg);
w_byte(TYPE_HASH, arg); w_byte(TYPE_HASH, arg);
w_long(RHASH(obj)->tbl->num_entries, arg); w_long(RHASH(obj)->tbl->num_entries, arg);
st_foreach(RHASH(obj)->tbl, hash_each, &c_arg); st_foreach(RHASH(obj)->tbl, rb_hash_each, &c_arg);
break; break;
case T_STRUCT: case T_STRUCT:
@ -344,10 +335,10 @@ w_object(obj, arg, limit)
w_long(len, arg); w_long(len, arg);
mem = rb_ivar_get(CLASS_OF(obj), rb_intern("__member__")); mem = rb_ivar_get(CLASS_OF(obj), rb_intern("__member__"));
if (mem == Qnil) { if (mem == Qnil) {
Fatal("non-initialized struct"); rb_raise(rb_eTypeError, "non-initialized struct");
} }
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
w_symbol(FIX2INT(RARRAY(mem)->ptr[i]), arg); w_symbol(FIX2LONG(RARRAY(mem)->ptr[i]), arg);
w_object(RSTRUCT(obj)->ptr[i], arg, limit); w_object(RSTRUCT(obj)->ptr[i], arg, limit);
} }
} }
@ -356,17 +347,17 @@ w_object(obj, arg, limit)
case T_OBJECT: case T_OBJECT:
w_byte(TYPE_OBJECT, arg); w_byte(TYPE_OBJECT, arg);
{ {
VALUE class = CLASS_OF(obj); VALUE klass = CLASS_OF(obj);
char *path; char *path;
if (FL_TEST(class, FL_SINGLETON)) { if (FL_TEST(klass, FL_SINGLETON)) {
TypeError("singleton can't be dumped"); rb_raise(rb_eTypeError, "singleton can't be dumped");
} }
path = rb_class2name(class); path = rb_class2name(klass);
w_unique(path, arg); w_unique(path, arg);
if (ROBJECT(obj)->iv_tbl) { if (ROBJECT(obj)->iv_tbl) {
w_long(ROBJECT(obj)->iv_tbl->num_entries, arg); w_long(ROBJECT(obj)->iv_tbl->num_entries, arg);
st_foreach(ROBJECT(obj)->iv_tbl, obj_each, &c_arg); st_foreach(ROBJECT(obj)->iv_tbl, rb_obj_each, &c_arg);
} }
else { else {
w_long(0, arg); w_long(0, arg);
@ -375,7 +366,8 @@ w_object(obj, arg, limit)
break; break;
default: default:
TypeError("can't dump %s", rb_class2name(CLASS_OF(obj))); rb_raise(rb_eTypeError, "can't dump %s",
rb_class2name(CLASS_OF(obj)));
break; break;
} }
} }
@ -386,6 +378,7 @@ dump(arg)
struct dump_call_arg *arg; struct dump_call_arg *arg;
{ {
w_object(arg->obj, arg->arg, arg->limit); w_object(arg->obj, arg->arg, arg->limit);
return 0;
} }
static VALUE static VALUE
@ -394,6 +387,7 @@ dump_ensure(arg)
{ {
st_free_table(arg->symbol); st_free_table(arg->symbol);
st_free_table(arg->data); st_free_table(arg->data);
return 0;
} }
static VALUE static VALUE
@ -403,7 +397,6 @@ marshal_dump(argc, argv)
{ {
VALUE obj, port, a1, a2; VALUE obj, port, a1, a2;
int limit = -1; int limit = -1;
extern VALUE cIO;
struct dump_arg arg; struct dump_arg arg;
struct dump_call_arg c_arg; struct dump_call_arg c_arg;
@ -418,21 +411,21 @@ marshal_dump(argc, argv)
else port = a1; else port = a1;
} }
if (port) { if (port) {
if (obj_is_kind_of(port, cIO)) { if (rb_obj_is_kind_of(port, rb_cIO)) {
OpenFile *fptr; OpenFile *fptr;
io_binmode(port); rb_io_binmode(port);
GetOpenFile(port, fptr); GetOpenFile(port, fptr);
io_writable(fptr); rb_io_check_writable(fptr);
arg.fp = (fptr->f2) ? fptr->f2 : fptr->f; arg.fp = (fptr->f2) ? fptr->f2 : fptr->f;
} }
else { else {
TypeError("instance of IO needed"); rb_raise(rb_eTypeError, "instance of IO needed");
} }
} }
else { else {
arg.fp = 0; arg.fp = 0;
port = str_new(0, 0); port = rb_str_new(0, 0);
arg.str = port; arg.str = port;
} }
@ -445,14 +438,14 @@ marshal_dump(argc, argv)
w_byte(MARSHAL_MAJOR, &arg); w_byte(MARSHAL_MAJOR, &arg);
w_byte(MARSHAL_MINOR, &arg); w_byte(MARSHAL_MINOR, &arg);
rb_ensure(dump, &c_arg, dump_ensure, &arg); rb_ensure(dump, (VALUE)&c_arg, dump_ensure, (VALUE)&arg);
return port; return port;
} }
struct load_arg { struct load_arg {
FILE *fp; FILE *fp;
UCHAR *ptr, *end; char *ptr, *end;
st_table *symbol; st_table *symbol;
st_table *data; st_table *data;
VALUE proc; VALUE proc;
@ -463,19 +456,19 @@ r_byte(arg)
struct load_arg *arg; struct load_arg *arg;
{ {
if (arg->fp) return getc(arg->fp); if (arg->fp) return getc(arg->fp);
if (arg->ptr < arg->end) return *arg->ptr++; if (arg->ptr < arg->end) return *(unsigned char*)arg->ptr++;
return EOF; return EOF;
} }
static USHORT static unsigned short
r_short(arg) r_short(arg)
struct load_arg *arg; struct load_arg *arg;
{ {
USHORT x; unsigned short x;
int i; int i;
x = 0; x = 0;
for (i=0; i<sizeof(USHORT); i++) { for (i=0; i<sizeof(short); i++) {
x |= r_byte(arg)<<(i*8); x |= r_byte(arg)<<(i*8);
} }
@ -486,16 +479,17 @@ static void
long_toobig(size) long_toobig(size)
int size; int size;
{ {
TypeError("long too big for this architecture (size %d, given %d)", rb_raise(rb_eTypeError, "long too big for this architecture (size %d, given %d)",
sizeof(long), size); sizeof(long), size);
} }
static long static long
r_long(arg) r_long(arg)
struct load_arg *arg; struct load_arg *arg;
{ {
int c = r_byte(arg), i;
register long x; register long x;
int c = (char)r_byte(arg);
int i;
if (c == 0) return 0; if (c == 0) return 0;
if (c > 0) { if (c > 0) {
@ -505,7 +499,7 @@ r_long(arg)
x |= (long)r_byte(arg) << (8*i); x |= (long)r_byte(arg) << (8*i);
} }
} }
else if (c < 0) { else {
c = -c; c = -c;
if (c > sizeof(long)) long_toobig((int)c); if (c > sizeof(long)) long_toobig((int)c);
x = -1; x = -1;
@ -517,12 +511,20 @@ r_long(arg)
return x; return x;
} }
#define r_bytes(s, arg) \ #define r_bytes2(s, len, arg) do { \
(s = (char*)r_long(arg), r_bytes0(&s,ALLOCA_N(char,(long)s),(long)s,arg)) (len) = r_long(arg); \
(s) = ALLOCA_N(char,(len)+1); \
r_bytes0((s),(len),(arg)); \
} while (0)
static int #define r_bytes(s, arg) do { \
r_bytes0(sp, s, len, arg) int r_bytes_len; \
char **sp, *s; r_bytes2((s), r_bytes_len, (arg)); \
} while (0)
static void
r_bytes0(s, len, arg)
char *s;
int len; int len;
struct load_arg *arg; struct load_arg *arg;
{ {
@ -536,11 +538,7 @@ r_bytes0(sp, s, len, arg)
memcpy(s, arg->ptr, len); memcpy(s, arg->ptr, len);
arg->ptr += len; arg->ptr += len;
} }
s[len] = '\0';
(s)[len] = '\0';
*sp = s;
return len;
} }
static ID static ID
@ -549,7 +547,6 @@ r_symbol(arg)
{ {
char *buf; char *buf;
ID id; ID id;
char type;
if (r_byte(arg) == TYPE_SYMLINK) { if (r_byte(arg) == TYPE_SYMLINK) {
int num = r_long(arg); int num = r_long(arg);
@ -557,7 +554,7 @@ r_symbol(arg)
if (st_lookup(arg->symbol, num, &id)) { if (st_lookup(arg->symbol, num, &id)) {
return id; return id;
} }
TypeError("bad symbol"); rb_raise(rb_eTypeError, "bad symbol");
} }
r_bytes(buf, arg); r_bytes(buf, arg);
id = rb_intern(buf); id = rb_intern(buf);
@ -578,9 +575,10 @@ r_string(arg)
struct load_arg *arg; struct load_arg *arg;
{ {
char *buf; char *buf;
int len = r_bytes(buf, arg); int len;
return str_taint(str_new(buf, len)); r_bytes2(buf, len, arg);
return rb_str_new(buf, len);
} }
static VALUE static VALUE
@ -588,6 +586,7 @@ r_regist(v, arg)
VALUE v; VALUE v;
struct load_arg *arg; struct load_arg *arg;
{ {
OBJ_TAINT(v);
if (arg->proc) { if (arg->proc) {
rb_funcall(arg->proc, rb_intern("call"), 1, v); rb_funcall(arg->proc, rb_intern("call"), 1, v);
} }
@ -604,14 +603,14 @@ r_object(arg)
switch (type) { switch (type) {
case EOF: case EOF:
eof_error(); rb_eof_error();
return Qnil; return Qnil;
case TYPE_LINK: case TYPE_LINK:
if (st_lookup(arg->data, r_long(arg), &v)) { if (st_lookup(arg->data, r_long(arg), &v)) {
return v; return v;
} }
ArgError("dump format error (unlinked)"); rb_raise(rb_eArgError, "dump format error (unlinked)");
break; break;
case TYPE_UCLASS: case TYPE_UCLASS:
@ -619,9 +618,9 @@ r_object(arg)
VALUE c = rb_path2class(r_unique(arg)); VALUE c = rb_path2class(r_unique(arg));
v = r_object(arg); v = r_object(arg);
if (rb_special_const_p(v)) { if (rb_special_const_p(v)) {
ArgError("dump format error (user class)"); rb_raise(rb_eArgError, "dump format error (user class)");
} }
RBASIC(v)->class = c; RBASIC(v)->klass = c;
return v; return v;
} }
@ -629,10 +628,10 @@ r_object(arg)
return Qnil; return Qnil;
case TYPE_TRUE: case TYPE_TRUE:
return TRUE; return Qtrue;
case TYPE_FALSE: case TYPE_FALSE:
return FALSE; return Qfalse;
case TYPE_FIXNUM: case TYPE_FIXNUM:
{ {
@ -648,26 +647,26 @@ r_object(arg)
char *buf; char *buf;
r_bytes(buf, arg); r_bytes(buf, arg);
v = float_new(atof(buf)); v = rb_float_new(atof(buf));
return r_regist(v, arg); return r_regist(v, arg);
} }
case TYPE_BIGNUM: case TYPE_BIGNUM:
{ {
int len; int len;
USHORT *digits; unsigned short *digits;
NEWOBJ(big, struct RBignum); NEWOBJ(big, struct RBignum);
OBJSETUP(big, cBignum, T_BIGNUM); OBJSETUP(big, rb_cBignum, T_BIGNUM);
big->sign = (r_byte(arg) == '+'); big->sign = (r_byte(arg) == '+');
big->len = len = r_long(arg); big->len = len = r_long(arg);
big->digits = digits = ALLOC_N(USHORT, len); big->digits = digits = ALLOC_N(unsigned short, len);
while (len--) { while (len--) {
*digits++ = r_short(arg); *digits++ = r_short(arg);
} }
big = RBIGNUM(big_norm((VALUE)big)); big = RBIGNUM(rb_big_norm((VALUE)big));
if (TYPE(big) == T_BIGNUM) { if (TYPE(big) == T_BIGNUM) {
r_regist(big, arg); r_regist((VALUE)big, arg);
} }
return (VALUE)big; return (VALUE)big;
} }
@ -678,18 +677,21 @@ r_object(arg)
case TYPE_REGEXP: case TYPE_REGEXP:
{ {
char *buf; char *buf;
int len = r_bytes(buf, arg); int len;
int ci = r_byte(arg); int options;
return r_regist(reg_new(buf, len, ci), arg);
r_bytes2(buf, len, arg);
options = r_byte(arg);
return r_regist(rb_reg_new(buf, len, options), arg);
} }
case TYPE_ARRAY: case TYPE_ARRAY:
{ {
volatile int len = r_long(arg); volatile int len = r_long(arg);
v = ary_new2(len); v = rb_ary_new2(len);
r_regist(v, arg); r_regist(v, arg);
while (len--) { while (len--) {
ary_push(v, r_object(arg)); rb_ary_push(v, r_object(arg));
} }
return v; return v;
} }
@ -698,46 +700,46 @@ r_object(arg)
{ {
int len = r_long(arg); int len = r_long(arg);
v = hash_new(); v = rb_hash_new();
r_regist(v, arg); r_regist(v, arg);
while (len--) { while (len--) {
VALUE key = r_object(arg); VALUE key = r_object(arg);
VALUE value = r_object(arg); VALUE value = r_object(arg);
hash_aset(v, key, value); rb_hash_aset(v, key, value);
} }
return v; return v;
} }
case TYPE_STRUCT: case TYPE_STRUCT:
{ {
VALUE class, mem, values; VALUE klass, mem, values;
volatile int i; /* gcc 2.7.2.3 -O2 bug?? */ volatile int i; /* gcc 2.7.2.3 -O2 bug?? */
int len; int len;
ID slot; ID slot;
class = rb_path2class(r_unique(arg)); klass = rb_path2class(r_unique(arg));
mem = rb_ivar_get(class, rb_intern("__member__")); mem = rb_ivar_get(klass, rb_intern("__member__"));
if (mem == Qnil) { if (mem == Qnil) {
Fatal("non-initialized struct"); rb_raise(rb_eTypeError, "non-initialized struct");
} }
len = r_long(arg); len = r_long(arg);
values = ary_new2(len); values = rb_ary_new2(len);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
ary_push(values, Qnil); rb_ary_push(values, Qnil);
} }
v = struct_alloc(class, values); v = rb_struct_alloc(klass, values);
r_regist(v, arg); r_regist(v, arg);
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
slot = r_symbol(arg); slot = r_symbol(arg);
if (RARRAY(mem)->ptr[i] != INT2FIX(slot)) { if (RARRAY(mem)->ptr[i] != INT2FIX(slot)) {
TypeError("struct %s not compatible (:%s for :%s)", rb_raise(rb_eTypeError, "struct %s not compatible (:%s for :%s)",
rb_class2name(class), rb_class2name(klass),
rb_id2name(slot), rb_id2name(slot),
rb_id2name(FIX2INT(RARRAY(mem)->ptr[i]))); rb_id2name(FIX2INT(RARRAY(mem)->ptr[i])));
} }
struct_aset(v, INT2FIX(i), r_object(arg)); rb_struct_aset(v, INT2FIX(i), r_object(arg));
} }
return v; return v;
} }
@ -745,27 +747,26 @@ r_object(arg)
case TYPE_USERDEF: case TYPE_USERDEF:
{ {
VALUE class; VALUE klass;
int len;
class = rb_path2class(r_unique(arg)); klass = rb_path2class(r_unique(arg));
if (rb_respond_to(class, s_load)) { if (rb_respond_to(klass, s_load)) {
v = rb_funcall(class, s_load, 1, r_string(arg)); v = rb_funcall(klass, s_load, 1, r_string(arg));
return r_regist(v, arg); return r_regist(v, arg);
} }
TypeError("class %s needs to have method `_load_from'", rb_raise(rb_eTypeError, "class %s needs to have method `_load_from'",
rb_class2name(class)); rb_class2name(klass));
} }
break; break;
case TYPE_OBJECT: case TYPE_OBJECT:
{ {
VALUE class; VALUE klass;
int len; int len;
class = rb_path2class(r_unique(arg)); klass = rb_path2class(r_unique(arg));
len = r_long(arg); len = r_long(arg);
v = obj_alloc(class); v = rb_obj_alloc(klass);
r_regist(v, arg); r_regist(v, arg);
if (len > 0) { if (len > 0) {
while (len--) { while (len--) {
@ -786,9 +787,10 @@ r_object(arg)
} }
default: default:
ArgError("dump format error(0x%x)", type); rb_raise(rb_eArgError, "dump format error(0x%x)", type);
break; break;
} }
return Qnil; /* not reached */
} }
static VALUE static VALUE
@ -804,6 +806,7 @@ load_ensure(arg)
{ {
st_free_table(arg->symbol); st_free_table(arg->symbol);
st_free_table(arg->data); st_free_table(arg->data);
return 0;
} }
static VALUE static VALUE
@ -812,57 +815,57 @@ marshal_load(argc, argv)
VALUE *argv; VALUE *argv;
{ {
VALUE port, proc; VALUE port, proc;
FILE *fp;
int major; int major;
VALUE v; VALUE v;
OpenFile *fptr; OpenFile *fptr;
struct load_arg arg; struct load_arg arg;
rb_scan_args(argc, argv, "11", &port, &proc); rb_scan_args(argc, argv, "11", &port, &proc);
if (TYPE(port) == T_STRING) { if (rb_obj_is_kind_of(port, rb_cIO)) {
rb_io_binmode(port);
GetOpenFile(port, fptr);
rb_io_check_readable(fptr);
arg.fp = fptr->f;
}
else if (rb_respond_to(port, rb_intern("to_str"))) {
int len;
arg.fp = 0; arg.fp = 0;
arg.ptr = RSTRING(port)->ptr; arg.ptr = str2cstr(port, &len);
arg.end = arg.ptr + RSTRING(port)->len; arg.end = arg.ptr + len;
} }
else { else {
if (obj_is_kind_of(port, cIO)) { rb_raise(rb_eTypeError, "instance of IO needed");
io_binmode(port);
GetOpenFile(port, fptr);
io_readable(fptr);
arg.fp = fptr->f;
}
else {
TypeError("instance of IO needed");
}
} }
major = r_byte(&arg); major = r_byte(&arg);
if (major == MARSHAL_MAJOR) { if (major == MARSHAL_MAJOR) {
if (r_byte(&arg) != MARSHAL_MINOR) { if (r_byte(&arg) != MARSHAL_MINOR) {
Warning("Old marshal file format (can be read)"); rb_warn("Old marshal file format (can be read)");
} }
arg.symbol = st_init_numtable(); arg.symbol = st_init_numtable();
arg.data = st_init_numtable(); arg.data = st_init_numtable();
if (NIL_P(proc)) arg.proc = 0; if (NIL_P(proc)) arg.proc = 0;
else arg.proc = proc; else arg.proc = proc;
v = rb_ensure(load, &arg, load_ensure, &arg); v = rb_ensure(load, (VALUE)&arg, load_ensure, (VALUE)&arg);
} }
else { else {
TypeError("Old marshal file format (can't read)"); rb_raise(rb_eTypeError, "Old marshal file format (can't read)");
} }
return v; return v;
} }
void
Init_marshal() Init_marshal()
{ {
VALUE mMarshal = rb_define_module("Marshal"); VALUE rb_mMarshal = rb_define_module("Marshal");
s_dump = rb_intern("_dump_to"); s_dump = rb_intern("_dump");
s_load = rb_intern("_load_from"); s_load = rb_intern("_load");
rb_define_module_function(mMarshal, "dump", marshal_dump, -1); rb_define_module_function(rb_mMarshal, "dump", marshal_dump, -1);
rb_define_module_function(mMarshal, "load", marshal_load, -1); rb_define_module_function(rb_mMarshal, "load", marshal_load, -1);
rb_define_module_function(mMarshal, "restore", marshal_load, 1); rb_define_module_function(rb_mMarshal, "restore", marshal_load, 1);
rb_provide("marshal.o"); /* for backward compatibility */ rb_provide("marshal.so"); /* for backward compatibility */
} }

74
math.c
View file

@ -6,14 +6,14 @@
$Date$ $Date$
created at: Tue Jan 25 14:12:56 JST 1994 created at: Tue Jan 25 14:12:56 JST 1994
Copyright (C) 1993-1996 Yukihiro Matsumoto Copyright (C) 1993-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
#include "ruby.h" #include "ruby.h"
#include <math.h> #include <math.h>
VALUE mMath; VALUE rb_mMath;
#define Need_Float(x) (x) = rb_Float(x) #define Need_Float(x) (x) = rb_Float(x)
#define Need_Float2(x,y) {\ #define Need_Float2(x,y) {\
@ -26,7 +26,7 @@ math_atan2(obj, x, y)
VALUE obj, x, y; VALUE obj, x, y;
{ {
Need_Float2(x, y); Need_Float2(x, y);
return float_new(atan2(RFLOAT(x)->value, RFLOAT(y)->value)); return rb_float_new(atan2(RFLOAT(x)->value, RFLOAT(y)->value));
} }
static VALUE static VALUE
@ -35,7 +35,7 @@ math_cos(obj, x)
{ {
Need_Float(x); Need_Float(x);
return float_new(cos(RFLOAT(x)->value)); return rb_float_new(cos(RFLOAT(x)->value));
} }
static VALUE static VALUE
@ -44,7 +44,7 @@ math_sin(obj, x)
{ {
Need_Float(x); Need_Float(x);
return float_new(sin(RFLOAT(x)->value)); return rb_float_new(sin(RFLOAT(x)->value));
} }
static VALUE static VALUE
@ -53,7 +53,7 @@ math_tan(obj, x)
{ {
Need_Float(x); Need_Float(x);
return float_new(tan(RFLOAT(x)->value)); return rb_float_new(tan(RFLOAT(x)->value));
} }
static VALUE static VALUE
@ -61,7 +61,7 @@ math_exp(obj, x)
VALUE obj, x; VALUE obj, x;
{ {
Need_Float(x); Need_Float(x);
return float_new(exp(RFLOAT(x)->value)); return rb_float_new(exp(RFLOAT(x)->value));
} }
static VALUE static VALUE
@ -69,7 +69,7 @@ math_log(obj, x)
VALUE obj, x; VALUE obj, x;
{ {
Need_Float(x); Need_Float(x);
return float_new(log(RFLOAT(x)->value)); return rb_float_new(log(RFLOAT(x)->value));
} }
static VALUE static VALUE
@ -77,7 +77,7 @@ math_log10(obj, x)
VALUE obj, x; VALUE obj, x;
{ {
Need_Float(x); Need_Float(x);
return float_new(log10(RFLOAT(x)->value)); return rb_float_new(log10(RFLOAT(x)->value));
} }
static VALUE static VALUE
@ -86,34 +86,60 @@ math_sqrt(obj, x)
{ {
Need_Float(x); Need_Float(x);
if (RFLOAT(x)->value < 0.0) ArgError("square root for negative number"); if (RFLOAT(x)->value < 0.0) rb_raise(rb_eArgError, "square root for negative number");
return float_new(sqrt(RFLOAT(x)->value)); return rb_float_new(sqrt(RFLOAT(x)->value));
}
static VALUE
math_frexp(obj, x)
VALUE obj, x;
{
double d;
int exp;
Need_Float(x);
d = frexp(RFLOAT(x)->value, &exp);
return rb_assoc_new(rb_float_new(d), INT2NUM(exp));
}
static VALUE
math_ldexp(obj, x, n)
VALUE obj, x, n;
{
double d;
Need_Float(x);
return rb_float_new(d = ldexp(RFLOAT(x)->value, NUM2INT(n)));
} }
void void
Init_Math() Init_Math()
{ {
mMath = rb_define_module("Math"); rb_mMath = rb_define_module("Math");
#ifdef M_PI #ifdef M_PI
rb_define_const(mMath, "PI", float_new(M_PI)); rb_define_const(rb_mMath, "PI", rb_float_new(M_PI));
#else #else
rb_define_const(mMath, "PI", float_new(atan(1.0)*4.0)); rb_define_const(rb_mMath, "PI", rb_float_new(atan(1.0)*4.0));
#endif #endif
#ifdef M_E #ifdef M_E
rb_define_const(mMath, "E", float_new(M_E)); rb_define_const(rb_mMath, "E", rb_float_new(M_E));
#else #else
rb_define_const(mMath, "E", float_new(exp(1.0))); rb_define_const(rb_mMath, "E", rb_float_new(exp(1.0)));
#endif #endif
rb_define_module_function(mMath, "atan2", math_atan2, 2); rb_define_module_function(rb_mMath, "atan2", math_atan2, 2);
rb_define_module_function(mMath, "cos", math_cos, 1); rb_define_module_function(rb_mMath, "cos", math_cos, 1);
rb_define_module_function(mMath, "sin", math_sin, 1); rb_define_module_function(rb_mMath, "sin", math_sin, 1);
rb_define_module_function(mMath, "tan", math_tan, 1); rb_define_module_function(rb_mMath, "tan", math_tan, 1);
rb_define_module_function(mMath, "exp", math_exp, 1); rb_define_module_function(rb_mMath, "exp", math_exp, 1);
rb_define_module_function(mMath, "log", math_log, 1); rb_define_module_function(rb_mMath, "log", math_log, 1);
rb_define_module_function(mMath, "log10", math_log10, 1); rb_define_module_function(rb_mMath, "log10", math_log10, 1);
rb_define_module_function(mMath, "sqrt", math_sqrt, 1); rb_define_module_function(rb_mMath, "sqrt", math_sqrt, 1);
rb_define_module_function(rb_mMath, "frexp", math_frexp, 1);
rb_define_module_function(rb_mMath, "ldexp", math_ldexp, 2);
} }

View file

@ -1,11 +1,11 @@
/* $RCSfile: dir.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:10 $ /* $RCSfile: dir.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:10 $
* *
* (C) Copyright 1987, 1990 Diomidis Spinellis. * (C) Copyright 1987, 1990 Diomidis Spinellis.
* *
* You may distribute under the terms of either the GNU General Public * You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file. * License or the Artistic License, as specified in the README file.
* *
* $Log: dir.h,v $ * $Log: dir.h,v $
* Revision 4.0.1.1 91/06/07 11:22:10 lwall * Revision 4.0.1.1 91/06/07 11:22:10 lwall
* patch4: new copyright notice * patch4: new copyright notice
* *
@ -61,125 +61,3 @@ void rewinddir(DIR *dirp);
void closedir(DIR *dirp); void closedir(DIR *dirp);
#endif /* __DIR_INCLUDED */ #endif /* __DIR_INCLUDED */
/* $RCSfile: dir.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:10 $
*
* (C) Copyright 1987, 1990 Diomidis Spinellis.
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
* $Log: dir.h,v $
* Revision 4.0.1.1 91/06/07 11:22:10 lwall
* patch4: new copyright notice
*
* Revision 4.0 91/03/20 01:34:20 lwall
* 4.0 baseline.
*
* Revision 3.0.1.1 90/03/27 16:07:08 lwall
* patch16: MSDOS support
*
* Revision 1.1 90/03/18 20:32:29 dds
* Initial revision
*
*
*/
/*
* defines the type returned by the directory(3) functions
*/
#ifndef __DIR_INCLUDED
#define __DIR_INCLUDED
/*Directory entry size */
#ifdef DIRSIZ
#undef DIRSIZ
#endif
#define DIRSIZ(rp) (sizeof(struct direct))
/*
* Structure of a directory entry
*/
struct direct {
ino_t d_ino; /* inode number (not used by MS-DOS) */
int d_namlen; /* Name length */
char d_name[256]; /* file name */
};
struct _dir_struc { /* Structure used by dir operations */
char *start; /* Starting position */
char *curr; /* Current position */
struct direct dirstr; /* Directory structure to return */
};
typedef struct _dir_struc DIR; /* Type returned by dir operations */
DIR *cdecl opendir(char *filename);
struct direct *readdir(DIR *dirp);
long telldir(DIR *dirp);
void seekdir(DIR *dirp,long loc);
void rewinddir(DIR *dirp);
void closedir(DIR *dirp);
#endif /* __DIR_INCLUDED */
/* $RCSfile: dir.h,v $$Revision: 4.0.1.1 $$Date: 91/06/07 11:22:10 $
*
* (C) Copyright 1987, 1990 Diomidis Spinellis.
*
* You may distribute under the terms of either the GNU General Public
* License or the Artistic License, as specified in the README file.
*
* $Log: dir.h,v $
* Revision 4.0.1.1 91/06/07 11:22:10 lwall
* patch4: new copyright notice
*
* Revision 4.0 91/03/20 01:34:20 lwall
* 4.0 baseline.
*
* Revision 3.0.1.1 90/03/27 16:07:08 lwall
* patch16: MSDOS support
*
* Revision 1.1 90/03/18 20:32:29 dds
* Initial revision
*
*
*/
/*
* defines the type returned by the directory(3) functions
*/
#ifndef __DIR_INCLUDED
#define __DIR_INCLUDED
/*Directory entry size */
#ifdef DIRSIZ
#undef DIRSIZ
#endif
#define DIRSIZ(rp) (sizeof(struct direct))
/*
* Structure of a directory entry
*/
struct direct {
ino_t d_ino; /* inode number (not used by MS-DOS) */
int d_namlen; /* Name length */
char d_name[256]; /* file name */
};
struct _dir_struc { /* Structure used by dir operations */
char *start; /* Starting position */
char *curr; /* Current position */
struct direct dirstr; /* Directory structure to return */
};
typedef struct _dir_struc DIR; /* Type returned by dir operations */
DIR *cdecl opendir(char *filename);
struct direct *readdir(DIR *dirp);
long telldir(DIR *dirp);
void seekdir(DIR *dirp,long loc);
void rewinddir(DIR *dirp);
void closedir(DIR *dirp);
#endif /* __DIR_INCLUDED */

View file

@ -24,7 +24,6 @@
#define F_OK 0 /* does file exist */ #define F_OK 0 /* does file exist */
#define X_OK 1 /* is it executable by caller */ #define X_OK 1 /* is it executable by caller */
#define W_OK 2 /* is it writable by caller */ #define W_OK 2 /* is it writable by caller */
#define R_OK 4 /* is it readable by caller */ #define R_OK 4 /* is it readable by caller */

View file

@ -10,3 +10,27 @@
#include "x68/_round.c" #include "x68/_round.c"
#include "x68/fconvert.c" #include "x68/fconvert.c"
#endif #endif
/* missing some basic syscalls */
int
link(const char *src, const char *dst)
{
return symlink(src, dst);
}
#include <time.h>
#include <sys/time.h>
struct timezone {
int tz_minueswest;
int tz_dsttime;
};
int
gettimeofday(struct timeval *tv, struct timezone *tz)
{
tv->tv_sec = (long)time((time_t*)0);
tv->tv_usec = 0;
return 0;
}

View file

@ -26,14 +26,14 @@ v_others = []
File.foreach "config.status" do |$_| File.foreach "config.status" do |$_|
next if /^#/ next if /^#/
if /^s%@program_transform_name@%s,(.*)%g$/ if /^s%@program_transform_name@%s,(.*)%g$/
ptn = $1.sub(/\$\$/, '$').split(/,/) ptn = $1.sub(/\$\$/, '$').split(/,/) #'
v_fast << " CONFIG[\"ruby_install_name\"] = \"" + "ruby".sub(ptn[0],ptn[1]) + "\"\n" v_fast << " CONFIG[\"ruby_install_name\"] = \"" + "ruby".sub(ptn[0],ptn[1]) + "\"\n"
elsif /^s%@(\w+)@%(.*)%g/ elsif /^s%@(\w+)@%(.*)%g/
name = $1 name = $1
val = $2 || "" val = $2 || ""
next if name =~ /^(INSTALL|DEFS|configure_input|srcdir|top_srcdir)$/ next if name =~ /^(INSTALL|DEFS|configure_input|srcdir|top_srcdir)$/
v = " CONFIG[\"" + name + "\"] = " + v = " CONFIG[\"" + name + "\"] = " +
val.sub(/^\s*(.*)\s*$/, '"\1"').gsub(/\$\{?([^}]*)\}?/) { val.sub(/^\s*(.*)\s*$/, '"\1"').gsub(/\$[{(]?([^})]+)[})]?/) {
"\#{CONFIG[\\\"#{$1}\\\"]}" "\#{CONFIG[\\\"#{$1}\\\"]}"
} + "\n" } + "\n"
if fast[name] if fast[name]

231
node.h
View file

@ -6,7 +6,7 @@
$Date$ $Date$
created at: Fri May 28 15:14:02 JST 1993 created at: Fri May 28 15:14:02 JST 1993
Copyright (C) 1993-1996 Yukihiro Matsumoto Copyright (C) 1993-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
@ -41,11 +41,14 @@ enum node_type {
NODE_MASGN, NODE_MASGN,
NODE_LASGN, NODE_LASGN,
NODE_DASGN, NODE_DASGN,
NODE_DASGN_PUSH,
NODE_GASGN, NODE_GASGN,
NODE_IASGN, NODE_IASGN,
NODE_CASGN, NODE_CASGN,
NODE_OP_ASGN1, NODE_OP_ASGN1,
NODE_OP_ASGN2, NODE_OP_ASGN2,
NODE_OP_ASGN_AND,
NODE_OP_ASGN_OR,
NODE_CALL, NODE_CALL,
NODE_FCALL, NODE_FCALL,
NODE_VCALL, NODE_VCALL,
@ -63,8 +66,6 @@ enum node_type {
NODE_CVAR, NODE_CVAR,
NODE_NTH_REF, NODE_NTH_REF,
NODE_BACK_REF, NODE_BACK_REF,
NODE_MATCH_REF,
NODE_LASTLINE,
NODE_MATCH, NODE_MATCH,
NODE_MATCH2, NODE_MATCH2,
NODE_MATCH3, NODE_MATCH3,
@ -77,6 +78,10 @@ enum node_type {
NODE_DREGX, NODE_DREGX,
NODE_DREGX_ONCE, NODE_DREGX_ONCE,
NODE_ARGS, NODE_ARGS,
NODE_ARGSCAT,
NODE_RESTARGS,
NODE_BLOCK_ARG,
NODE_BLOCK_PASS,
NODE_DEFN, NODE_DEFN,
NODE_DEFS, NODE_DEFS,
NODE_ALIAS, NODE_ALIAS,
@ -86,6 +91,7 @@ enum node_type {
NODE_MODULE, NODE_MODULE,
NODE_SCLASS, NODE_SCLASS,
NODE_COLON2, NODE_COLON2,
NODE_COLON3,
NODE_CNAME, NODE_CNAME,
NODE_CREF, NODE_CREF,
NODE_DOT2, NODE_DOT2,
@ -98,13 +104,15 @@ enum node_type {
NODE_TRUE, NODE_TRUE,
NODE_FALSE, NODE_FALSE,
NODE_DEFINED, NODE_DEFINED,
NODE_TAG,
NODE_NEWLINE, NODE_NEWLINE,
NODE_POSTEXE, NODE_POSTEXE,
#ifdef C_ALLOCA
NODE_ALLOCA,
#endif
}; };
typedef struct RNode { typedef struct RNode {
UINT flags; unsigned long flags;
char *nd_file; char *nd_file;
union { union {
struct RNode *node; struct RNode *node;
@ -131,13 +139,15 @@ typedef struct RNode {
#define RNODE(obj) (R_CAST(RNode)(obj)) #define RNODE(obj) (R_CAST(RNode)(obj))
#define nd_type(n) (((RNODE(n))->flags>>FL_USHIFT)&0x7f) #define nd_type(n) (((RNODE(n))->flags>>FL_USHIFT)&0xff)
#define nd_set_type(n,t) \ #define nd_set_type(n,t) \
RNODE(n)->flags=((RNODE(n)->flags&~FL_UMASK)|(((t)<<FL_USHIFT)&FL_UMASK)) RNODE(n)->flags=((RNODE(n)->flags&~FL_UMASK)|(((t)<<FL_USHIFT)&FL_UMASK))
#define nd_line(n) (((RNODE(n))->flags>>18)&0x3fff) #define NODE_LSHIFT (FL_USHIFT+8)
#define NODE_LMASK ((1<<(sizeof(NODE*)*CHAR_BIT-NODE_LSHIFT))-1)
#define nd_line(n) (((RNODE(n))->flags>>NODE_LSHIFT)&NODE_LMASK)
#define nd_set_line(n,l) \ #define nd_set_line(n,l) \
RNODE(n)->flags=((RNODE(n)->flags&~(-1<<18))|(((l)&0x7fff)<<18)) RNODE(n)->flags=((RNODE(n)->flags&~(-1<<NODE_LSHIFT))|(((l)&NODE_LMASK)<<NODE_LSHIFT))
#define nd_head u1.node #define nd_head u1.node
#define nd_alen u2.argc #define nd_alen u2.argc
@ -185,8 +195,8 @@ typedef struct RNode {
#define nd_noex u1.id #define nd_noex u1.id
#define nd_defn u3.node #define nd_defn u3.node
#define nd_old u1.id
#define nd_new u2.id #define nd_new u2.id
#define nd_old u3.id
#define nd_cfnc u1.cfunc #define nd_cfnc u1.cfunc
#define nd_argc u2.argc #define nd_argc u2.argc
@ -200,114 +210,133 @@ typedef struct RNode {
#define nd_beg u1.node #define nd_beg u1.node
#define nd_end u2.node #define nd_end u2.node
#define nd_state u3.state #define nd_state u3.state
#define nd_rval u3.value #define nd_rval u2.value
#define nd_nth u2.argc #define nd_nth u2.argc
#define nd_tag u1.id #define nd_tag u1.id
#define nd_tlev u3.cnt
#define nd_tval u2.value #define nd_tval u2.value
#define NEW_METHOD(n,x) node_newnode(NODE_METHOD,x,n,0) #define NEW_METHOD(n,x) rb_node_newnode(NODE_METHOD,x,n,0)
#define NEW_FBODY(n,i,o) node_newnode(NODE_FBODY,n,i,o) #define NEW_FBODY(n,i,o) rb_node_newnode(NODE_FBODY,n,i,o)
#define NEW_DEFN(i,a,d,p) node_newnode(NODE_DEFN,p,i,NEW_RFUNC(a,d)) #define NEW_DEFN(i,a,d,p) rb_node_newnode(NODE_DEFN,p,i,NEW_RFUNC(a,d))
#define NEW_DEFS(r,i,a,d) node_newnode(NODE_DEFS,r,i,NEW_RFUNC(a,d)) #define NEW_DEFS(r,i,a,d) rb_node_newnode(NODE_DEFS,r,i,NEW_RFUNC(a,d))
#define NEW_CFUNC(f,c) node_newnode(NODE_CFUNC,f,c,0) #define NEW_CFUNC(f,c) rb_node_newnode(NODE_CFUNC,f,c,0)
#define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2)) #define NEW_RFUNC(b1,b2) NEW_SCOPE(block_append(b1,b2))
#define NEW_SCOPE(b) node_newnode(NODE_SCOPE,local_tbl(),(b),cur_cref) #define NEW_SCOPE(b) rb_node_newnode(NODE_SCOPE,local_tbl(),cur_cref,(b))
#define NEW_BLOCK(a) node_newnode(NODE_BLOCK,a,0,0) #define NEW_BLOCK(a) rb_node_newnode(NODE_BLOCK,a,0,0)
#define NEW_IF(c,t,e) node_newnode(NODE_IF,c,t,e) #ifdef NOBLOCK_RECUR
#define NEW_UNLESS(c,t,e) node_newnode(NODE_IF,c,e,t) #define NEW_IF(c,t,e) block_append(c,rb_node_newnode(NODE_IF,0,t,e))
#define NEW_CASE(h,b) node_newnode(NODE_CASE,h,b,0) #else
#define NEW_WHEN(c,t,e) node_newnode(NODE_WHEN,c,t,e) #define NEW_IF(c,t,e) rb_node_newnode(NODE_IF,c,t,e)
#define NEW_OPT_N(b) node_newnode(NODE_OPT_N,0,b,0) #endif
#define NEW_WHILE(c,b,n) node_newnode(NODE_WHILE,c,b,n) #define NEW_UNLESS(c,t,e) NEW_IF(c,e,t)
#define NEW_UNTIL(c,b,n) node_newnode(NODE_UNTIL,c,b,n) #ifdef NOBLOCK_RECUR
#define NEW_FOR(v,i,b) node_newnode(NODE_FOR,v,b,i) #define NEW_CASE(h,b) block_append(h,rb_node_newnode(NODE_CASE,0,b,0))
#define NEW_ITER(v,i,b) node_newnode(NODE_ITER,v,b,i) #else
#define NEW_BREAK() node_newnode(NODE_BREAK,0,0,0) #define NEW_CASE(h,b) rb_node_newnode(NODE_CASE,h,b,0)
#define NEW_NEXT() node_newnode(NODE_NEXT,0,0,0) #endif
#define NEW_REDO() node_newnode(NODE_REDO,0,0,0) #define NEW_WHEN(c,t,e) rb_node_newnode(NODE_WHEN,c,t,e)
#define NEW_RETRY() node_newnode(NODE_RETRY,0,0,0) #define NEW_OPT_N(b) rb_node_newnode(NODE_OPT_N,0,b,0)
#define NEW_BEGIN(b) node_newnode(NODE_BEGIN,0,b,0) #define NEW_WHILE(c,b,n) rb_node_newnode(NODE_WHILE,c,b,n)
#define NEW_RESCUE(b,res) node_newnode(NODE_RESCUE,b,res,0) #define NEW_UNTIL(c,b,n) rb_node_newnode(NODE_UNTIL,c,b,n)
#define NEW_RESBODY(a,ex,n) node_newnode(NODE_RESBODY,n,ex,a) #define NEW_FOR(v,i,b) rb_node_newnode(NODE_FOR,v,b,i)
#define NEW_ENSURE(b,en) node_newnode(NODE_ENSURE,b,0,en) #define NEW_ITER(v,i,b) rb_node_newnode(NODE_ITER,v,b,i)
#define NEW_RET(s) node_newnode(NODE_RETURN,s,0,0) #define NEW_BREAK() rb_node_newnode(NODE_BREAK,0,0,0)
#define NEW_YIELD(a) node_newnode(NODE_YIELD,a,0,0) #define NEW_NEXT() rb_node_newnode(NODE_NEXT,0,0,0)
#define NEW_REDO() rb_node_newnode(NODE_REDO,0,0,0)
#define NEW_RETRY() rb_node_newnode(NODE_RETRY,0,0,0)
#define NEW_BEGIN(b) rb_node_newnode(NODE_BEGIN,0,b,0)
#define NEW_RESCUE(b,res,e) rb_node_newnode(NODE_RESCUE,b,res,e)
#define NEW_RESBODY(a,ex,n) rb_node_newnode(NODE_RESBODY,n,ex,a)
#define NEW_ENSURE(b,en) rb_node_newnode(NODE_ENSURE,b,0,en)
#define NEW_RETURN(s) rb_node_newnode(NODE_RETURN,s,0,0)
#define NEW_YIELD(a) rb_node_newnode(NODE_YIELD,a,0,0)
#define NEW_LIST(a) NEW_ARRAY(a) #define NEW_LIST(a) NEW_ARRAY(a)
#define NEW_ARRAY(a) node_newnode(NODE_ARRAY,a,1,0) #define NEW_ARRAY(a) rb_node_newnode(NODE_ARRAY,a,1,0)
#define NEW_ZARRAY() node_newnode(NODE_ZARRAY,0,0,0) #define NEW_ZARRAY() rb_node_newnode(NODE_ZARRAY,0,0,0)
#define NEW_HASH(a) node_newnode(NODE_HASH,a,0,0) #define NEW_HASH(a) rb_node_newnode(NODE_HASH,a,0,0)
#define NEW_NOT(a) node_newnode(NODE_NOT,0,a,0) #define NEW_NOT(a) rb_node_newnode(NODE_NOT,0,a,0)
#define NEW_MASGN(l,r) node_newnode(NODE_MASGN,l,0,r) #define NEW_MASGN(l,r) rb_node_newnode(NODE_MASGN,l,0,r)
#define NEW_GASGN(v,val) node_newnode(NODE_GASGN,v,val,rb_global_entry(v)) #define NEW_GASGN(v,val) rb_node_newnode(NODE_GASGN,v,val,rb_global_entry(v))
#define NEW_LASGN(v,val) node_newnode(NODE_LASGN,v,val,local_cnt(v)) #define NEW_LASGN(v,val) rb_node_newnode(NODE_LASGN,v,val,local_cnt(v))
#define NEW_DASGN(v,val) node_newnode(NODE_DASGN,v,val,0); #define NEW_DASGN(v,val) rb_node_newnode(NODE_DASGN,v,val,0);
#define NEW_IASGN(v,val) node_newnode(NODE_IASGN,v,val,0) #define NEW_DASGN_PUSH(v,val) rb_node_newnode(NODE_DASGN_PUSH,v,val,0);
#define NEW_CASGN(v,val) node_newnode(NODE_CASGN,v,val,0) #define NEW_IASGN(v,val) rb_node_newnode(NODE_IASGN,v,val,0)
#define NEW_OP_ASGN1(p,id,a) node_newnode(NODE_OP_ASGN1,p,id,a) #define NEW_CASGN(v,val) rb_node_newnode(NODE_CASGN,v,val,0)
#define NEW_OP_ASGN2(r,i,o,val) node_newnode(NODE_OP_ASGN2,r,val,NEW_OP_ASGN3(i,o)) #define NEW_OP_ASGN1(p,id,a) rb_node_newnode(NODE_OP_ASGN1,p,id,a)
#define NEW_OP_ASGN3(i,o) node_newnode(NODE_OP_ASGN2,i,o,0) #define NEW_OP_ASGN2(r,i,o,val) rb_node_newnode(NODE_OP_ASGN2,r,val,NEW_OP_ASGN22(i,o))
#define NEW_GVAR(v) node_newnode(NODE_GVAR,v,0,rb_global_entry(v)) #define NEW_OP_ASGN22(i,o) rb_node_newnode(NODE_OP_ASGN2,i,o,rb_id_attrset(i))
#define NEW_LVAR(v) node_newnode(NODE_LVAR,v,0,local_cnt(v)) #define NEW_OP_ASGN_OR(i,val) rb_node_newnode(NODE_OP_ASGN_OR,i,val,0)
#define NEW_DVAR(v) node_newnode(NODE_DVAR,v,0,0); #define NEW_OP_ASGN_AND(i,val) rb_node_newnode(NODE_OP_ASGN_AND,i,val,0)
#define NEW_IVAR(v) node_newnode(NODE_IVAR,v,0,0) #define NEW_GVAR(v) rb_node_newnode(NODE_GVAR,v,0,rb_global_entry(v))
#define NEW_CVAR(v) node_newnode(NODE_CVAR,v,0,0) #define NEW_LVAR(v) rb_node_newnode(NODE_LVAR,v,0,local_cnt(v))
#define NEW_NTH_REF(n) node_newnode(NODE_NTH_REF,0,n,local_cnt('~')) #define NEW_DVAR(v) rb_node_newnode(NODE_DVAR,v,0,0);
#define NEW_BACK_REF(n) node_newnode(NODE_BACK_REF,0,n,local_cnt('~')) #define NEW_IVAR(v) rb_node_newnode(NODE_IVAR,v,0,0)
#define NEW_MATCH(c) node_newnode(NODE_MATCH,c,0,0) #define NEW_CVAR(v) rb_node_newnode(NODE_CVAR,v,0,0)
#define NEW_MATCH2(n1,n2) node_newnode(NODE_MATCH2,n1,n2,0) #define NEW_NTH_REF(n) rb_node_newnode(NODE_NTH_REF,0,n,local_cnt('~'))
#define NEW_MATCH3(r,n2) node_newnode(NODE_MATCH3,r,n2,0) #define NEW_BACK_REF(n) rb_node_newnode(NODE_BACK_REF,0,n,local_cnt('~'))
#define NEW_LIT(l) node_newnode(NODE_LIT,l,0,0) #define NEW_MATCH(c) rb_node_newnode(NODE_MATCH,c,0,0)
#define NEW_STR(s) node_newnode(NODE_STR,s,0,0) #define NEW_MATCH2(n1,n2) rb_node_newnode(NODE_MATCH2,n1,n2,0)
#define NEW_DSTR(s) node_newnode(NODE_DSTR,s,0,0) #define NEW_MATCH3(r,n2) rb_node_newnode(NODE_MATCH3,r,n2,0)
#define NEW_XSTR(s) node_newnode(NODE_XSTR,s,0,0) #define NEW_LIT(l) rb_node_newnode(NODE_LIT,l,0,0)
#define NEW_DXSTR(s) node_newnode(NODE_DXSTR,s,0,0) #define NEW_STR(s) rb_node_newnode(NODE_STR,s,0,0)
#define NEW_EVSTR(s,l) node_newnode(NODE_EVSTR,str_new(s,l),0,0) #define NEW_DSTR(s) rb_node_newnode(NODE_DSTR,s,0,0)
#define NEW_CALL(r,m,a) node_newnode(NODE_CALL,r,m,a) #define NEW_XSTR(s) rb_node_newnode(NODE_XSTR,s,0,0)
#define NEW_FCALL(m,a) node_newnode(NODE_FCALL,0,m,a) #define NEW_DXSTR(s) rb_node_newnode(NODE_DXSTR,s,0,0)
#define NEW_VCALL(m) node_newnode(NODE_VCALL,0,m,0) #define NEW_EVSTR(s,l) rb_node_newnode(NODE_EVSTR,rb_str_new(s,l),0,0)
#define NEW_SUPER(a) node_newnode(NODE_SUPER,0,0,a) #ifdef NOBLOCK_RECUR_incomplete
#define NEW_ZSUPER() node_newnode(NODE_ZSUPER,0,0,0) #define NEW_CALL(r,m,a) block_append(r,rb_node_newnode(NODE_CALL,0,m,a))
#define NEW_ARGS(f,o,r) node_newnode(NODE_ARGS,o,r,f) #else
#define NEW_ALIAS(n,o) node_newnode(NODE_ALIAS,0,n,o) #define NEW_CALL(r,m,a) rb_node_newnode(NODE_CALL,r,m,a)
#define NEW_VALIAS(n,o) node_newnode(NODE_VALIAS,0,n,o) #endif
#define NEW_UNDEF(i) node_newnode(NODE_UNDEF,0,i,0) #define NEW_FCALL(m,a) rb_node_newnode(NODE_FCALL,0,m,a)
#define NEW_CLASS(n,b,s) node_newnode(NODE_CLASS,n,NEW_CBODY(b),s) #define NEW_VCALL(m) rb_node_newnode(NODE_VCALL,0,m,0)
#define NEW_SCLASS(r,b) node_newnode(NODE_SCLASS,r,NEW_CBODY(b),0) #define NEW_SUPER(a) rb_node_newnode(NODE_SUPER,0,0,a)
#define NEW_MODULE(n,b) node_newnode(NODE_MODULE,n,NEW_CBODY(b),0) #define NEW_ZSUPER() rb_node_newnode(NODE_ZSUPER,0,0,0)
#define NEW_COLON2(c,i) node_newnode(NODE_COLON2,c,i,0) #define NEW_ARGS(f,o,r) rb_node_newnode(NODE_ARGS,o,r,f)
#define NEW_CREF0() (cur_cref=node_newnode(NODE_CREF,RNODE(the_frame->cbase)->nd_clss,0,0)) #define NEW_ARGSCAT(a,b) rb_node_newnode(NODE_ARGSCAT,a,b,0)
#define NEW_CREF() (cur_cref=node_newnode(NODE_CREF,0,0,cur_cref)) #define NEW_RESTARGS(a) rb_node_newnode(NODE_RESTARGS,a,0,0)
#define NEW_BLOCK_ARG(v) rb_node_newnode(NODE_BLOCK_ARG,v,0,local_cnt(v))
#define NEW_BLOCK_PASS(b) rb_node_newnode(NODE_BLOCK_PASS,0,b,0)
#define NEW_ALIAS(n,o) rb_node_newnode(NODE_ALIAS,o,n,0)
#define NEW_VALIAS(n,o) rb_node_newnode(NODE_VALIAS,o,n,0)
#define NEW_UNDEF(i) rb_node_newnode(NODE_UNDEF,0,i,0)
#define NEW_CLASS(n,b,s) rb_node_newnode(NODE_CLASS,n,NEW_CBODY(b),(s))
#define NEW_SCLASS(r,b) rb_node_newnode(NODE_SCLASS,r,NEW_CBODY(b),0)
#define NEW_MODULE(n,b) rb_node_newnode(NODE_MODULE,n,NEW_CBODY(b),0)
#define NEW_COLON2(c,i) rb_node_newnode(NODE_COLON2,c,i,0)
#define NEW_COLON3(i) rb_node_newnode(NODE_COLON3,0,i,0)
#define NEW_CREF0() (cur_cref=rb_node_newnode(NODE_CREF,RNODE(ruby_frame->cbase)->nd_clss,0,0))
#define NEW_CREF() (cur_cref=rb_node_newnode(NODE_CREF,0,0,cur_cref))
#define NEW_CBODY(b) (cur_cref->nd_body=NEW_SCOPE(b),cur_cref) #define NEW_CBODY(b) (cur_cref->nd_body=NEW_SCOPE(b),cur_cref)
#define NEW_DOT2(b,e) node_newnode(NODE_DOT2,b,e,0) #define NEW_DOT2(b,e) rb_node_newnode(NODE_DOT2,b,e,0)
#define NEW_DOT3(b,e) node_newnode(NODE_DOT3,b,e,0) #define NEW_DOT3(b,e) rb_node_newnode(NODE_DOT3,b,e,0)
#define NEW_ATTRSET(a) node_newnode(NODE_ATTRSET,a,0,0) #define NEW_ATTRSET(a) rb_node_newnode(NODE_ATTRSET,a,0,0)
#define NEW_SELF() node_newnode(NODE_SELF,0,0,0) #define NEW_SELF() rb_node_newnode(NODE_SELF,0,0,0)
#define NEW_NIL() node_newnode(NODE_NIL,0,0,0) #define NEW_NIL() rb_node_newnode(NODE_NIL,0,0,0)
#define NEW_TRUE() node_newnode(NODE_TRUE,0,0,0) #define NEW_TRUE() rb_node_newnode(NODE_TRUE,0,0,0)
#define NEW_FALSE() node_newnode(NODE_FALSE,0,0,0) #define NEW_FALSE() rb_node_newnode(NODE_FALSE,0,0,0)
#define NEW_DEFINED(e) node_newnode(NODE_DEFINED,e,0,0) #define NEW_DEFINED(e) rb_node_newnode(NODE_DEFINED,e,0,0)
#define NEW_NEWLINE(n) node_newnode(NODE_NEWLINE,0,0,n) #define NEW_NEWLINE(n) rb_node_newnode(NODE_NEWLINE,0,0,n)
#define NEW_PREEXE(b) NEW_SCOPE(b) #define NEW_PREEXE(b) NEW_SCOPE(b)
#define NEW_POSTEXE() node_newnode(NODE_POSTEXE,0,0,0) #define NEW_POSTEXE() rb_node_newnode(NODE_POSTEXE,0,0,0)
NODE *node_newnode(); NODE *rb_node_newnode();
VALUE rb_method_booundp(); VALUE rb_method_booundp();
#define NOEX_PUBLIC 0 #define NOEX_PUBLIC 0
#define NOEX_PRIVATE 1 #define NOEX_UNDEF 1
#define NOEX_CFUNC 1
#define NOEX_PRIVATE 2
#define NOEX_PROTECTED 4
NODE *compile_string _((char *, char *, int)); NODE *rb_compile_cstr _((char *, char *, int));
NODE *compile_file _((char *, VALUE, int)); NODE *rb_compile_string _((char *, VALUE));
NODE *rb_compile_file _((char *, VALUE, int));
void rb_add_method _((VALUE, ID, NODE *, int)); void rb_add_method _((VALUE, ID, NODE *, int));
void rb_remove_method _((VALUE, ID)); NODE *rb_node_newnode();
NODE *node_newnode();
enum node_type nodetype _((NODE *));
int nodeline _((NODE *));
struct global_entry *rb_global_entry _((ID)); struct global_entry *rb_global_entry _((ID));
VALUE rb_gvar_get _((struct global_entry *)); VALUE rb_gvar_get _((struct global_entry *));

1042
numeric.c

File diff suppressed because it is too large Load diff

869
object.c

File diff suppressed because it is too large Load diff

407
pack.c
View file

@ -6,13 +6,13 @@
$Date$ $Date$
created at: Thu Feb 10 15:17:05 JST 1994 created at: Thu Feb 10 15:17:05 JST 1994
Copyright (C) 1993-1996 Yukihiro Matsumoto Copyright (C) 1993-1998 Yukihiro Matsumoto
************************************************/ ************************************************/
#include "ruby.h" #include "ruby.h"
#include <ctype.h>
#include <sys/types.h> #include <sys/types.h>
#include <ctype.h>
#define swaps(x) ((((x)&0xFF)<<8) + (((x)>>8)&0xFF)) #define swaps(x) ((((x)&0xFF)<<8) + (((x)>>8)&0xFF))
#define swapl(x) ((((x)&0xFF)<<24) \ #define swapl(x) ((((x)&0xFF)<<24) \
@ -74,14 +74,22 @@ endian()
#endif #endif
#endif #endif
extern VALUE cString, cArray;
#ifndef atof
double atof();
#endif
static char *toofew = "too few arguments"; static char *toofew = "too few arguments";
static void encodes(); static void encodes _((VALUE,char*,int,int));
static void qpencode _((VALUE,VALUE,int));
static void
pack_add_ptr(str, add)
VALUE str, add;
{
#define STR_NO_ORIG FL_USER3 /* copied from string.c */
if (!RSTRING(str)->orig) {
RSTRING(str)->orig = rb_ary_new();
FL_SET(str, STR_NO_ORIG);
}
rb_ary_push(RSTRING(str)->orig, add);
}
static VALUE static VALUE
pack_pack(ary, fmt) pack_pack(ary, fmt)
@ -89,23 +97,22 @@ pack_pack(ary, fmt)
{ {
static char *nul10 = "\0\0\0\0\0\0\0\0\0\0"; static char *nul10 = "\0\0\0\0\0\0\0\0\0\0";
static char *spc10 = " "; static char *spc10 = " ";
UCHAR *p, *pend; char *p, *pend;
VALUE res, from; VALUE res, from;
char type; char type;
int items, len, idx; int items, len, idx;
UCHAR *ptr; char *ptr;
int plen; int plen;
Check_Type(fmt, T_STRING);
p = rb_str2cstr(fmt, &plen);
p = RSTRING(fmt)->ptr; pend = p + plen;
pend = RSTRING(fmt)->ptr + RSTRING(fmt)->len; res = rb_str_new(0, 0);
res = str_new(0, 0);
items = RARRAY(ary)->len; items = RARRAY(ary)->len;
idx = 0; idx = 0;
#define NEXTFROM (items-- > 0 ? RARRAY(ary)->ptr[idx++] : (ArgError(toofew),0)) #define NEXTFROM (items-- > 0 ? RARRAY(ary)->ptr[idx++] : (rb_raise(rb_eArgError, toofew),0))
while (p < pend) { while (p < pend) {
type = *p++; /* get data type */ type = *p++; /* get data type */
@ -114,7 +121,7 @@ pack_pack(ary, fmt)
len = strchr("@Xxu", type) ? 0 : items; len = strchr("@Xxu", type) ? 0 : items;
p++; p++;
} }
else if (isdigit(*p)) { else if (ISDIGIT(*p)) {
len = strtoul(p, (char**)&p, 10); len = strtoul(p, (char**)&p, 10);
} }
else { else {
@ -127,11 +134,11 @@ pack_pack(ary, fmt)
case 'H': case 'h': case 'H': case 'h':
from = NEXTFROM; from = NEXTFROM;
if (NIL_P(from)) { if (NIL_P(from)) {
ptr = 0; ptr = "";
plen = 0; plen = 0;
} }
else { else {
from = obj_as_string(from); from = rb_obj_as_string(from);
ptr = RSTRING(from)->ptr; ptr = RSTRING(from)->ptr;
plen = RSTRING(from)->len; plen = RSTRING(from)->len;
} }
@ -143,15 +150,15 @@ pack_pack(ary, fmt)
case 'a': case 'a':
case 'A': case 'A':
if (plen >= len) if (plen >= len)
str_cat(res, ptr, len); rb_str_cat(res, ptr, len);
else { else {
str_cat(res, ptr, plen); rb_str_cat(res, ptr, plen);
len -= plen; len -= plen;
while (len >= 10) { while (len >= 10) {
str_cat(res, (type == 'A')?spc10:nul10, 10); rb_str_cat(res, (type == 'A')?spc10:nul10, 10);
len -= 10; len -= 10;
} }
str_cat(res, (type == 'A')?spc10:nul10, len); rb_str_cat(res, (type == 'A')?spc10:nul10, len);
} }
break; break;
@ -167,7 +174,7 @@ pack_pack(ary, fmt)
byte >>= 1; byte >>= 1;
else { else {
char c = byte & 0xff; char c = byte & 0xff;
str_cat(res, &c, 1); rb_str_cat(res, &c, 1);
byte = 0; byte = 0;
} }
} }
@ -175,7 +182,7 @@ pack_pack(ary, fmt)
char c; char c;
byte >>= 7 - (len & 7); byte >>= 7 - (len & 7);
c = byte & 0xff; c = byte & 0xff;
str_cat(res, &c, 1); rb_str_cat(res, &c, 1);
} }
} }
break; break;
@ -191,7 +198,7 @@ pack_pack(ary, fmt)
byte <<= 1; byte <<= 1;
else { else {
char c = byte & 0xff; char c = byte & 0xff;
str_cat(res, &c, 1); rb_str_cat(res, &c, 1);
byte = 0; byte = 0;
} }
} }
@ -199,7 +206,7 @@ pack_pack(ary, fmt)
char c; char c;
byte <<= 7 - (len & 7); byte <<= 7 - (len & 7);
c = byte & 0xff; c = byte & 0xff;
str_cat(res, &c, 1); rb_str_cat(res, &c, 1);
} }
} }
break; break;
@ -210,8 +217,8 @@ pack_pack(ary, fmt)
int i; int i;
for (i=0; i++ < len; ptr++) { for (i=0; i++ < len; ptr++) {
if (isxdigit(*ptr)) { if (ISXDIGIT(*ptr)) {
if (isalpha(*ptr)) if (ISALPHA(*ptr))
byte |= (((*ptr & 15) + 9) & 15) << 4; byte |= (((*ptr & 15) + 9) & 15) << 4;
else else
byte |= (*ptr & 15) << 4; byte |= (*ptr & 15) << 4;
@ -219,14 +226,14 @@ pack_pack(ary, fmt)
byte >>= 4; byte >>= 4;
else { else {
char c = byte & 0xff; char c = byte & 0xff;
str_cat(res, &c, 1); rb_str_cat(res, &c, 1);
byte = 0; byte = 0;
} }
} }
} }
if (len & 1) { if (len & 1) {
char c = byte & 0xff; char c = byte & 0xff;
str_cat(res, &c, 1); rb_str_cat(res, &c, 1);
} }
} }
break; break;
@ -237,8 +244,8 @@ pack_pack(ary, fmt)
int i; int i;
for (i=0; i++ < len; ptr++) { for (i=0; i++ < len; ptr++) {
if (isxdigit(*ptr)) { if (ISXDIGIT(*ptr)) {
if (isalpha(*ptr)) if (ISALPHA(*ptr))
byte |= ((*ptr & 15) + 9) & 15; byte |= ((*ptr & 15) + 9) & 15;
else else
byte |= *ptr & 15; byte |= *ptr & 15;
@ -246,14 +253,14 @@ pack_pack(ary, fmt)
byte <<= 4; byte <<= 4;
else { else {
char c = byte & 0xff; char c = byte & 0xff;
str_cat(res, &c, 1); rb_str_cat(res, &c, 1);
byte = 0; byte = 0;
} }
} }
} }
if (len & 1) { if (len & 1) {
char c = byte & 0xff; char c = byte & 0xff;
str_cat(res, &c, 1); rb_str_cat(res, &c, 1);
} }
} }
break; break;
@ -270,7 +277,7 @@ pack_pack(ary, fmt)
else { else {
c = NUM2INT(from); c = NUM2INT(from);
} }
str_cat(res, &c, sizeof(char)); rb_str_cat(res, &c, sizeof(char));
} }
break; break;
@ -284,7 +291,7 @@ pack_pack(ary, fmt)
else { else {
s = NUM2INT(from); s = NUM2INT(from);
} }
str_cat(res, (UCHAR*)&s, sizeof(short)); rb_str_cat(res, (char*)&s, sizeof(short));
} }
break; break;
@ -296,9 +303,9 @@ pack_pack(ary, fmt)
from = NEXTFROM; from = NEXTFROM;
if (NIL_P(from)) i = 0; if (NIL_P(from)) i = 0;
else { else {
i = NUM2INT(from); i = NUM2UINT(from);
} }
str_cat(res, (UCHAR*)&i, sizeof(int)); rb_str_cat(res, (char*)&i, sizeof(int));
} }
break; break;
@ -310,9 +317,9 @@ pack_pack(ary, fmt)
from = NEXTFROM; from = NEXTFROM;
if (NIL_P(from)) l = 0; if (NIL_P(from)) l = 0;
else { else {
l = NUM2INT(from); l = NUM2ULONG(from);
} }
str_cat(res, (UCHAR*)&l, sizeof(long)); rb_str_cat(res, (char*)&l, sizeof(long));
} }
break; break;
@ -326,7 +333,7 @@ pack_pack(ary, fmt)
s = NUM2INT(from); s = NUM2INT(from);
} }
s = htons(s); s = htons(s);
str_cat(res, (UCHAR*)&s, sizeof(short)); rb_str_cat(res, (char*)&s, sizeof(short));
} }
break; break;
@ -337,10 +344,10 @@ pack_pack(ary, fmt)
from = NEXTFROM; from = NEXTFROM;
if (NIL_P(from)) l = 0; if (NIL_P(from)) l = 0;
else { else {
l = NUM2INT(from); l = NUM2ULONG(from);
} }
l = htonl(l); l = htonl(l);
str_cat(res, (UCHAR*)&l, sizeof(long)); rb_str_cat(res, (char*)&l, sizeof(long));
} }
break; break;
@ -354,7 +361,7 @@ pack_pack(ary, fmt)
s = NUM2INT(from); s = NUM2INT(from);
} }
s = htovs(s); s = htovs(s);
str_cat(res, (UCHAR*)&s, sizeof(short)); rb_str_cat(res, (char*)&s, sizeof(short));
} }
break; break;
@ -365,10 +372,10 @@ pack_pack(ary, fmt)
from = NEXTFROM; from = NEXTFROM;
if (NIL_P(from)) l = 0; if (NIL_P(from)) l = 0;
else { else {
l = NUM2INT(from); l = NUM2ULONG(from);
} }
l = htovl(l); l = htovl(l);
str_cat(res, (UCHAR*)&l, sizeof(long)); rb_str_cat(res, (char*)&l, sizeof(long));
} }
break; break;
@ -388,7 +395,7 @@ pack_pack(ary, fmt)
f = (float)NUM2INT(from); f = (float)NUM2INT(from);
break; break;
} }
str_cat(res, (UCHAR*)&f, sizeof(float)); rb_str_cat(res, (char*)&f, sizeof(float));
} }
break; break;
@ -408,23 +415,23 @@ pack_pack(ary, fmt)
d = (double)NUM2INT(from); d = (double)NUM2INT(from);
break; break;
} }
str_cat(res, (UCHAR*)&d, sizeof(double)); rb_str_cat(res, (char*)&d, sizeof(double));
} }
break; break;
case 'x': case 'x':
grow: grow:
while (len >= 10) { while (len >= 10) {
str_cat(res, nul10, 10); rb_str_cat(res, nul10, 10);
len -= 10; len -= 10;
} }
str_cat(res, nul10, len); rb_str_cat(res, nul10, len);
break; break;
case 'X': case 'X':
shrink: shrink:
if (RSTRING(res)->len < len) if (RSTRING(res)->len < len)
ArgError("X outside of string"); rb_raise(rb_eArgError, "X outside of string");
RSTRING(res)->len -= len; RSTRING(res)->len -= len;
RSTRING(res)->ptr[RSTRING(res)->len] = '\0'; RSTRING(res)->ptr[RSTRING(res)->len] = '\0';
break; break;
@ -437,12 +444,12 @@ pack_pack(ary, fmt)
break; break;
case '%': case '%':
ArgError("% may only be used in unpack"); rb_raise(rb_eArgError, "% may only be used in unpack");
break; break;
case 'u': case 'u':
case 'm': case 'm':
from = obj_as_string(NEXTFROM); from = rb_obj_as_string(NEXTFROM);
ptr = RSTRING(from)->ptr; ptr = RSTRING(from)->ptr;
plen = RSTRING(from)->len; plen = RSTRING(from)->len;
@ -463,6 +470,29 @@ pack_pack(ary, fmt)
} }
break; break;
case 'M':
from = rb_obj_as_string(NEXTFROM);
if (len <= 1)
len = 72;
qpencode(res, from, len);
break;
case 'P':
len = 1;
/* FALL THROUGH */
case 'p':
while (len-- > 0) {
char *t;
from = NEXTFROM;
if (NIL_P(from)) t = "";
else {
t = STR2CSTR(from);
pack_add_ptr(res, from);
}
rb_str_cat(res, (char*)&t, sizeof(char*));
}
break;
default: default:
break; break;
} }
@ -479,42 +509,124 @@ static char b64_table[] =
static void static void
encodes(str, s, len, type) encodes(str, s, len, type)
VALUE str; VALUE str;
UCHAR *s; char *s;
int len; int len;
int type; int type;
{ {
char hunk[4]; char *buff = ALLOCA_N(char, len * 4 / 3 + 6);
UCHAR *p, *pend; int i = 0;
char *trans = type == 'u' ? uu_table : b64_table; char *trans = type == 'u' ? uu_table : b64_table;
int padding; int padding;
if (type == 'u') { if (type == 'u') {
*hunk = len + ' '; buff[i++] = len + ' ';
str_cat(str, hunk, 1);
padding = '`'; padding = '`';
} }
else { else {
padding = '='; padding = '=';
} }
while (len > 0) { while (len >= 3) {
hunk[0] = trans[077 & (*s >> 2)]; buff[i++] = trans[077 & (*s >> 2)];
hunk[1] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))]; buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
hunk[2] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))]; buff[i++] = trans[077 & (((s[1] << 2) & 074) | ((s[2] >> 6) & 03))];
hunk[3] = trans[077 & s[2]]; buff[i++] = trans[077 & s[2]];
str_cat(str, hunk, 4);
s += 3; s += 3;
len -= 3; len -= 3;
} }
p = RSTRING(str)->ptr; if (len == 2) {
pend = RSTRING(str)->ptr + RSTRING(str)->len; buff[i++] = trans[077 & (*s >> 2)];
if (len == -1) { buff[i++] = trans[077 & (((*s << 4) & 060) | ((s[1] >> 4) & 017))];
pend[-1] = padding; buff[i++] = trans[077 & (((s[1] << 2) & 074) | (('\0' >> 6) & 03))];
buff[i++] = padding;
} }
else if (len == -2) { else if (len == 1) {
pend[-2] = padding; buff[i++] = trans[077 & (*s >> 2)];
pend[-1] = padding; buff[i++] = trans[077 & (((*s << 4) & 060) | (('\0' >> 4) & 017))];
buff[i++] = padding;
buff[i++] = padding;
}
buff[i++] = '\n';
rb_str_cat(str, buff, i);
}
static char hex_table[] = "0123456789ABCDEF";
static void
qpencode(str, from, len)
VALUE str, from;
int len;
{
char buff[1024];
int i = 0, n = 0, prev = EOF;
unsigned char *s = RSTRING(from)->ptr;
unsigned char *send = s + RSTRING(from)->len;
while (s < send) {
if ((*s > 126) ||
(*s < 32 && *s != '\n' && *s != '\t') ||
(*s == '=')) {
buff[i++] = '=';
buff[i++] = hex_table[*s >> 4];
buff[i++] = hex_table[*s & 0x0f];
n += 3;
prev = EOF;
}
else if (*s == '\n') {
if (prev == ' ' || prev == '\t') {
buff[i++] = '=';
buff[i++] = *s;
}
buff[i++] = *s;
n = 0;
prev = *s;
}
else {
buff[i++] = *s;
n++;
prev = *s;
}
if (n > len) {
buff[i++] = '=';
buff[i++] = '\n';
n = 0;
prev = '\n';
}
if (i > 1024 - 5) {
rb_str_cat(str, buff, i);
i = 0;
}
s++;
}
if (n > 0) {
buff[i++] = '=';
buff[i++] = '\n';
}
if (i > 0) {
rb_str_cat(str, buff, i);
}
}
#if defined(__GNUC__) && __GNUC__ >= 2 && !defined(RUBY_NO_INLINE)
static __inline__ int
#else
static int
#endif
hex2num(c)
char c;
{
switch (c) {
case '0': case '1': case '2': case '3': case '4':
case '5': case '6': case '7': case '8': case '9':
return c - '0';
case 'a': case 'b': case 'c':
case 'd': case 'e': case 'f':
return c - 'a' + 10;
case 'A': case 'B': case 'C':
case 'D': case 'E': case 'F':
return c - 'A' + 10;
default:
return -1;
} }
str_cat(str, "\n", 1);
} }
static VALUE static VALUE
@ -522,27 +634,25 @@ pack_unpack(str, fmt)
VALUE str, fmt; VALUE str, fmt;
{ {
static char *hexdigits = "0123456789abcdef0123456789ABCDEFx"; static char *hexdigits = "0123456789abcdef0123456789ABCDEFx";
UCHAR *s, *send; char *s, *send;
UCHAR *p, *pend; char *p, *pend;
VALUE ary; VALUE ary;
char type; char type;
int len; int len;
Check_Type(fmt, T_STRING); s = rb_str2cstr(str, &len);
send = s + len;
p = rb_str2cstr(fmt, &len);
pend = p + len;
s = RSTRING(str)->ptr; ary = rb_ary_new();
send = s + RSTRING(str)->len;
p = RSTRING(fmt)->ptr;
pend = p + RSTRING(fmt)->len;
ary = ary_new();
while (p < pend) { while (p < pend) {
type = *p++; type = *p++;
if (*p == '*') { if (*p == '*') {
len = send - s; len = send - s;
p++; p++;
} }
else if (isdigit(*p)) { else if (ISDIGIT(*p)) {
len = strtoul(p, (char**)&p, 10); len = strtoul(p, (char**)&p, 10);
} }
else { else {
@ -551,41 +661,41 @@ pack_unpack(str, fmt)
switch (type) { switch (type) {
case '%': case '%':
ArgError("% is not supported(yet)"); rb_raise(rb_eArgError, "% is not supported(yet)");
break; break;
case 'A': case 'A':
if (len > send - s) len = send - s; if (len > send - s) len = send - s;
{ {
int end = len; int end = len;
UCHAR *t = s + len - 1; char *t = s + len - 1;
while (t >= s) { while (t >= s) {
if (*t != ' ' && *t != '\0') break; if (*t != ' ' && *t != '\0') break;
t--; t--;
len--; len--;
} }
ary_push(ary, str_new(s, len)); rb_ary_push(ary, rb_str_new(s, len));
s += end; s += end;
} }
break; break;
case 'a': case 'a':
if (len > send - s) len = send - s; if (len > send - s) len = send - s;
ary_push(ary, str_new(s, len)); rb_ary_push(ary, rb_str_new(s, len));
s += len; s += len;
break; break;
case 'b': case 'b':
{ {
VALUE bitstr; VALUE bitstr;
UCHAR *t; char *t;
int bits, i; int bits, i;
if (p[-1] == '*' || len > (send - s) * 8) if (p[-1] == '*' || len > (send - s) * 8)
len = (send - s) * 8; len = (send - s) * 8;
bits = 0; bits = 0;
ary_push(ary, bitstr = str_new(0, len)); rb_ary_push(ary, bitstr = rb_str_new(0, len));
t = RSTRING(bitstr)->ptr; t = RSTRING(bitstr)->ptr;
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 7) bits >>= 1; if (i & 7) bits >>= 1;
@ -598,13 +708,13 @@ pack_unpack(str, fmt)
case 'B': case 'B':
{ {
VALUE bitstr; VALUE bitstr;
UCHAR *t; char *t;
int bits, i; int bits, i;
if (p[-1] == '*' || len > (send - s) * 8) if (p[-1] == '*' || len > (send - s) * 8)
len = (send - s) * 8; len = (send - s) * 8;
bits = 0; bits = 0;
ary_push(ary, bitstr = str_new(0, len)); rb_ary_push(ary, bitstr = rb_str_new(0, len));
t = RSTRING(bitstr)->ptr; t = RSTRING(bitstr)->ptr;
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 7) bits <<= 1; if (i & 7) bits <<= 1;
@ -617,13 +727,13 @@ pack_unpack(str, fmt)
case 'h': case 'h':
{ {
VALUE bitstr; VALUE bitstr;
UCHAR *t; char *t;
int bits, i; int bits, i;
if (p[-1] == '*' || len > (send - s) * 2) if (p[-1] == '*' || len > (send - s) * 2)
len = (send - s) * 2; len = (send - s) * 2;
bits = 0; bits = 0;
ary_push(ary, bitstr = str_new(0, len)); rb_ary_push(ary, bitstr = rb_str_new(0, len));
t = RSTRING(bitstr)->ptr; t = RSTRING(bitstr)->ptr;
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 1) if (i & 1)
@ -638,13 +748,13 @@ pack_unpack(str, fmt)
case 'H': case 'H':
{ {
VALUE bitstr; VALUE bitstr;
UCHAR *t; char *t;
int bits, i; int bits, i;
if (p[-1] == '*' || len > (send - s) * 2) if (p[-1] == '*' || len > (send - s) * 2)
len = (send - s) * 2; len = (send - s) * 2;
bits = 0; bits = 0;
ary_push(ary, bitstr = str_new(0, len)); rb_ary_push(ary, bitstr = rb_str_new(0, len));
t = RSTRING(bitstr)->ptr; t = RSTRING(bitstr)->ptr;
for (i=0; i<len; i++) { for (i=0; i<len; i++) {
if (i & 1) if (i & 1)
@ -662,7 +772,7 @@ pack_unpack(str, fmt)
while (len-- > 0) { while (len-- > 0) {
int c = *s++; int c = *s++;
if (c > (char)127) c-=256; if (c > (char)127) c-=256;
ary_push(ary, INT2FIX(c)); rb_ary_push(ary, INT2FIX(c));
} }
break; break;
@ -670,8 +780,8 @@ pack_unpack(str, fmt)
if (len > send - s) if (len > send - s)
len = send - s; len = send - s;
while (len-- > 0) { while (len-- > 0) {
UCHAR c = *s++; unsigned char c = *s++;
ary_push(ary, INT2FIX(c)); rb_ary_push(ary, INT2FIX(c));
} }
break; break;
@ -682,7 +792,7 @@ pack_unpack(str, fmt)
short tmp; short tmp;
memcpy(&tmp, s, sizeof(short)); memcpy(&tmp, s, sizeof(short));
s += sizeof(short); s += sizeof(short);
ary_push(ary, INT2FIX(tmp)); rb_ary_push(ary, INT2FIX(tmp));
} }
break; break;
@ -693,7 +803,7 @@ pack_unpack(str, fmt)
unsigned short tmp; unsigned short tmp;
memcpy(&tmp, s, sizeof(short)); memcpy(&tmp, s, sizeof(short));
s += sizeof(short); s += sizeof(short);
ary_push(ary, INT2FIX(tmp)); rb_ary_push(ary, INT2FIX(tmp));
} }
break; break;
@ -704,7 +814,7 @@ pack_unpack(str, fmt)
int tmp; int tmp;
memcpy(&tmp, s, sizeof(int)); memcpy(&tmp, s, sizeof(int));
s += sizeof(int); s += sizeof(int);
ary_push(ary, int2inum(tmp)); rb_ary_push(ary, rb_int2inum(tmp));
} }
break; break;
@ -715,7 +825,7 @@ pack_unpack(str, fmt)
unsigned int tmp; unsigned int tmp;
memcpy(&tmp, s, sizeof(int)); memcpy(&tmp, s, sizeof(int));
s += sizeof(int); s += sizeof(int);
ary_push(ary, int2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
break; break;
@ -726,7 +836,7 @@ pack_unpack(str, fmt)
long tmp; long tmp;
memcpy(&tmp, s, sizeof(long)); memcpy(&tmp, s, sizeof(long));
s += sizeof(long); s += sizeof(long);
ary_push(ary, int2inum(tmp)); rb_ary_push(ary, rb_int2inum(tmp));
} }
break; break;
@ -737,7 +847,7 @@ pack_unpack(str, fmt)
unsigned long tmp; unsigned long tmp;
memcpy(&tmp, s, sizeof(long)); memcpy(&tmp, s, sizeof(long));
s += sizeof(long); s += sizeof(long);
ary_push(ary, uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
break; break;
@ -749,7 +859,7 @@ pack_unpack(str, fmt)
memcpy(&tmp, s, sizeof(short)); memcpy(&tmp, s, sizeof(short));
s += sizeof(short); s += sizeof(short);
tmp = ntohs(tmp); tmp = ntohs(tmp);
ary_push(ary, uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
break; break;
@ -761,7 +871,7 @@ pack_unpack(str, fmt)
memcpy(&tmp, s, sizeof(long)); memcpy(&tmp, s, sizeof(long));
s += sizeof(long); s += sizeof(long);
tmp = ntohl(tmp); tmp = ntohl(tmp);
ary_push(ary, uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
break; break;
@ -773,7 +883,7 @@ pack_unpack(str, fmt)
memcpy(&tmp, s, sizeof(short)); memcpy(&tmp, s, sizeof(short));
s += sizeof(short); s += sizeof(short);
tmp = vtohs(tmp); tmp = vtohs(tmp);
ary_push(ary, uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
break; break;
@ -785,7 +895,7 @@ pack_unpack(str, fmt)
memcpy(&tmp, s, sizeof(long)); memcpy(&tmp, s, sizeof(long));
s += sizeof(long); s += sizeof(long);
tmp = vtohl(tmp); tmp = vtohl(tmp);
ary_push(ary, uint2inum(tmp)); rb_ary_push(ary, rb_uint2inum(tmp));
} }
break; break;
@ -797,7 +907,7 @@ pack_unpack(str, fmt)
float tmp; float tmp;
memcpy(&tmp, s, sizeof(float)); memcpy(&tmp, s, sizeof(float));
s += sizeof(float); s += sizeof(float);
ary_push(ary, float_new((double)tmp)); rb_ary_push(ary, rb_float_new((double)tmp));
} }
break; break;
@ -809,14 +919,14 @@ pack_unpack(str, fmt)
double tmp; double tmp;
memcpy(&tmp, s, sizeof(double)); memcpy(&tmp, s, sizeof(double));
s += sizeof(double); s += sizeof(double);
ary_push(ary, float_new(tmp)); rb_ary_push(ary, rb_float_new(tmp));
} }
break; break;
case 'u': case 'u':
{ {
VALUE str = str_new(0, (send - s)*3/4); VALUE str = rb_str_new(0, (send - s)*3/4);
UCHAR *ptr = RSTRING(str)->ptr; char *ptr = RSTRING(str)->ptr;
int total = 0; int total = 0;
while (s < send && *s > ' ' && *s < 'a') { while (s < send && *s > ' ' && *s < 'a') {
@ -863,15 +973,14 @@ pack_unpack(str, fmt)
s += 2; /* possible checksum byte */ s += 2; /* possible checksum byte */
} }
RSTRING(str)->len = total; RSTRING(str)->len = total;
ary_push(ary, str); rb_ary_push(ary, str);
} }
break; break;
case 'm': case 'm':
{ {
VALUE str = str_new(0, (send - s)*3/4); VALUE str = rb_str_new(0, (send - s)*3/4);
UCHAR *ptr = RSTRING(str)->ptr; char *ptr = RSTRING(str)->ptr;
int total = 0;
int a,b,c,d; int a,b,c,d;
static int first = 1; static int first = 1;
static int b64_xtable[256]; static int b64_xtable[256];
@ -906,7 +1015,33 @@ pack_unpack(str, fmt)
*ptr++ = b << 4 | c >> 2; *ptr++ = b << 4 | c >> 2;
} }
RSTRING(str)->len = ptr - RSTRING(str)->ptr; RSTRING(str)->len = ptr - RSTRING(str)->ptr;
ary_push(ary, str); rb_ary_push(ary, str);
}
break;
case 'M':
{
VALUE str = rb_str_new(0, send - s);
char *ptr = RSTRING(str)->ptr;
int c1, c2;
while (s < send) {
if (*s == '=') {
if (++s == send) break;
if (*s != '\n') {
if ((c1 = hex2num(*s)) == -1) break;
if (++s == send) break;
if ((c2 = hex2num(*s)) == -1) break;
*ptr++ = c1 << 4 | c2;
}
}
else {
*ptr++ = *s;
}
s++;
}
RSTRING(str)->len = ptr - RSTRING(str)->ptr;
rb_ary_push(ary, str);
} }
break; break;
@ -916,16 +1051,46 @@ pack_unpack(str, fmt)
case 'X': case 'X':
if (len > s - RSTRING(str)->ptr) if (len > s - RSTRING(str)->ptr)
ArgError("X outside of string"); rb_raise(rb_eArgError, "X outside of string");
s -= len; s -= len;
break; break;
case 'x': case 'x':
if (len > send - s) if (len > send - s)
ArgError("x outside of string"); rb_raise(rb_eArgError, "x outside of string");
s += len; s += len;
break; break;
case 'P':
if (sizeof(char *) <= send - s) {
char *t;
VALUE str = rb_str_new(0, 0);
memcpy(&t, s, sizeof(char *));
s += sizeof(char *);
if (t)
rb_str_cat(str, t, len);
rb_ary_push(ary, str);
}
break;
case 'p':
if (len > (send - s) / sizeof(char *))
len = (send - s) / sizeof(char *);
while (len-- > 0) {
if (send - s < sizeof(char *))
break;
else {
char *t;
VALUE str = rb_str_new(0, 0);
memcpy(&t, s, sizeof(char *));
s += sizeof(char *);
if (t)
rb_str_cat(str, t, strlen(t));
rb_ary_push(ary, str);
}
}
break;
default: default:
break; break;
} }
@ -937,6 +1102,6 @@ pack_unpack(str, fmt)
void void
Init_pack() Init_pack()
{ {
rb_define_method(cArray, "pack", pack_pack, 1); rb_define_method(rb_cArray, "pack", pack_pack, 1);
rb_define_method(cString, "unpack", pack_unpack, 1); rb_define_method(rb_cString, "unpack", pack_unpack, 1);
} }

Some files were not shown because too many files have changed in this diff Show more