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

ruby 1.3 cycle

git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/RUBY@372 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
This commit is contained in:
matz 1999-01-20 04:59:39 +00:00
parent aeb049c573
commit 62e648e148
198 changed files with 36551 additions and 13171 deletions

332
COPYING
View file

@ -1,37 +1,40 @@
GNU GENERAL PUBLIC LICENSE
Version 1, February 1989
Version 2, June 1991
Copyright (C) 1989 Free Software Foundation, Inc.
675 Mass Ave, Cambridge, MA 02139, USA
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The license agreements of most software companies try to keep users
at the mercy of those companies. By contrast, our General Public
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
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
General Public License applies to the Free Software Foundation's
software and to any other program whose authors commit to using it.
You can use it for your programs, too.
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
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
price. Specifically, the General Public License is designed to make
sure that you have the freedom to give away or sell copies of free
software, that you receive source code or can get it if you want it,
that you can change the software or use pieces of it in new free
programs; and that you know you can do these things.
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
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.
These restrictions translate to certain responsibilities for you if you
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
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
(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
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
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License Agreement applies to any program or other work which
contains a notice placed by the copyright holder saying it may be
distributed under the terms of this General Public License. The
"Program", below, refers to any such program or work, and a "work based
on the Program" means either the Program or any work containing the
Program or a portion of it, either verbatim or with modifications. Each
licensee is addressed as "you".
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
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
code as you receive it, in any medium, provided that you conspicuously and
appropriately publish on each copy an appropriate copyright notice and
disclaimer of warranty; keep intact all the notices that refer to this
General Public License and to the absence of any warranty; and give any
other recipients of the Program a copy of this General Public License
along with the Program. You may charge a fee for the physical act of
transferring a copy.
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
2. You may modify your copy or copies of the Program or any portion of
it, and copy and distribute such modifications under the terms of Paragraph
1 above, provided that you also do the following:
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
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 changed the files and the date of any change; and
You may charge a fee for the physical act of transferring a copy, 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
in whole or in part contains the Program or any part thereof, either
with or without modifications, to be licensed at no charge to all
third parties under the terms of this General Public License (except
that you may choose to grant warranty protection to some or all
third parties, at your option).
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
c) If the modified program normally reads commands interactively when
run, you must cause it, when started running for such interactive use
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.
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
d) You may charge a fee for the physical act of transferring a
copy, and you may at your option offer warranty protection in
exchange for a fee.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
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
derivative) on a volume of a storage or distribution medium does not bring
the other work under the scope of these terms.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
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
it, under Paragraph 2) in object code or executable form under the terms of
Paragraphs 1 and 2 above provided that you also do one of the following:
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
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
source code, which must be distributed under the terms of
Paragraphs 1 and 2 above; or,
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
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
years, to give any third party free (except for a nominal charge
for the cost of distribution) a complete machine-readable copy of the
corresponding source code, to be distributed under the terms of
Paragraphs 1 and 2 above; or,
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
c) accompany it with the information you received as to where the
corresponding source code may be obtained. (This alternative is
3. You may copy and distribute the Program (or a work based on it,
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
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
modifications to it. For an executable file, complete source code means
all the source code for all modules it contains; but, as a special
exception, it need not include source code for modules which are standard
libraries that accompany the operating system on which the executable
file runs, or for standard header files or definitions files that
accompany that operating system.
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
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
Program except as expressly provided under this General Public License.
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
the Program is void, and will automatically terminate your rights to use
the Program under this License. However, parties who have received
copies, or rights to use copies, from you under this General Public
License will not have their licenses terminated so long as such parties
remain in full compliance.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
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
on the Program) you indicate your acceptance of this license to do so,
and all its terms and conditions.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
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
Program), the recipient automatically receives a license from the original
licensor to copy, distribute or modify the Program subject to these
terms and conditions. You may not impose any further restrictions on the
recipients' exercise of the rights granted herein.
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
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
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
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
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
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.
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
to ask for permission. For software which is copyrighted by the Free
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
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
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
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,
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
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
@ -189,25 +279,24 @@ POSSIBILITY OF SUCH DAMAGES.
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
possible use to humanity, the best way to achieve this is to make it
free software which everyone can redistribute and change under these
terms.
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 terms.
To do so, attach the following notices to the program. It is safest to
attach them to the start of each source file to most effectively convey
the exclusion of warranty; and each file should have at least the
"copyright" line and a pointer to where the full notice is found.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
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.>
Copyright (C) 19yy <name of author>
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version.
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
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
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.
If the program is interactive, make it output a short notice like this
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'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the
appropriate parts of the General Public License. Of course, the
commands you use may be called something other than `show w' and `show
c'; they could even be mouse-clicks or menu items--whatever suits your
program.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
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
necessary. Here a sample; alter the names:
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the
program `Gnomovision' (a program to direct compilers to make passes
at assemblers) written by James Hacker.
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
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.jp
README.EXT
README.EXT.jp
ToDo
array.c
bignum.c
@ -13,7 +14,8 @@ compar.c
configure
configure.bat
configure.in
config.dj
config_h.dj
config_s.dj
config.guess
config.sub
defines.h
@ -36,7 +38,6 @@ install-sh
instruby.rb
intern.h
io.c
io.h
keywords
lex.c
main.c
@ -47,6 +48,7 @@ node.h
numeric.c
object.c
pack.c
parse.c
parse.y
process.c
random.c
@ -58,8 +60,9 @@ regex.h
ruby.1
ruby.c
ruby.h
rubyio.h
rubysig.h
rubytest.rb
sig.h
signal.c
sprintf.c
st.c
@ -73,74 +76,89 @@ util.c
variable.c
version.c
version.h
beos/ruby.def.in
ext/Setup
ext/Setup.dj
ext/Setup.nt
ext/Setup.x68
ext/aix_ld.rb
ext/cygwin32_ld.rb
ext/extmk.rb.in
ext/extmk.rb.nt
ext/aix_ld.rb
lib/English.rb
lib/Env.rb
lib/README
lib/base64.rb
lib/cgi-lib.rb
lib/complex.rb
lib/date.rb
lib/date2.rb
lib/debug.rb
lib/delegate.rb
lib/e2mmap.rb
lib/eregex.rb
lib/find.rb
lib/final.rb
lib/finalize.rb
lib/ftplib.rb
lib/ftools.rb
lib/getopts.rb
lib/getoptlong.rb
lib/importenv.rb
lib/jcode.rb
lib/mailread.rb
lib/mathn.rb
lib/matrix.rb
lib/mkmf.rb
lib/monitor.rb
lib/mutex_m.rb
lib/observer.rb
lib/open3.rb
lib/ostruct.rb
lib/parsearg.rb
lib/parsedate.rb
lib/ping.rb
lib/profile.rb
lib/pstore.rb
lib/rational.rb
lib/readbytes.rb
lib/shellwords.rb
lib/singleton.rb
lib/sync.rb
lib/telnet.rb
lib/tempfile.rb
lib/thread.rb
lib/thwait.rb
lib/tk.rb
lib/tkcanvas.rb
lib/tkclass.rb
lib/tkdialog.rb
lib/tkentry.rb
lib/tkscrollbox.rb
lib/tktext.rb
lib/timeout.rb
lib/tracer.rb
lib/weakref.rb
misc/README
misc/inf-ruby.el
misc/ruby-mode.el
misc/rubydb2x.el
misc/rubydb3x.el
missing/alloca.c
missing/crypt.c
missing/dir.h
missing/dup2.c
missing/file.h
missing/flock.c
missing/memcmp.c
missing/memmove.c
missing/mkdir.c
missing/nt.c
missing/nt.h
missing/setenv.c
missing/strcasecmp.c
missing/strchr.c
missing/strdup.c
missing/strerror.c
missing/strftime.c
missing/strstr.c
missing/strtol.c
missing/strtoul.c
missing/vsnprintf.c
missing/x68.c
sample/README
sample/biorhythm.rb
sample/cal.rb
sample/cbreak.rb
sample/clnt.rb
sample/dbmtest.rb
@ -151,44 +169,38 @@ sample/exyacc.rb
sample/fact.rb
sample/fib.awk
sample/fib.pl
sample/fib.py
sample/fib.rb
sample/fib.scm
sample/freq.rb
sample/from.rb
sample/fullpath.rb
sample/getopts.test
sample/goodfriday.rb
sample/less.rb
sample/list.rb
sample/list2.rb
sample/list3.rb
sample/mrshtest.rb
sample/mine.rb
sample/mkproto.rb
sample/mpart.rb
sample/mrshtest.rb
sample/observ.rb
sample/occur.pl
sample/occur.rb
sample/occur2.rb
sample/philos.rb
sample/pi.rb
sample/rename.rb
sample/rbc.rb
sample/rcs.awk
sample/rcs.dat
sample/rcs.rb
sample/regx.rb
sample/ruby-mode.el
sample/rubydb2x.el
sample/rubydb3x.el
sample/sieve.rb
sample/svr.rb
sample/test.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/tsvr.rb
sample/uumerge.rb
@ -198,6 +210,8 @@ win32/ntsetup.bat
win32/ruby.def
win32/sdbm.c
win32/sdbm.h
win32/win32.c
win32/win32.h
x68/fconvert.c
x68/select.c
x68/_dtos18.c

View file

@ -8,19 +8,26 @@ VPATH = @srcdir@:@srcdir@/missing
CC = @CC@
YACC = @YACC@
PURIFY =
AUTOCONF = autoconf
@SET_MAKE@
CFLAGS = @CFLAGS@ -I@srcdir@
prefix = @prefix@
CFLAGS = @CFLAGS@ -I. -I@srcdir@ -I@includedir@
LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@
EXTLIBS =
LIBS = @LIBS@ $(EXTLIBS)
MISSING = @LIBOBJS@ @ALLOCA@
LDSHARED = @LDSHARED@
DLDFLAGS = @DLDFLAGS@
SOLIBS = @SOLIBS@
binsuffix = @binsuffix@
#### End of system configuration section. ####
LIBRUBY = libruby.a
LIBRUBY = @LIBRUBY@
LIBRUBYARG = @LIBRUBYARG@
EXTOBJS =
@ -42,8 +49,8 @@ OBJS = array.o \
hash.o \
inits.o \
io.o \
math.o \
marshal.o \
math.o \
numeric.o \
object.o \
pack.o \
@ -66,44 +73,58 @@ OBJS = array.o \
$(MISSING)
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 $@
$(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)
@rm -f $@
$(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBY) $(LIBS) -o ruby
$(PURIFY) $(CC) $(LDFLAGS) $(MAINOBJ) $(EXTOBJS) $(LIBRUBYARG) $(LIBS) -o $@
$(LIBRUBY): $(OBJS) dmyext.o
@AR@ rcu $(LIBRUBY) $(OBJS) dmyext.o
@-@RANLIB@ $(LIBRUBY) 2> /dev/null || true
libruby.a: $(OBJS) dmyext.o
@AR@ rcu $@ $(OBJS) dmyext.o
@-@RANLIB@ $@ 2> /dev/null || true
libruby.so: $(OBJS) dmyext.o
$(LDSHARED) $(DLDFLAGS) $(SOLIBS) $(OBJS) dmyext.o -o $@
install: rbconfig.rb
./miniruby$(binsuffix) $(srcdir)/instruby.rb
./miniruby$(binsuffix) $(srcdir)/instruby.rb $(DESTDIR)
clean:; @rm -f $(OBJS) $(LIBRUBY) $(MAINOBJ) rbconfig.rb
@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
@rm -f Makefile ext/extmk.rb ext/config.cache
@rm -f config.cache config.h config.log config.status
@rm -f parse.c lex.c *~ core *.core gmon.out
distclean: clean
@rm -f Makefile ext/extmk.rb config.h
@rm -f ext/config.cache config.cache config.log config.status
@rm -f parse.c *~ core *.core gmon.out y.tab.c y.output
@rm -f ruby$(binsuffix) miniruby$(binsuffix)
realclean: distclean
@rm -f lex.c
test: miniruby$(binsuffix)
@./miniruby$(binsuffix) $(srcdir)/rubytest.rb
rbconfig.rb: config.status miniruby$(binsuffix)
@./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:
$(CC) $(CFLAGS) $(CPPFLAGS) -c $<
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
$(YACC) $<
@ -121,24 +142,30 @@ dup2.o: @srcdir@/missing/dup2.c
flock.o: @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
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/memmove.c
mkdir.o: @srcdir@/missing/mkdir.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/mkdir.c
setenv.o: @srcdir@/missing/setenv.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/setenv.c
vsnprintf.o: @srcdir@/missing/vsnprintf.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/vsnprintf.c
strcasecmp.o: @srcdir@/missing/strcasecmp.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strcasecmp.c
strerror.o: @srcdir@/missing/strerror.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strerror.c
strchr.o: @srcdir@/missing/strchr.c
$(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/strchr.c
strdup.o: @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
$(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.
.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
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
compar.o: compar.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
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
eval.o: eval.c ruby.h config.h defines.h intern.h env.h node.h sig.h st.h dln.h
file.o: file.c ruby.h config.h defines.h intern.h io.h sig.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
hash.o: hash.c ruby.h config.h defines.h intern.h st.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 rubyio.h rubysig.h
fnmatch.o: fnmatch.c config.h fnmatch.h
gc.o: gc.c ruby.h config.h defines.h intern.h rubysig.h st.h node.h env.h re.h regex.h
glob.o: config.h glob.c fnmatch.h
hash.o: hash.c ruby.h config.h defines.h intern.h st.h rubysig.h
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
main.o: main.c
marshal.o: marshal.c ruby.h config.h defines.h intern.h io.h sig.h st.h
io.o: io.c ruby.h config.h defines.h intern.h rubyio.h rubysig.h
main.o: main.c ruby.h config.h defines.h intern.h
marshal.o: marshal.c ruby.h config.h defines.h intern.h rubyio.h st.h
math.o: math.c ruby.h config.h defines.h intern.h
numeric.o: numeric.c ruby.h config.h defines.h intern.h
object.o: object.c ruby.h config.h defines.h intern.h st.h
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
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
ruby.o: ruby.c ruby.h config.h defines.h intern.h re.h regex.h dln.h
signal.o: signal.c ruby.h config.h defines.h intern.h sig.h
regex.o: regex.c config.h regex.h util.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
st.o: st.c config.h st.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
time.o: time.c ruby.h config.h defines.h intern.h
util.o: util.c defines.h intern.h config.h util.h
variable.o: variable.c ruby.h config.h defines.h intern.h env.h st.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 node.h st.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
easy object-oriented programming. It has many features to
process text files and to do system management tasks (as in
perl). It is simple, straight-forward, and extensible.
Perl). It is simple, straight-forward, and extensible.
* Features of Ruby
@ -15,7 +15,8 @@ perl). It is simple, straight-forward, and extensible.
+ Iterators and Closures
+ Garbage Collection
+ 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
@ -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.
3. Remove comment mark(#) before the module names from ext/Setup, if
you want to link modules statically.
3. Remove comment mark(#) before the module names from ext/Setup (or
add module names if not present), if you want to link modules
statically.
If you want to link all the extension modules, remove comment
mark from the line "#option nodynamic".
If you don't want to compile non static extension modules
(probably on architectures which does not allow dynamic loading),
remove comment mark from the line "#option nodynamic" in
ext/Setup.
4. Run make.
5. Optionally, run 'make test' to check that the compiled Ruby
interpreter works well. If you see the message "test succeeded",
your Ruby works as it should (hopefully).
5. Optionally, run 'make test' to check whether the compiled Ruby
interpreter works well. If you see the message "test succeeded",
your ruby works as it should (hopefully).
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.
* 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
you do at least ONE of the following:
a) place your modifications in the Public Domain or otherwise make them
Freely Available, such as by posting said modifications to Usenet
or an equivalent medium, or by allowing the author to include your
modifications in the software.
a) place your modifications in the Public Domain or otherwise
make them Freely Available, such as by posting said
modifications to Usenet or an equivalent medium, or by allowing
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
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.
c) give non-standard executables non-standard names, with
instructions on where to get the original software
distribution.
instructions on where to get the original software distribution.
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.
They are gc.c(partly), utils.c(partly), regex.[ch], fnmatch.[ch],
glob.c, st.[ch] and some files under the ./missing directory. See
each files for the copying condition.
each file for the copying condition.
5. The scripts and library files supplied as input to or produced as
output from the software do not automatically fall under the

View file

@ -1,21 +1,16 @@
.\" 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
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.
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.
rubyのデータはVALUEというCの型で表現されますVALUE型のデー
タはそのデータタイプを自分で知っています.このデータタイプと
いうのはデータ(オブジェクト)の実際の構造を意味していてruby
のクラスとはまた違ったものです.
To retrieve an C data from the VALUE, you need to:
(1) Identify VALUE's data type
@ -38,7 +33,7 @@ Ruby interpreter has data-types as below:
T_ARRAY array
T_FIXNUM Fixnum(31bit integer)
T_HASH assosiative array
T_STRUCT (ruby) structure
T_STRUCT (Ruby) structure
T_BIGNUM multi precision integer
T_TRUE true
T_FALSE false
@ -89,37 +84,28 @@ There are faster check-macros for fixnums and nil.
1.3 Convert VALUE into C data
データタイプがT_NIL, T_FALSE, T_TRUEである時データはそれぞ
れnil, FALSE, TRUEですこのデータタイプのオブジェクトはひと
つずつしか存在しません.
The data for type T_NIL, T_FALSE, T_TRUE are nil, true, false
respectively. They are singletons for the data type.
データタイプがT_FIXNUMの時これは31bitのサイズを持つ整数で
FIXNUMをCの整数に変換するためにはマクロ「FIX2INT()」を使
いますそれからFIXNUMに限らずrubyのデータを整数に変換する
「NUM2INT()」というマクロがあります.このマクロはデータタイ
プのチェック無しで使えます(整数に変換できない場合には例外が
発生する)
The T_FIXNUM data is the 31bit length fixed integer (63bit length on
some machines), which can be conver to the C integer by using
FIX2INT() macro. There also be NUM2INT() which converts any Ruby
numbers into C integer. The NUM2INT() macro includes type check, so
the exception will be raised if conversion failed.
それ以外のデータタイプは対応するCの構造体があります対応す
る構造体のあるVALUEはそのままキャスト(型変換)すれば構造体の
ポインタに変換できます.
Other data types have corresponding C structures, e.g. struct RArray
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で定義されていま
例えば文字列は「struct RString」です実際に使う可能性が
あるのは文字列と配列くらいだと思います.
For example, `RSTRING(size)->len' is the way to get the size of the
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()」(全部大文
字にしたもの)という名前で提供されています(例: RSTRING())
例えば文字列strの長さを得るためには「RSTRING(str)->len」と
文字列strをchar*として得るためには「RSTRING(str)->ptr」
とします配列の場合にはそれぞれ「RARRAT(str)->len」
「RARRAT(str)->ptr」となります
rubyの構造体を直接アクセスする時に気をつけなければならないこ
とは,配列や文字列の構造体の中身は参照するだけで,直接変更し
ないことです.直接変更した場合,オブジェクトの内容の整合性が
とれなくなって,思わぬバグの原因になります.
Notice: Do not change the value of the structure directly, unless you
are responsible about the result. It will be the cause of interesting
bugs.
1.4 Convert C data into VALUE
@ -137,10 +123,10 @@ VALUE
うかわかるわけです(ポインタのLSBが立っていないことを仮定して
いる)
ですからFIXNUM以外のrubyのオブジェクトの構造体は単にVALUE
ですからFIXNUM以外のRubyのオブジェクトの構造体は単にVALUE
にキャストするだけでVALUEに変換出来ますただし任意の構造
体がVALUEにキャスト出来るわけではありませんキャストするの
rubyの知っている構造体(ruby.hで定義されているstruct RXxxx
Rubyの知っている構造体(ruby.hで定義されているstruct RXxxx
のもの)だけにしておいてください.
FIXNUMに関しては変換マクロを経由する必要がありますCの整数
@ -153,256 +139,241 @@ FIXNUM
INT2NUM()は整数がFIXNUMの範囲に収まらない場合Bignumに変換
してくれます(が,少し遅い)
1.5 Manipulate ruby data
1.5 Manipulate Ruby data
先程も述べた通りrubyの構造体をアクセスする時に内容の更新を
行うことは勧められませんrubyのデータを操作する時には
rubyが用意している関数を用いてください
ここではもっとも使われるであろう文字列と配列の生成/操作を行
い関数をあげます(全部ではないです)
As I already told, it is not recommended to modify object's internal
structure. To manipulate objects, use functions supplied by Ruby
interpreter. Useful functions are listed below (not all):
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
str_new(ptr, strlen(ptr)).
Creates a new Ruby string from C string. This is equivalent to
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
ary_new()
rb_ary_new()
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
for len elements.
ary_new3(int n, ...)
rb_ary_new3(int n, ...)
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.
ary_push(VALUE ary)
ary_pop(VALUE ary, VALUE val)
ary_shift(VALUE ary)
ary_unshift(VALUE ary, VALUE val)
ary_entry(VALUE ary, int idx)
rb_ary_push(VALUE ary, VALUE val)
rb_ary_pop(VALUE ary)
rb_ary_shift(VALUE ary)
rb_ary_unshift(VALUE ary, VALUE val)
rb_ary_entry(VALUE ary, int idx)
Array operations. The first argument to each functions must be an
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
クラスやモジュールを定義するためには,以下の関数を使います.
To define class or module, use functions below:
VALUE rb_define_class(char *name, VALUE super)
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
メソッドや特異メソッドを定義するには以下の関数を使います.
To define methods or singleton methods, use functions below:
void rb_define_method(VALUE class, char *name,
VALUE (*func)(), int argc)
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. :-)
念のため説明すると「特異メソッド」とは,その特定のオブジェク
トに対してだけ有効なメソッドですrubyではよくSmalltalkにお
けるクラスメソッドとして,クラスに対する特異メソッドが使われ
ます.
If `argc' is negative, it specifies calling sequence, not number of
the arguments.
これらの関数の argcという引数はCの関数へ渡される引数の数(と
形式)を決めますargcが正の時は関数に引き渡す引数の数を意味
します16個以上の引数は使えません(が,要りませんよね,そん
なに)
If argc is -1, the function will be called like:
argcが負の時は引数の数ではなく形式を指定したことになります
argcが-1の時は引数を配列に入れて渡されますargcが-2の時は引
数はrubyの配列として渡されます
VALUE func(int argc, VALUE *argv, VALUE obj)
メソッドを定義する関数はもう二つありますひとつはprivateメ
ソッドを定義する関数で引数はrb_define_method()と同じです.
where argc is the actual number of arguments, argv is the C array of
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,
VALUE (*func)(), int argc)
privateメソッドとは関数形式でしか呼び出すことの出来ないメソッ
ドです.
もうひとつはモジュール関数を定義するものです.モジュール関数
とはモジュールの特異メソッドであり同時にprivateメソッドで
もあるものです例をあげるとMathモジュールのsqrt()などがあげ
られます.このメソッドは
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:
Math.sqrt(4)
という形式でも
or
include Math
sqrt(4)
という形式でも使えます.モジュール関数を定義する関数は以下の
通りです.
To define module function
void rb_define_module_function(VALUE module, char *name,
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)
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_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のデータを操作する』で一部紹介したような関数を
使えばrubyの機能を実現している関数を直接呼び出すことが出来
ます.
There are several ways to invoke Ruby's features from C code.
# このような関数の一覧表はいまのところありません.ソースを見
# るしかないですね.
2.2.1 Evaluate Ruby Program in String
それ以外にもrubyの機能を呼び出す方法はいくつかあります
2.2.1 rubyのプログラムをevalする
Cからrubyの機能を呼び出すもっとも簡単な方法として文字列で
与えられた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.
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
Cから文字列を経由せずにrubyのメソッドを呼び出すこともできま
その前にrubyインタプリタ内でメソッドや変数名を指定する
時に使われているIDについて説明しておきましょう
You can invoke methods directly, without parsing the string. First I
need to explain about symbols (which data type is ID). ID is the
integer number to represent Ruby's identifiers such as variable names.
It can be accessed from Ruby in the form like:
IDとは変数名メソッド名を表す整数ですrubyの中では
:Identifier
:識別子
でアクセスできますCからこの整数を得るためには関数
You can get the symbol value from string within C code, by using
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, ...)
この関数はオブジェクト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の大域変数としてアクセ
スできます.ローカル変数を参照する方法は公開していません.
オブジェクトのインスタンス変数を参照・更新する関数は以下の通
りです.
The functions to access/modify instance variables are below:
VALUE rb_ivar_get(VALUE obj, ID id)
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)
クラス定数を新しく定義するためには『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
FALSE
Qtrue
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
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()です.
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)
@ -421,13 +392,13 @@ setter
# getterもsetterも0ならばrb_define_variable()と同じになる.
それからCの関数によって実現されるrubyの大域変数を定義する
それからCの関数によって実現されるRubyの大域変数を定義する
関数があります.
void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)())
この関数によって定義されたrubyの大域変数が参照された時には
この関数によって定義されたRubyの大域変数が参照された時には
getterが変数に値がセットされた時にはsetterが呼ばれます
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);
(*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という
rubyオブジェクトにCの構造体(へのポインタ)をくるむことでruby
RubyオブジェクトにCの構造体(へのポインタ)をくるむことでRuby
オブジェクトとして取り扱えるようになります.
Dataオブジェクトを生成して構造体をrubyオブジェクトにカプセル
Dataオブジェクトを生成して構造体をRubyオブジェクトにカプセル
化するためには,以下のマクロを使います.
Data_Wrap_Struct(class,mark,free,ptr)
@ -450,7 +421,7 @@ Data
このマクロの戻り値は生成されたDataオブジェクトです
classはこのDataオブジェクトのクラスですptrはカプセル化する
Cの構造体へのポインタですmarkはこの構造体がrubyのオブジェ
Cの構造体へのポインタですmarkはこの構造体がRubyのオブジェ
クトへの参照がある時に使う関数です.そのような参照を含まない
時には0を指定します
@ -482,47 +453,38 @@ C
4Example - Create dbm module
ここまでの説明でとりあえず拡張モジュールは作れるはずです.
rubyのextディレクトリにすでに含まれているdbmモジュールを例に
ここまでの説明でとりあえず拡張ライブラリは作れるはずです.
Rubyのextディレクトリにすでに含まれているdbmモジュールを例に
して段階的に説明します.
(1) make the directory
% mkdir ext/dbm
rubyを展開したディレクトリの下extディレクトリの中に拡張モ
ジュール用のディレクトリを作ります.名前は適当に選んで構いま
せん.
Make a directory for the extension library under ext directory.
(2) create MANIFEST file
% cd ext/dbm
% touch MANIFEST
拡張モジュールのディレクトリの下にはMANIFESTというファイルが
必要なので,とりあえず空のファイルを作っておきます.後でこの
ファイルには必要なファイル一覧が入ることになります.
MANIFESTというファイルはmakeの時にディレクトリが拡張モジュー
ルを含んでいるかどうか判定するために使われれています.
There should be MANIFEST file in the directory for the extension
library. Make empty file now.
(3) design the library
まあ,当然なんですけど,どういう機能を実現するかどうかまず設
計する必要があります.どんなクラスをつくるか,そのクラスには
どんなメソッドがあるか,クラスが提供する定数などについて設計
しますdbmクラスについてはext/dbm.docを参照してください
You need to design the library features, before making it.
(4) write C code.
拡張モジュール本体となるC言語のソースを書きますC言語のソー
拡張ライブラリ本体となるC言語のソースを書きますC言語のソー
スがひとつの時には「モジュール名.c」を選ぶと良いでしょうC
言語のソースが複数の場合には逆に「モジュール名.c」というファ
イル名は避ける必要があります.オブジェクトファイルとモジュー
ル生成時に中間的に生成される「モジュール名.o」というファイル
とが衝突するからです.
rubyは拡張モジュールをロードする時に「Init_モジュール名」と
Rubyは拡張ライブラリをロードする時に「Init_モジュール名」と
いう関数を自動的に実行しますdbmモジュールの場合「Init_dbm」
です.この関数の中でクラス,モジュール,メソッド,定数などの
定義を行いますdbm.cから一部引用します
@ -530,27 +492,25 @@ ruby
--
Init_dbm()
{
/* DBMクラスを定義する */
cDBM = rb_define_class("DBM", cObject);
/* DBMはEnumerateモジュールをインクルードする */
rb_include_module(cDBM, mEnumerable);
/* define DBM class */
cDBM = rb_define_class("DBM", rb_cObject);
/* DBM includes Enumerate module */
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);
/* DBMクラスのメソッドclose(): 引数はなし */
/* DBM instance method close(): no args */
rb_define_method(cDBM, "close", fdbm_close, 0);
/* DBMクラスのメソッド[]: 引数は1個 */
/* DBM instance method []: 1 argument */
rb_define_method(cDBM, "[]", fdbm_fetch, 1);
:
/* DBMデータを格納するインスタンス変数名のためのID */
id_dbm = rb_intern("dbm");
}
--
DBMモジュールはdbmのデータと対応するオブジェクトになるはずで
すからCの世界のdbmをrubyの世界に取り込む必要があります
すからCの世界のdbmをRubyの世界に取り込む必要があります
dbm.cではData_Make_Structを以下のように使っています
@ -600,7 +560,7 @@ fdbm_delete(obj, keystr)
引数の数が固定のタイプは第1引数がself第2引数以降がメソッド
の引数となります.
引数の数が不定のものはCの配列で受けるものとrubyの配列で受け
引数の数が不定のものはCの配列で受けるものとRubyの配列で受け
るものとがありますdbmモジュールの中でCの配列で受けるもの
はDBMのクラスメソッドであるopen()です.これを実装している関
数fdbm_s_open()はこうなっています.
@ -634,7 +594,7 @@ fdbm_s_open(argc, argv, class)
2つまで許されるという意味になります省略されている時の
変数の値は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でも同じこと
です.
** 注意事項
** Notice
rubyと共有はしないがrubyのオブジェクトを格納する可能性のある
Cの大域変数は以下の関数を使ってrubyインタプリタに変数の存在
を教えてあげてくださいでないとGCでトラブルを起こします
GC should know about global variables which refers Ruby's objects, but
not exported to the Ruby world. You need to protect them by
void rb_global_variable(VALUE *var)
@ -665,7 +624,7 @@ C
make時に実行されますなければ適当にMakefileが生成されます
extconf.rbはモジュールのコンパイルに必要な条件のチェックなど
を行うことが目的ですextconf.rbの中では以下のruby関数を使う
を行うことが目的ですextconf.rbの中では以下のRuby関数を使う
ことが出来ます.
have_library(lib, func): ライブラリの存在チェック
@ -704,31 +663,31 @@ make
(8) make
rubyのディレクトリでmakeを実行するとMakefileを生成からmake
必要によってはそのモジュールのrubyへのリンクまで自動的に実行
Rubyのディレクトリでmakeを実行するとMakefileを生成からmake
必要によってはそのモジュールのRubyへのリンクまで自動的に実行
してくれますextconf.rbを書き換えるなどしてMakefileの再生成
が必要な時はまたrubyディレクトリでmakeしてください
が必要な時はまたRubyディレクトリでmakeしてください
(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
error.c
@ -780,13 +739,13 @@ class library
Appendix B. 拡張用関数リファレンス
C言語からrubyの機能を利用するAPIは以下の通りである
C言語からRubyの機能を利用するAPIは以下の通りである
** 型
VALUE
rubyオブジェクトを表現する型必要に応じてキャストして用いる
Rubyオブジェクトを表現する型必要に応じてキャストして用いる
組み込み型を表現するCの型はruby.hに記述してあるRで始まる構造
体であるVALUE型をこれらにキャストするためにRで始まる構造体
名を全て大文字にした名前のマクロが用意されている.
@ -797,21 +756,21 @@ ruby
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データのカプセル化
Data_Wrap_Struct(VALUE class, void (*mark)(), void (*free)(), void *sval)
Cの任意のポインタをカプセル化したrubyオブジェクトを返す
のポインタがrubyからアクセスされなくなった時freeで指定した
関数が呼ばれる.また,このポインタの指すデータが他のrubyオブ
Cの任意のポインタをカプセル化したRubyオブジェクトを返す
のポインタがRubyからアクセスされなくなった時freeで指定した
関数が呼ばれる.また,このポインタの指すデータが他のRubyオブ
ジェクトを指している場合markに指定する関数でマークする必要
がある.
@ -828,20 +787,20 @@ data
VALUE rb_define_class(char *name, VALUE super)
superのサブクラスとして新しいrubyクラスを定義する
superのサブクラスとして新しいRubyクラスを定義する
VALUE rb_define_class_under(VALUE module, char *name, VALUE super)
superのサブクラスとして新しいrubyクラスを定義しmoduleの定
superのサブクラスとして新しいRubyクラスを定義しmoduleの定
数として定義する.
VALUE rb_define_module(char *name)
新しいrubyモジュールを定義する
新しいRubyモジュールを定義する
VALUE rb_define_module_under(VALUE module, char *name, VALUE super)
新しいrubyモジュールを定義しmoduleの定数として定義する
新しいRubyモジュールを定義し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)
rubyとCとで共有するグローバル変数を定義する変数名が`$'で始
まらない時には自動的に追加されるnameとしてrubyの識別子とし
て許されない文字(例えば` ')を含む場合にはrubyプログラムから
は見えなくなる.
Defines a global variable which is shared between C and Ruby. If name
contains the character which is not allowed to be part of the symbol,
it can't be seen from Ruby programs.
void rb_define_readonly_variable(char *name, VALUE *var)
rubyとCとで共有するread onlyのグローバル変数を定義するread
onlyであること以外はrb_define_variable()と同じ.
Defines a read-only global variable. Works just like
rb_define_variable(), except defined variable is read-only.
void rb_define_virtual_variable(char *name,
VALUE (*getter)(), VALUE (*setter)())
関数によって実現されるruby変数を定義する変数が参照された時
にはgetterが変数に値がセットされた時にはsetterが呼ばれる
Defines a virtual variable, whose behavior is defined by pair of C
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,
VALUE (*getter)(), VALUE (*setter)())
関数によってhookのつけられたグローバル変数を定義する変数が
参照された時にはgetterが関数に値がセットされた時にはsetter
が呼ばれるgetterやsetterに0を指定した時にはhookを指定しな
いのと同じ事になる.
Defines hooked variable. It's virtual variable with C variable. The
getter is called as
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)
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)
大域定数を定義する.
Defines global contant. This is just work as
rb_define_const(cKernal, name, val)
と同じ意味.
** メソッド定義
** Method Definition
rb_define_method(VALUE class, char *name, VALUE (*func)(), int argc)
メソッドを定義するargcはselfを除く引数の数argcが-1の時,
関数には引数の数(selfを含まない)を第1引数, 引数の配列を第2引
数とする形式で与えられる(第3引数はself)argcが-2の時, 第1引
数がself, 第2引数がargs(argsは引数を含むrubyの配列)という形
数がself, 第2引数がargs(argsは引数を含むRubyの配列)という形
式で与えられる.
rb_define_private_method(VALUE class, char *name, VALUE (*func)(), int argc)
@ -927,7 +895,7 @@ argc,argv
数に対応する引数が与えられていない場合は変数にQnilが代入され
る.
** rubyメソッド呼び出し
** Rubyメソッド呼び出し
VALUE rb_funcall(VALUE recv, ID mid, int narg, ...)
@ -939,7 +907,7 @@ argc,argv
VALUE rb_eval_string(char *str)
文字列をrubyとスクリプトしてコンパイル・実行する
文字列をRubyとスクリプトしてコンパイル・実行する
ID rb_intern(char *name)
@ -959,7 +927,7 @@ class
VALUE rb_iv_get(VALUE obj, char *name)
objのインスタンス変数の値を得る`@'で始まらないインスタンス
変数は rubyプログラムからアクセスできない「隠れた」インスタ
変数は Rubyプログラムからアクセスできない「隠れた」インスタ
ンス変数になる.
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()と同じ.
void Fatal(char *fmt, ...)
void rb_fatal(char *fmt, ...)
致命的例外を発生させる.通常の例外処理は行なわれず, インター
プリタが終了する(ただし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)
rubyインタプリタの初期化を行なう
Initializes the interpreter.
void ruby_run()
rubyインタプリタを実行する
Starts execution of the interpreter.
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の中では利用可能なコンパイル条件チェックの関数は以
下の通りである.
have_library(lib, func)
関数funcを定義しているライブラリlibの存在をチェックする
イブラリが存在する時TRUEを返す
Checks whether library which contains specified function exists.
Returns true if the library exists.
have_func(func)
関数funcの存在をチェックするfuncが標準ではリンクされないラ
イブラリ内のものである時には先にhave_libraryでそのライブラリ
をチェックしておく事関数が存在する時TRUEを返す
Checks whether func exists. Returns true if the function exists. To
check functions in the additional library, you need to check that
library first using have_library().
have_header(header)
ヘッダファイルの存在をチェックする.ヘッダファイルが存在する
時TRUEを返す
Checks for the header files. Returns true if the header file exists.
create_makefile(target)
拡張モジュール用のMakefileを生成するこの関数を呼ばなければ
そのモジュールはコンパイルされないtargetはモジュール名を表
す.
Generates the Makefile for the extension library. If you don't invoke
this method, the compilation will not be done.
/*
* Local variables:

1147
README.EXT.jp Normal file

File diff suppressed because it is too large Load diff

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

41
ToDo
View file

@ -1,4 +1,37 @@
* non-blocking open/write for thread
* パッケージまたは大域変数のアクセス制御
* format機能
* re-write regex code for speed and copyright
Language Spec.
* package or access control for global variables
* 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$
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 "node.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 VALUE cClass;
extern VALUE cModule;
VALUE
class_new(super)
rb_class_new(super)
VALUE super;
{
NEWOBJ(klass, struct RClass);
OBJSETUP(klass, cClass, T_CLASS);
OBJSETUP(klass, rb_cClass, T_CLASS);
klass->super = super;
klass->iv_tbl = 0;
klass->m_tbl = 0; /* safe GC */
klass->m_tbl = new_idhash();
klass->m_tbl = st_init_numtable();
return (VALUE)klass;
}
VALUE
singleton_class_new(super)
rb_singleton_class_new(super)
VALUE super;
{
VALUE klass = class_new(super);
VALUE klass = rb_class_new(super);
FL_SET(klass, FL_SINGLETON);
return klass;
@ -56,7 +57,7 @@ clone_method(mid, body, tbl)
}
VALUE
singleton_class_clone(klass)
rb_singleton_class_clone(klass)
VALUE klass;
{
if (!FL_TEST(klass, FL_SINGLETON))
@ -69,7 +70,7 @@ singleton_class_clone(klass)
clone->super = RCLASS(klass)->super;
clone->iv_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);
FL_SET(clone, FL_SINGLETON);
return (VALUE)clone;
@ -77,7 +78,7 @@ singleton_class_clone(klass)
}
void
singleton_class_attached(klass, obj)
rb_singleton_class_attached(klass, obj)
VALUE klass, obj;
{
if (FL_TEST(klass, FL_SINGLETON))
@ -91,15 +92,15 @@ rb_define_class_id(id, super)
{
VALUE klass;
if (!super) super = cObject;
klass = class_new(super);
if (!super) super = rb_cObject;
klass = rb_class_new(super);
rb_name_class(klass, id);
/* make metaclass */
RBASIC(klass)->class = singleton_class_new(RBASIC(super)->class);
singleton_class_attached(RBASIC(klass)->class, klass);
RBASIC(klass)->klass = rb_singleton_class_new(RBASIC(super)->klass);
rb_singleton_class_attached(RBASIC(klass)->klass, klass);
rb_funcall(super, rb_intern("inherited"), 1, klass);
return (VALUE)klass;
return klass;
}
VALUE
@ -112,14 +113,15 @@ rb_define_class(name, super)
id = rb_intern(name);
klass = rb_define_class_id(id, super);
st_add_direct(rb_class_tbl, id, klass);
return klass;
}
VALUE
rb_define_class_under(under, name, super)
VALUE under;
rb_define_class_under(outer, name, super)
VALUE outer;
char *name;
VALUE super;
{
@ -128,22 +130,22 @@ rb_define_class_under(under, name, super)
id = rb_intern(name);
klass = rb_define_class_id(id, super);
rb_const_set(under, id, klass);
rb_set_class_path(klass, under, name);
rb_const_set(outer, id, klass);
rb_set_class_path(klass, outer, name);
return klass;
}
VALUE
module_new()
rb_module_new()
{
NEWOBJ(mdl, struct RClass);
OBJSETUP(mdl, cModule, T_MODULE);
OBJSETUP(mdl, rb_cModule, T_MODULE);
mdl->super = 0;
mdl->iv_tbl = 0;
mdl->m_tbl = 0;
mdl->m_tbl = new_idhash();
mdl->m_tbl = st_init_numtable();
return (VALUE)mdl;
}
@ -152,9 +154,9 @@ VALUE
rb_define_module_id(id)
ID id;
{
extern st_table *rb_class_tbl;
VALUE mdl = module_new();
VALUE mdl;
mdl = rb_module_new();
rb_name_class(mdl, id);
return mdl;
@ -175,8 +177,8 @@ rb_define_module(name)
}
VALUE
rb_define_module_under(under, name)
VALUE under;
rb_define_module_under(outer, name)
VALUE outer;
char *name;
{
VALUE module;
@ -184,8 +186,8 @@ rb_define_module_under(under, name)
id = rb_intern(name);
module = rb_define_module_id(id);
rb_const_set(under, id, module);
rb_set_class_path(module, under, name);
rb_const_set(outer, id, module);
rb_set_class_path(module, outer, name);
return module;
}
@ -195,16 +197,16 @@ include_class_new(module, super)
VALUE module, super;
{
NEWOBJ(klass, struct RClass);
OBJSETUP(klass, cClass, T_ICLASS);
OBJSETUP(klass, rb_cClass, T_ICLASS);
klass->m_tbl = RCLASS(module)->m_tbl;
klass->iv_tbl = RCLASS(module)->iv_tbl;
klass->super = super;
if (TYPE(module) == T_ICLASS) {
RBASIC(klass)->class = RBASIC(module)->class;
RBASIC(klass)->klass = RBASIC(module)->klass;
}
else {
RBASIC(klass)->class = module;
RBASIC(klass)->klass = module;
}
return (VALUE)klass;
@ -217,61 +219,66 @@ rb_include_module(klass, module)
VALUE p;
if (NIL_P(module)) return;
if (klass == module) return;
switch (TYPE(module)) {
case T_MODULE:
case T_CLASS:
case T_ICLASS:
break;
default:
Check_Type(module, T_MODULE);
}
if (klass == module) return;
rb_clear_cache();
while (module) {
/* ignore if the module included already in superclasses */
for (p = RCLASS(klass)->super; p; p = RCLASS(p)->super) {
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;
}
}
RCLASS(klass)->super =
include_class_new(module, RCLASS(klass)->super);
klass = RCLASS(klass)->super;
module = RCLASS(module)->super;
}
rb_clear_cache();
}
VALUE
mod_included_modules(mod)
rb_mod_included_modules(mod)
VALUE mod;
{
VALUE ary = ary_new();
VALUE ary = rb_ary_new();
VALUE p;
for (p = RCLASS(mod)->super; p; p = RCLASS(p)->super) {
if (BUILTIN_TYPE(p) == T_ICLASS) {
ary_push(ary, RBASIC(p)->class);
rb_ary_push(ary, RBASIC(p)->klass);
}
}
return ary;
}
VALUE
mod_ancestors(mod)
rb_mod_ancestors(mod)
VALUE mod;
{
VALUE ary = ary_new();
VALUE ary = rb_ary_new();
VALUE p;
for (p = mod; p; p = RCLASS(p)->super) {
if (FL_TEST(p, FL_SINGLETON))
continue;
if (BUILTIN_TYPE(p) == T_ICLASS) {
ary_push(ary, RBASIC(p)->class);
rb_ary_push(ary, RBASIC(p)->klass);
}
else {
ary_push(ary, p);
rb_ary_push(ary, p);
}
}
return ary;
@ -283,19 +290,43 @@ ins_methods_i(key, body, ary)
NODE *body;
VALUE ary;
{
if (!body->nd_noex) {
VALUE name = str_new2(rb_id2name(key));
if ((body->nd_noex&(NOEX_PRIVATE|NOEX_PROTECTED)) == 0) {
VALUE name = rb_str_new2(rb_id2name(key));
if (!ary_includes(ary, name)) {
if (!rb_ary_includes(ary, name)) {
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) {
ary_push(ary, Qnil);
ary_push(ary, str_new2(rb_id2name(key)));
rb_ary_push(ary, Qnil);
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
}
return ST_CONTINUE;
}
@ -307,19 +338,19 @@ ins_methods_priv_i(key, body, ary)
VALUE ary;
{
if (!body->nd_body) {
ary_push(ary, Qnil);
ary_push(ary, str_new2(rb_id2name(key)));
rb_ary_push(ary, Qnil);
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
}
else if (body->nd_noex) {
VALUE name = str_new2(rb_id2name(key));
else if (body->nd_noex & NOEX_PRIVATE) {
VALUE name = rb_str_new2(rb_id2name(key));
if (!ary_includes(ary, name)) {
ary_push(ary, name);
if (!rb_ary_includes(ary, name)) {
rb_ary_push(ary, name);
}
}
else if (nd_type(body->nd_body) == NODE_ZSUPER) {
ary_push(ary, Qnil);
ary_push(ary, str_new2(rb_id2name(key)));
rb_ary_push(ary, Qnil);
rb_ary_push(ary, rb_str_new2(rb_id2name(key)));
}
return ST_CONTINUE;
}
@ -334,7 +365,7 @@ method_list(mod, option, func)
VALUE klass;
VALUE *p, *q, *pend;
ary = ary_new();
ary = rb_ary_new();
for (klass = mod; klass; klass = RCLASS(klass)->super) {
st_foreach(RCLASS(klass)->m_tbl, func, ary);
if (!option) break;
@ -352,7 +383,7 @@ method_list(mod, option, func)
}
VALUE
class_instance_methods(argc, argv, mod)
rb_class_instance_methods(argc, argv, mod)
int argc;
VALUE *argv;
VALUE mod;
@ -364,7 +395,19 @@ class_instance_methods(argc, argv, mod)
}
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;
VALUE *argv;
VALUE mod;
@ -376,14 +419,14 @@ class_private_instance_methods(argc, argv, mod)
}
VALUE
obj_singleton_methods(obj)
rb_obj_singleton_methods(obj)
VALUE obj;
{
VALUE ary;
VALUE klass;
VALUE *p, *q, *pend;
ary = ary_new();
ary = rb_ary_new();
klass = CLASS_OF(obj);
while (klass && FL_TEST(klass, FL_SINGLETON)) {
st_foreach(RCLASS(klass)->m_tbl, ins_methods_i, ary);
@ -409,7 +452,7 @@ rb_define_method_id(klass, name, func, argc)
VALUE (*func)();
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
@ -419,15 +462,22 @@ rb_define_method(klass, name, func, argc)
VALUE (*func)();
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
rb_undef_method(klass, name)
rb_define_protected_method(klass, name, func, argc)
VALUE klass;
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
@ -437,7 +487,16 @@ rb_define_private_method(klass, name, func, argc)
VALUE (*func)();
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
@ -445,14 +504,14 @@ rb_singleton_class(obj)
VALUE 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)) {
return (VALUE)RBASIC(obj)->class;
if (FL_TEST(RBASIC(obj)->klass, FL_SINGLETON)) {
return RBASIC(obj)->klass;
}
RBASIC(obj)->class = singleton_class_new(RBASIC(obj)->class);
singleton_class_attached(RBASIC(obj)->class, obj);
return RBASIC(obj)->class;
RBASIC(obj)->klass = rb_singleton_class_new(RBASIC(obj)->klass);
rb_singleton_class_attached(RBASIC(obj)->klass, obj);
return RBASIC(obj)->klass;
}
void
@ -476,15 +535,13 @@ rb_define_module_function(module, name, func, argc)
rb_define_singleton_method(module, name, func, argc);
}
extern VALUE mKernel;
void
rb_define_global_function(name, func, argc)
char *name;
VALUE (*func)();
int argc;
{
rb_define_private_method(mKernel, name, func, argc);
rb_define_module_function(rb_mKernel, name, func, argc);
}
void
@ -496,57 +553,50 @@ rb_define_alias(klass, name1, name2)
}
void
rb_define_attr(klass, id, read, write)
rb_define_attr(klass, name, read, write)
VALUE klass;
ID id;
char *name;
int read, write;
{
char *name;
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);
}
rb_attr(klass, rb_intern(name), read, write, Qfalse);
}
#ifdef HAVE_STDARG_PROTOTYPES
#include <stdarg.h>
#define va_init_list(a,b) va_start(a,b)
#else
#include <varargs.h>
#include <ctype.h>
#define va_init_list(a,b) va_start(a)
#endif
int
#ifdef HAVE_STDARG_PROTOTYPES
rb_scan_args(int argc, VALUE *argv, char *fmt, ...)
#else
rb_scan_args(argc, argv, fmt, va_alist)
int argc;
VALUE *argv;
char *fmt;
va_dcl
#endif
{
int n, i;
char *p = fmt;
VALUE *var;
va_list vargs;
va_start(vargs);
va_init_list(vargs, fmt);
if (*p == '*') {
var = va_arg(vargs, VALUE*);
*var = ary_new4(argc, argv);
*var = rb_ary_new4(argc, argv);
return argc;
}
if (isdigit(*p)) {
if (ISDIGIT(*p)) {
n = *p - '0';
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++) {
var = va_arg(vargs, VALUE*);
*var = argv[i];
@ -557,7 +607,7 @@ rb_scan_args(argc, argv, fmt, va_alist)
goto error;
}
if (isdigit(*p)) {
if (ISDIGIT(*p)) {
n = i + *p - '0';
for (; i<n; i++) {
var = va_arg(vargs, VALUE*);
@ -574,15 +624,15 @@ rb_scan_args(argc, argv, fmt, va_alist)
if(*p == '*') {
var = va_arg(vargs, VALUE*);
if (argc > i) {
*var = ary_new4(argc-i, argv+i);
*var = rb_ary_new4(argc-i, argv+i);
}
else {
*var = ary_new();
*var = rb_ary_new();
}
}
else if (*p == '\0') {
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 {
@ -593,6 +643,6 @@ rb_scan_args(argc, argv, fmt, va_alist)
return argc;
error:
Fatal("bad scan arg format: %s", fmt);
rb_fatal("bad scan arg format: %s", fmt);
return 0;
}

View file

@ -6,13 +6,13 @@
$Date$
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"
VALUE mComparable;
VALUE rb_mComparable;
static ID cmp;
@ -23,8 +23,8 @@ cmp_eq(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
if (t == 0) return TRUE;
return FALSE;
if (t == 0) return Qtrue;
return Qfalse;
}
static VALUE
@ -34,8 +34,8 @@ cmp_gt(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
if (t > 0) return TRUE;
return FALSE;
if (t > 0) return Qtrue;
return Qfalse;
}
static VALUE
@ -45,8 +45,8 @@ cmp_ge(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
if (t >= 0) return TRUE;
return FALSE;
if (t >= 0) return Qtrue;
return Qfalse;
}
static VALUE
@ -56,8 +56,8 @@ cmp_lt(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
if (t < 0) return TRUE;
return FALSE;
if (t < 0) return Qtrue;
return Qfalse;
}
static VALUE
@ -67,8 +67,8 @@ cmp_le(x, y)
VALUE c = rb_funcall(x, cmp, 1, y);
int t = NUM2INT(c);
if (t <= 0) return TRUE;
return FALSE;
if (t <= 0) return Qtrue;
return Qfalse;
}
static VALUE
@ -76,25 +76,25 @@ cmp_between(x, min, max)
VALUE x, min, max;
{
VALUE c = rb_funcall(x, cmp, 1, min);
int t = NUM2INT(c);
if (t < 0) return FALSE;
long t = NUM2LONG(c);
if (t < 0) return Qfalse;
c = rb_funcall(x, cmp, 1, max);
t = NUM2INT(c);
if (t > 0) return FALSE;
return TRUE;
t = NUM2LONG(c);
if (t > 0) return Qfalse;
return Qtrue;
}
void
Init_Comparable()
{
mComparable = rb_define_module("Comparable");
rb_define_method(mComparable, "==", cmp_eq, 1);
rb_define_method(mComparable, ">", cmp_gt, 1);
rb_define_method(mComparable, ">=", cmp_ge, 1);
rb_define_method(mComparable, "<", cmp_lt, 1);
rb_define_method(mComparable, "<=", cmp_le, 1);
rb_define_method(mComparable, "between?", cmp_between, 2);
rb_mComparable = rb_define_module("Comparable");
rb_define_method(rb_mComparable, "==", cmp_eq, 1);
rb_define_method(rb_mComparable, ">", cmp_gt, 1);
rb_define_method(rb_mComparable, ">=", cmp_ge, 1);
rb_define_method(rb_mComparable, "<", cmp_lt, 1);
rb_define_method(rb_mComparable, "<=", cmp_le, 1);
rb_define_method(rb_mComparable, "between?", cmp_between, 2);
cmp = rb_intern("<=>");
}

485
config.guess vendored
View file

@ -1,6 +1,6 @@
#! /bin/sh
# 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
# 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
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 Tn.n version is a released field test version.
# A Xn.n version is an unreleased experimental baselevel.
# 1.2 uses "1.2" for uname -r.
echo alpha-dec-osf`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 ;;
21064:Windows_NT:50:3)
echo alpha-dec-winnt3.5
@ -78,17 +120,54 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
amiga:NetBSD:*:*)
echo m68k-cbm-netbsd${UNAME_RELEASE}
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]*:*)
echo arm-acorn-riscix${UNAME_RELEASE}
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
echo pyramid-pyramid-sysv3
else
echo pyramid-pyramid-bsd
fi
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/[^.]*//'`
exit 0 ;;
i86pc:SunOS:5.*:*)
@ -112,25 +191,84 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
sun3*:SunOS:*:*)
echo m68k-sun-sunos${UNAME_RELEASE}
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:*:*)
echo m68k-atari-netbsd${UNAME_RELEASE}
exit 0 ;;
atari*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:NetBSD:*:*)
echo m68k-sun-netbsd${UNAME_RELEASE}
exit 0 ;;
sun3*:OpenBSD:*:*)
echo m68k-unknown-openbsd${UNAME_RELEASE}
exit 0 ;;
mac68k:NetBSD:*:*)
echo m68k-apple-netbsd${UNAME_RELEASE}
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:*:*)
echo mips-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
VAX*:ULTRIX*:*:*)
echo vax-dec-ultrix${UNAME_RELEASE}
exit 0 ;;
mips:*:4*:UMIPS)
echo mips-mips-riscos4sysv
2020:CLIX:*:*)
echo clipper-intergraph-clix${UNAME_RELEASE}
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}
exit 0 ;;
Night_Hawk:Power_UNIX:*:*)
@ -174,10 +312,10 @@ case "${UNAME_MACHINE}:${UNAME_SYSTEM}:${UNAME_RELEASE}:${UNAME_VERSION}" in
*:IRIX*:*:*)
echo mips-sgi-irix`echo ${UNAME_RELEASE}|sed -e 's/-/_/g'`
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
exit 0 ;; # Note that: echo "'`uname -s`'" gives 'AIX '
i[34]86:AIX:*:*)
i?86:AIX:*:*)
echo i386-ibm-aix
exit 0 ;;
*:AIX:2:3)
@ -203,7 +341,8 @@ EOF
fi
exit 0 ;;
*: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
else
IBM_ARCH=powerpc
@ -236,12 +375,44 @@ EOF
hp300:4.4BSD:*:* | 9000/[34]??:4.3bsd:2.*:*)
echo m68k-hp-bsd4.4
exit 0 ;;
9000/[3478]??:HP-UX:*:*)
9000/[34678]??:HP-UX:*:*)
case "${UNAME_MACHINE}" in
9000/31? ) HP_ARCH=m68000 ;;
9000/[34]?? ) HP_ARCH=m68k ;;
9000/7?? | 9000/8?[679] ) HP_ARCH=hppa1.1 ;;
9000/8?? ) HP_ARCH=hppa1.0 ;;
9000/6?? | 9000/7?? | 9000/80[24] | 9000/8?[13679] | 9000/892 )
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
HPUX_REV=`echo ${UNAME_RELEASE}|sed -e 's/[^.]*.[0B]*//'`
echo ${HP_ARCH}-hp-hpux${HPUX_REV}
@ -288,6 +459,13 @@ EOF
hp8??:OSF1:*:*)
echo hppa1.0-hp-osf
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*:*:*)
echo hppa1.1-hp-lites
exit 0 ;;
@ -315,18 +493,40 @@ EOF
CRAY*Y-MP:*:*:*)
echo ymp-cray-unicos${UNAME_RELEASE}
exit 0 ;;
CRAY*C90:*:*:*)
echo c90-cray-unicos${UNAME_RELEASE}
CRAY*[A-Z]90:*:*:*)
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 ;;
CRAY-2:*:*:*)
echo cray2-cray-unicos
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:*:*)
echo m68k-hp-netbsd${UNAME_RELEASE}
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}
exit 0 ;;
*:BSD/OS:*:*)
echo ${UNAME_MACHINE}-unknown-bsdi${UNAME_RELEASE}
exit 0 ;;
*:FreeBSD:*:*)
echo ${UNAME_MACHINE}-unknown-freebsd`echo ${UNAME_RELEASE}|sed -e 's/[-(].*//'`
exit 0 ;;
@ -340,33 +540,142 @@ EOF
echo i386-pc-bow
exit 0 ;;
i*:CYGWIN*:*)
echo i386-pc-cygwin32
echo ${UNAME_MACHINE}-pc-cygwin
exit 0 ;;
i*:MINGW*:*)
echo ${UNAME_MACHINE}-pc-mingw32
exit 0 ;;
p*:CYGWIN*:*)
echo powerpcle-unknown-cygwin32
echo powerpcle-unknown-cygwin
exit 0 ;;
prep*:SunOS:5.*:*)
echo powerpcle-unknown-solaris2`echo ${UNAME_RELEASE}|sed -e 's/[^.]*//'`
exit 0 ;;
*:GNU:*:*)
echo `echo ${UNAME_MACHINE}|sed -e 's,/.*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
echo `echo ${UNAME_MACHINE}|sed -e 's,[-/].*$,,'`-unknown-gnu`echo ${UNAME_RELEASE}|sed -e 's,/.*$,,'`
exit 0 ;;
*:Linux:*:*)
echo ${UNAME_MACHINE}-pc-linux
exit 0 ;;
# uname on the ARM produces all sorts of strangeness, and we need to
# 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
# 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
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
echo ${UNAME_MACHINE}-univel-sysv${UNAME_RELEASE}
else
echo ${UNAME_MACHINE}-pc-sysv${UNAME_RELEASE}
fi
exit 0 ;;
i[34]86:*:3.2:*)
i?86:*:3.2:*)
if test -f /usr/options/cb.name; then
UNAME_REL=`sed -n 's/.*Version //p' </usr/options/cb.name`
echo ${UNAME_MACHINE}-pc-isc$UNAME_REL
@ -380,6 +689,18 @@ EOF
echo ${UNAME_MACHINE}-pc-sysv32
fi
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*:*)
echo i386-pc-mach3
exit 0 ;;
@ -397,28 +718,36 @@ EOF
# "miniframe"
echo m68010-convergent-sysv
exit 0 ;;
M680[234]0:*:R3V[567]*:*)
M68*:*:R3V[567]*:*)
test -r /sysV68 && echo 'm68k-motorola-sysv' && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0)
uname -p 2>/dev/null | grep 86 >/dev/null \
&& echo i486-ncr-sysv4.3 && exit 0 ;;
3[34]??:*:4.0:3.0 | 3[34]??,*:*:4.0:3.0 | 4850:*:4.0:3.0)
OS_REL=''
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:*)
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 ;;
m680[234]0:LynxOS:2.[23]*:*)
echo m68k-lynx-lynxos${UNAME_RELEASE}
m68*:LynxOS:2.*:*)
echo m68k-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
mc68030:UNIX_System_V:4.*:*)
echo m68k-atari-sysv4
exit 0 ;;
i[34]86:LynxOS:2.[23]*:*)
echo i386-lynx-lynxos${UNAME_RELEASE}
i?86:LynxOS:2.*:*)
echo i386-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
TSUNAMI:LynxOS:2.[23]*:*)
echo sparc-lynx-lynxos${UNAME_RELEASE}
TSUNAMI:LynxOS:2.*:*)
echo sparc-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
rs6000:LynxOS:2.[23]*:*)
echo rs6000-lynx-lynxos${UNAME_RELEASE}
rs6000:LynxOS:2.*:* | PowerPC:LynxOS:2.*:*)
echo rs6000-unknown-lynxos${UNAME_RELEASE}
exit 0 ;;
SM[BE]S:UNIX_SV:*:*)
echo mips-dde-sysv${UNAME_RELEASE}
exit 0 ;;
RM*:SINIX-*:*:*)
echo mips-sni-sysv4
@ -431,42 +760,58 @@ EOF
echo ns32k-sni-sysv
fi
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:*:*)
echo m68k-apple-aux${UNAME_RELEASE}
exit 0 ;;
X680[02346]0:Human68k:*:*)
echo m68k-sharp-human
news*:NEWS-OS:*:6*)
echo mips-sony-newsos6
exit 0 ;;
R[34]000:*System_V*:*:*)
R[34]000:*System_V*:*:* | R4000:UNIX_SYSV:*:* | R4000:UNIX_SV:*:*)
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
echo mips-unknown-sysv${UNAME_RELEASE}
fi
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*)
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 ;;
esac
@ -511,7 +856,11 @@ main ()
#endif
int version;
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);
#endif
@ -567,16 +916,12 @@ main ()
printf ("i860-alliant-bsd\n"); exit (0);
#endif
#if defined (__human68k__) || defined (HUMAN68K)
printf ("m68k-sharp-human\n"); exit (0);
#endif
exit (1);
}
EOF
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm -f dummy.c dummy.x dummy && exit 0
rm -f dummy.c dummy.x dummy
${CC-cc} dummy.c -o dummy 2>/dev/null && ./dummy && rm dummy.c dummy && exit 0
rm -f dummy.c dummy
# Apollos put the system type in the environment.

156
config.sub vendored
View file

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

64
config_h.dj Normal file
View file

@ -0,0 +1,64 @@
#define USE_THREAD 1
#define SIZEOF_INT 4
#define SIZEOF_LONG 4
#define SIZEOF_VOIDP 4
#define HAVE_PROTOTYPES 1
#define HAVE_STDARG_PROTOTYPES 1
#define HAVE_ATTR_NORETURN 1
#define HAVE_DIRENT_H 1
#define STDC_HEADERS 1
#define HAVE_STDLIB_H 1
#define HAVE_UNISTD_H 1
#define HAVE_LIMITS_H 1
#define HAVE_SYS_FILE_H 1
#define HAVE_SYS_IOCTL_H 1
#define HAVE_PWD_H 1
#define HAVE_SYS_TIME_H 1
#define HAVE_SYS_TIMES_H 1
#define HAVE_SYS_PARAM_H 1
#define HAVE_SYS_WAIT_H 1
#define HAVE_STRING_H 1
#define HAVE_UTIME_H 1
#define HAVE_MEMORY_H 1
#define HAVE_DIRECT_H 1
#define HAVE_ST_BLKSIZE 1
#define HAVE_ST_RDEV 1
#define GETGROUPS_T gid_t
#define RETSIGTYPE void
#define HAVE_ALLOCA 1
#define vfork fork
#define HAVE_DUP2 1
#define HAVE_SETENV 1
#define HAVE_MEMMOVE 1
#define HAVE_MKDIR 1
#define HAVE_STRCASECMP 1
#define HAVE_STRERROR 1
#define HAVE_STRFTIME 1
#define HAVE_STRCHR 1
#define HAVE_STRSTR 1
#define HAVE_STRTOUL 1
#define HAVE_STRDUP 1
#define HAVE_FMOD 1
#define HAVE_RANDOM 1
#define HAVE_WAITPID 1
#define HAVE_GETCWD 1
#define HAVE_TRUNCATE 1
#define HAVE_CHSIZE 1
#define HAVE_TIMES 1
#define HAVE_UTIMES 1
#define HAVE_FCNTL 1
/*#define HAVE_SETITIMER 1*/
#define HAVE_GETGROUPS 1
#define HAVE_SIGPROCMASK 1
#define HAVE_SIGACTION 1
#define HAVE_SETSID 1
#define POSIX_SIGNAL 1
#define BSD_SETPGRP setpgrp
#define RSHIFT(x,y) ((x)>>y)
#define FILE_COUNT _cnt
#define DLEXT ".o"
#define RUBY_LIB "/usr/local/lib/ruby"
#define RUBY_SITE_LIB "/usr/local/lib/ruby/site_ruby"
#define RUBY_ARCHLIB "/usr/local/lib/ruby/i386-djgpp"
#define RUBY_SITE_ARCHLIB "/usr/local/lib/ruby/site_ruby/i386-djgpp"
#define RUBY_PLATFORM "i386-djgpp"

51
config_s.dj Normal file
View file

@ -0,0 +1,51 @@
s%@CFLAGS@%-g -O2%g
s%@CPPFLAGS@%%g
s%@CXXFLAGS@%%g
s%@DEFS@% -DUSE_THREAD=1 -DSIZEOF_INT=4 -DSIZEOF_LONG=4 -DSIZEOF_VOIDP=4 -DHAVE_PROTOTYPES=1 -DHAVE_STDARG_PROTOTYPES=1 -DHAVE_ATTR_NORETURN=1 -DHAVE_DIRENT_H=1 -DSTDC_HEADERS=1 -DHAVE_STDLIB_H=1 -DHAVE_UNISTD_H=1 -DHAVE_LIMITS_H=1 -DHAVE_SYS_FILE_H=1 -DHAVE_SYS_IOCTL_H=1 -DHAVE_PWD_H=1 -DHAVE_SYS_TIME_H=1 -DHAVE_SYS_TIMES_H=1 -DHAVE_SYS_PARAM_H=1 -DHAVE_SYS_WAIT_H=1 -DHAVE_STRING_H=1 -DHAVE_UTIME_H=1 -DHAVE_MEMORY_H=1 -DHAVE_DIRECT_H=1 -DHAVE_ST_BLKSIZE=1 -DHAVE_ST_RDEV=1 -DGETGROUPS_T=gid_t -DRETSIGTYPE=void -DHAVE_ALLOCA=1 -Dvfork=fork -DHAVE_DUP2=1 -DHAVE_SETENV=1 -DHAVE_MEMMOVE=1 -DHAVE_MKDIR=1 -DHAVE_STRCASECMP=1 -DHAVE_STRERROR=1 -DHAVE_STRFTIME=1 -DHAVE_STRCHR=1 -DHAVE_STRSTR=1 -DHAVE_STRTOUL=1 -DHAVE_STRDUP=1 -DHAVE_FMOD=1 -DHAVE_RANDOM=1 -DHAVE_WAITPID=1 -DHAVE_GETCWD=1 -DHAVE_TRUNCATE=1 -DHAVE_CHSIZE=1 -DHAVE_TIMES=1 -DHAVE_UTIMES=1 -DHAVE_FCNTL=1 -DHAVE_SETITIMER=1 -DHAVE_GETGROUPS=1 -DHAVE_SIGPROCMASK=1 -DHAVE_SIGACTION=1 -DHAVE_SETSID=1 -DPOSIX_SIGNAL=1 -DBSD_SETPGRP=setpgrp -DRSHIFT=\(x,y\)\ \(\(x\)\>\>y\) -DFILE_COUNT=_cnt -DDLEXT=\".so\" -DRUBY_LIB=\"/usr/local/lib/ruby\" -DRUBY_SITE_LIB=\"/usr/local/lib/ruby/site_ruby\" -DRUBY_ARCHLIB=\"/usr/local/lib/ruby/i386-djgpp\" -DRUBY_SITE_ARCHLIB=\"/usr/local/lib/ruby/site_ruby/i386-djgpp\" -DRUBY_PLATFORM=\"i386-djgpp\" %g
s%@LDFLAGS@%%g
s%@LIBS@%-lm %g
s%@exec_prefix@%${prefix}%g
s%@prefix@%/usr/local%g
s%@program_transform_name@%s,x,x,%g
s%@bindir@%${exec_prefix}/bin%g
s%@sbindir@%${exec_prefix}/sbin%g
s%@libexecdir@%${exec_prefix}/libexec%g
s%@datadir@%${prefix}/share%g
s%@sysconfdir@%${prefix}/etc%g
s%@sharedstatedir@%${prefix}/com%g
s%@localstatedir@%${prefix}/var%g
s%@libdir@%${exec_prefix}/lib%g
s%@includedir@%${prefix}/include%g
s%@oldincludedir@%/usr/include%g
s%@infodir@%${prefix}/info%g
s%@mandir@%${prefix}/man%g
s%@host@%i386-pc-djgpp%g
s%@host_alias@%i386-djgpp%g
s%@host_cpu@%i386%g
s%@host_vendor@%pc%g
s%@host_os@%djgpp%g
s%@CC@%gcc%g
s%@CPP@%gcc -E%g
s%@YACC@%bison -y%g
s%@RANLIB@%ranlib%g
s%@AR@%ar%g
s%@INSTALL_PROGRAM@%${INSTALL}%g
s%@INSTALL_DATA@%${INSTALL} -m 644%g
s%@SET_MAKE@%%g
s%@LIBOBJS@% crypt.o flock.o snprintf.o%g
s%@ALLOCA@%%g
s%@DLDFLAGS@%%g
s%@STATIC@%%g
s%@CCDLFLAGS@%%g
s%@LDSHARED@%ld%g
s%@DLEXT@%o%g
s%@STRIP@%strip%g
s%@EXTSTATIC@%%g
s%@binsuffix@%.exe%g
s%@setup@%Setup%g
s%@LIBRUBY@%libruby.a%g
s%@LIBRUBYARG@%libruby.a%g
s%@SOLIBS@%%g
s%@srcdir%.%g
s%@arch@%i386-djgpp%g
ac_given_srcdir=.

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 ext/extmk.rb.in > ext\extmk.rb
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
])
if test $rb_thread = yes; then
AC_DEFINE(THREAD)
AC_DEFINE(USE_THREAD)
fi
AC_CANONICAL_HOST
dnl checks for fat-binary
fat_binary=no
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 ] )
if test "$fat_binary" = yes ; then
if test "$fat_binary" = yes ; then
AC_MSG_CHECKING( target architecture )
if test "$TARGET_ARCHS" = "" ; then
if test `/usr/bin/arch` = "m68k" ; then
TARGET_ARCHS="m68k i486"
case "$host_os" in
rhapsody*)
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
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
;;
esac
# /usr/lib/arch_tool -archify_list $TARGET_ARCHS
for archs in $TARGET_ARCHS
do
@ -56,7 +75,6 @@ if test "$fat_binary" = yes ; then
echo "."
fi
AC_ARG_PROGRAM
dnl Checks for programs.
@ -72,22 +90,70 @@ AC_PROG_MAKE_SET
# checks for UNIX variants that set C preprocessor variables
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.
case "$host_os" in
nextstep*) ;;
openstep*) ;;
rhapsody*) ;;
human*) ;;
beos*) ;;
*) LIBS="-lm $LIBS";;
esac
AC_CHECK_LIB(crypt, crypt)
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(xpg4, setlocale) # FreeBSD needs this
dnl Checks for header files.
AC_HEADER_DIRENT
AC_HEADER_STDC
AC_CHECK_HEADERS(stdlib.h unistd.h limits.h sys/file.h sys/ioctl.h pwd.h \
sys/select.h sys/time.h sys/times.h sys/param.h sys/wait.h\
syscall.h a.out.h string.h utime.h memory.h)
syscall.h a.out.h string.h utime.h memory.h direct.h)
dnl Checks for typedefs, structures, and compiler characteristics.
AC_TYPE_UID_T
@ -98,23 +164,19 @@ AC_STRUCT_ST_BLOCKS
LIBOBJS="$save_LIBOBJS"
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.
AC_TYPE_GETGROUPS
AC_TYPE_SIGNAL
AC_FUNC_ALLOCA
AC_FUNC_VFORK
AC_REPLACE_FUNCS(dup2 setenv memmove mkdir strcasecmp strerror strftime\
strstr strtoul strdup crypt flock)
AC_CHECK_FUNCS(fmod killpg random wait4 waitpid syscall getcwd\
AC_FUNC_MEMCMP
AC_REPLACE_FUNCS(dup2 memmove mkdir strcasecmp strerror strftime\
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\
setruid seteuid setreuid setrgid setegid setregid\
setpgrp2 getpgid getgroups getpriority\
dlopen sigprocmask sigaction _setjmp)
setpgrp2 getpgid setpgid getgroups getpriority\
dlopen sigprocmask sigaction _setjmp setpgrp setsid)
if test "$ac_cv_func_strftime" = no; then
AC_STRUCT_TIMEZONE
AC_TRY_LINK([],
@ -181,6 +243,26 @@ fi
AC_C_BIGENDIAN
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_CACHE_VAL(rb_cv_fcnt,
[AC_TRY_COMPILE([#include <stdio.h>],
@ -205,17 +287,6 @@ else
AC_DEFINE_UNQUOTED(FILE_COUNT, $rb_cv_fcnt)
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
AC_ARG_WITH(dln-a-out, [--with-dln-a-out use dln_a_out if possible], [
case $withval in
@ -271,7 +342,10 @@ if test "$with_dln_a_out" != yes; then
if test "$GCC" = yes; then
case "$host_os" in
nextstep*) ;;
openstep*) ;;
rhapsody*) ;;
human*) ;;
cygwin*) CCDLFLAGS=-DDLLIMPORT;;
*) CCDLFLAGS=-fpic;;
esac
else
@ -301,21 +375,44 @@ if test "$with_dln_a_out" != yes; then
rb_cv_dlopen=yes ;;
linux*) LDSHARED="gcc -shared"
rb_cv_dlopen=yes ;;
freebsd3*) LDSHARED="ld -Bshareable"
LDFLAGS="-rdynamic"
rb_cv_dlopen=yes ;;
freebsd*) LDSHARED="ld -Bshareable"
rb_cv_dlopen=yes ;;
netbsd*) LDSHARED="ld -Bshareable"
rb_cv_dlopen=yes ;;
openbsd*) LDSHARED="ld -Bshareable"
openbsd*) LDSHARED="ld -Bforcearchive -Bshareable"
CCDLFLAGS=-fPIC
rb_cv_dlopen=yes ;;
nextstep*) LDSHARED='cc -r'
LDFLAGS="-u libsys_s"
DLDFLAGS="$ARCH_FLAG"
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)'
rb_cv_dlopen=yes ;;
human*) DLDFLAGS=''
LDSHARED=''
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' ;;
esac
AC_MSG_RESULT($rb_cv_dlopen)
@ -357,6 +454,12 @@ else
AC_DEFINE(DLEXT, ".sl");;
nextstep*) 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
AC_DEFINE(DLEXT, ".so");;
esac
@ -374,6 +477,10 @@ case "$host_os" in
STRIP='strip -S -x';;
nextstep*)
STRIP='strip -A -n';;
openstep*)
STRIP='strip -A -n';;
rhapsody*)
STRIP='strip -A -n';;
esac
EXTSTATIC=
@ -435,11 +542,18 @@ rb_cv_missing_fconvert=yes, rb_cv_missing_fconvert=no)])
binsuffix=.x
setup=Setup.x68
;;
cygwin*)
binsuffix=.exe
setup=Setup
;;
*)
binsuffix=
setup=Setup
;;
esac
AC_SUBST(binsuffix)
AC_SUBST(setup)
@ -448,23 +562,82 @@ if test "$prefix" = NONE; then
fi
if test "$fat_binary" = yes ; then
CFLAGS="$CFLAGS -pipe $ARCH_FLAG"
CFLAGS="$CFLAGS $ARCH_FLAG"
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
if test "$fat_binary" = yes ; then
arch="fat-${host_os}"
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}" )
else
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}")
fi

View file

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

145
dir.c
View file

@ -6,7 +6,7 @@
$Date$
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
# include <dirent.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#elif HAVE_DIRECT_H
# include <direct.h>
# define NAMLEN(dirent) strlen((dirent)->d_name)
#else
# define dirent direct
# define NAMLEN(dirent) (dirent)->d_namlen
@ -39,7 +42,7 @@
# if HAVE_NDIR_H
# include <ndir.h>
# endif
# ifdef NT
# if defined(NT) && defined(_MSC_VER)
# include "missing/dir.h"
# endif
#endif
@ -50,7 +53,11 @@
char *getenv();
#endif
static VALUE cDir;
#ifdef USE_CWGUSI
# include <sys/errno.h>
#endif
VALUE rb_cDir;
static void
free_dir(dir)
@ -59,6 +66,8 @@ free_dir(dir)
if (dir) closedir(dir);
}
static VALUE dir_close _((VALUE));
static VALUE
dir_s_open(dir_class, dirname)
VALUE dir_class, dirname;
@ -71,7 +80,7 @@ dir_s_open(dir_class, dirname)
dirp = opendir(RSTRING(dirname)->ptr);
if (dirp == NULL) {
if (errno == EMFILE || errno == ENFILE) {
gc_gc();
rb_gc();
dirp = opendir(RSTRING(dirname)->ptr);
}
if (dirp == NULL) {
@ -81,13 +90,17 @@ dir_s_open(dir_class, dirname)
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;
}
static void
dir_closed()
{
Fail("closed directory");
rb_raise(rb_eIOError, "closed directory");
}
#define GetDIR(obj, dirp) {\
@ -95,6 +108,27 @@ 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
dir_each(dir)
VALUE dir;
@ -105,7 +139,7 @@ dir_each(dir)
GetDIR(dir, 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);
}
return dir;
@ -118,10 +152,10 @@ dir_tell(dir)
DIR *dirp;
int pos;
#if !defined(__CYGWIN32__)
#if !defined(__CYGWIN32__) && !defined(__BEOS__)
GetDIR(dir, dirp);
pos = telldir(dirp);
return int2inum(pos);
return rb_int2inum(pos);
#else
rb_notimplement();
#endif
@ -133,7 +167,7 @@ dir_seek(dir, pos)
{
DIR *dirp;
#if !defined(__CYGWIN32__)
#if !defined(__CYGWIN32__) && !defined(__BEOS__)
GetDIR(dir, dirp);
seekdir(dirp, NUM2INT(pos));
return dir;
@ -177,8 +211,7 @@ dir_s_chdir(argc, argv, obj)
char *dist = "";
rb_secure(2);
rb_scan_args(argc, argv, "01", &path);
if (!NIL_P(path)) {
if (rb_scan_args(argc, argv, "01", &path) == 1) {
Check_SafeStr(path);
dist = RSTRING(path)->ptr;
}
@ -190,7 +223,7 @@ dir_s_chdir(argc, argv, obj)
}
if (chdir(dist) < 0)
rb_sys_fail(0);
rb_sys_fail(dist);
return INT2FIX(0);
}
@ -199,32 +232,33 @@ static VALUE
dir_s_getwd(dir)
VALUE dir;
{
extern char *getwd();
char path[MAXPATHLEN];
#ifdef HAVE_GETCWD
if (getcwd(path, sizeof(path)) == 0) rb_sys_fail(path);
#else
extern char *getwd();
if (getwd(path) == 0) rb_sys_fail(path);
#endif
return str_taint(str_new2(path));
return rb_tainted_str_new2(path);
}
static VALUE
dir_s_chroot(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);
Check_SafeStr(path);
if (chroot(RSTRING(path)->ptr) == -1)
rb_sys_fail(0);
rb_sys_fail(RSTRING(path)->ptr);
return INT2FIX(0);
#else
rb_notimplement();
return Qnil; /* not reached */
#endif
}
@ -246,7 +280,7 @@ dir_s_mkdir(argc, argv, obj)
}
Check_SafeStr(path);
#ifndef NT
#if !defined(NT) && !defined(USE_CWGUSI)
if (mkdir(RSTRING(path)->ptr, mode) == -1)
rb_sys_fail(RSTRING(path)->ptr);
#else
@ -266,7 +300,7 @@ dir_s_rmdir(obj, dir)
if (rmdir(RSTRING(dir)->ptr) < 0)
rb_sys_fail(RSTRING(dir)->ptr);
return TRUE;
return Qtrue;
}
#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);
ff = fnames;
while (*ff) {
ary_push(ary, str_taint(str_new2(*ff)));
rb_ary_push(ary, rb_tainted_str_new2(*ff));
free(*ff);
ff++;
}
@ -341,22 +375,24 @@ push_braces(ary, s)
}
static VALUE
dir_s_glob(dir, vstr)
VALUE dir, vstr;
dir_s_glob(dir, str)
VALUE dir, str;
{
char *p, *pend;
char buf[MAXPATHLEN];
char *t, *t0;
int nest;
VALUE ary;
struct RString *str;
Check_SafeStr(vstr);
str = RSTRING(vstr);
ary = ary_new();
Check_SafeStr(str);
if (RSTRING(str)->len > MAXPATHLEN) {
rb_raise(rb_eArgError, "pathname too long (%d bytes)",
RSTRING(str)->len);
}
ary = rb_ary_new();
p = str->ptr;
pend = p + str->len;
p = RSTRING(str)->ptr;
pend = p + RSTRING(str)->len;
while (p < pend) {
t = buf;
@ -389,37 +425,48 @@ dir_foreach(io, dirname)
{
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);
}
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
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_singleton_method(cDir, "foreach", dir_foreach, 1);
rb_define_method(rb_cDir,"read", dir_read, 0);
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_method(cDir,"rewind", dir_rewind, 0);
rb_define_method(cDir,"tell", dir_tell, 0);
rb_define_method(cDir,"seek", dir_seek, 1);
rb_define_method(cDir,"close", dir_close, 0);
rb_define_singleton_method(rb_cDir,"chdir", dir_s_chdir, -1);
rb_define_singleton_method(rb_cDir,"getwd", dir_s_getwd, 0);
rb_define_singleton_method(rb_cDir,"pwd", dir_s_getwd, 0);
rb_define_singleton_method(rb_cDir,"chroot", dir_s_chroot, 1);
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(cDir,"getwd", dir_s_getwd, 0);
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);
rb_define_singleton_method(rb_cDir,"glob", dir_s_glob, 1);
rb_define_singleton_method(rb_cDir,"[]", dir_s_glob, 1);
}

298
dln.c
View file

@ -6,20 +6,20 @@
$Date$
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 "defines.h"
#include "dln.h"
char *dln_argv0;
#ifdef _AIX
#pragma alloca
#endif
#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
#include <alloca.h>
#endif
@ -36,7 +36,9 @@ void *xrealloc();
#include <stdio.h>
#ifndef NT
#include <sys/file.h>
# ifndef USE_CWGUSI
# include <sys/file.h>
# endif
#else
#include "missing/file.h"
#endif
@ -58,15 +60,25 @@ char *strdup();
char *getenv();
#endif
#ifdef __MACOS__
# include <TextUtils.h>
# include <CodeFragments.h>
# include <Aliases.h>
#endif
#ifdef __BEOS__
# include <image.h>
#endif
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() */
# define USE_DLN_DLOPEN
#endif
#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"
# else
# define FUNCNAME_PATTERN "Init_%.200s"
@ -81,7 +93,11 @@ init_funcname(buf, file)
/* Load the file as an object one */
for (p = file, slash = p-1; *p; p++) /* Find position of last '/' */
#ifdef __MACOS__
if (*p == ':') slash = p;
#else
if (*p == '/') slash = p;
#endif
sprintf(buf, FUNCNAME_PATTERN, slash + 1);
for (p = buf; *p; p++) { /* Delete suffix it it exists */
@ -407,7 +423,7 @@ load_text_data(fd, hdrp, bss, disp)
}
static int
undef_print(key, value)
underb_f_print(key, value)
char *key, *value;
{
fprintf(stderr, " %s\n", key);
@ -418,7 +434,7 @@ static void
dln_print_undef()
{
fprintf(stderr, " Undefined symbols:\n");
st_foreach(undef_tbl, undef_print, NULL);
st_foreach(undef_tbl, underb_f_print, NULL);
}
static void
@ -814,7 +830,7 @@ load_1(fd, disp, need_init)
for (sym = syms; sym<end; sym++) {
char *name = sym->n_un.n_name;
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;
}
else if (strcmp(name+1, buf) == 0) {
@ -869,11 +885,11 @@ search_undef(key, value, lib_tbl)
}
struct symdef {
int str_index;
int rb_str_index;
int lib_offset;
};
char *dln_library_path = DLN_DEFAULT_LIB_PATH;
char *dln_librrb_ary_path = DLN_DEFAULT_LIB_PATH;
static int
load_lib(lib)
@ -904,10 +920,10 @@ load_lib(lib)
/* library search path: */
/* 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. */
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);
fd = open(file, O_RDONLY);
@ -936,7 +952,7 @@ load_lib(lib)
base = (struct symdef*)(data + 1);
name_base = (char*)(base + nsym) + sizeof(int);
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));
nsym--;
@ -1065,14 +1081,18 @@ dln_sym(name)
#include "dl.h"
#endif
#ifdef _AIX
#if defined(_AIX)
#include <ctype.h> /* for isdigit() */
#include <errno.h> /* for global errno */
#include <sys/ldr.h>
#endif
#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
#ifdef _WIN32
@ -1109,21 +1129,28 @@ dln_strerror()
#ifdef _WIN32
static char message[1024];
int error = GetLastError();
char *p = message;
p += sprintf(message, "%d: ", error);
FormatMessage(
FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US),
message,
sizeof message,
error,
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
p,
sizeof message - strlen(message),
NULL);
for (p = message; *p; p++) {
if (*p == '\n' || *p == '\r')
*p = ' ';
}
return message;
#endif
}
#ifdef _AIX
#if defined(_AIX)
static void
aix_loaderror(char *pathname)
{
@ -1166,7 +1193,7 @@ aix_loaderror(char *pathname)
ERRBUF_APPEND("\n");
}
errbuf[strlen(errbuf)-1] = '\0'; /* trim off last newline */
LoadError(errbuf);
rb_loaderror(errbuf);
return;
}
#endif
@ -1193,7 +1220,7 @@ dln_load(file)
/* Load file */
if ((handle =
LoadLibraryExA(winfile, NULL, LOAD_WITH_ALTERED_SEARCH_PATH)) == NULL) {
printf("LoadLibraryExA\n");
printf("LoadLibraryExA: %s\n", winfile);
goto failed;
}
@ -1229,15 +1256,15 @@ dln_load(file)
void *handle;
void (*init_fct)();
# ifndef RTLD_LAZY
# define RTLD_LAZY 1
# endif
# ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
# endif
#ifndef RTLD_LAZY
# define RTLD_LAZY 1
#endif
#ifndef RTLD_GLOBAL
# define RTLD_GLOBAL 0
#endif
/* Load file */
if ((handle = dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {
if ((handle = (void*)dlopen(file, RTLD_LAZY|RTLD_GLOBAL)) == NULL) {
goto failed;
}
@ -1260,15 +1287,15 @@ dln_load(file)
flags = BIND_DEFERRED;
lib = shl_load(file, flags, 0);
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);
if (init_fct == NULL) {
shl_findsym(&lib, buf, TYPE_UNDEFINED, (void*)&init_fct);
if (init_fct == NULL) {
extern int errno;
errno = ENOSYM;
rb_sys_fail(file);
rb_loaderror("%s - %s", strerror(ENOSYM), file);
}
}
(*init_fct)();
@ -1276,7 +1303,7 @@ dln_load(file)
}
#endif /* hpux */
#ifdef _AIX
#if defined(_AIX)
#define DLN_DEFINED
{
void (*init_fct)();
@ -1300,6 +1327,7 @@ dln_load(file)
Mi hisho@tasihara.nest.or.jp,
and... Miss ARAI Akino(^^;)
----------------------------------------------------*/
#if NS_TARGET_MAJOR < 4 /* NeXTSTEP rld functions */
{
unsigned long init_address;
char *object_files[2] = {NULL, NULL};
@ -1310,12 +1338,12 @@ dln_load(file)
/* Load object file, if return value ==0 , load failed*/
if(rld_load(NULL, NULL, object_files, NULL) == 0) {
LoadError("Failed to load %.200s", file);
rb_loaderror("Failed to load %.200s", file);
}
/* lookup the initial function */
if(rld_lookup(NULL, buf, &init_address) == 0) {
LoadError("Failed to lookup Init function %.200s",file);
rb_loaderror("Failed to lookup Init function %.200s", file);
}
/* Cannot call *init_address directory, so copy this value to
@ -1325,8 +1353,133 @@ dln_load(file)
(*init_fct)();
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
#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
rb_notimplement("dynamic link not supported");
#endif
@ -1335,7 +1488,7 @@ dln_load(file)
#endif
#if !defined(_AIX) && !defined(NeXT)
failed:
LoadError("%s - %s", dln_strerror(), file);
rb_loaderror("%s - %s", dln_strerror(), file);
#endif
}
@ -1346,15 +1499,21 @@ dln_find_exe(fname, path)
char *fname;
char *path;
{
if (!path) {
#if defined(__human68k__)
if (!path)
path = getenv("path");
if (!path)
path = "/usr/local/bin;/usr/usb;/usr/bin;/bin;.";
#else
if (!path) path = getenv("PATH");
if (!path) path = "/usr/local/bin:/usr/ucb:/usr/bin:/bin:.";
path = getenv("PATH");
#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);
}
@ -1367,6 +1526,30 @@ dln_find_file(fname, path)
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 *
@ -1380,15 +1563,24 @@ dln_find_1(fname, path, exe_flag)
register char *bp;
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 (strncmp("./", fname, 2) == 0 || strncmp("../", fname, 3) == 0)
return fname;
if (exe_flag && strchr(fname, '/')) return fname;
#if defined(MSDOS) || defined(NT) || defined(__human68k__)
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)
return fname;
if (exe_flag && strchr(fname, '\\')) return fname;
#endif
#endif /* __MACOS__ */
for (dp = path;; dp = ++ep) {
register int l;
@ -1396,11 +1588,7 @@ dln_find_1(fname, path, exe_flag)
int fspace;
/* extract a component */
#if !defined(MSDOS) && !defined(NT) && !defined(__human68k__)
ep = strchr(dp, ':');
#else
ep = strchr(dp, ';');
#endif
ep = strchr(dp, RUBY_PATH_SEP[0]);
if (ep == NULL)
ep = dp+strlen(dp);
@ -1417,7 +1605,11 @@ dln_find_1(fname, path, exe_flag)
** 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;
home = getenv("HOME");
@ -1440,7 +1632,11 @@ dln_find_1(fname, path, exe_flag)
/* add a "/" between directory and filename */
if (ep[-1] != '/')
#ifdef __MACOS__
*bp++ = ':';
#else
*bp++ = '/';
#endif
}
/* now append the file name */

14
dln.h
View file

@ -11,12 +11,20 @@
#ifndef DLN_H
#define DLN_H
char *dln_find_exe();
char *dln_find_file();
#ifndef _
#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
extern char *dln_argv0;
#endif
void dln_load();
void dln_load _((char*));
#endif

137
enum.c
View file

@ -6,13 +6,13 @@
$Date$
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"
VALUE mEnumerable;
VALUE rb_mEnumerable;
static ID id_each, id_eqq, id_cmp;
VALUE
@ -27,7 +27,7 @@ grep_i(i, arg)
VALUE i, *arg;
{
if (RTEST(rb_funcall(arg[0], id_eqq, 1, i))) {
ary_push(arg[1], i);
rb_ary_push(arg[1], i);
}
return Qnil;
}
@ -46,14 +46,14 @@ static VALUE
enum_grep(obj, pat)
VALUE obj, pat;
{
if (iterator_p()) {
if (rb_iterator_p()) {
rb_iterate(rb_each, obj, grep_iter_i, pat);
return obj;
}
else {
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);
return tmp;
@ -71,7 +71,7 @@ find_i(i, arg)
struct find_arg *arg;
{
if (RTEST(rb_yield(i))) {
arg->found = TRUE;
arg->found = Qtrue;
arg->val = i;
rb_iter_break();
}
@ -88,7 +88,7 @@ enum_find(argc, argv, obj)
VALUE 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);
if (arg.found) {
return arg.val;
@ -104,7 +104,7 @@ find_all_i(i, tmp)
VALUE i, tmp;
{
if (RTEST(rb_yield(i))) {
ary_push(tmp, i);
rb_ary_push(tmp, i);
}
return Qnil;
}
@ -115,7 +115,7 @@ enum_find_all(obj)
{
VALUE tmp;
tmp = ary_new();
tmp = rb_ary_new();
rb_iterate(rb_each, obj, find_all_i, tmp);
return tmp;
@ -125,12 +125,7 @@ static VALUE
collect_i(i, tmp)
VALUE i, tmp;
{
VALUE retval;
retval = rb_yield(i);
if (RTEST(retval)) {
ary_push(tmp, retval);
}
rb_ary_push(tmp, rb_yield(i));
return Qnil;
}
@ -140,37 +135,17 @@ enum_collect(obj)
{
VALUE tmp;
tmp = ary_new();
tmp = rb_ary_new();
rb_iterate(rb_each, obj, collect_i, 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
enum_all(i, ary)
VALUE i, ary;
{
ary_push(ary, i);
rb_ary_push(ary, i);
return Qnil;
}
@ -180,7 +155,7 @@ enum_to_a(obj)
{
VALUE ary;
ary = ary_new();
ary = rb_ary_new();
rb_iterate(rb_each, obj, enum_all, ary);
return ary;
@ -190,7 +165,7 @@ static VALUE
enum_sort(obj)
VALUE obj;
{
return ary_sort(enum_to_a(obj));
return rb_ary_sort(enum_to_a(obj));
}
static VALUE
@ -203,7 +178,7 @@ min_i(i, min)
*min = i;
else {
cmp = rb_funcall(i, id_cmp, 1, *min);
if (FIX2INT(cmp) < 0)
if (FIX2LONG(cmp) < 0)
*min = i;
}
return Qnil;
@ -218,8 +193,8 @@ min_ii(i, min)
if (NIL_P(*min))
*min = i;
else {
cmp = rb_yield(assoc_new(i, *min));
if (FIX2INT(cmp) < 0)
cmp = rb_yield(rb_assoc_new(i, *min));
if (FIX2LONG(cmp) < 0)
*min = i;
}
return Qnil;
@ -231,7 +206,7 @@ enum_min(obj)
{
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;
}
@ -245,7 +220,7 @@ max_i(i, max)
*max = i;
else {
cmp = rb_funcall(i, id_cmp, 1, *max);
if (FIX2INT(cmp) > 0)
if (FIX2LONG(cmp) > 0)
*max = i;
}
return Qnil;
@ -260,8 +235,8 @@ max_ii(i, max)
if (NIL_P(*max))
*max = i;
else {
cmp = rb_yield(assoc_new(i, *max));
if (FIX2INT(cmp) > 0)
cmp = rb_yield(rb_assoc_new(i, *max));
if (FIX2LONG(cmp) > 0)
*max = i;
}
return Qnil;
@ -273,7 +248,7 @@ enum_max(obj)
{
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;
}
@ -333,8 +308,8 @@ enum_member(obj, val)
iv.i = 0;
iv.v = val;
rb_iterate(rb_each, obj, member_i, (VALUE)&iv);
if (iv.i) return TRUE;
return FALSE;
if (iv.i) return Qtrue;
return Qfalse;
}
static VALUE
@ -346,7 +321,7 @@ length_i(i, length)
return Qnil;
}
VALUE
static VALUE
enum_length(obj)
VALUE obj;
{
@ -356,26 +331,58 @@ enum_length(obj)
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
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(mEnumerable,"grep", enum_grep, 1);
rb_define_method(mEnumerable,"find", enum_find, -1);
rb_define_method(mEnumerable,"find_all", enum_find_all, 0);
rb_define_method(mEnumerable,"collect", enum_collect, 0);
rb_define_method(mEnumerable,"reverse", enum_reverse, 0);
rb_define_method(mEnumerable,"min", enum_min, 0);
rb_define_method(mEnumerable,"max", enum_max, 0);
rb_define_method(mEnumerable,"index", enum_index, 1);
rb_define_method(mEnumerable,"member?", enum_member, 1);
rb_define_method(mEnumerable,"include?", enum_member, 1);
rb_define_method(mEnumerable,"length", enum_length, 0);
rb_define_method(mEnumerable,"size", enum_length, 0);
rb_define_method(rb_mEnumerable,"sort", enum_sort, 0);
rb_define_method(rb_mEnumerable,"grep", enum_grep, 1);
rb_define_method(rb_mEnumerable,"find", enum_find, -1);
rb_define_method(rb_mEnumerable,"find_all", enum_find_all, 0);
rb_define_method(rb_mEnumerable,"collect", enum_collect, 0);
rb_define_method(rb_mEnumerable,"min", enum_min, 0);
rb_define_method(rb_mEnumerable,"max", enum_max, 0);
rb_define_method(rb_mEnumerable,"index", enum_index, 1);
rb_define_method(rb_mEnumerable,"member?", enum_member, 1);
rb_define_method(rb_mEnumerable,"include?", enum_member, 1);
rb_define_method(rb_mEnumerable,"length", enum_length, 0);
rb_define_method(rb_mEnumerable,"size", enum_length, 0);
rb_define_method(rb_mEnumerable,"each_with_index", enum_each_with_index, 0);
id_eqq = rb_intern("===");
id_each = rb_intern("each");

11
env.h
View file

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

648
error.c
View file

@ -6,56 +6,46 @@
$Date$
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 "env.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>
#define va_init_list(a,b) va_start(a)
#endif
extern char *sourcefile;
extern int sourceline;
#ifdef USE_CWGUSI
#include <sys/errno.h>
int sys_nerr = 256;
#endif
int nerrs;
int ruby_nerrs;
static void
err_sprintf(buf, fmt, args)
err_snprintf(buf, len, fmt, args)
char *buf, *fmt;
int len;
va_list args;
{
if (!sourcefile) {
vsprintf(buf, fmt, args);
if (!ruby_sourcefile) {
vsnprintf(buf, len, fmt, args);
}
else {
sprintf(buf, "%s:%d: ", sourcefile, sourceline);
vsprintf((char*)buf+strlen(buf), 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);
int n = snprintf(buf, len, "%s:%d: ", ruby_sourcefile, ruby_sourceline);
if (len > n) {
vsnprintf((char*)buf+n, len-n, fmt, args);
}
}
}
static void err_append _((char*));
static void
err_print(fmt, args)
char *fmt;
@ -63,66 +53,102 @@ err_print(fmt, args)
{
char buf[BUFSIZ];
err_sprintf(buf, fmt, args);
err_snprintf(buf, BUFSIZ, fmt, args);
err_append(buf);
}
void
Error(fmt, va_alist)
#ifdef HAVE_STDARG_PROTOTYPES
rb_compile_error(char *fmt, ...)
#else
rb_compile_error(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list args;
va_start(args);
va_init_list(args, fmt);
err_print(fmt, args);
va_end(args);
nerrs++;
ruby_nerrs++;
}
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;
va_dcl
#endif
{
va_list args;
char buf[BUFSIZ];
va_start(args);
vsprintf(buf, fmt, args);
va_init_list(args, fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args);
err_append(buf);
}
void
Warning(fmt, va_alist)
#ifdef HAVE_STDARG_PROTOTYPES
rb_warn(char *fmt, ...)
#else
rb_warn(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
char buf[BUFSIZ];
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);
va_end(args);
}
void
Bug(fmt, va_alist)
#ifdef HAVE_STDARG_PROTOTYPES
rb_bug(char *fmt, ...)
#else
rb_bug(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
char buf[BUFSIZ];
va_list args;
sprintf(buf, "[BUG] %s", fmt);
snprintf(buf, BUFSIZ, "[BUG] %s", fmt);
rb_in_eval = 0;
va_start(args);
va_init_list(args, fmt);
err_print(buf, args);
va_end(args);
abort();
@ -156,94 +182,133 @@ static struct types {
-1, 0,
};
extern void TypeError();
void
rb_check_type(x, t)
VALUE x;
int t;
{
struct types *type = builtin_types;
int tt = TYPE(x);
if (TYPE(x)!=(t)) {
if (tt != t) {
while (type->type >= 0) {
if (type->type == t) {
TypeError("wrong argument type %s (expected %s)",
rb_class2name(CLASS_OF(x)), type->name);
char *etype;
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++;
}
Bug("unknown type 0x%x", t);
rb_bug("unknown type 0x%x", t);
}
}
/* exception classes */
#include "errno.h"
#include <errno.h>
extern VALUE cString;
VALUE eGlobalExit, eException;
VALUE eSystemExit, eInterrupt, eFatal;
VALUE eRuntimeError;
VALUE eSyntaxError;
VALUE eTypeError;
VALUE eArgError;
VALUE eNameError;
VALUE eIndexError;
VALUE eNotImpError;
VALUE eLoadError;
VALUE eSecurityError;
VALUE rb_eException;
VALUE rb_eSystemExit, rb_eInterrupt, rb_eFatal;
VALUE rb_eStandardError;
VALUE rb_eRuntimeError;
VALUE rb_eSyntaxError;
VALUE rb_eTypeError;
VALUE rb_eArgError;
VALUE rb_eNameError;
VALUE rb_eIndexError;
VALUE rb_eLoadError;
VALUE rb_eSecurityError;
VALUE rb_eNotImpError;
VALUE eSystemCallError;
VALUE mErrno;
VALUE rb_eSystemCallError;
VALUE rb_mErrno;
VALUE
exc_new(etype, ptr, len)
rb_exc_new(etype, ptr, len)
VALUE etype;
char *ptr;
UINT len;
int len;
{
NEWOBJ(exc, struct RString);
OBJSETUP(exc, etype, T_STRING);
VALUE exc = rb_obj_alloc(etype);
exc->len = len;
exc->orig = 0;
exc->ptr = ALLOC_N(char,len+1);
if (ptr) {
memcpy(exc->ptr, ptr, len);
}
exc->ptr[len] = '\0';
return (VALUE)exc;
rb_iv_set(exc, "mesg", rb_str_new(ptr, len));
return exc;
}
VALUE
exc_new2(etype, s)
rb_exc_new2(etype, s)
VALUE etype;
char *s;
{
return exc_new(etype, s, strlen(s));
return rb_exc_new(etype, s, strlen(s));
}
VALUE
exc_new3(etype, str)
rb_exc_new3(etype, str)
VALUE etype, str;
{
Check_Type(str, T_STRING);
return exc_new(etype, RSTRING(str)->ptr, RSTRING(str)->len);
char *s;
int len;
s = str2cstr(str, &len);
return rb_exc_new(etype, s, len);
}
static VALUE
exc_s_new(argc, argv, etype)
exc_initialize(argc, argv, exc)
int argc;
VALUE *argv;
VALUE etype;
VALUE exc;
{
VALUE arg;
VALUE mesg;
if (rb_scan_args(argc, argv, "01", &arg) == 0) {
return exc_new(etype, 0, 0);
if (rb_scan_args(argc, argv, "01", &mesg) == 1) {
STR2CSTR(mesg); /* ensure mesg can be converted to String */
}
Check_Type(arg, T_STRING);
return exc_new3(etype, arg);
rb_iv_set(exc, "mesg", mesg);
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
@ -253,185 +318,314 @@ exc_inspect(exc)
VALUE str, klass;
klass = CLASS_OF(exc);
exc = rb_obj_as_string(exc);
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);
str_cat(str, RSTRING(klass)->ptr, RSTRING(klass)->len);
str_cat(str, ":", 1);
str_cat(str, RSTRING(exc)->ptr, RSTRING(exc)->len);
str_cat(str, ">", 1);
rb_str_concat(str, klass);
rb_str_cat(str, ":", 1);
rb_str_concat(str, exc);
rb_str_cat(str, ">", 1);
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
exception(argc, argv)
int argc;
VALUE *argv;
{
void ArgError();
VALUE v = Qnil;
VALUE etype = rb_eStandardError;
int i;
ID id;
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 */
id = rb_to_id(argv[i]);
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)) {
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++) {
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;
}
#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;
#endif
#ifndef NT
extern int sys_nerr;
#endif
static void
static VALUE
set_syserr(i, name)
int i;
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) {
syserr_list[i] = rb_define_class_under(mErrno, name, eSystemCallError);
rb_global_variable(&syserr_list[i]);
syserr_list[i] = error;
}
#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
Init_Exception()
{
eGlobalExit = rb_define_class("GlobalExit", cString);
rb_define_singleton_method(eGlobalExit, "new", exc_s_new, -1);
rb_define_method(eGlobalExit, "inspect", exc_inspect, 0);
rb_eException = rb_define_class("Exception", rb_cObject);
rb_define_method(rb_eException, "new", exc_new, -1);
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);
eFatal = rb_define_class("fatal", eGlobalExit);
eInterrupt = rb_define_class("Interrupt", eGlobalExit);
rb_eSystemExit = rb_define_class("SystemExit", rb_eException);
rb_eFatal = rb_define_class("fatal", rb_eException);
rb_eInterrupt = rb_define_class("Interrupt", rb_eException);
eException = rb_define_class("Exception", eGlobalExit);
eSyntaxError = rb_define_class("SyntaxError", eException);
eTypeError = rb_define_class("TypeError", eException);
eArgError = rb_define_class("ArgumentError", eException);
eNameError = rb_define_class("NameError", eException);
eIndexError = rb_define_class("IndexError", eException);
eNotImpError = rb_define_class("NotImplementError", eException);
eLoadError = rb_define_class("LoadError", eException);
rb_eStandardError = rb_define_class("StandardError", rb_eException);
rb_eSyntaxError = rb_define_class("SyntaxError", rb_eStandardError);
rb_eTypeError = rb_define_class("TypeError", rb_eStandardError);
rb_eArgError = rb_define_class("ArgumentError", rb_eStandardError);
rb_eNameError = rb_define_class("NameError", rb_eStandardError);
rb_eIndexError = rb_define_class("IndexError", rb_eStandardError);
rb_eLoadError = rb_define_class("LoadError", rb_eStandardError);
eRuntimeError = rb_define_class("RuntimeError", eException);
eSecurityError = rb_define_class("SecurityError", eException);
rb_eRuntimeError = rb_define_class("RuntimeError", rb_eStandardError);
rb_eSecurityError = rb_define_class("SecurityError", rb_eStandardError);
rb_eNotImpError = rb_define_class("NotImplementError", rb_eException);
init_syserr();
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
Raise(exc, fmt, va_alist)
#ifdef HAVE_STDARG_PROTOTYPES
rb_raise(VALUE exc, char *fmt, ...)
#else
rb_raise(exc, fmt, va_alist)
VALUE exc;
char *fmt;
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
TypeError(fmt, va_alist)
#ifdef HAVE_STDARG_PROTOTYPES
rb_loaderror(char *fmt, ...)
#else
rb_loaderror(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
RAISE_ERROR(eTypeError);
}
va_list args;
char buf[BUFSIZ];
void
ArgError(fmt, va_alist)
char *fmt;
va_dcl
{
RAISE_ERROR(eArgError);
}
void
NameError(fmt, va_alist)
char *fmt;
va_dcl
{
RAISE_ERROR(eNameError);
}
void
IndexError(fmt, va_alist)
char *fmt;
va_dcl
{
RAISE_ERROR(eIndexError);
}
void
Fail(fmt, va_alist)
char *fmt;
va_dcl
{
RAISE_ERROR(eRuntimeError);
va_init_list(args, fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args);
rb_exc_raise(rb_exc_new2(rb_eLoadError, buf));
}
void
rb_notimplement()
{
Raise(eNotImpError,
"The %s() function is unimplemented on this machine",
rb_id2name(the_frame->last_func));
rb_raise(rb_eNotImpError,
"The %s() function is unimplemented on this machine",
rb_id2name(ruby_frame->last_func));
}
void
LoadError(fmt, va_alist)
char *fmt;
va_dcl
{
RAISE_ERROR(eLoadError);
}
void
Fatal(fmt, va_alist)
#ifdef HAVE_STDARG_PROTOTYPES
rb_fatal(char *fmt, ...)
#else
rb_fatal(fmt, va_alist)
char *fmt;
va_dcl
#endif
{
va_list args;
char buf[BUFSIZ];
va_start(args);
vsprintf(buf, fmt, args);
va_init_list(args, fmt);
vsnprintf(buf, BUFSIZ, fmt, args);
va_end(args);
rb_in_eval = 0;
rb_fatal(exc_new2(eFatal, buf));
rb_exc_fatal(rb_exc_new2(rb_eFatal, buf));
}
void
@ -441,32 +635,79 @@ rb_sys_fail(mesg)
#ifndef NT
char *strerror();
#endif
char buf[BUFSIZ];
char *err;
char *buf;
extern int errno;
int n = errno;
VALUE ee;
if (RTEST(mesg))
sprintf(buf, "%s - %s", strerror(errno), mesg);
else
sprintf(buf, "%s", strerror(errno));
err = strerror(errno);
if (mesg) {
buf = ALLOCA_N(char, strlen(err)+strlen(mesg)+4);
sprintf(buf, "%s - %s", err, mesg);
}
else {
buf = ALLOCA_N(char, strlen(err)+1);
strcpy(buf, err);
}
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]) {
char name[6];
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
init_syserr()
{
eSystemCallError = rb_define_class("SystemCallError", eException);
mErrno = rb_define_module("Errno");
#ifdef __BEOS__
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);
MEMZERO(syserr_list, VALUE, sys_nerr+1);
#endif
#ifdef EPERM
set_syserr(EPERM, "EPERM");
@ -835,3 +1076,28 @@ init_syserr()
set_syserr(EDQUOT, "EDQUOT");
#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
#tkutil
#tcltklib
#gtk

7
ext/Win32API/MANIFEST Normal file
View file

@ -0,0 +1,7 @@
MANIFEST
depend
MANIFEST
Win32API.c
extconf.rb
getch.rb
point.rb

223
ext/Win32API/Win32API.c Normal file
View file

@ -0,0 +1,223 @@
/*
Win32API - Ruby Win32 API Import Facility
*/
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
#define _T_VOID 0
#define _T_NUMBER 1
#define _T_POINTER 2
#define _T_INTEGER 3
typedef char *ApiPointer(void);
typedef long ApiNumber(void);
typedef void ApiVoid(void);
typedef int ApiInteger(void);
#include "ruby.h"
typedef struct {
HANDLE dll;
HANDLE proc;
VALUE dllname;
VALUE import;
VALUE export;
} Win32API;
static void
Win32API_FreeLibrary(hdll)
HINSTANCE hdll;
{
FreeLibrary(hdll);
}
static VALUE
Win32API_initialize(self, dllname, proc, import, export)
VALUE self;
VALUE dllname;
VALUE proc;
VALUE import;
VALUE export;
{
HANDLE hproc;
HINSTANCE hdll;
VALUE str;
VALUE a_import;
VALUE *ptr;
int i;
int len;
int ex;
hdll = GetModuleHandle(RSTRING(dllname)->ptr);
if (!hdll) {
hdll = LoadLibrary(RSTRING(dllname)->ptr);
if (!hdll)
Fail("LoadLibrary: %s\n", RSTRING(dllname)->ptr);
Data_Wrap_Struct(self, 0, Win32API_FreeLibrary, hdll);
}
hproc = GetProcAddress(hdll, RSTRING(proc)->ptr);
if (!hproc) {
str = str_new3(proc);
str = str_cat(str, "A", 1);
hproc = GetProcAddress(hdll, RSTRING(str)->ptr);
if (!hproc)
Fail("GetProcAddress: %s or %s\n",
RSTRING(proc)->ptr, RSTRING(str)->ptr);
}
rb_iv_set(self, "__dll__", INT2NUM((int)hdll));
rb_iv_set(self, "__dllname__", dllname);
rb_iv_set(self, "__proc__", INT2NUM((int)hproc));
a_import = ary_new();
ptr = RARRAY(import)->ptr;
for (i = 0, len = RARRAY(import)->len; i < len; i++) {
int c = *(char *)RSTRING(ptr[i])->ptr;
switch (c) {
case 'N': case 'n': case 'L': case 'l':
ary_push(a_import, INT2FIX(_T_NUMBER));
break;
case 'P': case 'p':
ary_push(a_import, INT2FIX(_T_POINTER));
break;
case 'I': case 'i':
ary_push(a_import, INT2FIX(_T_INTEGER));
break;
}
}
rb_iv_set(self, "__import__", a_import);
switch (*RSTRING(export)->ptr) {
case 'V': case 'v':
ex = _T_VOID;
break;
case 'N': case 'n': case 'L': case 'l':
ex = _T_NUMBER;
break;
case 'P': case 'p':
ex = _T_POINTER;
break;
case 'I': case 'i':
ex = _T_INTEGER;
break;
}
rb_iv_set(self, "__export__", INT2FIX(ex));
return Qnil;
}
static VALUE
Win32API_Call(argc, argv, obj)
VALUE argc;
VALUE argv;
VALUE obj;
{
VALUE args;
FARPROC ApiFunction;
ApiPointer *ApiFunctionPointer;
ApiNumber *ApiFunctionNumber;
ApiVoid *ApiFunctionVoid;
ApiInteger *ApiFunctionInteger;
long lParam;
char *pParam;
VALUE Return;
VALUE obj_proc;
VALUE obj_import;
VALUE obj_export;
VALUE import_type;
int nimport, timport, texport, i;
int items;
items = rb_scan_args(argc, argv, "0*", &args);
obj_proc = rb_iv_get(obj, "__proc__");
ApiFunction = (FARPROC)NUM2INT(obj_proc);
obj_import = rb_iv_get(obj, "__import__");
obj_export = rb_iv_get(obj, "__export__");
nimport = RARRAY(obj_import)->len;
texport = FIX2INT(obj_export);
if (items != nimport)
Fail("Wrong number of parameters: expected %d, got %d.\n",
nimport, items);
if (0 < nimport) {
for (i = nimport - 1; 0 <= i; i--) {
VALUE str;
import_type = ary_entry(obj_import, i);
timport = FIX2INT(import_type);
switch (timport) {
case _T_NUMBER:
case _T_INTEGER:
lParam = NUM2INT(ary_entry(args, i));
#if defined(_MSC_VER) || defined(__LCC__)
_asm {
mov eax, lParam
push eax
}
#elif defined(__CYGWIN32__) || defined(__MINGW32__)
asm volatile ("pushl %0" :: "g" (lParam));
#else
#error
#endif
break;
case _T_POINTER:
str = ary_entry(args, i);
Check_Type(str, T_STRING);
str_modify(str);
pParam = RSTRING(str)->ptr;
#if defined(_MSC_VER) || defined(__LCC__)
_asm {
mov eax, dword ptr pParam
push eax
}
#elif defined(__CYGWIN32__) || defined(__MINGW32__)
asm volatile ("pushl %0" :: "g" (pParam));
#else
#error
#endif
break;
}
}
}
switch (texport) {
case _T_NUMBER:
ApiFunctionNumber = (ApiNumber *) ApiFunction;
Return = INT2NUM(ApiFunctionNumber());
break;
case _T_POINTER:
ApiFunctionPointer = (ApiPointer *) ApiFunction;
Return = str_new2((char *)ApiFunctionPointer());
break;
case _T_INTEGER:
ApiFunctionInteger = (ApiInteger *) ApiFunction;
Return = INT2NUM(ApiFunctionInteger());
break;
case _T_VOID:
default:
ApiFunctionVoid = (ApiVoid *) ApiFunction;
ApiFunctionVoid();
Return = INT2NUM(0);
break;
}
return Return;
}
void
Init_Win32API()
{
VALUE cWin32API = rb_define_class("Win32API", cObject);
rb_define_method(cWin32API, "initialize", Win32API_initialize, 4);
rb_define_method(cWin32API, "call", Win32API_Call, -1);
rb_define_alias(cWin32API, "Call", "call");
}

7
ext/Win32API/extconf.rb Normal file
View file

@ -0,0 +1,7 @@
case PLATFORM
when /cygwin/,/mingw/
$CFLAGS = "-fno-defer-pop"
create_makefile("Win32API")
when /win32/
create_makefile("Win32API")
end

5
ext/Win32API/getch.rb Normal file
View file

@ -0,0 +1,5 @@
require 'Win32API'
getch = Win32API.new("crtdll", "_getch", [], 'L')
puts getch.Call.chr

18
ext/Win32API/point.rb Normal file
View file

@ -0,0 +1,18 @@
require 'Win32API'
getCursorPos = Win32API.new("user32", "GetCursorPos", ['P'], 'V')
lpPoint = " " * 8 # store two LONGs
getCursorPos.Call(lpPoint)
x, y = lpPoint.unpack("LL") # get the actual values
print "x: ", x, "\n"
print "y: ", y, "\n"
ods = Win32API.new("kernel32", "OutputDebugString", ['P'], 'V')
ods.Call("Hello, World\n");
GetDesktopWindow = Win32API.new("user32", "GetDesktopWindow", [], 'L')
GetActiveWindow = Win32API.new("user32", "GetActiveWindow", [], 'L')
SendMessage = Win32API.new("user32", "SendMessage", ['L'] * 4, 'L')
SendMessage.Call GetDesktopWindow.Call, 274, 0xf140, 0

View file

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

View file

@ -2,7 +2,7 @@
* ext/curses/curses.c
*
* 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
@ -12,12 +12,18 @@
# include <ncurses/curses.h>
# else
# include <curses.h>
# if defined(__NetBSD__) && !defined(_maxx)
# if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_maxx)
# define _maxx maxx
# endif
# if defined(__NetBSD__) && !defined(_maxy)
# if (defined(__bsdi__) || defined(__NetBSD__)) && !defined(_maxy)
# define _maxy maxy
# 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
@ -32,14 +38,10 @@ struct windata {
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
no_window()
{
Fail("already closed window");
rb_raise(rb_eRuntimeError, "already closed window");
}
#define GetWINDOW(obj, winp) {\
@ -55,6 +57,7 @@ free_window(winp)
{
if (winp->window && winp->window != stdscr) delwin(winp->window);
winp->window = 0;
free(winp);
}
static VALUE
@ -66,7 +69,7 @@ prep_window(class, window)
struct windata *winp;
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);
@ -83,7 +86,7 @@ curses_init_screen()
{
initscr();
if (stdscr == 0) {
Fail("cannot initialize curses");
rb_raise(rb_eRuntimeError, "cannot initialize curses");
}
clear();
rb_stdscr = prep_window(cWindow, stdscr);
@ -102,19 +105,33 @@ curses_stdscr()
static VALUE
curses_close_screen()
{
endwin();
#ifdef HAVE_ISENDWIN
if (!isendwin())
#endif
endwin();
return Qnil;
}
static void
curses_finalize()
{
if (stdscr
#ifdef HAVE_ISENDWIN
&& !isendwin()
#endif
)
endwin();
}
/* def closed? */
static VALUE
curses_closed()
{
#ifdef HAVE_ENDWIN
#ifdef HAVE_ISENDWIN
if (isendwin()) {
return TRUE;
return Qtrue;
}
return FALSE;
return Qfalse;
#else
rb_notimplement();
#endif
@ -138,12 +155,16 @@ curses_refresh(obj)
return Qnil;
}
/* def refresh */
/* def doupdate */
static VALUE
curses_doupdate(obj)
VALUE obj;
{
#ifdef HAVE_DOUPDATE
doupdate();
#else
refresh();
#endif
return Qnil;
}
@ -235,7 +256,9 @@ static VALUE
curses_flash(obj)
VALUE obj;
{
#ifdef HAVE_FLASH
flash();
#endif
return Qnil;
}
@ -287,7 +310,7 @@ static VALUE
curses_inch(obj)
VALUE obj;
{
return CHAR2FIX(inch());
return CHR2FIX(inch());
}
/* def addch(ch) */
@ -296,7 +319,7 @@ curses_addch(obj, ch)
VALUE obj;
VALUE ch;
{
addch(NUM2CHAR(ch));
addch(NUM2CHR(ch));
return Qnil;
}
@ -306,7 +329,7 @@ curses_insch(obj, ch)
VALUE obj;
VALUE ch;
{
insch(NUM2CHAR(ch));
insch(NUM2CHR(ch));
return Qnil;
}
@ -316,7 +339,9 @@ curses_addstr(obj, str)
VALUE obj;
VALUE str;
{
addstr(RSTRING(str)->ptr);
if (!NIL_P(str)) {
addstr(STR2CSTR(str));
}
return Qnil;
}
@ -325,7 +350,7 @@ static VALUE
curses_getch(obj)
VALUE obj;
{
return CHAR2FIX(getch());
return CHR2FIX(getch());
}
/* def getstr */
@ -335,7 +360,7 @@ curses_getstr(obj)
{
char rtn[1024]; /* This should be big enough.. I hope */
getstr(rtn);
return str_taint(str_new2(rtn));
return rb_tainted_str_new2(rtn);
}
/* def delch */
@ -352,7 +377,9 @@ static VALUE
curses_deleteln(obj)
VALUE obj;
{
#ifdef HAVE_DELETELN
deleteln();
#endif
return Qnil;
}
@ -379,11 +406,15 @@ window_s_new(class, lines, cols, top, left)
VALUE top;
VALUE left;
{
VALUE w;
WINDOW *window;
window = newwin(NUM2INT(lines), NUM2INT(cols), NUM2INT(top), NUM2INT(left));
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) */
@ -412,7 +443,8 @@ window_close(obj)
struct windata *winp;
GetWINDOW(obj, winp);
free_window(winp);
delwin(winp->window);
winp->window = 0;
return Qnil;
}
@ -453,7 +485,7 @@ window_box(obj, vert, hor)
struct windata *winp;
GetWINDOW(obj, winp);
box(winp->window, NUM2CHAR(vert), NUM2CHAR(hor));
box(winp->window, NUM2CHR(vert), NUM2CHR(hor));
return Qnil;
}
@ -622,7 +654,7 @@ window_inch(obj)
struct windata *winp;
GetWINDOW(obj, winp);
return CHAR2FIX(winch(winp->window));
return CHR2FIX(winch(winp->window));
}
/* def addch(ch) */
@ -634,7 +666,7 @@ window_addch(obj, ch)
struct windata *winp;
GetWINDOW(obj, winp);
waddch(winp->window, NUM2CHAR(ch));
waddch(winp->window, NUM2CHR(ch));
return Qnil;
}
@ -648,7 +680,7 @@ window_insch(obj, ch)
struct windata *winp;
GetWINDOW(obj, winp);
winsch(winp->window, NUM2CHAR(ch));
winsch(winp->window, NUM2CHR(ch));
return Qnil;
}
@ -659,11 +691,12 @@ window_addstr(obj, str)
VALUE obj;
VALUE str;
{
struct windata *winp;
GetWINDOW(obj, winp);
waddstr(winp->window, RSTRING(str)->ptr);
if (!NIL_P(str)) {
struct windata *winp;
GetWINDOW(obj, winp);
waddstr(winp->window, STR2CSTR(str));
}
return Qnil;
}
@ -685,7 +718,7 @@ window_getch(obj)
struct windata *winp;
GetWINDOW(obj, winp);
return CHAR2FIX(wgetch(winp->window));
return CHR2FIX(wgetch(winp->window));
}
/* def getstr */
@ -698,7 +731,7 @@ window_getstr(obj)
GetWINDOW(obj, winp);
wgetstr(winp->window, rtn);
return str_taint(str_new2(rtn));
return rb_tainted_str_new2(rtn);
}
/* def delch */
@ -718,10 +751,12 @@ static VALUE
window_deleteln(obj)
VALUE obj;
{
#ifdef HAVE_WDELETELN
struct windata *winp;
GetWINDOW(obj, winp);
wdeleteln(winp->window);
#endif
return Qnil;
}
@ -764,7 +799,7 @@ Init_curses()
rb_define_module_function(mCurses, "lines", curses_lines, 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_method(cWindow, "subwin", window_subwin, 4);
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, "delch", window_delch, 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"
$LDFLAGS="-L/usr/local/lib"
make=FALSE
have_library("mytinfo", "tgetent") if /bow/ =~ PLATFORM
if have_header("ncurses.h") and have_library("ncurses", "initscr")
make=TRUE
elsif have_header("ncurses/curses.h") and have_library("ncurses", "initscr")
@ -14,7 +17,7 @@ else
end
if make then
for f in ["isendwin", "ungetch", "beep"]
for f in %w(isendwin ungetch beep doupdate flash deleteln wdeleteln)
have_func(f)
end
create_makefile("curses")

View file

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

View file

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

90
ext/cygwin32_ld.rb Normal file
View file

@ -0,0 +1,90 @@
#!/usr/local/bin/ruby
require '../../rbconfig'
include Config
args = ARGV.join(" ")
objs = []
flags = []
libname = ''
Init = "../init"
path = ''
def writeInit
out = open("#{Init}.c", "w")
out.print %q@
#include <windows.h>
#include <stdio.h>
extern struct _reent *__imp_reent_data;
WINAPI dll_entry(int a, int b, int c)
{
_impure_ptr =__imp_reent_data;
return 1;
}
main(){}
//void impure_setup(struct _reent *_impure_ptrMain)
//{
// _impure_ptr =__imp_reent_data;
//}
@
out.close
end
def xsystem cmd
print cmd, "\n"
system cmd
end
if args =~ /-o (\w+)\.dll/i
libname = $1
# Check for path:
if libname =~ /(\w+\/)(\w+)$/
path = $1
libname = $2
end
for arg in ARGV
case arg
when /\.[oa]$/i
objs.push(arg)
when /-o/, /\w+\.dll/i
;
else
flags << arg
end
end
writeInit unless FileTest.exist?("#{Init}.c")
unless FileTest.exist?("#{Init}.o") and
File.mtime("#{Init}.c") < File.mtime("#{Init}.o")
xsystem "gcc -c #{Init}.c -o #{Init}.o"
end
command = "echo EXPORTS > #{libname}.def"
xsystem command
# xsystem "echo impure_setup >> #{libname}.def"
xsystem "nm --extern-only " + objs.join(" ") +
" | sed -n '/^........ [CDT] _/s///p' >> #{libname}.def"
command = "gcc -nostdlib -o junk.o -Wl,--base-file,#{libname}.base,--dll " +
objs.join(" ") + " #{Init}.o "
command.concat(flags.join(" ") +
" -Wl,-e,_dll_entry@12 -lcygwin -lkernel32 #{CONFIG['srcdir']}/libruby.a")
xsystem command
command = "dlltool --as=as --dllname #{libname}.dll --def #{libname}.def --base-file #{libname}.base --output-exp #{libname}.exp"
xsystem command
command = "gcc -s -nostdlib -o #{libname}.dll -Wl,--dll #{libname}.exp " +
objs.join(" ") + " #{Init}.o "
command.concat(flags.join(" ") +
" -Wl,-e,_dll_entry@12 -lcygwin -lkernel32 #{CONFIG['srcdir']}/libruby.a")
xsystem command
File.unlink "junk.o" if FileTest.exist? "junk.o"
else
# no special processing, just call ld
xsystem "ld #{args}"
end

View file

@ -6,7 +6,7 @@
$Date$
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 <fcntl.h>
#include <errno.h>
#ifdef USE_CWGUSI
# include <sys/errno.h>
#endif
VALUE cDBM;
extern VALUE mEnumerable;
struct dbmdata {
int di_size;
DBM *di_dbm;
@ -28,7 +29,7 @@ struct dbmdata {
static void
closed_dbm()
{
Fail("closed DBM file");
rb_raise(rb_eRuntimeError, "closed DBM file");
}
#define GetDBM(obj, dbmp) {\
@ -41,13 +42,14 @@ free_dbm(dbmp)
struct dbmdata *dbmp;
{
if (dbmp->di_dbm) dbm_close(dbmp->di_dbm);
free(dbmp);
}
static VALUE
fdbm_s_open(argc, argv, class)
fdbm_s_open(argc, argv, klass)
int argc;
VALUE *argv;
VALUE class;
VALUE klass;
{
VALUE file, vmode;
DBM *dbm;
@ -79,9 +81,10 @@ fdbm_s_open(argc, argv, class)
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_size = -1;
rb_obj_call_init(obj);
return obj;
}
@ -118,23 +121,23 @@ fdbm_fetch(obj, keystr)
if (value.dptr == 0) {
return Qnil;
}
return str_taint(str_new(value.dptr, value.dsize));
return rb_tainted_str_new(value.dptr, value.dsize);
}
static VALUE
fdbm_indexes(obj, ag)
VALUE obj, ag;
fdbm_indexes(argc, argv, obj)
int argc;
VALUE *argv;
VALUE obj;
{
VALUE *p, *pend;
VALUE new;
int i = 0;
struct RArray *args = RARRAY(rb_Array(ag));
int i;
new = ary_new2(args->len);
p = args->ptr; pend = p + args->len;
while (p < pend) {
ary_push(new, fdbm_fetch(obj, *p++));
new = rb_ary_new2(argc);
for (i=0; i<argc; i++) {
rb_ary_push(new, fdbm_fetch(obj, argv[i]));
}
return new;
}
@ -156,13 +159,13 @@ fdbm_delete(obj, keystr)
value = dbm_fetch(dbm, key);
if (value.dptr == 0) {
if (iterator_p()) rb_yield(keystr);
if (rb_iterator_p()) rb_yield(keystr);
return Qnil;
}
if (dbm_delete(dbm, key)) {
dbmp->di_size = -1;
Fail("dbm_delete failed");
rb_raise(rb_eRuntimeError, "dbm_delete failed");
}
else if (dbmp->di_size >= 0) {
dbmp->di_size--;
@ -188,9 +191,9 @@ fdbm_shift(obj)
val = dbm_fetch(dbm, key);
dbm_delete(dbm, key);
keystr = str_taint(str_new(key.dptr, key.dsize));
valstr = str_taint(str_new(val.dptr, val.dsize));
return assoc_new(keystr, valstr);
keystr = rb_tainted_str_new(key.dptr, key.dsize);
valstr = rb_tainted_str_new(val.dptr, val.dsize);
return rb_assoc_new(keystr, valstr);
}
static VALUE
@ -207,11 +210,11 @@ fdbm_delete_if(obj)
dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
keystr = str_taint(str_new(key.dptr, key.dsize));
valstr = str_taint(str_new(val.dptr, val.dsize));
if (RTEST(rb_yield(assoc_new(keystr, valstr)))) {
keystr = rb_tainted_str_new(key.dptr, key.dsize);
valstr = rb_tainted_str_new(val.dptr, val.dsize);
if (RTEST(rb_yield(rb_assoc_new(keystr, valstr)))) {
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;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
if (dbm_delete(dbm, key)) {
Fail("dbm_delete failed");
rb_raise(rb_eRuntimeError, "dbm_delete failed");
}
}
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
fdbm_store(obj, keystr, valstr)
VALUE obj, keystr, valstr;
@ -252,14 +314,14 @@ fdbm_store(obj, keystr, valstr)
}
rb_secure(4);
keystr = obj_as_string(keystr);
keystr = rb_obj_as_string(keystr);
key.dptr = RSTRING(keystr)->ptr;
key.dsize = RSTRING(keystr)->len;
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.dsize = RSTRING(valstr)->len;
@ -267,9 +329,11 @@ fdbm_store(obj, keystr, valstr)
dbmp->di_size = -1;
dbm = dbmp->di_dbm;
if (dbm_store(dbm, key, val, DBM_REPLACE)) {
#ifdef HAVE_DBM_CLAERERR
dbm_clearerr(dbm);
if (errno == EPERM) rb_sys_fail(Qnil);
Fail("dbm_store failed");
#endif
if (errno == EPERM) rb_sys_fail(0);
rb_raise(rb_eRuntimeError, "dbm_store failed");
}
return valstr;
@ -316,8 +380,8 @@ fdbm_empty_p(obj)
else {
i = dbmp->di_size;
}
if (i == 0) return TRUE;
return FALSE;
if (i == 0) return Qtrue;
return Qfalse;
}
static VALUE
@ -332,7 +396,7 @@ fdbm_each_value(obj)
dbm = dbmp->di_dbm;
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
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;
}
@ -348,7 +412,7 @@ fdbm_each_key(obj)
GetDBM(obj, dbmp);
dbm = dbmp->di_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;
}
@ -367,9 +431,9 @@ fdbm_each_pair(obj)
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
keystr = str_taint(str_new(key.dptr, key.dsize));
valstr = str_taint(str_new(val.dptr, val.dsize));
rb_yield(assoc_new(keystr, valstr));
keystr = rb_tainted_str_new(key.dptr, key.dsize);
valstr = rb_tainted_str_new(val.dptr, val.dsize);
rb_yield(rb_assoc_new(keystr, valstr));
}
return obj;
@ -387,9 +451,9 @@ fdbm_keys(obj)
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
ary = ary_new();
ary = rb_ary_new();
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;
@ -407,10 +471,10 @@ fdbm_values(obj)
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
ary = ary_new();
ary = rb_ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
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;
@ -431,8 +495,8 @@ fdbm_has_key(obj, keystr)
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
val = dbm_fetch(dbm, key);
if (val.dptr) return TRUE;
return FALSE;
if (val.dptr) return Qtrue;
return Qfalse;
}
static VALUE
@ -453,9 +517,9 @@ fdbm_has_value(obj, valstr)
val = dbm_fetch(dbm, key);
if (val.dsize == RSTRING(valstr)->len &&
memcmp(val.dptr, RSTRING(valstr)->ptr, val.dsize) == 0)
return TRUE;
return Qtrue;
}
return FALSE;
return Qfalse;
}
static VALUE
@ -470,26 +534,29 @@ fdbm_to_a(obj)
GetDBM(obj, dbmp);
dbm = dbmp->di_dbm;
ary = ary_new();
ary = rb_ary_new();
for (key = dbm_firstkey(dbm); key.dptr; key = dbm_nextkey(dbm)) {
val = dbm_fetch(dbm, key);
ary_push(ary, assoc_new(str_taint(str_new(key.dptr, key.dsize)),
str_taint(str_new(val.dptr, val.dsize))));
rb_ary_push(ary, rb_assoc_new(rb_tainted_str_new(key.dptr, key.dsize),
rb_tainted_str_new(val.dptr, val.dsize)));
}
return ary;
}
void
Init_dbm()
{
cDBM = rb_define_class("DBM", cObject);
rb_include_module(cDBM, mEnumerable);
cDBM = rb_define_class("DBM", rb_cObject);
rb_include_module(cDBM, rb_mEnumerable);
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, "[]", fdbm_fetch, 1);
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_alias(cDBM, "size", "length");
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_if", fdbm_delete_if, 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, "has_key?", fdbm_has_key, 1);
rb_define_method(cDBM, "has_value?", fdbm_has_value, 1);

View file

@ -1,5 +1,9 @@
require 'mkmf'
$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")
have_func("dbm_clearerr")
create_makefile("dbm")
end

View file

@ -37,7 +37,7 @@ etc_getlogin(obj)
#endif
if (login)
return str_new2(login);
return rb_tainted_str_new2(login);
return Qnil;
}
@ -47,34 +47,36 @@ setup_passwd(pwd)
struct passwd *pwd;
{
if (pwd == 0) rb_sys_fail("/etc/passwd");
return struct_new(sPasswd,
str_new2(pwd->pw_name),
str_new2(pwd->pw_passwd),
INT2FIX(pwd->pw_uid),
INT2FIX(pwd->pw_gid),
str_new2(pwd->pw_gecos),
str_new2(pwd->pw_dir),
str_new2(pwd->pw_shell),
return rb_struct_new(sPasswd,
rb_tainted_str_new2(pwd->pw_name),
rb_tainted_str_new2(pwd->pw_passwd),
INT2FIX(pwd->pw_uid),
INT2FIX(pwd->pw_gid),
#ifdef PW_GECOS
rb_tainted_str_new2(pwd->pw_gecos),
#endif
rb_tainted_str_new2(pwd->pw_dir),
rb_tainted_str_new2(pwd->pw_shell),
#ifdef PW_CHANGE
INT2FIX(pwd->pw_change),
INT2FIX(pwd->pw_change),
#endif
#ifdef PW_QUOTA
INT2FIX(pwd->pw_quota),
INT2FIX(pwd->pw_quota),
#endif
#ifdef PW_AGE
INT2FIX(pwd->pw_age),
INT2FIX(pwd->pw_age),
#endif
#ifdef PW_CLASS
str_new2(pwd->pw_class),
rb_tainted_str_new2(pwd->pw_class),
#endif
#ifdef PW_COMMENT
str_new2(pwd->pw_comment),
rb_tainted_str_new2(pwd->pw_comment),
#endif
#ifdef PW_EXPIRE
INT2FIX(pwd->pw_expire),
INT2FIX(pwd->pw_expire),
#endif
0 /*dummy*/
);
0 /*dummy*/
);
}
#endif
@ -96,7 +98,7 @@ etc_getpwuid(argc, argv, obj)
uid = getuid();
}
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);
#else
return Qnil;
@ -112,7 +114,7 @@ etc_getpwnam(obj, nam)
Check_Type(nam, T_STRING);
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);
#else
return Qnil;
@ -123,10 +125,10 @@ static VALUE
etc_passwd(obj)
VALUE obj;
{
#if defined(HAVE_GETPWENT) && !defined(__CYGWIN32__)
#if defined(HAVE_GETPWENT)
struct passwd *pw;
if (iterator_p()) {
if (rb_iterator_p()) {
setpwent();
while (pw = getpwent()) {
rb_yield(setup_passwd(pw));
@ -135,7 +137,7 @@ etc_passwd(obj)
return obj;
}
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);
#else
return Qnil;
@ -150,17 +152,17 @@ setup_group(grp)
VALUE mem;
char **tbl;
mem = ary_new();
mem = rb_ary_new();
tbl = grp->gr_mem;
while (*tbl) {
ary_push(mem, str_new2(*tbl));
rb_ary_push(mem, rb_tainted_str_new2(*tbl));
tbl++;
}
return struct_new(sGroup,
str_new2(grp->gr_name),
str_new2(grp->gr_passwd),
INT2FIX(grp->gr_gid),
mem);
return rb_struct_new(sGroup,
rb_tainted_str_new2(grp->gr_name),
rb_tainted_str_new2(grp->gr_passwd),
INT2FIX(grp->gr_gid),
mem);
}
#endif
@ -174,7 +176,7 @@ etc_getgrgid(obj, id)
gid = NUM2INT(id);
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);
#else
return Qnil;
@ -190,7 +192,7 @@ etc_getgrnam(obj, nam)
Check_Type(nam, T_STRING);
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);
#else
return Qnil;
@ -204,7 +206,7 @@ etc_group(obj)
#ifdef HAVE_GETGRENT
struct group *grp;
if (iterator_p()) {
if (rb_iterator_p()) {
setgrent();
while (grp = getgrent()) {
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, "group", etc_group, 0);
sPasswd = struct_define("Passwd",
"name", "passwd", "uid", "gid",
"gecos", "dir", "shell",
sPasswd = rb_struct_define("Passwd",
"name", "passwd", "uid", "gid",
#ifdef PW_GECOS
"gecos",
#endif
"dir", "shell",
#ifdef PW_CHANGE
"change",
"change",
#endif
#ifdef PW_QUOTA
"quota",
"quota",
#endif
#ifdef PW_AGE
"age",
"age",
#endif
#ifdef PW_CLASS
"class",
"class",
#endif
#ifdef PW_COMMENT
"comment",
"comment",
#endif
#ifdef PW_EXPIRE
"expire",
"expire",
#endif
0);
0);
rb_global_variable(&sPasswd);
#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);
#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
a = have_func("getlogin")
b = have_func("getpwent")
c = have_func("getgrent")
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")
end

View file

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

View file

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

View file

@ -5,7 +5,7 @@
$Author$
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 in, out;
int in_code, out_code;
char *codename = 0;
rb_scan_args(argc, argv, "12", &src, &out, &in);
Check_Type(src, T_STRING);
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 {
out_code = NUM2INT(out);
@ -1794,12 +1812,28 @@ kconv_kconv(argc, argv)
if (NIL_P(in)) {
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 {
in_code = NUM2INT(in);
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);
return dst;
@ -1813,7 +1847,7 @@ kconv_tojis(obj, src)
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);
return dst;
@ -1827,7 +1861,7 @@ kconv_toeuc(obj, src)
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);
return (VALUE)dst;
@ -1841,7 +1875,7 @@ kconv_tosjis(obj, src)
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);
return dst;
@ -1857,10 +1891,29 @@ static VALUE
kconv_guess(obj, src)
VALUE obj, src;
{
unsigned char *p = RSTRING(src)->ptr;
unsigned char *pend = p + RSTRING(src)->len;
unsigned char *p;
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) {
if (*p == '\033') {
@ -1874,37 +1927,41 @@ kconv_guess(obj, src)
if (0x81 <= *p && *p <= 0x8d) {
return INT2FIX(_SJIS);
}
if (*p == 0x8e) {
if (0x8f <= *p && *p <= 0x9f) {
return INT2FIX(_SJIS);
}
if (*p == 0x8e) { /* SS2 */
INCR;
if ((0x40 <= *p && *p <= 0x7e) ||
(0x80 <= *p && *p <= 0xa0) ||
(0xe0 <= *p && *p <= 0xfc))
return INT2FIX(_SJIS);
}
if (0xa1 <= *p && *p <= 0xdf) {
else if (0xa1 <= *p && *p <= 0xdf) {
INCR;
if (0xf0 <= *p && *p <= 0xfe)
return INT2FIX(_EUC);
if (0xe0 <= *p && *p <= 0xef) {
while (*p >= 0x40) {
while (p < pend && *p >= 0x40) {
if (*p >= 0x81) {
if (0x8d <= *p || (0x8f <= *p && *p <= 0x9f)) {
if (*p <= 0x8d || (0x8f <= *p && *p <= 0x9f)) {
return INT2FIX(_SJIS);
}
else if (0xfd <= *p && *p <= 0xfe) {
return INT2FIX(_EUC);
}
}
INCR;
}
}
if (*p <= 0x9f) {
else if (*p <= 0x9f) {
return INT2FIX(_SJIS);
}
}
if (0xf0 <= *p && *p <= 0xfe) {
else if (0xf0 <= *p && *p <= 0xfe) {
return INT2FIX(_EUC);
}
if (0xe0 <= *p && *p <= 0xef) {
else if (0xe0 <= *p && *p <= 0xef) {
INCR;
if ((0x40 <= *p && *p <= 0x7e) ||
(0x80 <= *p && *p <= 0xa0)) {
@ -1914,7 +1971,7 @@ kconv_guess(obj, src)
return INT2FIX(_EUC);
}
}
p++;
INCR;
}
return INT2FIX(_UNKNOWN);
}

View file

@ -5,7 +5,7 @@
$Author$
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,
@ -42,7 +42,7 @@ md5_digest(obj)
ctx = *md5;
MD5Final(digest, &ctx);
return str_new(digest, 16);
return rb_str_new(digest, 16);
}
static VALUE
@ -53,7 +53,7 @@ md5_clone(obj)
MD5_CTX *md5, *md5_new;
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;
return obj;
@ -61,6 +61,9 @@ md5_clone(obj)
static VALUE
md5_new(argc, argv, class)
int argc;
VALUE* argv;
VALUE class;
{
int i;
VALUE arg, obj;
@ -69,18 +72,19 @@ md5_new(argc, argv, class)
rb_scan_args(argc, argv, "01", &arg);
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);
if (!NIL_P(arg)) {
md5_update(obj, arg);
}
rb_obj_call_init(obj);
return obj;
}
Init_md5()
{
cMD5 = rb_define_class("MD5", cObject);
cMD5 = rb_define_class("MD5", rb_cObject);
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
when /mswin32/
test_func = "WSACleanup"
have_library("wsock32", "WSACleanup")
when /cygwin32/
test_func = "cygwin32_socket"
test_func = "socket"
when /beos/
test_func = "socket"
have_library("net", "socket")
else
test_func = "socket"
have_library("nsl", "t_open")
have_library("socket", "socket")
have_library("inet", "gethostbyname")
have_library("nsl", "gethostbyname")
end
have_header("sys/un.h")
if have_func(test_func)
have_func("inet_aton")
have_func("hsterror")
unless have_func("gethostname")
have_func("uname")

File diff suppressed because it is too large Load diff

View file

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

View file

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

View file

@ -5,22 +5,31 @@
*/
#include "ruby.h"
#include "sig.h"
#include "rubysig.h"
#include <stdio.h>
#include <string.h>
#include <tcl.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);}
#define DUMP2(ARG1, ARG2) if (debug) { fprintf(stderr, "tcltklib: ");\
/* for rb_debug */
#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"); }
/*
#define DUMP1(ARG1)
#define DUMP2(ARG1, ARG2)
*/
/* for callback break & continue */
VALUE eTkCallbackBreak;
VALUE eTkCallbackContinue;
/* from tkAppInit.c */
/*
@ -33,26 +42,52 @@ int *tclDummyMathPtr = (int *) matherr;
/*---- 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 */
static VALUE
lib_mainloop(VALUE self)
{
int old_trapflg;
int flags = RTEST(thread_safe)?TCL_DONT_WAIT:0;
Tk_TimerData *timer;
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");
while (Tk_GetNumMainWindows() > 0) {
old_trapflg = trap_immediate;
trap_immediate = 1;
Tcl_DoOneEvent(flags);
trap_immediate = old_trapflg;
CHECK_INTS;
flags = (thread_safe == 0 || thread_safe == Qnil)?0:TCL_DONT_WAIT;
Tcl_DoOneEvent(0);
}
DUMP1("stop Tk_Mainloop");
#ifdef USE_THREAD
if (timer->flag) {
Tk_DeleteTimerHandler(timer->token);
}
#endif
return Qnil;
}
@ -71,27 +106,49 @@ ip_eval_rescue(VALUE *failed, VALUE einfo)
}
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[])
#endif
{
VALUE res;
int old_trapflg;
VALUE failed = 0;
char *arg;
int dummy;
/* ruby command has 1 arg. */
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 */
DUMP2("rb_eval_string(%s)", argv[1]);
old_trapflg = trap_immediate;
trap_immediate = 0;
res = rb_rescue(rb_eval_string, argv[1], ip_eval_rescue, &failed);
trap_immediate = old_trapflg;
/* get C string from Tcl object */
#if TCL_MAJOR_VERSION >= 8
arg = Tcl_GetStringFromObj(argv[1], &dummy);
#else
arg = argv[1];
#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) {
Tcl_AppendResult(interp, RSTRING(failed)->ptr, (char*)NULL);
return TCL_ERROR;
VALUE eclass = CLASS_OF(failed);
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 */
@ -99,12 +156,11 @@ ip_ruby(ClientData clientData, Tcl_Interp *interp, int argc, char *argv[])
DUMP1("(rb_eval_string result) nil");
return TCL_OK;
}
Check_Type(res, T_STRING);
/* 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");
Tcl_AppendResult(interp, RSTRING(res)->ptr, (char *)NULL);
Tcl_AppendResult(interp, STR2CSTR(res), (char *)NULL);
return TCL_OK;
}
@ -115,6 +171,7 @@ ip_free(struct tcltkip *ptr)
{
DUMP1("Tcl_DeleteInterp");
Tcl_DeleteInterp(ptr->ip);
free(ptr);
}
/* create and initialize interpreter */
@ -135,20 +192,26 @@ ip_new(VALUE self)
/* from Tcl_AppInit() */
DUMP1("Tcl_Init");
if (Tcl_Init(ptr->ip) == TCL_ERROR) {
Fail("Tcl_Init");
rb_raise(rb_eRuntimeError, "Tcl_Init");
}
DUMP1("Tk_Init");
if (Tk_Init(ptr->ip) == TCL_ERROR) {
Fail("Tk_Init");
rb_raise(rb_eRuntimeError, "Tk_Init");
}
DUMP1("Tcl_StaticPackage(\"Tk\")");
Tcl_StaticPackage(ptr->ip, "Tk", Tk_Init,
(Tcl_PackageInitProc *) NULL);
/* 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\")");
Tcl_CreateCommand(ptr->ip, "ruby", ip_ruby, (ClientData *)NULL,
(Tcl_CmdDeleteProc *)NULL);
#endif
return obj;
}
@ -157,6 +220,7 @@ ip_new(VALUE self)
static VALUE
ip_eval(VALUE self, VALUE str)
{
char *s;
char *buf; /* Tcl_Eval requires re-writable string region */
struct tcltkip *ptr; /* tcltkip data struct */
@ -164,18 +228,162 @@ ip_eval(VALUE self, VALUE str)
Data_Get_Struct(self, struct tcltkip, ptr);
/* call Tcl_Eval() */
Check_Type(str, T_STRING);
buf = ALLOCA_N(char,RSTRING(str)->len+1);
strcpy(buf, RSTRING(str)->ptr);
s = STR2CSTR(str);
buf = ALLOCA_N(char, strlen(s)+1);
strcpy(buf, s);
DUMP2("Tcl_Eval(%s)", buf);
ptr->return_value = Tcl_Eval(ptr->ip, buf);
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);
/* 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() */
@ -190,27 +398,44 @@ ip_retval(VALUE self)
return (INT2FIX(ptr->return_value));
}
#ifdef __MACOS__
static void
_macinit()
{
tcl_macQdPtr = &qd; /* setup QuickDraw globals */
Tcl_MacSetEventProc(TkMacConvertEvent); /* setup event handler */
}
#endif
/*---- initialization ----*/
void Init_tcltklib()
{
extern VALUE rb_argv0; /* the argv[0] */
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_singleton_method(ip, "new", ip_new, 0);
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, "mainloop", lib_mainloop, 0);
#ifdef __MACOS__
_macinit();
#endif
/*---- initialize tcl/tk libraries ----*/
/* from Tk_Main() */
DUMP1("Tcl_FindExecutable");
Tcl_FindExecutable(RSTRING(rb_argv0)->ptr);
rb_define_variable("$tk_thread_safe", &thread_safe);
}
/* eof */

25
ext/tk/MANIFEST Normal file
View file

@ -0,0 +1,25 @@
MANIFEST
extconf.rb
depend
tkutil.c
lib/tk.rb
lib/tkafter.rb
lib/tkbgerror.rb
lib/tkcanvas.rb
lib/tkclass.rb
lib/tkdialog.rb
lib/tkentry.rb
lib/tkfont.rb
lib/tkmenubar.rb
lib/tkmngfocus.rb
lib/tkpalette.rb
lib/tkscrollbox.rb
lib/tktext.rb
lib/tkvirtevent.rb
sample/tkbiff.rb
sample/tkbrowse.rb
sample/tkdialog.rb
sample/tkfrom.rb
sample/tkhello.rb
sample/tkline.rb
sample/tktimer.rb

1
ext/tk/depend Normal file
View file

@ -0,0 +1 @@
tkutil.o: tkutil.c $(hdrdir)/ruby.h $(hdrdir)/config.h $(hdrdir)/defines.h

2
ext/tk/extconf.rb Normal file
View file

@ -0,0 +1,2 @@
require 'mkmf'
create_makefile("tkutil")

2499
ext/tk/lib/tk.rb Normal file

File diff suppressed because it is too large Load diff

296
ext/tk/lib/tkafter.rb Normal file
View file

@ -0,0 +1,296 @@
#
# tkafter.rb : methods for Tcl/Tk after command
# 1998/07/02 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>
#
require 'tk'
class TkAfter
include TkCore
extend TkCore
Tk_CBID = [0]
Tk_CBTBL = {}
INTERP._invoke("proc", "rb_after", "args", "ruby [format \"TkAfter.callback %%Q!%s!\" $args]")
###############################
# class methods
###############################
def TkAfter.callback(arg)
@after_id = nil
arg = Array(tk_split_list(arg))
obj_id = arg.shift
ex_obj = Tk_CBTBL[obj_id]
return nil if ex_obj == nil; # canceled
_get_eval_string(ex_obj.do_callback(*arg))
end
def TkAfter.info
tk_call('after', 'info').split(' ').filter{|id|
ret = Tk_CBTBL.find{|key,val| val.after_id == id}
(ret == nil)? id: ret[1]
}
end
###############################
# instance methods
###############################
def do_callback(*args)
@in_callback = true
ret = @current_proc.call(*args)
if @set_next
set_next_callback(*args)
else
@set_next = true
end
@in_callback = false
ret
end
def set_callback(sleep, args=nil)
@after_script = "rb_after #{@id} #{_get_eval_string(args)}"
@after_id = tk_call('after', sleep, @after_script)
@current_script = [sleep, @after_script]
end
def set_next_callback(*args)
if @running == false || @proc_max == 0 || @do_loop == 0
Tk_CBTBL[@id] = nil ;# for GC
@running = false
return
end
if @current_pos >= @proc_max
if @do_loop < 0 || (@do_loop -= 1) > 0
@current_pos = 0
else
Tk_CBTBL[@id] = nil ;# for GC
@running = false
return
end
end
@current_args = args
if @sleep_time.kind_of? Proc
sleep = @sleep_time.call(*args)
else
sleep = @sleep_time
end
@current_sleep = sleep
cmd, *cmd_args = @loop_proc[@current_pos]
@current_pos += 1
@current_proc = cmd
if cmd_args[0].kind_of? Proc
#c = cmd_args.shift
#cb_args = c.call(*(cmd_args + args))
cb_args = cmd_args[0].call(*args)
else
cb_args = cmd_args
end
set_callback(sleep, cb_args)
end
def initialize(*args)
@id = format("a%.4d", Tk_CBID[0])
Tk_CBID[0] += 1
@set_next = true
@init_sleep = 0
@init_proc = nil
@init_args = []
@current_script = []
@current_proc = nil
@current_args = nil
@sleep_time = 0
@current_sleep = 0
@loop_exec = 0
@do_loop = 0
@loop_proc = []
@proc_max = 0
@current_pos = 0
@after_id = nil
@after_script = nil
set_procs(*args) if args != []
@running = false
end
attr :after_id
attr :after_script
attr :current_proc
attr :current_sleep
attr_accessor :loop_exec
def get_procs
[@init_sleep, @init_proc, @init_args, @sleep_time, @loop_exec, @loop_proc]
end
def current_status
[@running, @current_sleep, @current_proc, @current_args, @do_loop]
end
def running?
@running
end
def loop_rest
@do_loop
end
def loop_rest=(rest)
@do_loop = rest
end
def set_procs(interval, loop_exec, *procs)
if !interval == 'idle' \
&& !interval.kind_of?(Integer) && !interval.kind_of?(Proc)
fail format("%s need to be Integer or Proc", interval.inspect)
end
@sleep_time = interval
@loop_proc = []
procs.each{|e|
if e.kind_of? Proc
@loop_proc.push([e])
else
@loop_proc.push(e)
end
}
@proc_max = @loop_proc.size
@current_pos = 0
@do_loop = 0
if loop_exec
if loop_exec.kind_of?(Integer) && loop_exec < 0
@loop_exec = -1
elsif loop_exec == nil || loop_exec == false || loop_exec == 0
@loop_exec = 1
else
if not loop_exec.kind_of?(Integer)
fail format("%s need to be Integer", loop_exec.inspect)
end
@loop_exec = loop_exec
end
@do_loop = @loop_exec
end
self
end
def add_procs(*procs)
procs.each{|e|
if e.kind_of? Proc
@loop_proc.push([e])
else
@loop_proc.push(e)
end
}
@proc_max = @loop_proc.size
self
end
def set_start_proc(sleep, init_proc, *init_args)
if !sleep == 'idle' && !sleep.kind_of?(Integer)
fail format("%s need to be Integer", sleep.inspect)
end
@init_sleep = sleep
@init_proc = init_proc
@init_args = init_args
self
end
def start(*init_args)
return nil if @running
Tk_CBTBL[@id] = self
@do_loop = @loop_exec
@current_pos = 0
argc = init_args.size
if argc > 0
sleep = init_args.shift
if !sleep == 'idle' && !sleep.kind_of?(Integer)
fail format("%s need to be Integer", sleep.inspect)
end
@init_sleep = sleep
end
@init_proc = init_args.shift if argc > 1
@init_args = init_args if argc > 0
@current_sleep = @init_sleep
@running = true
if @init_proc
if not @init_proc.kind_of? Proc
fail format("%s need to be Proc", @init_proc.inspect)
end
@current_proc = @init_proc
set_callback(sleep, @init_args)
@set_next = false if @in_callback
else
set_next_callback(*@init_args)
end
self
end
def restart(*restart_args)
cancel if @running
if restart_args == []
start(@init_sleep, @init_proc, *@init_args)
else
start(*restart_args)
end
end
def cancel
@running = false
tk_call 'after', 'cancel', @after_id if @after_id
@after_id = nil
Tk_CBTBL[@id] = nil ;# for GC
self
end
alias stop cancel
def continue(wait=nil)
sleep, cmd = @current_script
return nil if cmd == nil || @running == true
if wait
if not wait.kind_of? Integer
fail format("%s need to be Integer", wait.inspect)
end
sleep = wait
end
Tk_CBTBL[@id] = self
@running = true
@after_id = tk_call('after', sleep, cmd)
self
end
def skip
return nil if @running == false
cancel
Tk_CBTBL[@id] = self
@running = true
set_next_callback(@current_args)
self
end
def info
if @after_id
inf = tk_split_list(tk_call('after', 'info', @after_id))
[Tk_CBTBL[inf[0][1]], inf[1]]
else
nil
end
end
end

17
ext/tk/lib/tkbgerror.rb Normal file
View file

@ -0,0 +1,17 @@
#
# tkbgerror -- bgerror ( tkerror ) module
# 1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>
#
require 'tk'
module TkBgError
extend Tk
def bgerror(message)
tk_call 'bgerror', message
end
alias tkerror bgerror
alias show bgerror
module_function :bgerror, :tkerror, :show
end

829
ext/tk/lib/tkcanvas.rb Normal file
View file

@ -0,0 +1,829 @@
#
# tkcanvas.rb - Tk canvas classes
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp>
# $Date$
# by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>
require "tk"
require 'tkfont'
module TkTreatCItemFont
def tagfont_configinfo(tagOrId)
if tagOrId.kind_of?(TkcItem) || tagOrId.kind_of?(TkcTag)
pathname = self.path + ';' + tagOrId.id.to_s
else
pathname = self.path + ';' + tagOrId.to_s
end
ret = TkFont.used_on(pathname)
if ret == nil
ret = TkFont.init_widget_font(pathname,
self.path, 'itemconfigure', tagOrId)
end
ret
end
alias tagfontobj tagfont_configinfo
def tagfont_configure(tagOrId, slot)
if tagOrId.kind_of?(TkcItem) || tagOrId.kind_of?(TkcTag)
pathname = self.path + ';' + tagOrId.id.to_s
else
pathname = self.path + ';' + tagOrId.to_s
end
if (fnt = slot['font'])
slot['font'] = nil
if fnt.kind_of? TkFont
return fnt.call_font_configure(pathname,
self.path,'itemconfigure',tagOrId,slot)
else
latintagfont_configure(tagOrId, fnt) if fnt
end
end
if (ltn = slot['latinfont'])
slot['latinfont'] = nil
latintagfont_configure(tagOrId, ltn) if ltn
end
if (ltn = slot['asciifont'])
slot['asciifont'] = nil
latintagfont_configure(tagOrId, ltn) if ltn
end
if (knj = slot['kanjifont'])
slot['kanjifont'] = nil
kanjitagfont_configure(tagOrId, knj) if knj
end
tk_call(self.path, 'itemconfigure', tagOrId, *hash_kv(slot)) if slot != {}
self
end
def latintagfont_configure(tagOrId, ltn, keys=nil)
fobj = tagfontobj(tagOrId)
if ltn.kind_of? TkFont
conf = {}
ltn.latin_configinfo.each{|key,val| conf[key] = val if val != []}
if conf == {}
fobj.latin_replace(ltn)
fobj.latin_configure(keys) if keys
elsif keys
fobj.latin_configure(conf.update(keys))
else
fobj.latin_configure(conf)
end
else
fobj.latin_replace(ltn)
end
end
alias asciitagfont_configure latintagfont_configure
def kanjitagfont_configure(tagOrId, knj, keys=nil)
fobj = tagfontobj(tagOrId)
if knj.kind_of? TkFont
conf = {}
knj.kanji_configinfo.each{|key,val| conf[key] = val if val != []}
if conf == {}
fobj.kanji_replace(knj)
fobj.kanji_configure(keys) if keys
elsif keys
fobj.kanji_configure(conf.update(keys))
else
fobj.kanji_configure(conf)
end
else
fobj.kanji_replace(knj)
end
end
def tagfont_copy(tagOrId, window, wintag=nil)
if wintag
window.tagfontobj(wintag).configinfo.each{|key,value|
tagfontobj(tagOrId).configure(key,value)
}
tagfontobj(tagOrId).replace(window.tagfontobj(wintag).latin_font,
window.tagfontobj(wintag).kanji_font)
else
window.tagfont(tagOrId).configinfo.each{|key,value|
tagfontobj(tagOrId).configure(key,value)
}
tagfontobj(tagOrId).replace(window.fontobj.latin_font,
window.fontobj.kanji_font)
end
end
def latintagfont_copy(tagOrId, window, wintag=nil)
if wintag
tagfontobj(tagOrId).latin_replace(window.tagfontobj(wintag).latin_font)
else
tagfontobj(tagOrId).latin_replace(window.fontobj.latin_font)
end
end
alias asciitagfont_copy latintagfont_copy
def kanjitagfont_copy(tagOrId, window, wintag=nil)
if wintag
tagfontobj(tagOrId).kanji_replace(window.tagfontobj(wintag).kanji_font)
else
tagfontobj(tagOrId).kanji_replace(window.fontobj.kanji_font)
end
end
end
class TkCanvas<TkWindow
include TkTreatCItemFont
WidgetClassName = 'Canvas'.freeze
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
def self.to_eval
WidgetClassName
end
def create_self
tk_call 'canvas', path
end
def tagid(tag)
if tag.kind_of?(TkcItem) || tag.kind_of?(TkcTag)
tag.id
else
tag
end
end
private :tagid
def addtag(tag, mode, *args)
tk_send 'addtag', tagid(tag), mode, *args
end
def addtag_above(tagOrId, target)
addtag(tagOrId, 'above', tagid(target))
end
def addtag_all(tagOrId)
addtag(tagOrId, 'all')
end
def addtag_below(tagOrId, target)
addtag(tagOrId, 'below', tagid(target))
end
def addtag_closest(tagOrId, x, y, halo=None, start=None)
addtag(tagOrId, 'closest', x, y, halo, start)
end
def addtag_enclosed(tagOrId, x1, y1, x2, y2)
addtag(tagOrId, 'enclosed', x1, y1, x2, y2)
end
def addtag_overlapping(tagOrId, x1, y1, x2, y2)
addtag(tagOrId, 'overlapping', x1, y1, x2, y2)
end
def addtag_withtag(tagOrId, tag)
addtag(tagOrId, 'withtag', tagid(tag))
end
def bbox(tagOrId, *tags)
list(tk_send('bbox', tagid(tagOrId), *tags))
end
def itembind(tag, context, cmd=Proc.new, args=nil)
id = install_bind(cmd, args)
begin
tk_send 'bind', tagid(tag), "<#{tk_event_sequence(context)}>", id
rescue
uninstall_cmd(cmd)
fail
end
# @cmdtbl.push id
end
def itembindinfo(tag, context=nil)
if context
(tk_send('bind', tagid(tag),
"<#{tk_event_sequence(context)}>")).collect{|cmdline|
if cmdline =~ /^rb_out (c\d+)\s+(.*)$/
[Tk_CMDTBL[$1], $2]
else
cmdline
end
}
else
tk_split_list(tk_send 'bind', tagid(tag)).filter{|seq|
seq[1..-2].gsub(/></,',')
}
end
end
def canvasx(x, *args)
tk_tcl2ruby(tk_send 'canvasx', x, *args)
end
def canvasy(y, *args)
tk_tcl2ruby(tk_send 'canvasy', y, *args)
end
def coords(tag, *args)
if args == []
tk_split_list(tk_send('coords', tagid(tag)))
else
tk_send('coords', tagid(tag), *args)
end
end
def dchars(tag, first, last=None)
tk_send 'dchars', tagid(tag), first, last
end
def delete(*args)
tk_send 'delete', *args
end
alias remove delete
def dtag(tag, tag_to_del=None)
tk_send 'dtag', tagid(tag), tag_to_del
end
def find(mode, *args)
list(tk_send 'find', mode, *args).filter{|id|
TkcItem.id2obj(id)
}
end
def find_above(target)
find('above', tagid(target))
end
def find_all
find('all')
end
def find_below(target)
find('below', tagid(target))
end
def find_closest(x, y, halo=None, start=None)
find('closest', x, y, halo, start)
end
def find_enclosed(x1, y1, x2, y2)
find('enclosed', x1, y1, x2, y2)
end
def find_overlapping(x1, y1, x2, y2)
find('overlapping', x1, y1, x2, y2)
end
def find_withtag(tag)
find('withtag', tag)
end
def itemfocus(tagOrId=nil)
if tagOrId
tk_send 'focus', tagid(tagOrId)
else
ret = tk_send('focus')
if ret == ""
nil
else
TkcItem.id2obj(ret)
end
end
end
def gettags(tagOrId)
list(tk_send('gettags', tagid(tagOrId))).collect{|tag|
TkcTag.id2obj(tag)
}
end
def icursor(tagOrId, index)
tk_send 'icursor', tagid(tagOrId), index
end
def index(tagOrId, index)
tk_send 'index', tagid(tagOrId), index
end
def insert(tagOrId, index, string)
tk_send 'insert', tagid(tagOrId), index, string
end
def itemcget(tagOrId, option)
tk_tcl2ruby tk_send 'itemcget', tagid(tagOrId), "-#{option}"
end
def itemconfigure(tagOrId, key, value=None)
if key.kind_of? Hash
if ( key['font'] || key['kanjifont'] \
|| key['latinfont'] || key['asciifont'] )
tagfont_configure(tagOrId, key.dup)
else
tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key)
end
else
if ( key == 'font' || key == 'kanjifont' \
|| key == 'latinfont' || key == 'asciifont' )
tagfont_configure(tagid(tagOrId), {key=>value})
else
tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value
end
end
end
# def itemconfigure(tagOrId, key, value=None)
# if key.kind_of? Hash
# tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(key)
# else
# tk_send 'itemconfigure', tagid(tagOrId), "-#{key}", value
# end
# end
# def itemconfigure(tagOrId, keys)
# tk_send 'itemconfigure', tagid(tagOrId), *hash_kv(keys)
# end
def itemconfiginfo(tagOrId, key=nil)
if key
conf = tk_split_list(tk_send 'itemconfigure', tagid(tagOrId), "-#{key}")
conf[0] = conf[0][1..-1]
conf
else
tk_split_list(tk_send 'itemconfigure', tagid(tagOrId)).collect{|conf|
conf[0] = conf[0][1..-1]
conf
}
end
end
def lower(tag, below=None)
tk_send 'lower', tagid(tag), below
end
def move(tag, x, y)
tk_send 'move', tagid(tag), x, y
end
def postscript(keys)
tk_send "postscript", *hash_kv(keys)
end
def raise(tag, above=None)
tk_send 'raise', tagid(tag), above
end
def scale(tag, x, y, xs, ys)
tk_send 'scale', tagid(tag), x, y, xs, ys
end
def scan_mark(x, y)
tk_send 'scan', 'mark', x, y
end
def scan_dragto(x, y)
tk_send 'scan', 'dragto', x, y
end
def select(mode, *args)
tk_send 'select', mode, *args
end
def select_adjust(tagOrId, index)
select('adjust', tagid(tagOrId), index)
end
def select_clear
select('clear')
end
def select_from(tagOrId, index)
select('from', tagid(tagOrId), index)
end
def select_item
select('item')
end
def select_to(tagOrId, index)
select('to', tagid(tagOrId), index)
end
def itemtype(tag)
TkcItem.type2class(tk_send 'type', tagid(tag))
end
def xview(*index)
tk_send 'xview', *index
end
def yview(*index)
tk_send 'yview', *index
end
end
module TkcTagAccess
include TkComm
include TkTreatTagFont
def addtag(tag)
@c.addtag(tag, 'with', @id)
end
def bbox
@c.bbox(@id)
end
def bind(seq, cmd=Proc.new, args=nil)
@c.itembind @id, seq, cmd, args
end
def bindinfo(seq=nil)
@c.itembindinfo @id, seq
end
def cget(option)
@c.itemcget @id, option
end
def configure(key, value=None)
@c.itemconfigure @id, key, value
end
# def configure(keys)
# @c.itemconfigure @id, keys
# end
def configinfo(key=nil)
@c.itemconfiginfo @id, key
end
def coords(*args)
@c.coords @id, *args
end
def dchars(first, last=None)
@c.dchars @id, first, last
end
def dtag(tag_to_del=None)
@c.dtag @id, tag_to_del
end
def find
@c.find 'withtag', @id
end
alias list find
def focus
@c.itemfocus @id
end
def gettags
@c.gettags @id
end
def icursor(index)
@c.icursor @id, index
end
def index(index)
@c.index @id, index
end
def insert(beforethis, string)
@c.insert @id, beforethis, string
end
def lower(belowthis=None)
@c.lower @id, belowthis
end
def move(xamount, yamount)
@c.move @id, xamount, yamount
end
def raise(abovethis=None)
@c.raise @id, abovethis
end
def scale(xorigin, yorigin, xscale, yscale)
@c.scale @id, xorigin, yorigin, xscale, yscale
end
def select_adjust(index)
@c.select('adjust', @id, index)
end
def select_from(index)
@c.select('from', @id, index)
end
def select_to(index)
@c.select('to', @id, index)
end
def itemtype
@c.itemtype @id
end
end
class TkcTag<TkObject
include TkcTagAccess
CTagID_TBL = {}
def TkcTag.id2obj(id)
CTagID_TBL[id]? CTagID_TBL[id]: id
end
$tk_canvas_tag = 'ctag0000'
def initialize(parent, mode=nil, *args)
if not parent.kind_of?(TkCanvas)
fail format("%s need to be TkCanvas", parent.inspect)
end
@c = parent
@path = @id = $tk_canvas_tag
CTagID_TBL[@id] = self
$tk_canvas_tag = $tk_canvas_tag.succ
if mode
tk_call @c.path, "addtag", @id, mode, *args
end
end
def id
return @id
end
def delete
@c.delete @id
CTagID_TBL[@id] = nil
end
alias remove delete
alias destroy delete
def set_to_above(target)
@c.addtag_above(@id, target)
end
alias above set_to_above
def set_to_all
@c.addtag_all(@id)
end
alias all set_to_all
def set_to_below(target)
@c.addtag_below(@id, target)
end
alias below set_to_below
def set_to_closest(x, y, halo=None, start=None)
@c.addtag_closest(@id, x, y, halo, start)
end
alias closest set_to_closest
def set_to_enclosed(x1, y1, x2, y2)
@c.addtag_enclosest(@id, x1, y1, x2, y2)
end
alias enclosed set_to_enclosed
def set_to_overlapping(x1, y1, x2, y2)
@c.addtag_overlapping(@id, x1, y1, x2, y2)
end
alias overlapping set_to_overlapping
def set_to_withtag(target)
@c.addtag_withtag(@id, target)
end
alias withtag set_to_withtag
end
class TkcTagAll<TkcTag
def initialize(parent)
if not parent.kind_of?(TkCanvas)
fail format("%s need to be TkCanvas", parent.inspect)
end
@c = parent
@path = @id = 'all'
CTagID_TBL[@id] = self
end
end
class TkcTagCurrent<TkcTag
def initialize(parent)
if not parent.kind_of?(TkCanvas)
fail format("%s need to be TkCanvas", parent.inspect)
end
@c = parent
@path = @id = 'current'
CTagID_TBL[@id] = self
end
end
class TkcGroup<TkcTag
$tk_group_id = 'tkg00000'
def create_self(parent, *args)
if not parent.kind_of?(TkCanvas)
fail format("%s need to be TkCanvas", parent.inspect)
end
@c = parent
@path = @id = $tk_group_id
CTagID_TBL[@id] = self
$tk_group_id = $tk_group_id.succ
add(*args) if args != []
end
def include(*tags)
for i in tags
i.addtag @id
end
end
def exclude(*tags)
for i in tags
i.delete @id
end
end
end
class TkcItem<TkObject
include TkcTagAccess
CItemTypeToClass = {}
CItemID_TBL = {}
def TkcItem.type2class(type)
CItemTypeToClass[type]
end
def TkcItem.id2obj(id)
CItemID_TBL[id]? CItemID_TBL[id]: id
end
def initialize(parent, *args)
if not parent.kind_of?(TkCanvas)
fail format("%s need to be TkCanvas", parent.inspect)
end
@parent = @c = parent
@path = parent.path
if args[-1].kind_of? Hash
keys = args.pop
end
@id = create_self(*args).to_i ;# 'canvas item id' is integer number
CItemID_TBL[@id] = self
if keys
# tk_call @path, 'itemconfigure', @id, *hash_kv(keys)
configure(keys) if keys
end
end
def create_self(*args); end
private :create_self
def id
return @id
end
def delete
@c.delete @id
CItemID_TBL[@id] = nil
end
alias remove delete
alias destroy delete
end
class TkcArc<TkcItem
CItemTypeToClass['arc'] = self
def create_self(*args)
tk_call(@path, 'create', 'arc', *args)
end
end
class TkcBitmap<TkcItem
CItemTypeToClass['bitmap'] = self
def create_self(*args)
tk_call(@path, 'create', 'bitmap', *args)
end
end
class TkcImage<TkcItem
CItemTypeToClass['image'] = self
def create_self(*args)
tk_call(@path, 'create', 'image', *args)
end
end
class TkcLine<TkcItem
CItemTypeToClass['line'] = self
def create_self(*args)
tk_call(@path, 'create', 'line', *args)
end
end
class TkcOval<TkcItem
CItemTypeToClass['oval'] = self
def create_self(*args)
tk_call(@path, 'create', 'oval', *args)
end
end
class TkcPolygon<TkcItem
CItemTypeToClass['polygon'] = self
def create_self(*args)
tk_call(@path, 'create', 'polygon', *args)
end
end
class TkcRectangle<TkcItem
CItemTypeToClass['rectangle'] = self
def create_self(*args)
tk_call(@path, 'create', 'rectangle', *args)
end
end
class TkcText<TkcItem
CItemTypeToClass['text'] = self
def create_self(*args)
tk_call(@path, 'create', 'text', *args)
end
end
class TkcWindow<TkcItem
CItemTypeToClass['window'] = self
def create_self(*args)
tk_call(@path, 'create', 'window', *args)
end
end
class TkImage<TkObject
include Tk
Tk_IMGTBL = {}
$tk_image_id = 'i00000'
def initialize(keys=nil)
@path = $tk_image_id
$tk_image_id = $tk_image_id.succ
tk_call 'image', 'create', @type, @path, *hash_kv(keys)
Tk_IMGTBL[@path] = self
end
def delete
Tk_IMGTBL[@id] = nil if @id
tk_call('image', 'delete', @path)
end
def height
number(tk_call('image', 'height', @path))
end
def itemtype
tk_call('image', 'type', @path)
end
def width
number(tk_call('image', 'width', @path))
end
def TkImage.names
Tk.tk_call('image', 'names').split.filter{|id|
(Tk_IMGTBL[id])? Tk_IMGTBL[id] : id
}
end
def TkImage.types
Tk.tk_call('image', 'types').split
end
end
class TkBitmapImage<TkImage
def initialize(*args)
@type = 'bitmap'
super
end
end
class TkPhotoImage<TkImage
def initialize(*args)
@type = 'photo'
super
end
def blank
tk_send 'blank'
end
def cget(option)
tk_tcl2ruby tk_send 'cget', option
end
def copy(source, *opts)
args = opts.collect{|term|
if term.kind_of?(String) && term.include?(?\s)
term.split
else
term
end
}.flatten
tk_send 'copy', source, *args
end
def get(x, y)
tk_send 'get', x, y
end
def put(data, *to)
if to == []
tk_send 'put', data
else
tk_send 'put', data, '-to', *to
end
end
def read(file, *opts)
args = opts.collect{|term|
if term.kind_of?(String) && term.include?(?\s)
term.split
else
term
end
}.flatten
tk_send 'read', file, *args
end
def redither
tk_send 'redither'
end
def write(file, *opts)
args = opts.collect{|term|
if term.kind_of?(String) && term.include?(?\s)
term.split
else
term
end
}.flatten
tk_send 'write', file, *args
end
end

38
ext/tk/lib/tkclass.rb Normal file
View file

@ -0,0 +1,38 @@
#
# tkclass.rb - Tk classes
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp>
require "tk"
TopLevel = TkToplevel
Frame = TkFrame
Label = TkLabel
Button = TkButton
Radiobutton = TkRadioButton
Checkbutton = TkCheckButton
Message = TkMessage
Entry = TkEntry
Text = TkText
Scale = TkScale
Scrollbar = TkScrollbar
Listbox = TkListbox
Menu = TkMenu
Menubutton = TkMenubutton
Canvas = TkCanvas
Arc = TkcArc
Bitmap = TkcBitmap
Line = TkcLine
Oval = TkcOval
Polygon = TkcPolygon
Rectangle = TkcRectangle
TextItem = TkcText
WindowItem = TkcWindow
Selection = TkSelection
Winfo = TkWinfo
Pack = TkPack
Variable = TkVariable
def Mainloop
Tk.mainloop
end

141
ext/tk/lib/tkdialog.rb Normal file
View file

@ -0,0 +1,141 @@
require "tk"
class TkDialog < TkWindow
extend Tk
# initialize tk_dialog
def initialize(keys = nil)
super()
@var = TkVariable.new
id = @var.id
@title = title
@message = message
@message_config = message_config
@bitmap = bitmap
@bitmap_config = message_config
@default_button = default_button
@buttons = buttons
@button_configs = proc{|num| button_configs num}
if keys.kind_of? Hash
@title = keys['title'] if keys['title']
@message = keys['message'] if keys['message']
@bitmap = keys['bitmap'] if keys['bitmap']
@default_button = keys['default'] if keys['default']
@buttons = keys['buttons'] if keys['buttons']
@command = keys['prev_command']
@message_config = keys['message_config'] if keys['message_config']
@bitmap_config = keys['bitmap_config'] if keys['bitmap_config']
@button_configs = keys['button_configs'] if keys['button_configs']
end
if @title.include? ?\s
@title = '{' + @title + '}'
end
@buttons = tk_split_list(@buttons) if @buttons.kind_of? String
@buttons = @buttons.collect{|s|
if s.kind_of? Array
s = s.join(' ')
end
if s.include? ?\s
'{' + s + '}'
else
s
end
}
config = ""
if @message_config.kind_of? Hash
config << format("%s.msg configure %s\n",
@path, hash_kv(@message_config).join(' '))
end
if @bitmap_config.kind_of? Hash
config << format("%s.msg configure %s\n",
@path, hash_kv(@bitmap_config).join(' '))
end
if @button_configs.kind_of? Proc
@buttons.each_index{|i|
if (c = @button_configs.call(i)).kind_of? Hash
config << format("%s.button%s configure %s\n",
@path, i, hash_kv(c).join(' '))
end
}
end
config = 'after idle {' + config + '};' if config != ""
if @command.kind_of? Proc
@command.call(self)
end
INTERP._eval('eval {global '+id+';'+config+
'set '+id+' [tk_dialog '+
@path+" "+@title+" {#{@message}} "+@bitmap+" "+
String(@default_button)+" "+@buttons.join(' ')+']}')
end
def value
return @var.value.to_i
end
######################################################
# #
# these methods must be overridden for each dialog #
# #
######################################################
def title
return "DIALOG"
end
def message
return "MESSAGE"
end
def message_config
return nil
end
def bitmap
return "info"
end
def bitmap_config
return nil
end
def default_button
return 0
end
def buttons
#return "BUTTON1 BUTTON2"
return ["BUTTON1", "BUTTON2"]
end
def button_configs(num)
return nil
end
end
#
# dialog for warning
#
class TkWarning < TkDialog
def initialize(mes)
@mes = mes
super()
end
def message
return @mes
end
def title
return "WARNING";
end
def bitmap
return "warning";
end
def default_button
return 0;
end
def buttons
return "OK";
end
end

73
ext/tk/lib/tkentry.rb Normal file
View file

@ -0,0 +1,73 @@
#
# tkentry.rb - Tk entry classes
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp>
require 'tk.rb'
class TkEntry<TkLabel
WidgetClassName = 'Entry'.freeze
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
def self.to_eval
WidgetClassName
end
def create_self
tk_call 'entry', @path
end
def scrollcommand(cmd)
configure 'scrollcommand', cmd
end
def delete(s, e=None)
tk_send 'delete', s, e
end
def cursor
tk_send 'index', 'insert'
end
def cursor=(index)
tk_send 'icursor', index
end
def index(index)
number(tk_send('index', index))
end
def insert(pos,text)
tk_send 'insert', pos, text
end
def mark(pos)
tk_send 'scan', 'mark', pos
end
def dragto(pos)
tk_send 'scan', 'dragto', pos
end
def selection_adjust(index)
tk_send 'selection', 'adjust', index
end
def selection_clear
tk_send 'selection', 'clear', 'end'
end
def selection_from(index)
tk_send 'selection', 'from', index
end
def selection_present()
tk_send('selection', 'present') == 1
end
def selection_range(s, e)
tk_send 'selection', 'range', s, e
end
def selection_to(index)
tk_send 'selection', 'to', index
end
def xview(*index)
tk_send 'xview', *index
end
def value
tk_send 'get'
end
def value= (val)
tk_send 'delete', 0, 'end'
tk_send 'insert', 0, val
end
end

944
ext/tk/lib/tkfont.rb Normal file
View file

@ -0,0 +1,944 @@
#
# tkfont.rb - the class to treat fonts on Ruby/Tk
#
# by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
#
require 'tk'
class TkFont
include Tk
extend TkCore
Tk_FontID = [0]
Tk_FontNameTBL = {}
Tk_FontUseTBL = {}
DEFAULT_LATIN_FONT_NAME = 'a14'.freeze
DEFAULT_KANJI_FONT_NAME = 'k14'.freeze
###################################
# class methods
###################################
def TkFont.families(window=nil)
case (Tk::TK_VERSION)
when /^4\.*/
['fixed']
when /^8\.*/
if window
tk_split_simplelist(tk_call('font', 'families', '-displayof', window))
else
tk_split_simplelist(tk_call('font', 'families'))
end
end
end
def TkFont.names
case (Tk::TK_VERSION)
when /^4\.*/
r = ['fixed']
r += ['a14', 'k14'] if JAPANIZED_TK
Tk_FontNameTBL.each_value{|obj| r.push(obj)}
r | []
when /^8\.*/
tk_split_simplelist(tk_call('font', 'names'))
end
end
def TkFont.create_copy(font)
keys = {}
font.configure.each{|key,value| keys[key] = value }
new_font = TkFont.new(font.latin_font, font.kanji_font, keys)
end
def TkFont.get_obj(name)
if name =~ /^(@font[0-9]+)(|c|l|k)$/
Tk_FontNameTBL[$1]
else
nil
end
end
def TkFont.init_widget_font(path, *args)
case (Tk::TK_VERSION)
when /^4\.*/
conf = tk_split_simplelist(tk_call(*args)).
find_all{|prop| prop[0..5]=='-font ' || prop[0..10]=='-kanjifont '}.
collect{|prop| tk_split_simplelist(prop)}
if font_inf = conf.assoc('-font')
ltn = font_inf[4]
ltn = nil if ltn == []
else
#ltn = nil
raise RuntimeError, "unknown option '-font'"
end
if font_inf = conf.assoc('-kanjifont')
knj = font_inf[4]
knj = nil if knj == []
else
knj = nil
end
TkFont.new(ltn, knj).call_font_configure(path, *(args + [{}]))
when /^8\.*/
font_prop = tk_split_simplelist(tk_call(*args)).find{|prop|
prop[0..5] == '-font '
}
unless font_prop
raise RuntimeError, "unknown option '-font'"
end
fnt = tk_split_simplelist(font_prop)[4]
if fnt == ""
TkFont.new(nil, nil).call_font_configure(path, *(args + [{}]))
else
begin
compound = Hash[*list(tk_call('font', 'configure',
fnt))].collect{|key,value|
[key[1..-1], value]
}.assoc('compound')[1]
rescue
compound = []
end
if compound == []
TkFont.new(fnt, DEFAULT_KANJI_FONT_NAME) \
.call_font_configure(path, *(args + [{}]))
else
TkFont.new(compound[0], compound[1]) \
.call_font_configure(path, *(args + [{}]))
end
end
end
end
def TkFont.used_on(path=nil)
if path
Tk_FontUseTBL[path]
else
Tk_FontUseTBL.values | []
end
end
###################################
private
###################################
def initialize(ltn=nil, knj=nil, keys=nil)
@id = format("@font%.4d", Tk_FontID[0])
Tk_FontID[0] += 1
Tk_FontNameTBL[@id] = self
ltn = DEFAULT_LATIN_FONT_NAME unless ltn
create_latinfont(ltn)
knj = DEFAULT_KANJI_FONT_NAME unless knj
create_kanjifont(knj)
create_compoundfont(keys)
end
def _get_font_info_from_hash(font)
foundry = (info = font['foundry'] .to_s)? info: '*'
family = (info = font['family'] .to_s)? info: '*'
weight = (info = font['weight'] .to_s)? info: '*'
slant = (info = font['slant'] .to_s)? info: '*'
swidth = (info = font['swidth'] .to_s)? info: '*'
adstyle = (info = font['adstyle'] .to_s)? info: '*'
pixels = (info = font['pixels'] .to_s)? info: '*'
points = (info = font['points'] .to_s)? info: '*'
resx = (info = font['resx'] .to_s)? info: '*'
resy = (info = font['resy'] .to_s)? info: '*'
space = (info = font['space'] .to_s)? info: '*'
avgWidth = (info = font['avgWidth'].to_s)? info: '*'
charset = (info = font['charset'] .to_s)? info: '*'
encoding = (info = font['encoding'].to_s)? info: '*'
Array([foundry, family, weight, slant, swidth, adstyle,
pixels, points, resx, resy, space, avgWidth, charset, encoding])
end
def create_latinfont_tk4x(font)
if font.kind_of? Hash
@latinfont = '-' + _get_font_info_from_hash(font).join('-') + '-'
elsif font.kind_of? Array
finfo = {}
finfo['family'] = font[0].to_s
if font[1]
fsize = font[1].to_s
if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/
if $1 == '-'
finfo['pixels'] = $2
else
finfo['points'] = $2
end
else
finfo['points'] = '13'
end
end
font[2..-1].each{|style|
case (style)
when 'normal'
finfo['weight'] = style
when 'bold'
finfo['weight'] = style
when 'roman'
finfo['slant'] = 'r'
when 'italic'
finfo['slant'] = 'i'
end
}
@latinfont = '-' + _get_font_info_from_hash(finfo).join('-') + '-'
elsif font.kind_of? TkFont
@latinfont = font.latin_font
else
@latinfont = font
end
end
def create_kanjifont_tk4x(font)
unless JAPANIZED_TK
@kanjifont = ""
return
end
if font.kind_of? Hash
@kanjifont = '-' + _get_font_info_from_hash(font).join('-') + '-'
elsif font.kind_of? Array
finfo = {}
finfo['family'] = font[0].to_s
if font[1]
fsize = font[1].to_s
if fsize != '0' && fsize =~ /^(|\+|-)([0-9]+)$/
if $1 == '-'
finfo['pixels'] = $2
else
finfo['points'] = $2
end
else
finfo['points'] = '13'
end
end
font[2..-1].each{|style|
case (style)
when 'normal'
finfo['weight'] = style
when 'bold'
finfo['weight'] = style
when 'roman'
finfo['slant'] = 'r'
when 'italic'
finfo['slant'] = 'i'
end
}
@kanjifont = '-' + _get_font_info_from_hash(finfo).join('-') + '-'
elsif font.kind_of? TkFont
@kanjifont = font.kanji_font
else
@kanjifont = font
end
end
def create_compoundfont_tk4x(keys)
if JAPANIZED_TK
@compoundfont = [[@latinfont], [@kanjifont]]
@fontslot = {'font'=>@latinfont, 'kanjifont'=>@kanjifont}
else
@compoundfont = @latinfont
@fontslot = {'font'=>@latinfont}
end
end
def create_latinfont_tk8x(font)
@latinfont = @id + 'l'
if JAPANIZED_TK
if font.kind_of? Hash
tk_call('font', 'create', @latinfont, *hash_kv(font))
elsif font.kind_of? Array
tk_call('font', 'create', @latinfont, '-copy', array2tk_list(font))
elsif font.kind_of? TkFont
tk_call('font', 'create', @latinfont, '-copy', font.latin_font)
else
tk_call('font', 'create', @latinfont, '-copy', font)
end
else
if font.kind_of? Hash
tk_call('font', 'create', @latinfont, *hash_kv(font))
else
keys = {}
if font.kind_of? Array
actual_core(array2tk_list(font)).each{|key,val| keys[key] = val}
elsif font.kind_of? TkFont
actual_core(font.latin_font).each{|key,val| keys[key] = val}
else
actual_core(font).each{|key,val| keys[key] = val}
end
tk_call('font', 'create', @latinfont, *hash_kv(keys))
end
end
end
def create_kanjifont_tk80(font)
unless JAPANIZED_TK
@kanjifont = ""
return
end
@kanjifont = @id + 'k'
if font.kind_of? Hash
if font['charset']
tk_call('font', 'create', @kanjifont, *hash_kv(font))
else
tk_call('font', 'create', @kanjifont,
'-charset', 'jisx0208.1983', *hash_kv(font))
end
elsif font.kind_of? Array
tk_call('font', 'create', @kanjifont, '-copy', array2tk_list(font))
tk_call('font', 'configure', @kanjifont, '-charset', 'jisx0208.1983')
elsif font.kind_of? TkFont
tk_call('font', 'create', @kanjifont, '-copy', font.kanji_font)
else
tk_call('font', 'create', @kanjifont, '-copy', font,
'-charset', 'jisx0208.1983')
end
end
def create_kanjifont_tk81(font)
@kanjifont = @id + 'k'
if font.kind_of? Hash
tk_call('font', 'create', @kanjifont, *hash_kv(font))
else
keys = {}
if font.kind_of? Array
actual_core(array2tk_list(font)).each{|key,val| keys[key] = val}
elsif font.kind_of? TkFont
actual_core(font.kanji_font).each{|key,val| keys[key] = val}
else
actual_core(font).each{|key,val| keys[key] = val}
end
tk_call('font', 'create', @kanjifont, *hash_kv(keys))
end
keys = {}
actual_core(@kanjifont).each{|key,val| keys[key] = val}
begin
tk_call('font', 'configure', @compoundfont, *hash_kv(keys))
rescue
end
end
def create_compoundfont_tk80(keys)
@compoundfont = @id + 'c'
if JAPANIZED_TK
@fontslot = {'font'=>@compoundfont}
tk_call('font', 'create', @compoundfont,
'-compound', [@latinfont, @kanjifont], *hash_kv(keys))
else
tk_call('font', 'create', @compoundfont)
latinkeys = {}
begin
actual_core(@latinfont).each{|key,val| latinkeys[key] = val}
rescue
latinkeys {}
end
if latinkeys != {}
tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))
end
@fontslot = {'font'=>@compoundfont}
tk_call('font', 'configure', @compoundfont, *hash_kv(keys))
end
end
def create_compoundfont_tk81(keys)
@compoundfont = @id + 'c'
tk_call('font', 'create', @compoundfont)
latinkeys = {}
begin
actual_core(@latinfont).each{|key,val| latinkeys[key] = val}
rescue
latinkeys {}
end
if latinkeys != {}
tk_call('font', 'configure', @compoundfont, *hash_kv(latinkeys))
end
kanjikeys = {}
begin
actual_core(@kanjifont).each{|key,val| kanjikeys[key] = val}
rescue
kanjikeys {}
end
if kanjikeys != {}
tk_call('font', 'configure', @compoundfont, *hash_kv(kanjikeys))
end
@fontslot = {'font'=>@compoundfont}
tk_call('font', 'configure', @compoundfont, *hash_kv(keys))
end
def actual_core_tk4x(font, window=nil, option=nil)
# dummy
if option
""
else
Array([ ['family',[]], ['size',[]], ['weight',[]], ['slant',[]],
['underline',[]], ['overstrike',[]], ['charset',[]],
['pointadjust',[]] ])
end
end
def actual_core_tk8x(font, window=nil, option=nil)
if option == 'compound'
""
elsif option
if window
tk_call('font', 'actual', font, "-#{option}")
else
tk_call('font', 'actual', font, "-displayof", window, "-#{option}")
end
else
l = tk_split_simplelist(if window
tk_call('font', 'actual', font,
"-displayof", window)
else
tk_call('font', 'actual', font)
end)
r = []
while key=l.shift
if key == '-compound'
l.shift
else
r.push [key[1..-1], l.shift]
end
end
r
end
end
def configure_core_tk4x(font, slot, value=None)
""
end
def configinfo_core_tk4x(font, option=nil)
# dummy
if option
""
else
Array([ ['family',[]], ['size',[]], ['weight',[]], ['slant',[]],
['underline',[]], ['overstrike',[]], ['charset',[]],
['pointadjust',[]] ])
end
end
def configure_core_tk8x(font, slot, value=None)
if slot.kind_of? Hash
tk_call 'font', 'configure', font, *hash_kv(slot)
else
tk_call 'font', 'configure', font, "-#{slot}", value
end
end
def configinfo_core_tk8x(font, option=nil)
if option == 'compound'
""
elsif option
tk_call('font', 'configure', font, "-#{option}")
else
l = tk_split_simplelist(tk_call('font', 'configure', font))
r = []
while key=l.shift
if key == '-compound'
l.shift
else
r.push [key[1..-1], l.shift]
end
end
r
end
end
def delete_core_tk4x
Tk_FontNameTBL[@id] = nil
Tk_FontUseTBL.delete_if{|key,value| value == self}
end
def delete_core_tk8x
begin
tk_call('font', 'delete', @latinfont)
rescue
end
begin
tk_call('font', 'delete', @kanjifont)
rescue
end
begin
tk_call('font', 'delete', @compoundfont)
rescue
end
Tk_FontNameTBL[@id] = nil
Tk_FontUseTBL.delete_if{|key,value| value == self}
end
def latin_replace_core_tk4x(ltn)
create_latinfont_tk4x(ltn)
@compoundfont[0] = [@latinfont] if JAPANIZED_TK
@fontslot['font'] = @latinfont
Tk_FontUseTBL.dup.each{|w, fobj|
if self == fobj
begin
if w.include?(';')
win, tag = w.split(';')
winobj = tk_tcl2ruby(win)
# winobj.tagfont_configure(tag, {'font'=>@latinfont})
if winobj.kind_of? TkText
tk_call(win, 'tag', 'configure', tag, '-font', @latinfont)
elsif winobj.kind_of? TkCanvas
tk_call(win, 'itemconfigure', tag, '-font', @latinfont)
elsif winobj.kind_of? TkMenu
tk_call(win, 'entryconfigure', tag, '-font', @latinfont)
else
raise RuntimeError, "unknown widget type"
end
else
# tk_tcl2ruby(w).font_configure('font'=>@latinfont)
tk_call(w, 'configure', '-font', @latinfont)
end
rescue
Tk_FontUseTBL[w] = nil
end
end
}
self
end
def kanji_replace_core_tk4x(knj)
return self unless JAPANIZED_TK
create_kanjifont_tk4x(knj)
@compoundfont[1] = [@kanjifont]
@fontslot['kanjifont'] = @kanjifont
Tk_FontUseTBL.dup.each{|w, fobj|
if self == fobj
begin
if w.include?(';')
win, tag = w.split(';')
winobj = tk_tcl2ruby(win)
# winobj.tagfont_configure(tag, {'kanjifont'=>@kanjifont})
if winobj.kind_of? TkText
tk_call(win, 'tag', 'configure', tag, '-kanjifont', @kanjifont)
elsif winobj.kind_of? TkCanvas
tk_call(win, 'itemconfigure', tag, '-kanjifont', @kanjifont)
elsif winobj.kind_of? TkMenu
tk_call(win, 'entryconfigure', tag, '-kanjifont', @latinfont)
else
raise RuntimeError, "unknown widget type"
end
else
# tk_tcl2ruby(w).font_configure('kanjifont'=>@kanjifont)
tk_call(w, 'configure', '-kanjifont', @kanjifont)
end
rescue
Tk_FontUseTBL[w] = nil
end
end
}
self
end
def latin_replace_core_tk8x(ltn)
begin
tk_call('font', 'delete', @latinfont)
rescue
end
create_latinfont(ltn)
self
end
def kanji_replace_core_tk80(knj)
return self unless JAPANIZED_TK
begin
tk_call('font', 'delete', @kanjifont)
rescue
end
create_kanjifont(knj)
self
end
def kanji_replace_core_tk81(knj)
if font.kind_of? Hash
tk_call('font', 'configure', @compoundfont, *hash_kv(font))
else
keys = {}
if font.kind_of? Array
actual_core(array2tk_list(font)).each{|key,val| keys[key] = val}
elsif font.kind_of? TkFont
actual_core(font.latin_font).each{|key,val| keys[key] = val}
else
actual_core(font).each{|key,val| keys[key] = val}
end
tk_call('font', 'configure', @compoundfont, *hash_kv(keys))
end
self
end
def measure_core_tk4x(window, text)
0
end
def measure_core_tk8x(window, text)
if window
number(tk_call('font', 'measure', @compoundfont,
'-displayof', window, text))
else
number(tk_call('font', 'measure', @compoundfont, text))
end
end
def metrics_core_tk4x(font, window, option=nil)
# dummy
if option
""
else
Array([ ['ascent',[]], ['descent',[]], ['linespace',[]], ['fixed',[]] ])
end
end
def metrics_core_tk8x(font, window, option=nil)
if option
if window
number(tk_call('font', 'metrics', font, "-#{option}"))
else
number(tk_call('font', 'metrics', font,
"-displayof", window, "-#{option}"))
end
else
l = tk_split_list(if window
tk_call('font','metrics',font,"-displayof",window)
else
tk_call('font','metrics',font)
end)
r = []
while key=l.shift
r.push [key[1..-1], l.shift.to_i]
end
r
end
end
###################################
# private alias
###################################
case (Tk::TK_VERSION)
when /^4\.*/
alias create_latinfont create_latinfont_tk4x
alias create_kanjifont create_kanjifont_tk4x
alias create_compoundfont create_compoundfont_tk4x
alias actual_core actual_core_tk4x
alias configure_core configure_core_tk4x
alias configinfo_core configinfo_core_tk4x
alias delete_core delete_core_tk4x
alias latin_replace_core latin_replace_core_tk4x
alias kanji_replace_core kanji_replace_core_tk4x
alias measure_core measure_core_tk4x
alias metrics_core metrics_core_tk4x
when /^8\.0/
alias create_latinfont create_latinfont_tk8x
alias create_kanjifont create_kanjifont_tk80
alias create_compoundfont create_compoundfont_tk80
alias actual_core actual_core_tk8x
alias configure_core configure_core_tk8x
alias configinfo_core configinfo_core_tk8x
alias delete_core delete_core_tk8x
alias latin_replace_core latin_replace_core_tk8x
alias kanji_replace_core kanji_replace_core_tk80
alias measure_core measure_core_tk8x
alias metrics_core metrics_core_tk8x
when /^8\.1/
alias create_latinfont create_latinfont_tk8x
alias create_kanjifont create_kanjifont_tk81
alias create_compoundfont create_compoundfont_tk81
alias actual_core actual_core_tk8x
alias configure_core configure_core_tk8x
alias configinfo_core configinfo_core_tk8x
alias delete_core delete_core_tk8x
alias latin_replace_core latin_replace_core_tk8x
alias kanji_replace_core kanji_replace_core_tk81
alias measure_core measure_core_tk8x
alias metrics_core metrics_core_tk8x
end
###################################
public
###################################
def call_font_configure(path, *args)
args += hash_kv(args.pop.update(@fontslot))
tk_call *args
Tk_FontUseTBL[path] = self
self
end
def used
ret = []
Tk_FontUseTBL.each{|key,value|
if key.include?(';')
win, tag = key.split(';')
winobj = tk_tcl2ruby(win)
if winobj.kind_of? TkText
ret.push([winobj, winobj.tagid2obj(tag)])
elsif winobj.kind_of? TkCanvas
if (tagobj = TkcTag.id2obj(tag)).kind_of? TkcTag
ret.push([winobj, tagobj])
elsif (tagobj = TkcItem.id2obj(tag)).kind_of? TkcItem
ret.push([winobj, tagobj])
else
ret.push([winobj, tag])
end
elsif winobj.kind_of? TkMenu
ret.push([winobj, tag])
else
ret.push([win, tag])
end
else
ret.push(tk_tcl2ruby(key)) if value == self
end
}
ret
end
def id
@id
end
def to_eval
font
end
def font
@compoundfont
end
def latin_font
@latinfont
end
def kanji_font
@kanjifont
end
def actual(option=nil)
actual_core(@compoundfont, nil, option)
end
def actual_displayof(window, option=nil)
window = '.' unless window
actual_core(@compoundfont, window, option)
end
def latin_actual(option=nil)
actual_core(@latinfont, nil, option)
end
def latin_actual_displayof(window, option=nil)
window = '.' unless window
actual_core(@latinfont, window, option)
end
def kanji_actual(option=nil)
#if JAPANIZED_TK
if @kanjifont != ""
actual_core(@kanjifont, nil, option)
else
actual_core_tk4x(nil, nil, option)
end
end
def kanji_actual_displayof(window, option=nil)
#if JAPANIZED_TK
if @kanjifont != ""
window = '.' unless window
actual_core(@kanjifont, window, option)
else
actual_core_tk4x(nil, window, option)
end
end
def [](slot)
configinfo slot
end
def []=(slot, val)
configure slot, val
end
def configure(slot, value=None)
configure_core(@compoundfont, slot, value)
end
def configinfo(slot=nil)
configinfo_core(@compoundfont, slot)
end
def delete
delete_core
end
def latin_configure(slot, value=None)
if JAPANIZED_TK
configure_core(@latinfont, slot, value)
else
configure(slot, value)
end
end
def latin_configinfo(slot=nil)
if JAPANIZED_TK
configinfo_core(@latinfont, slot)
else
configure(slot, value)
end
end
def kanji_configure(slot, value=None)
#if JAPANIZED_TK
if @kanjifont != ""
configure_core(@kanjifont, slot, value)
else
#""
configure(slot, value)
end
end
def kanji_configinfo(slot=nil)
#if JAPANIZED_TK
if @kanjifont != ""
configinfo_core(@kanjifont, slot)
else
#[]
configinfo(slot)
end
end
def replace(ltn, knj)
latin_replace(ltn)
kanji_replace(knj)
self
end
def latin_replace(ltn)
latin_replace_core(ltn)
end
def kanji_replace(knj)
kanji_replace_core(knj)
end
def measure(text)
measure_core(nil, text)
end
def measure_displayof(window, text)
window = '.' unless window
measure_core(window, text)
end
def metrics(option=nil)
metrics_core(@compoundfont, nil, option)
end
def metrics_displayof(window, option=nil)
window = '.' unless window
metrics_core(@compoundfont, window, option)
end
def latin_metrics(option=nil)
metrics_core(@latinfont, nil, option)
end
def latin_metrics_displayof(window, option=nil)
window = '.' unless window
metrics_core(@latinfont, window, option)
end
def kanji_metrics(option=nil)
if JAPANIZED_TK
metrics_core(@kanjifont, nil, option)
else
metrics_core_tk4x(nil, nil, option)
end
end
def kanji_metrics_displayof(window, option=nil)
if JAPANIZED_TK
window = '.' unless window
metrics_core(@kanjifont, window, option)
else
metrics_core_tk4x(nil, window, option)
end
end
###################################
# public alias
###################################
alias ascii_font latin_font
alias create_asciifont create_latinfont
alias ascii_actual latin_actual
alias ascii_actual_displayof latin_actual_displayof
alias ascii_configure latin_configure
alias ascii_configinfo latin_configinfo
alias ascii_replace latin_replace
alias ascii_metrics latin_metrics
end
module TkTreatTagFont
def font_configinfo
@parent.tagfont_configinfo(@id)
end
alias font font_configinfo
def font_configure(slot)
@parent.tagfont_configure(@id, slot)
end
def latinfont_configure(ltn, keys=nil)
@parent.latintagfont_configure(@id, ltn, keys)
end
alias asciifont_configure latinfont_configure
def kanjifont_configure(knj, keys=nil)
@parent.kanjitagfont_configure(@id, ltn, keys)
end
def font_copy(window, wintag=nil)
@parent.tagfont_copy(@id, window, wintag)
end
def latinfont_copy(window, wintag=nil)
@parent.latintagfont_copy(@id, window, wintag)
end
alias asciifont_copy latinfont_copy
def kanjifont_copy(window, wintag=nil)
@parent.kanjitagfont_copy(@id, window, wintag)
end
end

137
ext/tk/lib/tkmenubar.rb Normal file
View file

@ -0,0 +1,137 @@
#
# tkmenubar.rb
#
# Copyright (C) 1998 maeda shugo. All rights reserved.
# This file can be distributed under the terms of the Ruby.
# Usage:
#
# menu_spec = [
# [['File', 0],
# ['Open', proc{puts('Open clicked')}, 0],
# '---',
# ['Quit', proc{exit}, 0]],
# [['Edit', 0],
# ['Cut', proc{puts('Cut clicked')}, 2],
# ['Copy', proc{puts('Copy clicked')}, 0],
# ['Paste', proc{puts('Paste clicked')}, 0]]
# ]
# menubar = TkMenubar.new(nil, menu_spec,
# 'tearoff'=>false,
# 'foreground'=>'grey40',
# 'activeforeground'=>'red',
# 'font'=>'-adobe-helvetica-bold-r-*--12-*-iso8859-1')
# menubar.pack('side'=>'top', 'fill'=>'x')
#
#
# OR
#
#
# menubar = TkMenubar.new
# menubar.add_menu([['File', 0],
# ['Open', proc{puts('Open clicked')}, 0],
# '---',
# ['Quit', proc{exit}, 0]])
# menubar.add_menu([['Edit', 0],
# ['Cut', proc{puts('Cut clicked')}, 2],
# ['Copy', proc{puts('Copy clicked')}, 0],
# ['Paste', proc{puts('Paste clicked')}, 0]])
# menubar.configure('tearoff', false)
# menubar.configure('foreground', 'grey40')
# menubar.configure('activeforeground', 'red')
# menubar.configure('font', '-adobe-helvetica-bold-r-*--12-*-iso8859-1')
# menubar.pack('side'=>'top', 'fill'=>'x')
# The format of the menu_spec is:
# [
# [
# [button text, underline, accelerator],
# [menu label, command, underline, accelerator],
# '---', # separator
# ...
# ],
# ...
# ]
# underline and accelerator are optional parameters.
# Hashes are OK instead of Arrays.
# To use add_menu, configuration must be done by calling configure after
# adding all menus by add_menu, not by the constructor arguments.
require "tk"
class TkMenubar<TkFrame
include TkComposite
def initialize(parent = nil, spec = nil, options = nil)
super(parent, options)
@menus = []
if spec
for menu_info in spec
add_menu(menu_info)
end
end
if options
for key, value in options
configure(key, value)
end
end
end
def add_menu(menu_info)
btn_info = menu_info.shift
mbtn = TkMenubutton.new(@frame)
if btn_info.kind_of?(Hash)
for key, value in btn_info
mbtn.configure(key, value)
end
elsif btn_info.kind_of?(Array)
mbtn.configure('text', btn_info[0]) if btn_info[0]
mbtn.configure('underline', btn_info[1]) if btn_info[1]
mbtn.configure('accelerator', btn_info[2]) if btn_info[2]
else
mbtn.configure('text', btn_info)
end
menu = TkMenu.new(mbtn)
for item_info in menu_info
if item_info.kind_of?(Hash)
menu.add('command', item_info)
elsif item_info.kind_of?(Array)
options = {}
options['label'] = item_info[0] if item_info[0]
options['command'] = item_info[1] if item_info[1]
options['underline'] = item_info[2] if item_info[2]
options['accelerator'] = item_info[3] if item_info[3]
menu.add('command', options)
elsif /^-+$/ =~ item_info
menu.add('sep')
else
menu.add('command', 'label' => item_info)
end
end
mbtn.menu(menu)
@menus.push([mbtn, menu])
delegate('tearoff', menu)
delegate('foreground', mbtn, menu)
delegate('background', mbtn, menu)
delegate('disabledforeground', mbtn, menu)
delegate('activeforeground', mbtn, menu)
delegate('activebackground', mbtn, menu)
delegate('font', mbtn, menu)
delegate('kanjifont', mbtn, menu)
mbtn.pack('side' => 'left')
end
def [](index)
return @menus[index]
end
end

27
ext/tk/lib/tkmngfocus.rb Normal file
View file

@ -0,0 +1,27 @@
#
# tkmngfocus.rb : methods for Tcl/Tk standard library 'focus.tcl'
# 1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>
#
require 'tk'
module TkManageFocus
extend Tk
def TkManageFocus.followsMouse
tk_call 'tk_focusFollowsMouse'
end
def TkManageFocus.next(window)
tk_call 'tk_focusNext', window
end
def focusNext
TkManageFocus.next(self)
end
def TkManageFocus.prev(window)
tk_call 'tk_focusPrev', window
end
def focusPrev
TkManageFocus.prev(self)
end
end

48
ext/tk/lib/tkpalette.rb Normal file
View file

@ -0,0 +1,48 @@
#
# tkpalette.rb : methods for Tcl/Tk standard library 'palette.tcl'
# 1998/06/21 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>
#
require 'tk'
module TkPalette
include Tk
extend Tk
def TkPalette.set(*args)
args = args.to_a.flatten if args.kind_of? Hash
tk_call 'tk_setPalette', *args
end
def TkPalette.setPalette(*args)
TkPalette.set(*args)
end
def TkPalette.bisque
tk_call 'tk_bisque'
end
def TkPalette.darken(color, percent)
tk_call 'tkDarken', color, percent
end
def TkPalette.recolorTree(window, colors)
if not colors.kind_of?(Hash)
fail "2nd arg need to be Hash"
end
colors.each{|key, value|
begin
if window.cget(key) == tk_call('set', "tkPalette(#{key})")
window[key] = colors[key]
end
rescue
# ignore
end
}
TkWinfo.children(window).each{|w| TkPalette.recolorTree(w, colors)}
end
def recolorTree(colors)
TkPalette.recolorTree(self, colors)
end
end

27
ext/tk/lib/tkscrollbox.rb Normal file
View file

@ -0,0 +1,27 @@
#
# tkscrollbox.rb - Tk Listbox with Scrollbar
# as an example of Composite Widget
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp>
require 'tk.rb'
class TkScrollbox<TkListbox
include TkComposite
def initialize_composite
list = TkListbox.new(@frame)
scroll = TkScrollbar.new(@frame)
@path = list.path
list.configure 'yscroll', scroll.path+" set"
list.pack 'side'=>'left','fill'=>'both','expand'=>'yes'
scroll.configure 'command', list.path+" yview"
scroll.pack 'side'=>'right','fill'=>'y'
delegate('DEFAULT', list)
delegate('foreground', list)
delegate('background', list, scroll)
delegate('borderwidth', @frame)
delegate('relief', @frame)
end
end

797
ext/tk/lib/tktext.rb Normal file
View file

@ -0,0 +1,797 @@
#
# tktext.rb - Tk text classes
# $Date$
# by Yukihiro Matsumoto <matz@caelum.co.jp>
require 'tk.rb'
require 'tkfont'
module TkTreatTextTagFont
def tagfont_configinfo(tag)
if tag.kind_of? TkTextTag
pathname = self.path + ';' + tag.id
else
pathname = self.path + ';' + tag
end
ret = TkFont.used_on(pathname)
if ret == nil
ret = TkFont.init_widget_font(pathname,
self.path, 'tag', 'configure', tag)
end
ret
end
alias tagfontobj tagfont_configinfo
def tagfont_configure(tag, slot)
if tag.kind_of? TkTextTag
pathname = self.path + ';' + tag.id
else
pathname = self.path + ';' + tag
end
if (fnt = slot['font'])
slot['font'] = nil
if fnt.kind_of? TkFont
return fnt.call_font_configure(pathname,
self.path,'tag','configure',tag,slot)
else
latintagfont_configure(tag, fnt) if fnt
end
end
if (ltn = slot['latinfont'])
slot['latinfont'] = nil
latintagfont_configure(tag, ltn) if ltn
end
if (ltn = slot['asciifont'])
slot['asciifont'] = nil
latintagfont_configure(tag, ltn) if ltn
end
if (knj = slot['kanjifont'])
slot['kanjifont'] = nil
kanjitagfont_configure(tag, knj) if knj
end
tk_call(self.path, 'tag', 'configure', tag, *hash_kv(slot)) if slot != {}
self
end
def latintagfont_configure(tag, ltn, keys=nil)
fobj = tagfontobj(tag)
if ltn.kind_of? TkFont
conf = {}
ltn.latin_configinfo.each{|key,val| conf[key] = val if val != []}
if conf == {}
fobj.latin_replace(ltn)
fobj.latin_configure(keys) if keys
elsif keys
fobj.latin_configure(conf.update(keys))
else
fobj.latin_configure(conf)
end
else
fobj.latin_replace(ltn)
end
end
alias asciitagfont_configure latintagfont_configure
def kanjitagfont_configure(tag, knj, keys=nil)
fobj = tagfontobj(tag)
if knj.kind_of? TkFont
conf = {}
knj.kanji_configinfo.each{|key,val| conf[key] = val if val != []}
if conf == {}
fobj.kanji_replace(knj)
fobj.kanji_configure(keys) if keys
elsif keys
fobj.kanji_configure(conf.update(keys))
else
fobj.kanji_configure(conf)
end
else
fobj.kanji_replace(knj)
end
end
def tagfont_copy(tag, window, wintag=nil)
if wintag
window.tagfontobj(wintag).configinfo.each{|key,value|
tagfontobj(tag).configure(key,value)
}
tagfontobj(tag).replace(window.tagfontobj(wintag).latin_font,
window.tagfontobj(wintag).kanji_font)
else
window.tagfont(wintag).configinfo.each{|key,value|
tagfontobj(tag).configure(key,value)
}
tagfontobj(tag).replace(window.fontobj.latin_font,
window.fontobj.kanji_font)
end
end
def latintagfont_copy(tag, window, wintag=nil)
if wintag
tagfontobj(tag).latin_replace(window.tagfontobj(wintag).latin_font)
else
tagfontobj(tag).latin_replace(window.fontobj.latin_font)
end
end
alias asciitagfont_copy latintagfont_copy
def kanjitagfont_copy(tag, window, wintag=nil)
if wintag
tagfontobj(tag).kanji_replace(window.tagfontobj(wintag).kanji_font)
else
tagfontobj(tag).kanji_replace(window.fontobj.kanji_font)
end
end
end
class TkText<TkTextWin
include TkTreatTextTagFont
WidgetClassName = 'Text'.freeze
TkClassBind::WidgetClassNameTBL[WidgetClassName] = self
def self.to_eval
WidgetClassName
end
include Scrollable
def create_self
tk_call 'text', @path
@tags = {}
end
def index(index)
tk_send 'index', index
end
def value
tk_send 'get', "1.0", "end - 1 char"
end
def value= (val)
tk_send 'delete', "1.0", 'end'
tk_send 'insert', "1.0", val
end
def _addcmd(cmd)
@cmdtbl.push cmd
end
def _addtag(name, obj)
@tags[name] = obj
end
def tagid2obj(tagid)
if not @tags[tagid]
tagid
else
@tags[tagid]
end
end
def tag_names(index=None)
tk_split_list(tk_send('tag', 'names', index)).collect{|elt|
tagid2obj(elt)
}
end
def window_names
tk_send('window', 'names').collect{|elt|
tagid2obj(elt)
}
end
def image_names
tk_send('image', 'names').collect{|elt|
tagid2obj(elt)
}
end
def set_insert(index)
tk_send 'mark', 'set', 'insert', index
end
def set_current(index)
tk_send 'mark', 'set', 'current', index
end
def insert(index, chars, *tags)
super index, chars, tags.collect{|x|_get_eval_string(x)}.join(' ')
end
def destroy
@tags.each_value do |t|
t.destroy
end
super
end
def backspace
self.delete 'insert'
end
def compare(idx1, op, idx2)
bool(tk_send('compare', idx1, op, idx2))
end
def debug
bool(tk_send('debug'))
end
def debug=(boolean)
tk_send 'debug', boolean
end
def bbox(index)
inf = tk_send('bbox', index)
(inf == "")? [0,0,0,0]: inf
end
def dlineinfo(index)
inf = tk_send('dlineinfo', index)
(inf == "")? [0,0,0,0,0]: inf
end
def yview(*what)
tk_send 'yview', *what
end
def yview_pickplace(*what)
tk_send 'yview', '-pickplace', *what
end
def xview(*what)
tk_send 'xview', *what
end
def xview_pickplace(*what)
tk_send 'xview', '-pickplace', *what
end
def tag_add(tag,index1,index2=None)
tk_send 'tag', 'add', tag, index1, index2
end
def _tag_bind_core(mode, tag, seq, cmd=Proc.new, args=nil)
id = install_bind(cmd, args)
tk_send 'tag', 'bind', tag, "<#{tk_event_sequence(seq)}>", mode + id
# _addcmd cmd
end
private :_tag_bind_core
def tag_bind(tag, seq, cmd=Proc.new, args=nil)
_tag_bind_core('', tag, seq, cmd=Proc.new, args=nil)
end
def tag_bind_append(tag, seq, cmd=Proc.new, args=nil)
_tag_bind_core('+', tag, seq, cmd=Proc.new, args=nil)
end
def tag_bindinfo(tag, context=nil)
if context
(tk_send('tag', 'bind', tag,
"<#{tk_event_sequence(context)}>")).collect{|cmdline|
if cmdline =~ /^rb_out (c\d+)\s+(.*)$/
[Tk_CMDTBL[$1], $2]
else
cmdline
end
}
else
tk_split_list(tk_send('tag', 'bind', tag)).filter{|seq|
seq[1..-2].gsub(/></,',')
}
end
end
def tag_cget(tag, key)
tk_tcl2ruby tk_call @t.path, 'tag', 'cget', tag, "-#{key}"
end
def tag_configure(tag, key, val=None)
if key.kind_of? Hash
if ( key['font'] || key['kanjifont'] \
|| key['latinfont'] || key['asciifont'] )
tagfont_configure(tag, key.dup)
else
tk_send 'tag', 'configure', tag, *hash_kv(key)
end
else
if ( key == 'font' || key == 'kanjifont' \
|| key == 'latinfont' || key == 'asciifont' )
tagfont_configure({key=>val})
else
tk_call 'tag', 'configure', tag, "-#{key}", val
end
end
end
def tag_configinfo(tag, key=nil)
if key
conf = tk_split_list(tk_send('tag','configure',tag,"-#{key}"))
conf[0] = conf[0][1..-1]
conf
else
tk_split_list(tk_send('tag', 'configure', tag)).collect{|conf|
conf[0] = conf[0][1..-1]
conf
}
end
end
def tag_raise(tag, above=None)
tk_send 'tag', 'raise', tag, above
end
def tag_lower(tag, below=None)
tk_send 'tag', 'lower', tag, below
end
def tag_remove(tag, *index)
tk_send 'tag', 'remove', tag, *index
end
def tag_ranges(tag)
l = tk_split_list(tk_send('tag', 'ranges', tag))
r = []
while key=l.shift
r.push [key, l.shift]
end
r
end
def tag_nextrange(tag, first, last=None)
tk_split_list(tk_send('tag', 'nextrange', tag, first, last))
end
def tag_prevrange(tag, first, last=None)
tk_split_list(tk_send('tag', 'prevrange', tag, first, last))
end
def search_with_length(pat,start,stop=None)
pat = pat.char if pat.kind_of? Integer
if stop != None
return ["", 0] if compare(start,'>=',stop)
txt = get(start,stop)
if (pos = txt.index(pat))
pos = txt[0..(pos-1)].split('').length if pos > 0
if pat.kind_of? String
return [index(start + " + #{pos} chars"), pat.split('').length]
else
return [index(start + " + #{pos} chars"), $&.split('').length]
end
else
return ["", 0]
end
else
txt = get(start,'end - 1 char')
if (pos = txt.index(pat))
pos = txt[0..(pos-1)].split('').length if pos > 0
if pat.kind_of? String
return [index(start + " + #{pos} chars"), pat.split('').length]
else
return [index(start + " + #{pos} chars"), $&.split('').length]
end
else
txt = get('1.0','end - 1 char')
if (pos = txt.index(pat))
pos = txt[0..(pos-1)].split('').length if pos > 0
if pat.kind_of? String
return [index("1.0 + #{pos} chars"), pat.split('').length]
else
return [index("1.0 + #{pos} chars"), $&.split('').length]
end
else
return ["", 0]
end
end
end
end
def search(pat,start,stop=None)
search_with_length(pat,start,stop)[0]
end
def rsearch_with_length(pat,start,stop=None)
pat = pat.char if pat.kind_of? Integer
if stop != None
return ["", 0] if compare(start,'<=',stop)
txt = get(stop,start)
if (pos = txt.rindex(pat))
pos = txt[0..(pos-1)].split('').length if pos > 0
if pat.kind_of? String
return [index(stop + " + #{pos} chars"), pat.split('').length]
else
return [index(stop + " + #{pos} chars"), $&.split('').length]
end
else
return ["", 0]
end
else
txt = get('1.0',start)
if (pos = txt.rindex(pat))
pos = txt[0..(pos-1)].split('').length if pos > 0
if pat.kind_of? String
return [index("1.0 + #{pos} chars"), pat.split('').length]
else
return [index("1.0 + #{pos} chars"), $&.split('').length]
end
else
txt = get('1.0','end - 1 char')
if (pos = txt.rindex(pat))
pos = txt[0..(pos-1)].split('').length if pos > 0
if pat.kind_of? String
return [index("1.0 + #{pos} chars"), pat.split('').length]
else
return [index("1.0 + #{pos} chars"), $&.split('').length]
end
else
return ["", 0]
end
end
end
end
def rsearch(pat,start,stop=None)
rsearch_with_length(pat,start,stop)[0]
end
end
class TkTextTag<TkObject
include TkTreatTagFont
$tk_text_tag = 'tag0000'
def initialize(parent, keys=nil)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@parent = @t = parent
@path = @id = $tk_text_tag
$tk_text_tag = $tk_text_tag.succ
#tk_call @t.path, "tag", "configure", @id, *hash_kv(keys)
configure(keys) if keys
@t._addtag id, self
end
def id
return @id
end
def first
@id + '.first'
end
def last
@id + '.last'
end
def add(*index)
tk_call @t.path, 'tag', 'add', @id, *index
end
def remove(*index)
tk_call @t.path, 'tag', 'remove', @id, *index
end
def ranges
l = tk_split_list(tk_call(@t.path, 'tag', 'ranges', @id))
r = []
while key=l.shift
r.push [key, l.shift]
end
r
end
def nextrange(first, last=None)
tk_split_list(tk_call(@t.path, 'tag', 'nextrange', @id, first, last))
end
def prevrange(first, last=None)
tk_split_list(tk_call(@t.path, 'tag', 'prevrange', @id, first, last))
end
def [](key)
cget key
end
def []=(key,val)
configure key, val
end
def cget(key)
tk_tcl2ruby tk_call @t.path, 'tag', 'cget', @id, "-#{key}"
end
def configure(key, val=None)
@t.tag_configure @id, key, val
end
# def configure(key, val=None)
# if key.kind_of? Hash
# tk_call @t.path, 'tag', 'configure', @id, *hash_kv(key)
# else
# tk_call @t.path, 'tag', 'configure', @id, "-#{key}", val
# end
# end
# def configure(key, value)
# if value == FALSE
# value = "0"
# elsif value.kind_of? Proc
# value = install_cmd(value)
# end
# tk_call @t.path, 'tag', 'configure', @id, "-#{key}", value
# end
def configinfo(key=nil)
@t.tag_configinfo @id, key
end
# def configinfo(key=nil)
# if key
# conf = tk_split_list(tk_call(@t.path, 'tag','configure',@id,"-#{key}"))
# conf[0] = conf[0][1..-1]
# conf
# else
# tk_split_list(tk_call(@t.path, 'tag', 'configure', @id)).collect{|conf|
# conf[0] = conf[0][1..-1]
# conf
# }
# end
# end
def bind(seq, cmd=Proc.new, args=nil)
id = install_bind(cmd, args)
tk_call @t.path, 'tag', 'bind', @id, "<#{tk_event_sequence(seq)}>", id
# @t._addcmd cmd
end
def bindinfo(context=nil)
if context
(tk_call(@t.path, 'tag', 'bind', @id,
"<#{tk_event_sequence(context)}>")).collect{|cmdline|
if cmdline =~ /^rb_out (c\d+)\s+(.*)$/
[Tk_CMDTBL[$1], $2]
else
cmdline
end
}
else
tk_split_list(tk_call(@t.path, 'tag', 'bind', @id)).filter{|seq|
seq[1..-2].gsub(/></,',')
}
end
end
def raise(above=None)
tk_call @t.path, 'tag', 'raise', @id, above
end
def lower(below=None)
tk_call @t.path, 'tag', 'lower', @id, below
end
def destroy
tk_call @t.path, 'tag', 'delete', @id
end
end
class TkTextTagSel<TkTextTag
def initialize(parent, keys=nil)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
@path = @id = 'sel'
#tk_call @t.path, "tag", "configure", @id, *hash_kv(keys)
configure(keys) if keys
@t._addtag id, self
end
end
class TkTextMark<TkObject
$tk_text_mark = 'mark0000'
def initialize(parent, index)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
@path = @id = $tk_text_mark
$tk_text_mark = $tk_text_mark.succ
tk_call @t.path, 'mark', 'set', @id, index
@t._addtag id, self
end
def id
return @id
end
def set(where)
tk_call @t.path, 'mark', 'set', @id, where
end
def unset
tk_call @t.path, 'mark', 'unset', @id
end
alias destroy unset
def gravity
tk_call @t.path, 'mark', 'gravity', @id
end
def gravity=(direction)
tk_call @t.path, 'mark', 'gravity', @id, direction
end
end
class TkTextMarkInsert<TkTextMark
def initialize(parent, index=nil)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
@path = @id = 'insert'
tk_call @t.path, 'mark', 'set', @id, index if index
@t._addtag id, self
end
end
class TkTextMarkCurrent<TkTextMark
def initialize(parent,index=nil)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
@path = @id = 'current'
tk_call @t.path, 'mark', 'set', @id, index if index
@t._addtag id, self
end
end
class TkTextWindow<TkObject
def initialize(parent, index, keys)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
if index == 'end'
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
elsif index.kind_of? TkTextMark
if tk_call(@t.path,'index',index.path) == tk_call(@t.path,'index','end')
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
else
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', index.path))
end
else
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', index))
end
@path.gravity = 'left'
@index = @path.path
@id = keys['window']
if keys['create']
@p_create = keys['create']
if @p_create.kind_of? Proc
keys['create'] = install_cmd(proc{@id = @p_create.call; @id.path})
end
end
tk_call @t.path, 'window', 'create', @index, *hash_kv(keys)
end
def [](slot)
cget(slot)
end
def []=(slot, value)
configure(slot, value)
end
def cget(slot)
tk_tcl2ruby tk_call @t.path, 'window', 'cget', @index, "-#{slot}"
end
def configure(slot, value=None)
if slot.kind_of? Hash
@id = slot['window'] if slot['window']
if slot['create']
self.create=value
slot['create']=nil
end
if slot.size > 0
tk_call @t.path, 'window', 'configure', @index, *hash_kv(slot)
end
else
@id = value if slot == 'window'
if slot == 'create'
self.create=value
else
tk_call @t.path, 'window', 'configure', @index, "-#{slot}", value
end
end
end
def window
@id
end
def window=(value)
tk_call @t.path, 'window', 'configure', @index, '-window', value
@id = value
end
def create
@p_create
end
def create=(value)
@p_create = value
if @p_create.kind_of? Proc
value = install_cmd(proc{@id = @p_create.call})
end
tk_call @t.path, 'window', 'configure', @index, '-create', value
end
def configinfo(slot = nil)
if slot
conf = tk_split_list(tk_call @t.path, 'window', 'configure',
@index, "-#{slot}")
conf[0] = conf[0][1..-1]
conf
else
tk_split_list(tk_call @t.path, 'window', 'configure',
@index).collect{|conf|
conf[0] = conf[0][1..-1]
conf
}
end
end
end
class TkTextImage<TkObject
def initialize(parent, index, keys)
if not parent.kind_of?(TkText)
fail format("%s need to be TkText", parent.inspect)
end
@t = parent
if index == 'end'
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
elsif index.kind_of? TkTextMark
if tk_call(@t.path,'index',index.path) == tk_call(@t.path,'index','end')
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', 'end - 1 chars'))
else
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', index.path))
end
else
@path = TkTextMark.new(@t, tk_call(@t.path, 'index', index))
end
@path.gravity = 'left'
@index = @path.path
@id = tk_call(@t.path, 'image', 'create', @index, *hash_kv(keys))
end
def [](slot)
cget(slot)
end
def []=(slot, value)
configure(slot, value)
end
def cget(slot)
tk_tcl2ruby tk_call @t.path, 'image', 'cget', @index, "-#{slot}"
end
def configure(slot, value=None)
if slot.kind_of? Hash
tk_call @t.path, 'image', 'configure', @index, *hash_kv(slot)
else
tk_call @t.path, 'image', 'configure', @index, "-#{slot}", value
end
end
# def configure(slot, value)
# tk_call @t.path, 'image', 'configure', @index, "-#{slot}", value
# end
def image
tk_call @t.path, 'image', 'configure', @index, '-image'
end
def image=(value)
tk_call @t.path, 'image', 'configure', @index, '-image', value
end
def configinfo(slot = nil)
if slot
conf = tk_split_list(tk_call @t.path, 'image', 'configure',
@index, "-#{slot}")
conf[0] = conf[0][1..-1]
conf
else
tk_split_list(tk_call @t.path, 'image', 'configure',
@index).collect{|conf|
conf[0] = conf[0][1..-1]
conf
}
end
end
end

66
ext/tk/lib/tkvirtevent.rb Normal file
View file

@ -0,0 +1,66 @@
#
# tkvirtevent.rb : treats virtual events
# 1998/07/16 by Hidetoshi Nagai <nagai@ai.kyutech.ac.jp>
#
require 'tk'
class TkVirtualEvent<TkObject
extend Tk
TkVirturlEventID = [0]
TkVirturlEventTBL = {}
def TkVirtualEvent.getobj(event)
obj = TkVirturlEventTBL[event]
obj ? obj : event
end
def TkVirtualEvent.info
tk_call('event', 'info').split(/\s+/).filter{|seq|
TkVirtualEvent.getobj(seq[1..-2])
}
end
def initialize(*sequences)
@path = @id = format("<VirtEvent%.4d>", TkVirturlEventID[0])
TkVirturlEventID[0] += 1
add(*sequences)
end
def add(*sequences)
if sequences != []
tk_call('event', 'add', "<#{@id}>",
*(sequences.collect{|seq| "<#{tk_event_sequence(seq)}>"}) )
TkVirturlEventTBL[@id] = self
end
self
end
def delete(*sequences)
if sequences == []
tk_call('event', 'delete', "<#{@id}>")
TkVirturlEventTBL[@id] = nil
else
tk_call('event', 'delete', "<#{@id}>",
*(sequences.collect{|seq| "<#{tk_event_sequence(seq)}>"}) )
TkVirturlEventTBL[@id] = nil if info == []
end
self
end
def info
tk_call('event', 'info', "<#{@id}>").split(/\s+/).filter{|seq|
l = seq.scan(/<*[^<>]+>*/).filter{|subseq|
case (subseq)
when /^<<[^<>]+>>$/
TkVirtualEvent.getobj(subseq[1..-2])
when /^<[^<>]+>$/
subseq[1..-2]
else
subseq.split('')
end
}.flatten
(l.size == 1) ? l[0] : l
}
end
end

149
ext/tk/sample/tkbiff.rb Normal file
View file

@ -0,0 +1,149 @@
#! /usr/local/bin/ruby
if ARGV[0] != '-d'
unless $DEBUG
exit if fork
end
else
ARGV.shift
end
if ARGV.length == 0
if ENV['MAIL']
$spool = ENV['MAIL']
else
$spool = '/usr/spool/mail/' + ENV['USER']
end
else
$spool = ARGV[0]
end
require "parsedate"
require "base64"
include ParseDate
class Mail
def Mail.new(f)
if !f.kind_of?(IO)
f = open(f, "r")
me = super
f.close
else
me = super
end
return me
end
def initialize(f)
@header = {}
@body = []
while f.gets()
$_.chop!
next if /^From / # skip From-line
break if /^$/ # end of header
if /^(\S+):\s*(.*)/
@header[attr = $1.capitalize] = $2
elsif attr
sub(/^\s*/, '')
@header[attr] += "\n" + $_
end
end
return if ! $_
while f.gets()
break if /^From /
@body.push($_)
end
end
def header
return @header
end
def body
return @body
end
end
require "tkscrollbox"
$top = TkRoot.new
$top.withdraw
$list = TkScrollbox.new($top) {
relief 'raised'
width 80
height 8
setgrid 'yes'
pack
}
TkButton.new($top) {
text 'Dismiss'
command proc {$top.withdraw}
pack('fill'=>'both','expand'=>'yes')
}
$top.bind "Control-c", proc{exit}
$top.bind "Control-q", proc{exit}
$top.bind "space", proc{exit}
$spool_size = 0
$check_time = Time.now
def check
$check_time = Time.now
size = File.size($spool)
if size and size != $spool_size
$spool_size = size
pop_up if size > 0
end
Tk.after 5000, proc{check}
end
if defined? Thread
Thread.start do
loop do
sleep 600
if Time.now - $check_time > 200
Tk.after 5000, proc{check}
end
end
end
end
def pop_up
outcount = 0;
$list.delete 0, 'end'
f = open($spool, "r")
while !f.eof?
mail = Mail.new(f)
date, from, subj = mail.header['Date'], mail.header['From'], mail.header['Subject']
next if !date
y = m = d = 0
y, m, d = parsedate(date) if date
from = "sombody@somewhere" if ! from
subj = "(nil)" if ! subj
from = decode_b(from)
subj = decode_b(subj)
$list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj)
outcount += 1
end
f.close
if outcount == 0
$list.insert 'end', "You have no mail."
else
$list.see 'end'
end
$top.deiconify
Tk.after 2000, proc{$top.withdraw}
end
$list.insert 'end', "You have no mail."
check
Tk.after 2000, proc{$top.withdraw}
begin
Tk.mainloop
rescue
`echo #$! > /tmp/tkbiff`
end

79
ext/tk/sample/tkbrowse.rb Normal file
View file

@ -0,0 +1,79 @@
#!/usr/local/bin/ruby
#
# This script generates a directory browser, which lists the working
# directory and allows you to open files or subdirectories by
# double-clicking.
# Create a scrollbar on the right side of the main window and a listbox
# on the left side.
require "tkscrollbox"
# The procedure below is invoked to open a browser on a given file; if the
# file is a directory then another instance of this program is invoked; if
# the file is a regular file then the Mx editor is invoked to display
# the file.
$dirlist = {}
def browsedir (dir)
if $dirlist.key? dir
$dirlist[dir]
else
top = if $dirlist.size > 0 then TkToplevel.new else nil end
list = TkScrollbox.new(top) {
relief 'raised'
width 20
height 20
setgrid 'yes'
pack
}
list.insert 'end', *`ls #{dir}`.split
# Set up bindings for the browser.
list.focus
list.bind "Control-q", proc{exit}
list.bind "Control-c", proc{exit}
list.bind "Control-p", proc{
print "selection <", TkSelection.get, ">\n"
}
list.bind "Double-Button-1", proc{
for i in TkSelection.get.split
print "clicked ", i, "\n"
browse dir, i
end
}
$dirlist[dir] = list
end
end
def browse (dir, file)
file="#{dir}/#{file}"
if File.directory? file
browsedir(file)
else
if File.file? file
if ENV['EDITOR']
system format("%s %s&", ENV['EDITOR'], file)
else
system "xedit #{file}&"
end
else
STDERR.print "\"#{file}\" isn't a directory or regular file"
end
end
end
# Fill the listbox with a list of all the files in the directory (run
# the "ls" command to get that information).
if ARGV.length>0
dir = ARGV[0]
else
dir="."
end
browsedir(dir)
Tk.mainloop

62
ext/tk/sample/tkdialog.rb Normal file
View file

@ -0,0 +1,62 @@
#! /usr/local/bin/ruby
require "tk"
root = TkFrame.new
top = TkFrame.new(root) {
relief 'raised'
border 1
}
msg = TkMessage.new(top) {
text "File main.c hasn't been saved to disk since \
it was last modified. What should I do?"
justify 'center'
aspect 200
font '-Adobe-helvetica-medium-r-normal--*-240*'
pack('padx'=>5, 'pady'=>5, 'expand'=>'yes')
}
top.pack('fill'=>'both')
root.pack
bot = TkFrame.new(root) {
relief 'raised'
border 1
}
TkFrame.new(bot) { |left|
relief 'sunken'
border 1
pack('side'=>'left', 'expand'=>'yes', 'padx'=>10, 'pady'=> 10)
TkButton.new(left) {
text "Save File"
command "quit 'save'"
pack('expand'=>'yes','padx'=>6,'pady'=> 6)
top.bind "Enter", proc{state 'active'}
msg.bind "Enter", proc{state 'active'}
bot.bind "Enter", proc{state 'active'}
top.bind "Leave", proc{state 'normal'}
msg.bind "Leave", proc{state 'normal'}
bot.bind "Leave", proc{state 'normal'}
Tk.root.bind "ButtonRelease-1", proc{quit 'save'}
Tk.root.bind "Return", proc{quit 'save'}
}
}
TkButton.new(bot) {
text "Quit Anyway"
command "quit 'quit'"
pack('side'=>'left', 'expand'=>'yes', 'padx'=>10)
}
TkButton.new(bot) {
text "Return To Editor"
command "quit 'return'"
pack('side'=>'left', 'expand'=>'yes', 'padx'=>10)
}
bot.pack
root.pack('side'=>'top', 'fill'=>'both', 'expand'=>'yes')
def quit(button)
print "aaa\n"
print "You pressed the \"#{button}\" button; bye-bye!\n"
exit
end
Tk.mainloop

132
ext/tk/sample/tkfrom.rb Normal file
View file

@ -0,0 +1,132 @@
#! /usr/local/bin/ruby
require "parsedate"
require "base64"
include ParseDate
class Mail
def Mail.new(f)
if !f.kind_of?(IO)
f = open(f, "r")
me = super(f)
f.close
else
me = super
end
return me
end
def initialize(f)
@header = {}
@body = []
while f.gets()
$_.chop!
next if /^From / # skip From-line
break if /^$/ # end of header
if /^(\S+):\s*(.*)/
@header[attr = $1.capitalize] = $2
elsif attr
sub(/^\s*/, '')
@header[attr] += "\n" + $_
end
end
return if ! $_
while f.gets()
break if /^From /
@body.push($_)
end
end
def header
return @header
end
def body
return @body
end
end
if ARGV.length == 0
if ENV['MAIL']
ARGV[0] = ENV['MAIL']
elsif ENV['USER']
ARGV[0] = '/usr/spool/mail/' + ENV['USER']
elsif ENV['LOGNAME']
ARGV[0] = '/usr/spool/mail/' + ENV['LOGNAME']
end
end
require "tk"
list = scroll = nil
TkFrame.new{|f|
list = TkListbox.new(f) {
yscroll proc{|idx|
scroll.set *idx
}
relief 'raised'
# geometry "80x5"
width 80
height 5
setgrid 'yes'
pack('side'=>'left','fill'=>'both','expand'=>'yes')
}
scroll = TkScrollbar.new(f) {
command proc{|idx|
list.yview *idx
}
pack('side'=>'right','fill'=>'y')
}
pack
}
root = Tk.root
TkButton.new(root) {
text 'Dismiss'
command proc {exit}
pack('fill'=>'both','expand'=>'yes')
}
root.bind "Control-c", proc{exit}
root.bind "Control-q", proc{exit}
root.bind "space", proc{exit}
$outcount = 0;
for file in ARGV
next if File.exist?(file)
atime = File.atime(file)
mtime = File.mtime(file)
f = open(file, "r")
begin
until f.eof
mail = Mail.new(f)
date = mail.header['Date']
next unless date
from = mail.header['From']
subj = mail.header['Subject']
y = m = d = 0
y, m, d = parsedate(date) if date
from = "sombody@somewhere" unless from
subj = "(nil)" unless subj
from = decode_b(from)
subj = decode_b(subj)
list.insert 'end', format('%-02d/%02d/%02d [%-28.28s] %s',y,m,d,from,subj)
$outcount += 1
end
ensure
f.close
File.utime(atime, mtime, file)
list.see 'end'
end
end
limit = 10000
if $outcount == 0
list.insert 'end', "You have no mail."
limit = 2000
end
Tk.after limit, proc{
exit
}
Tk.mainloop

10
ext/tk/sample/tkhello.rb Normal file
View file

@ -0,0 +1,10 @@
require "tk"
TkButton.new(nil,
'text' => 'hello',
'command' => proc{print "hello\n"}).pack('fill'=>'x')
TkButton.new(nil,
'text' => 'quit',
'command' => 'exit').pack('fill'=>'x')
Tk.mainloop

45
ext/tk/sample/tkline.rb Normal file
View file

@ -0,0 +1,45 @@
require "tkclass"
$tkline_init = FALSE
def start_random
return if $tkline_init
$tkline_init = TRUE
if defined? Thread
Thread.start do
loop do
sleep 2
Line.new($c, rand(400), rand(200), rand(400), rand(200))
end
end
end
end
$c = Canvas.new
$c.pack
$start_x = start_y = 0
def do_press(x, y)
$start_x = x
$start_y = y
$current_line = Line.new($c, x, y, x, y)
start_random
end
def do_motion(x, y)
if $current_line
$current_line.coords $start_x, $start_y, x, y
end
end
def do_release(x, y)
if $current_line
$current_line.coords $start_x, $start_y, x, y
$current_line.fill 'black'
$current_line = nil
end
end
$c.bind("1", proc{|e| do_press e.x, e.y})
$c.bind("B1-Motion", proc{|x, y| do_motion x, y}, "%x %y")
$c.bind("ButtonRelease-1", proc{|x, y| do_release x, y}, "%x %y")
Tk.mainloop

50
ext/tk/sample/tktimer.rb Normal file
View file

@ -0,0 +1,50 @@
#!/usr/local/bin/ruby
# This script generates a counter with start and stop buttons.
require "tk"
$label = TkLabel.new {
text '0.00'
relief 'raised'
width 10
pack('side'=>'bottom', 'fill'=>'both')
}
TkButton.new {
text 'Start'
command proc {
if $stopped
$stopped = FALSE
tick
end
}
pack('side'=>'left','fill'=>'both','expand'=>'yes')
}
TkButton.new {
text 'Stop'
command proc{
exit if $stopped
$stopped = TRUE
}
pack('side'=>'right','fill'=>'both','expand'=>'yes')
}
$seconds=0
$hundredths=0
$stopped=TRUE
def tick
if $stopped then return end
Tk.after 50, proc{tick}
$hundredths+=5
if $hundredths >= 100
$hundredths=0
$seconds+=1
end
$label.text format("%d.%02d", $seconds, $hundredths)
end
root = Tk.root
root.bind "Control-c", proc{root.destroy}
root.bind "Control-q", proc{root.destroy}
Tk.root.focus
Tk.mainloop

45
ext/tk/tkutil.c Normal file
View file

@ -0,0 +1,45 @@
/************************************************
tk.c -
$Author$
$Date$
created at: Fri Nov 3 00:47:54 JST 1995
************************************************/
#include "ruby.h"
static VALUE
tk_eval_cmd(argc, argv)
int argc;
VALUE argv[];
{
VALUE cmd, rest;
rb_scan_args(argc, argv, "1*", &cmd, &rest);
return rb_eval_cmd(cmd, rest);
}
static VALUE
tk_s_new(argc, argv, class)
int argc;
VALUE *argv;
VALUE class;
{
VALUE obj = rb_obj_alloc(class);
rb_funcall2(obj, rb_intern("initialize"), argc, argv);
if (rb_iterator_p()) rb_obj_instance_eval(0, 0, obj);
return obj;
}
Init_tkutil()
{
VALUE mTK = rb_define_module("TkUtil");
VALUE cTK = rb_define_class("TkKernel", rb_cObject);
rb_define_singleton_method(mTK, "eval_cmd", tk_eval_cmd, -1);
rb_define_singleton_method(cTK, "new", tk_s_new, -1);
}

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 "fnmatch.h"
#ifdef USE_CWGUSI
#include <sys/errno.h>
#endif
#if !defined (__GNU_LIBRARY__) && !defined (STDC_HEADERS)
# if !defined (errno)
extern int errno;
@ -51,15 +55,23 @@ fnmatch (pattern, string, flags)
if (*n == '\0')
return (FNM_NOMATCH);
else if ((flags & FNM_PATHNAME) && *n == '/')
/* If we are matching a pathname, `?' can never match a `/'. */
return (FNM_NOMATCH);
else if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
/* `?' cannot match a `.' if it is the first character of the
string or if it is the first character following a slash and
we are matching a pathname. */
return (FNM_NOMATCH);
break;
case '\\':
if (!(flags & FNM_NOESCAPE))
c = *p++;
{
c = *p++;
if (c == '\0')
return (FNM_NOMATCH);
}
if (*n != c)
return (FNM_NOMATCH);
break;
@ -67,19 +79,38 @@ fnmatch (pattern, string, flags)
case '*':
if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
/* `*' cannot match a `.' if it is the first character of the
string or if it is the first character following a slash and
we are matching a pathname. */
return (FNM_NOMATCH);
for (c = *p++; c == '?' || c == '*'; c = *p++, ++n)
if (((flags & FNM_PATHNAME) && *n == '/') ||
(c == '?' && *n == '\0'))
return (FNM_NOMATCH);
/* Collapse multiple consecutive, `*' and `?', but make sure that
one character of the string is consumed for each `?'. */
for (c = *p++; c == '?' || c == '*'; c = *p++)
{
if ((flags & FNM_PATHNAME) && *n == '/')
/* A slash does not match a wildcard under FNM_PATHNAME. */
return (FNM_NOMATCH);
else if (c == '?')
{
if (*n == '\0')
return (FNM_NOMATCH);
/* One character of the string is consumed in matching
this ? wildcard, so *??? won't match if there are
fewer than three characters. */
n++;
}
}
if (c == '\0')
return (0);
/* General case, use recursion. */
{
char c1 = (!(flags & FNM_NOESCAPE) && c == '\\') ? *p : c;
for (--p; *n != '\0'; ++n)
/* Only call fnmatch if the first character indicates a
possible match. */
if ((c == '[' || *n == c1) &&
fnmatch (p, n, flags & ~FNM_PERIOD) == 0)
return (0);
@ -94,22 +125,30 @@ fnmatch (pattern, string, flags)
if (*n == '\0')
return (FNM_NOMATCH);
/* A character class cannot match a `.' if it is the first
character of the string or if it is the first character
following a slash and we are matching a pathname. */
if ((flags & FNM_PERIOD) && *n == '.' &&
(n == string || ((flags & FNM_PATHNAME) && n[-1] == '/')))
return (FNM_NOMATCH);
/* Make sure there is a closing `]'. If there isn't, the `['
is just a character to be matched. */
/* POSIX.2 2.8.3.1.2 says: `An expression containing a `[' that
is not preceded by a backslash and is not part of a bracket
expression produces undefined results.' This implementation
treats the `[' as just a character to be matched if there is
not a closing `]'. This code will have to be changed when
POSIX.2 character classes are implemented. */
{
register char *np;
for (np = p; np && *np && *np != ']'; np++);
for (np = p; np && *np && *np != ']'; np++)
;
if (np && !*np)
{
if (*n != '[')
return (FNM_NOMATCH);
goto next_char;
break;
}
}
@ -120,10 +159,18 @@ fnmatch (pattern, string, flags)
c = *p++;
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 == '\\')
cstart = cend = *p++;
{
if (*p == '\0')
return FNM_NOMATCH;
cstart = cend = *p++;
}
if (c == '\0')
/* [ (unterminated) loses. */
@ -135,6 +182,9 @@ fnmatch (pattern, string, flags)
/* [/] can never match. */
return (FNM_NOMATCH);
/* This introduces a range, unless the `-' is the last
character of the class. Find the end of the range
and move past it. */
if (c == '-' && *p != ']')
{
cend = *p++;
@ -142,6 +192,7 @@ fnmatch (pattern, string, flags)
cend = *p++;
if (cend == '\0')
return (FNM_NOMATCH);
c = *p++;
}
@ -153,8 +204,6 @@ fnmatch (pattern, string, flags)
}
if (!not)
return (FNM_NOMATCH);
next_char:
break;
matched:
@ -167,8 +216,12 @@ fnmatch (pattern, string, flags)
c = *p++;
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)
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
along with this program; if not, write to the Free Software
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
/* 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
based on specifications for the pattern matching. --RMS. */
#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_DIRENT_H)
# define HAVE_DIRENT_H
# endif /* !HAVE_DIRENT_H */
#endif /* !SHELL && (_POSIX_VERSION || USGr3) */
#if defined (HAVE_ALLOCA_H)
# include <alloca.h>
#endif
#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)
# include <dirent.h>
# if !defined (direct)
# define direct dirent
# endif /* !direct */
# define D_NAMLEN(d) strlen ((d)->d_name)
#elif HAVE_DIRECT_H
# include <direct.h>
# define D_NAMLEN(d) strlen ((d)->d_name)
#else /* !HAVE_DIRENT_H */
# define D_NAMLEN(d) ((d)->d_namlen)
# if defined (USG)
# if defined (Xenix)
# include <sys/ndir.h>
# else /* !Xenix (but USG...) */
# include "ndir.h"
# endif /* !Xenix */
# else /* !USG */
# if defined(NT)
# include "missing/dir.h"
# else
# if defined (HAVE_SYS_NDIR_H)
# include <sys/ndir.h>
# endif
# if defined (HAVE_SYS_DIR_H)
# include <sys/dir.h>
# endif /* !NT */
# endif /* !USG */
# endif /* HAVE_SYS_DIR_H */
# if defined (HAVE_NDIR_H)
# include <ndir.h>
# endif
# if !defined (dirent)
# define dirent direct
# endif
#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
systems do not provide it. */
# define REAL_DIR_ENTRY(dp) 1
#elif defined (__BORLANDC__)
# define REAL_DIR_ENTRY(dp) 1
#else
# define REAL_DIR_ENTRY(dp) (dp->d_ino != 0)
#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)
# include <string.h>
#else /* !HAVE_STRING_H */
# include <strings.h>
#endif /* !HAVE_STRING_H */
#ifndef bcopy
# define bcopy(s, d, n) (memcpy ((d), (s), (n)))
#endif
#ifdef _AIX
#pragma alloca
#else
#if defined(HAVE_ALLOCA_H) && !defined(__GNUC__)
#include <alloca.h>
#else
char *alloca ();
#endif
#endif
#include "fnmatch.h"
#if !defined (HAVE_BCOPY) && !defined (bcopy)
# define bcopy(s, d, n) ((void) memcpy ((d), (s), (n)))
#endif /* !HAVE_BCOPY */
/* If the opendir () on your system lets you open non-directory files,
then we consider that not robust. Define OPENDIR_NOT_ROBUST in the
SYSDEP_CFLAGS for your machines entry in machines.h. */
then we consider that not robust. */
#if defined (OPENDIR_NOT_ROBUST)
# if defined (SHELL)
# include "posixstat.h"
@ -99,6 +95,8 @@ char *alloca ();
# endif /* !SHELL */
#endif /* OPENDIR_NOT_ROBUST */
#include "fnmatch.h"
extern void *xmalloc (), *xrealloc ();
#if !defined (HAVE_STDLIB_H)
extern void free ();
@ -113,9 +111,15 @@ extern void free ();
#endif /* !NULL */
#if defined (SHELL)
extern void throw_to_top_level ();
extern int interrupt_state;
#endif /* SHELL */
#if defined(NT) && defined(_MSC_VER)
#include "missing/dir.h"
#endif
/* Global variable which controls whether or not * matches .*.
Non-zero means don't match .*. */
int noglob_dot_filenames = 1;
@ -123,7 +127,6 @@ int noglob_dot_filenames = 1;
/* Global variable to return to signify an error in globbing. */
char *glob_error_return;
/* Return nonzero if PATTERN has any special globbing chars in it. */
int
glob_pattern_p (pattern)
@ -205,7 +208,7 @@ glob_vector (pat, dir)
};
DIR *d;
register struct direct *dp;
register struct dirent *dp;
struct globval *lastlink;
register struct globval *nextlink;
register char *nextname;
@ -276,7 +279,8 @@ glob_vector (pat, dir)
continue;
/* 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;
flags = (noglob_dot_filenames ? FNM_PERIOD : 0) | FNM_PATHNAME;
@ -306,7 +310,9 @@ glob_vector (pat, dir)
}
/* Have we run out of memory? */
#if defined (SHELL)
lost:
#endif
if (lose)
{
/* Here free the strings we have got. */
@ -365,7 +371,14 @@ glob_dir_to_array (dir, array)
+ strlen (array[i]) + 1);
if (result[i] == 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;
@ -435,10 +448,14 @@ glob_filename (pathname)
if (directories == NULL)
goto memory_error;
else if (directories == (char **)&glob_error_return)
return ((char **) &glob_error_return);
{
free ((char *) result);
return ((char **) &glob_error_return);
}
else if (*directories == NULL)
{
free ((char *) directories);
free ((char *) result);
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$
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_var_tables();
Init_Object();
Init_Exception();
#ifdef THREAD
Init_Thread();
#endif
Init_Comparable();
Init_Enumerable();
Init_eval();
Init_String();
Init_Exception();
#ifdef USE_THREAD
Init_Thread();
#endif
Init_Numeric();
Init_Bignum();
Init_Array();

View file

@ -1,7 +1,10 @@
#!./miniruby
#!./miniruby -I.
require "rbconfig.rb"
include Config
destdir = ARGV[0] || ''
$:.unshift CONFIG["srcdir"]+"/lib"
require "ftools"
@ -12,26 +15,43 @@ else
prefix = CONFIG["prefix"]
end
ruby_install_name = CONFIG["ruby_install_name"]
bindir = prefix + "/bin"
libdir = prefix + "/lib/" + ruby_install_name
archdir = libdir+"/"+CONFIG["arch"]
bindir = CONFIG["bindir"]
libdir = CONFIG["libdir"]
pkglibdir = libdir + "/" + ruby_install_name
archdir = pkglibdir + "/" + CONFIG["arch"]
mandir = CONFIG["mandir"] + "/man1"
wdir = Dir.getwd
File.makedirs "#{destdir}#{bindir}", true
File.install "ruby#{binsuffix}",
"#{bindir}/#{ruby_install_name}#{binsuffix}", 0755, TRUE
File.makedirs libdir, TRUE
Dir.chdir "ext"
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
"#{destdir}#{bindir}/#{ruby_install_name}#{binsuffix}", 0755, true
for dll in Dir['*.dll']
File.install dll, "#{destdir}#{bindir}/#{dll}", 0755, true
end
File.install "rbconfig.rb", archdir, 0644, TRUE
File.install "ruby.1", mandir, 0644, TRUE
File.makedirs "#{destdir}#{libdir}", 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:

484
intern.h
View file

@ -3,289 +3,321 @@
*/
/* array.c */
void memclear _((register VALUE *, register int));
VALUE assoc_new _((VALUE, VALUE));
VALUE ary_new _((void));
VALUE ary_new2 _((int));
VALUE ary_new3();
VALUE ary_new4 _((int, VALUE *));
VALUE ary_freeze _((VALUE));
void ary_store _((VALUE, int, VALUE));
VALUE ary_push _((VALUE, VALUE));
VALUE ary_pop _((VALUE));
VALUE ary_shift _((VALUE));
VALUE ary_unshift _((VALUE, VALUE));
VALUE ary_entry _((VALUE, int));
VALUE ary_each _((VALUE));
VALUE ary_join _((VALUE, VALUE));
VALUE ary_to_s _((VALUE));
VALUE ary_print_on _((VALUE, VALUE));
VALUE ary_reverse _((VALUE));
VALUE ary_sort_bang _((VALUE));
VALUE ary_sort _((VALUE));
VALUE ary_delete _((VALUE, VALUE));
VALUE ary_delete_at _((VALUE, VALUE));
VALUE ary_plus _((VALUE, VALUE));
VALUE ary_concat _((VALUE, VALUE));
VALUE ary_assoc _((VALUE, VALUE));
VALUE ary_rassoc _((VALUE, VALUE));
VALUE ary_includes _((VALUE, VALUE));
void rb_mem_clear _((register VALUE*, register size_t));
VALUE rb_assoc_new _((VALUE, VALUE));
VALUE rb_ary_new _((void));
VALUE rb_ary_new2 _((size_t));
VALUE rb_ary_new3 __((size_t,...));
VALUE rb_ary_new4 _((size_t, VALUE *));
VALUE rb_ary_freeze _((VALUE));
VALUE rb_ary_aref _((int, VALUE*, VALUE));
void rb_ary_store _((VALUE, size_t, VALUE));
VALUE rb_ary_to_s _((VALUE));
VALUE rb_ary_push _((VALUE, VALUE));
VALUE rb_ary_pop _((VALUE));
VALUE rb_ary_shift _((VALUE));
VALUE rb_ary_unshift _((VALUE, VALUE));
VALUE rb_ary_entry _((VALUE, size_t));
VALUE rb_ary_each _((VALUE));
VALUE rb_ary_join _((VALUE, VALUE));
VALUE rb_ary_print_on _((VALUE, VALUE));
VALUE rb_ary_reverse _((VALUE));
VALUE rb_ary_sort _((VALUE));
VALUE rb_ary_sort_bang _((VALUE));
VALUE rb_ary_delete _((VALUE, VALUE));
VALUE rb_ary_delete_at _((VALUE, VALUE));
VALUE rb_ary_plus _((VALUE, VALUE));
VALUE rb_ary_concat _((VALUE, VALUE));
VALUE rb_ary_assoc _((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 */
VALUE big_clone _((VALUE));
void big_2comp _((VALUE));
VALUE big_norm _((VALUE));
VALUE uint2big _((UINT));
VALUE int2big _((INT));
VALUE uint2inum _((UINT));
VALUE int2inum _((INT));
VALUE str2inum _((UCHAR *, int));
VALUE big2str _((VALUE, int));
INT big2int _((VALUE));
VALUE big_to_i _((VALUE));
VALUE dbl2big _((double));
double big2dbl _((VALUE));
VALUE big_to_f _((VALUE));
VALUE big_plus _((VALUE, VALUE));
VALUE big_minus _((VALUE, VALUE));
VALUE big_mul _((VALUE, VALUE));
VALUE big_pow _((VALUE, VALUE));
VALUE big_and _((VALUE, VALUE));
VALUE big_or _((VALUE, VALUE));
VALUE big_xor _((VALUE, VALUE));
VALUE big_lshift _((VALUE, VALUE));
VALUE big_rand _((VALUE));
VALUE rb_big_clone _((VALUE));
void rb_big_2comp _((VALUE));
VALUE rb_big_norm _((VALUE));
VALUE rb_uint2big _((unsigned long));
VALUE rb_int2big _((long));
VALUE rb_uint2inum _((unsigned long));
VALUE rb_int2inum _((long));
VALUE rb_str2inum _((char*, int));
VALUE rb_big2str _((VALUE, int));
long rb_big2long _((VALUE));
#define rb_big2int(x) rb_big2long(x)
unsigned long rb_big2ulong _((VALUE));
#define rb_big2uint(x) rb_big2ulong(x)
VALUE rb_dbl2big _((double));
double rb_big2dbl _((VALUE));
VALUE rb_big_plus _((VALUE, VALUE));
VALUE rb_big_minus _((VALUE, VALUE));
VALUE rb_big_mul _((VALUE, VALUE));
VALUE rb_big_pow _((VALUE, VALUE));
VALUE rb_big_and _((VALUE, VALUE));
VALUE rb_big_or _((VALUE, VALUE));
VALUE rb_big_xor _((VALUE, VALUE));
VALUE rb_big_lshift _((VALUE, VALUE));
VALUE rb_big_rand _((VALUE));
/* class.c */
VALUE class_new _((VALUE));
VALUE singleton_class_new _((VALUE));
VALUE singleton_class_clone _((VALUE));
void singleton_class_attached _((VALUE,VALUE));
VALUE rb_class_new _((VALUE));
VALUE rb_singleton_class_new _((VALUE));
VALUE rb_singleton_class_clone _((VALUE));
void rb_singleton_class_attached _((VALUE,VALUE));
VALUE rb_define_class_id _((ID, VALUE));
VALUE module_new _((void));
VALUE rb_module_new _((void));
VALUE rb_define_module_id _((ID));
VALUE mod_included_modules _((VALUE));
VALUE mod_ancestors _((VALUE));
VALUE class_instance_methods _((int, VALUE *, VALUE));
VALUE class_private_instance_methods _((int, VALUE *, VALUE));
VALUE obj_singleton_methods _((VALUE));
VALUE rb_mod_included_modules _((VALUE));
VALUE rb_mod_ancestors _((VALUE));
VALUE rb_class_instance_methods _((int, VALUE*, VALUE));
VALUE rb_class_protected_instance_methods _((int, VALUE*, 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_undef_method _((VALUE, char *));
void rb_define_private_method _((VALUE, char *, VALUE (*)(), int));
void rb_undef_method _((VALUE, char*));
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_private_method _((VALUE,char*,VALUE(*)(),int));
VALUE rb_singleton_class _((VALUE));
/* enum.c */
VALUE enum_length _((VALUE));
VALUE rb_enum_length _((VALUE));
/* error.c */
VALUE exc_new _((VALUE, char *, UINT));
VALUE exc_new2 _((VALUE, char *));
VALUE exc_new3 _((VALUE, VALUE));
#ifdef __GNUC__
volatile voidfn TypeError;
volatile voidfn ArgError;
volatile voidfn NameError;
volatile voidfn IndexError;
volatile voidfn LoadError;
#else
void TypeError();
void ArgError();
void NameError();
void IndexError();
void LoadError();
#endif
extern int ruby_nerrs;
VALUE rb_exc_new _((VALUE, char*, int));
VALUE rb_exc_new2 _((VALUE, char*));
VALUE rb_exc_new3 _((VALUE, VALUE));
void rb_loaderror __((char*, ...)) NORETURN;
void rb_compile_error __((char*, ...));
void rb_compile_error_append __((char*, ...));
/* 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_alias _((VALUE, ID, ID));
void rb_attr _((VALUE,ID,int,int,int));
int rb_method_boundp _((VALUE, ID, int));
VALUE dyna_var_defined _((ID));
VALUE dyna_var_ref _((ID));
VALUE dyna_var_asgn _((ID, VALUE));
void ruby_init _((void));
void ruby_options _((int, char **));
void ruby_run _((void));
void rb_eval_cmd _((VALUE, VALUE));
void rb_trap_eval _((VALUE, int));
VALUE rb_dvar_defined _((ID));
VALUE rb_dvar_ref _((ID));
void rb_dvar_asgn _((ID, VALUE));
void rb_dvar_push _((ID, VALUE));
VALUE rb_eval_cmd _((VALUE, VALUE));
VALUE rb_trap_eval _((VALUE, int));
int rb_respond_to _((VALUE, ID));
void rb_raise _((VALUE));
void rb_fatal _((VALUE));
void rb_interrupt _((void));
int iterator_p _((void));
VALUE rb_yield_0 _((VALUE, volatile 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));
ID rb_frame_last_func _((void));
VALUE f_load _((VALUE, VALUE));
void rb_provide _((char *));
VALUE f_require _((VALUE, VALUE));
VALUE class_new_instance _((int, VALUE *, VALUE));
VALUE f_lambda _((void));
void rb_set_end_proc _((void (*)(),VALUE));
void gc_mark_threads _((void));
void thread_schedule _((void));
void thread_wait_fd _((int));
void thread_fd_writable _((int));
int thread_alone _((void));
void thread_sleep _((int));
void thread_sleep_forever _((void));
VALUE thread_create _((VALUE (*)(), void *));
void thread_interrupt _((void));
VALUE rb_obj_instance_eval _((int, VALUE*, VALUE));
void rb_load _((VALUE, int));
void rb_load_protect _((VALUE, int, int*));
void rb_jump_tag _((int)) NORETURN;
void rb_provide _((char*));
VALUE rb_f_require _((VALUE, VALUE));
void rb_obj_call_init _((VALUE));
VALUE rb_class_new_instance _((int, VALUE*, VALUE));
VALUE rb_f_lambda _((void));
VALUE rb_protect _((VALUE (*)(), VALUE, int*));
void rb_set_end_proc _((void (*)(), VALUE));
void rb_gc_mark_threads _((void));
void rb_thread_start_timer _((void));
void rb_thread_stop_timer _((void));
void rb_thread_schedule _((void));
void rb_thread_wait_fd _((int));
void rb_thread_fd_writable _((int));
int rb_thread_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 */
VALUE file_open _((char *, char *));
int eaccess _((char *, int));
VALUE file_s_expand_path _((VALUE, VALUE));
VALUE rb_file_open _((char*, char*));
int eaccess _((char*, int));
VALUE rb_file_s_expand_path _((int, VALUE *));
/* gc.c */
void rb_global_variable _((VALUE *));
void gc_mark_locations _((VALUE *, VALUE *));
void gc_mark_maybe();
void gc_mark();
void gc_force_recycle();
void gc_gc _((void));
void init_stack _((void));
void init_heap _((void));
void rb_global_variable _((VALUE*));
void rb_gc_mark_locations _((VALUE*, VALUE*));
void rb_mark_tbl _((struct st_table*));
void rb_mark_hash _((struct st_table*));
void rb_gc_mark_maybe();
void rb_gc_mark();
void rb_gc_force_recycle _((VALUE));
void rb_gc _((void));
void rb_gc_call_finalizer_at_exit _((void));
/* hash.c */
VALUE hash_freeze _((VALUE));
VALUE rb_hash _((VALUE));
VALUE hash_new _((void));
VALUE hash_aref _((VALUE, VALUE));
VALUE hash_aset _((VALUE, VALUE, VALUE));
VALUE rb_hash_new _((void));
VALUE rb_hash_freeze _((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 */
void eof_error _((void));
VALUE io_write _((VALUE, VALUE));
VALUE io_gets_method _((int, VALUE*, VALUE));
VALUE io_gets _((VALUE));
VALUE io_getc _((VALUE));
VALUE io_ungetc _((VALUE, VALUE));
VALUE io_close _((VALUE));
VALUE io_binmode _((VALUE));
int io_mode_flags _((char *));
VALUE io_reopen _((VALUE, VALUE));
VALUE f_gets _((void));
void rb_str_setter _((VALUE, ID, VALUE *));
extern VALUE rb_fs;
extern VALUE rb_output_fs;
extern VALUE rb_rs;
extern VALUE rb_default_rs;
extern VALUE rb_output_rs;
VALUE rb_io_write _((VALUE, VALUE));
VALUE rb_io_gets _((VALUE));
VALUE rb_io_getc _((VALUE));
VALUE rb_io_ungetc _((VALUE, VALUE));
VALUE rb_io_close _((VALUE));
VALUE rb_io_eof _((VALUE));
VALUE rb_io_binmode _((VALUE));
int rb_io_mode_flags _((char*));
VALUE rb_io_reopen _((VALUE, VALUE));
VALUE rb_gets _((void));
void rb_str_setter _((VALUE, ID, VALUE*));
/* numeric.c */
void num_zerodiv _((void));
VALUE num_coerce_bin _((VALUE, VALUE));
VALUE float_new _((double));
VALUE flo_pow _((VALUE, VALUE));
VALUE num2fix _((VALUE));
VALUE fix2str _((VALUE, int));
VALUE fix_to_s _((VALUE));
VALUE num_upto _((VALUE, VALUE));
VALUE fix_upto _((VALUE, VALUE));
void rb_num_zerodiv _((void));
VALUE rb_num_coerce_bin _((VALUE, VALUE));
VALUE rb_float_new _((double));
VALUE rb_num2fix _((VALUE));
VALUE rb_fix2str _((VALUE, int));
VALUE rb_fix_upto _((VALUE, VALUE));
/* object.c */
VALUE rb_equal _((VALUE, VALUE));
int rb_eql _((VALUE, VALUE));
VALUE obj_equal _((VALUE, VALUE));
VALUE any_to_s _((VALUE));
VALUE rb_any_to_s _((VALUE));
VALUE rb_inspect _((VALUE));
VALUE obj_is_instance_of _((VALUE, VALUE));
VALUE obj_is_kind_of _((VALUE, VALUE));
VALUE obj_alloc _((VALUE));
VALUE rb_obj_is_instance_of _((VALUE, VALUE));
VALUE rb_obj_is_kind_of _((VALUE, 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_Float _((VALUE));
VALUE rb_String _((VALUE));
VALUE rb_Array _((VALUE));
double num2dbl _((VALUE));
/* parse.y */
extern int ruby_sourceline;
extern char *ruby_sourcefile;
int yyparse _((void));
void pushback _((int));
ID id_attrset _((ID));
void yyappend_print _((void));
void yywhile_loop _((int, int));
ID rb_id_attrset _((ID));
void rb_parser_append_print _((void));
void rb_parser_while_loop _((int, int));
int rb_is_const_id _((ID));
int rb_is_instance_id _((ID));
void local_var_append _((ID));
VALUE backref_get _((void));
void backref_set _((VALUE));
VALUE lastline_get _((void));
void lastline_set _((VALUE));
VALUE rb_backref_get _((void));
void rb_backref_set _((VALUE));
VALUE rb_lastline_get _((void));
void rb_lastline_set _((VALUE));
/* process.c */
int rb_proc_exec _((char *));
int rb_proc_exec _((char*));
void rb_syswait _((int));
/* range.c */
VALUE range_new _((VALUE, VALUE));
VALUE range_beg_end _((VALUE, int *, int *));
VALUE rb_range_new _((VALUE, VALUE));
VALUE rb_range_beg_end _((VALUE, int*, int*));
/* re.c */
VALUE reg_nth_defined _((int, VALUE));
VALUE reg_nth_match _((int, VALUE));
VALUE reg_last_match _((VALUE));
VALUE reg_match_pre _((VALUE));
VALUE reg_match_post _((VALUE));
VALUE reg_match_last _((VALUE));
VALUE reg_new _((char *, int, int));
VALUE reg_match _((VALUE, VALUE));
VALUE reg_match2 _((VALUE));
void rb_set_kcode _((char *));
VALUE rb_reg_nth_defined _((int, VALUE));
VALUE rb_reg_nth_match _((int, VALUE));
VALUE rb_reg_last_match _((VALUE));
VALUE rb_reg_match_pre _((VALUE));
VALUE rb_reg_match_post _((VALUE));
VALUE rb_reg_match_last _((VALUE));
VALUE rb_reg_new _((char*, size_t, int));
VALUE rb_reg_match _((VALUE, VALUE));
VALUE rb_reg_match2 _((VALUE));
int rb_reg_options _((VALUE));
char*rb_get_kcode _((void));
void rb_set_kcode _((char*));
int rb_ignorecase_p _((void));
/* ruby.c */
void rb_require_modules _((void));
void rb_load_file _((char *));
void ruby_script _((char *));
void rb_load_file _((char*));
void ruby_script _((char*));
void ruby_prog_init _((void));
void ruby_set_argv _((int, char **));
void ruby_process_options _((int, char **));
void ruby_set_argv _((int, char**));
void ruby_process_options _((int, char**));
void ruby_require_modules _((void));
void ruby_load_script _((void));
/* signal.c */
VALUE f_kill _((int, VALUE *));
void gc_mark_trap_list _((void));
VALUE rb_f_kill _((int, VALUE*));
void rb_gc_mark_trap_list _((void));
#ifdef POSIX_SIGNAL
#define posix_signal ruby_posix_signal
void posix_signal _((int, void (*)()));
#endif
void rb_trap_exit _((void));
void rb_trap_exec _((void));
/* sprintf.c */
VALUE f_sprintf _((int, VALUE *));
VALUE rb_f_sprintf _((int, VALUE*));
/* string.c */
VALUE str_new _((UCHAR *, UINT));
VALUE str_new2 _((UCHAR *));
VALUE str_new3 _((VALUE));
VALUE str_new4 _((VALUE));
VALUE obj_as_string _((VALUE));
VALUE str_dup _((VALUE));
VALUE str_plus _((VALUE, VALUE));
VALUE str_times _((VALUE, VALUE));
VALUE str_substr _((VALUE, int, int));
void str_modify _((VALUE));
VALUE str_freeze _((VALUE));
VALUE str_dup_freezed _((VALUE));
VALUE str_taint _((VALUE));
VALUE str_tainted _((VALUE));
VALUE str_resize _((VALUE, int));
VALUE str_cat _((VALUE, UCHAR *, UINT));
int str_hash _((VALUE));
int str_cmp _((VALUE, VALUE));
VALUE str_upto _((VALUE, VALUE));
VALUE str_inspect _((VALUE));
VALUE str_split _((VALUE, char *));
VALUE rb_str_new _((char*, size_t));
VALUE rb_str_new2 _((char*));
VALUE rb_str_new3 _((VALUE));
VALUE rb_str_new4 _((VALUE));
VALUE rb_tainted_str_new _((char*, size_t));
VALUE rb_tainted_str_new2 _((char*));
VALUE rb_obj_as_string _((VALUE));
VALUE rb_str_to_str _((VALUE));
VALUE rb_str_dup _((VALUE));
VALUE rb_str_plus _((VALUE, VALUE));
VALUE rb_str_times _((VALUE, VALUE));
VALUE rb_str_substr _((VALUE, size_t, size_t));
void rb_str_modify _((VALUE));
VALUE rb_str_freeze _((VALUE));
VALUE rb_str_dup_frozen _((VALUE));
VALUE rb_str_resize _((VALUE, size_t));
VALUE rb_str_cat _((VALUE, char*, size_t));
VALUE rb_str_concat _((VALUE, VALUE));
int rb_str_hash _((VALUE));
int rb_str_cmp _((VALUE, VALUE));
VALUE rb_str_upto _((VALUE, VALUE));
VALUE rb_str_inspect _((VALUE));
VALUE rb_str_split _((VALUE, char*));
/* struct.c */
VALUE struct_new();
VALUE struct_define();
VALUE struct_alloc _((VALUE, VALUE));
VALUE struct_aref _((VALUE, VALUE));
VALUE struct_aset _((VALUE, VALUE, VALUE));
VALUE struct_getmember _((VALUE, ID));
VALUE rb_struct_new __((VALUE, ...));
VALUE rb_struct_define __((char*, ...));
VALUE rb_struct_alloc _((VALUE, VALUE));
VALUE rb_struct_aref _((VALUE, VALUE));
VALUE rb_struct_aset _((VALUE, VALUE, VALUE));
VALUE rb_struct_getmember _((VALUE, ID));
/* time.c */
VALUE 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 *));
VALUE rb_time_new _((int, int));
/* variable.c */
VALUE mod_name _((VALUE));
VALUE rb_mod_name _((VALUE));
VALUE rb_class_path _((VALUE));
void rb_set_class_path _((VALUE, VALUE, char *));
VALUE rb_path2class _((char *));
void rb_set_class_path _((VALUE, VALUE, char*));
VALUE rb_path2class _((char*));
void rb_name_class _((VALUE, ID));
void rb_autoload _((char *, char *));
VALUE f_autoload _((VALUE, VALUE, VALUE));
void gc_mark_global_tbl _((void));
VALUE f_trace_var _((int, VALUE *));
VALUE f_untrace_var _((int, VALUE *));
VALUE rb_gvar_set2 _((char *, VALUE));
VALUE f_global_variables _((void));
void rb_autoload _((char*, char*));
VALUE rb_f_autoload _((VALUE, VALUE, VALUE));
void rb_gc_mark_global_tbl _((void));
VALUE rb_f_trace_var _((int, VALUE*));
VALUE rb_f_untrace_var _((int, VALUE*));
VALUE rb_gvar_set2 _((char*, VALUE));
VALUE rb_f_global_variables _((void));
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_set _((VALUE, ID, VALUE));
VALUE rb_ivar_defined _((VALUE, ID));
VALUE obj_instance_variables _((VALUE));
VALUE mod_const_at _((VALUE, VALUE));
VALUE mod_constants _((VALUE));
VALUE mod_const_of _((VALUE, VALUE));
VALUE rb_obj_instance_variables _((VALUE));
VALUE rb_obj_remove_instance_variable _((VALUE, VALUE));
VALUE rb_mod_const_at _((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_autoload_defined _((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;};
%%
__LINE__, k__LINE__, k__LINE__, EXPR_END
__FILE__, k__FILE__, k__FILE__, EXPR_END
BEGIN, klBEGIN, klBEGIN, EXPR_END
END, klEND, klEND, EXPR_END
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 */
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 MAX_WORD_LENGTH 8
#define MIN_HASH_VALUE 6
#define MAX_HASH_VALUE 52
/* maximum key range = 47, duplicates = 0 */
#define MAX_HASH_VALUE 55
/* maximum key range = 50, duplicates = 0 */
#ifdef __GNUC__
inline
@ -19,19 +19,19 @@ hash (str, len)
{
static unsigned char asso_values[] =
{
53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 11, 53, 53, 34, 53, 1, 35,
53, 1, 53, 53, 53, 53, 53, 53, 1, 53,
53, 53, 53, 53, 53, 53, 53, 53, 53, 53,
53, 53, 53, 53, 53, 53, 53, 29, 1, 2,
1, 1, 4, 24, 53, 17, 53, 20, 9, 2,
9, 26, 14, 53, 5, 1, 1, 16, 53, 21,
24, 9, 53, 53, 53, 53, 53, 53,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 11, 56, 56, 36, 56, 1, 37,
31, 1, 56, 56, 56, 56, 29, 56, 1, 56,
56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
56, 56, 56, 56, 56, 1, 56, 32, 1, 2,
1, 1, 4, 23, 56, 17, 56, 20, 9, 2,
9, 26, 14, 56, 5, 1, 1, 16, 56, 21,
20, 9, 56, 56, 56, 56, 56, 56,
};
register int hval = len;
@ -87,17 +87,19 @@ rb_reserved_word (str, len)
{"until", kUNTIL, kUNTIL_MOD, EXPR_BEG},
{"unless", kUNLESS, kUNLESS_MOD, EXPR_BEG},
{"or", kOR, kOR, EXPR_BEG},
{"and", kAND, kAND, EXPR_BEG},
{"next", kNEXT, kNEXT, EXPR_END},
{"when", kWHEN, kWHEN, EXPR_BEG},
{"redo", kREDO, kREDO, EXPR_END},
{"class", kCLASS, kCLASS, EXPR_CLASS},
{"next", kNEXT, kNEXT, EXPR_END},
{"and", kAND, kAND, 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},
{"BEGIN", klBEGIN, klBEGIN, EXPR_END},
{"",}, {"",},
{"while", kWHILE, kWHILE_MOD, EXPR_BEG},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",}, {"",},
{"",},
{"alias", kALIAS, kALIAS, EXPR_FNAME},
};

31
lib/Env.rb Normal file
View file

@ -0,0 +1,31 @@
# Env.rb -- imports environment variables as global variables
#
# Usage:
#
# require 'Env'
# p $USER
# $USER = "matz"
# p ENV["USER"]
for k,v in ENV
next unless /^[a-zA-Z][_a-zA-Z0-9]*/ =~ k
eval <<EOS
$#{k} = %q!#{v}!
trace_var "$#{k}", proc{|v|
ENV[%q!#{k}!] = v;
$#{k} = %q!#{v}!
if v == nil
untrace_var "$#{k}"
end
}
EOS
end
if __FILE__ == $0
p $TERM
$TERM = nil
p $TERM
p ENV["TERM"]
$TERM = "foo"
p ENV["TERM"]
end

61
lib/README Normal file
View file

@ -0,0 +1,61 @@
English.rb access global variables by english names
Env.rb access environment variables as globals
README this file
base64.rb encode/decode base64 (bit obsolete)
cgi-lib.rb decode CGI data
complex.rb complex number suppor
date.rb date object (compatible)
date2.rb date object based on Julian date
debug.rb ruby debugger
delegate.rb delegate messages to other object
e2mmap.rb exception utilities
eregex.rb extended regular expression (just a proof of concept)
final.rb add finalizer to the object (simple)
finalize.rb add finalizer to the object
find.rb traverse directory tree
ftools.rb file tools
ftplib.rb ftp access library
getopts.rb parse command line options
importenv.rb access environment variables as globals
jcode.rb japanese text handling (replace String methods)
mailread.rb read mail headers
mathn.rb extended math operation
matrix.rb matrix calculation library
mkmf.rb Makefile maker
monitor.rb exclusive region monitor for thread
mutex_m.rb mutex mixin
observer.rb observer desing pattern library (provides Observable)
open3.rb open subprocess connection stdin/stdout/stderr
ostruct.rb python style object
parsearg.rb argument parser using getopts
parsedate.rb parse date string
ping.rb
profile.rb ruby profiler
pstore.rb persistent object strage using marshal
rational.rb rational number support
readbytes.rb define IO#readbytes
shell.rb shell like operation under Ruby (imcomlete)
shellwords.rb split into words like shell
singleton.rb singleton design pattern library
sync.rb 2 phase lock
telnet.rb telnet library
tempfile.rb temporary file that automatically removed
thread.rb thread support
thwait.rb thread syncronization class
timeout.rb provids timeout
tk.rb Tk interface
tkafter.rb
tkbgerror.rb Tk error module
tkcanvas.rb Tk canvas interface
tkclass.rb provides generic names for Tk classes
tkdialog.rb Tk dialog class
tkentry.rb Tk entry class
tkfont.rb Tk font support
tkmenubar.rb TK menubar utility
tkmngfocus.rb focus manager
tkpalette.rb pallete support
tkscrollbox.rb scroll box, also example of compound widget
tktext.rb text classes
tkvirtevent.rb virtual event support
tracer.rb execution tracer
weakref.rb weak reference class

View file

@ -1,50 +1,25 @@
def decode64(str)
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
require "kconv"
def j2e(str)
while str =~ /\033\$B([^\033]*)\033\(B/
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
def decode64(str)
str.unpack("m")[0]
end
def decode_b(str)
str.gsub!(/=\?ISO-2022-JP\?B\?([!->@-~]+)\?=/i) {
decode64($1)
}
str = Kconv::toeuc(str)
str.gsub!(/=\?SHIFT_JIS\?B\?([!->@-~]+)\?=/i) {
decode64($1)
}
str = Kconv::toeuc(str)
str.gsub!(/\n/, ' ')
str.gsub!(/\0/, '')
j2e(str)
str
end
def encode64(bin)
encode = ""
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)
[bin].pack("m")
end
def b64encode(bin, len = 60)

View file

@ -1,4 +1,3 @@
#!/usr/local/bin/ruby
#
# Get CGI String
#
@ -7,26 +6,26 @@
# foo = CGI.new
# foo['field'] <== value of 'field'
# 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 ENV['SERVER_SOFTWARE'] =~ /^Microsoft-/ then
Dir.chdir ENV['PATH_TRANSLATED'].sub(/[^\\]+$/, '')
end
require "shellwords.rb"
require "delegate"
class CGI
include Shellwords
class CGI < SimpleDelegator
attr("inputs")
# original is CGI.pm
def read_from_cmdline
words = shellwords(if not ARGV.empty? then
require "shellwords.rb"
words = Shellwords.shellwords(if not ARGV.empty? then
ARGV.join(' ')
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/, '')
end.gsub(/\\=/, '%3D').gsub(/\\&/, '%26'))
@ -47,32 +46,32 @@ class CGI
end
module_function :escape, :unescape
def initialize
# exception messages should be printed to stdout.
STDERR.reopen(STDOUT)
def initialize(input = $stdin)
@inputs = {}
case ENV['REQUEST_METHOD']
when "GET"
# exception messages should be printed to stdout.
STDERR.reopen(STDOUT)
ENV['QUERY_STRING'] or ""
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
read_from_cmdline
end.split(/&/).each do |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
super(@inputs)
end
def keys
@inputs.keys
end
def [](key)
@inputs[key]
end
def CGI.message(msg, title = "")
print "Content-type: text/html\n\n"
print "<html><head><title>"
@ -84,7 +83,7 @@ class CGI
end
def CGI.error
m = $!.dup
m = $!.to_s.dup
m.gsub!(/&/, '&amp;')
m.gsub!(/</, '&lt;')
m.gsub!(/>/, '&gt;')

View file

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

View file

@ -1,8 +1,8 @@
#
# Date.rb -
# $Release Version: $
# $Revision: 1.2 $
# $Date: 1997/02/14 11:05:29 $
# $Revision: 1.1.1.1.4.5 $
# $Date: 1998/03/03 02:39:34 $
# by Yasuo OHBA(SHL Japan Inc. Technology Dept.)
#
# --
@ -17,15 +17,34 @@
class Date
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)
if y.kind_of?(String) && y.size == 8
@year = y[0,4].to_i
@month = y[4,2].to_i
@day = y[6,2].to_i
if y.kind_of?(String)
case y
when /(\d\d\d\d)-?(?:(\d\d)-?(\d\d)?)?/
@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
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 = ml[m.downcase]
m = Monthtab[m.downcase]
if m.nil?
raise ArgumentError, "Wrong argument. (month)"
end
@ -53,25 +72,35 @@ class Date
def period
return Date.period!(@year, @month, @day)
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
dl = Date.daylist(@year)
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)
return (period + 5) % 7
end
Weektag = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
def name_of_week
return Weektag[self.day_of_week]
end
def name_of_month
return Monthtag[@month-1]
end
def +(o)
if o.kind_of?(Numeric)
d = Integer(self.period + o)
@ -80,6 +109,9 @@ class Date
else
raise TypeError, "Illegal type. (Integer or Date)"
end
if d <= 0
raise ArgumentError, "argument out of range. (self > other)"
end
return Date.at(d)
end
@ -117,14 +149,13 @@ class Date
end
def leapyear?
if Date.leapyear(@year) == 1
return FALSE
else
return TRUE
end
Date.leapyear(@year) != 1
end
def _check_date
if @year == nil or @month == nil or @day == nil
raise ArgumentError, "argument contains nil"
end
m = Date.daylist(@year)
if @month < 1 || @month > 12
raise ArgumentError, "argument(month) out of range."
@ -151,7 +182,7 @@ end
def Date.at(d)
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
if d.kind_of? Date
return Date.at(d.period)
@ -189,10 +220,10 @@ def Date.period!(y, m, d)
p += dl[mm]
end
p += (y - 1) * 365 + ((y - 1) / 4.0).to_i
if (y - 1) > 1752
p -= ((y - 1 - 1752) / 100.0).to_i
p += ((y - 1 - 1752) / 400.0).to_i
p -= (14 - 3)
if y > 1752
p -= ((y - 1) / 100.0).to_i
p += ((y - 1) / 400.0).to_i
p += 2
elsif y == 1752 && m == 9 && d >= 14 && d <= 30
p -= (14 - 3)
end

219
lib/date2.rb Normal file
View file

@ -0,0 +1,219 @@
# date.rb: Written by Tadayoshi Funaba 1998
# $Id: date.rb,v 1.4 1998/06/01 12:52:33 tadf Exp $
class Date
include Comparable
MONTHNAMES = [ '', 'January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December' ]
DAYNAMES = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday',
'Friday', 'Saturday' ]
ITALY = 2299161 # Oct 15, 1582
ENGLAND = 2361222 # Sept 14, 1752
def Date.civil_to_jd(y, m, d, gs = true)
if m <= 2 then
y -= 1
m += 12
end
a = (y / 100).to_i
b = 2 - a + (a / 4).to_i
jd = (365.25 * (y + 4716)).to_i +
(30.6001 * (m + 1)).to_i +
d + b - 1524
unless
(if gs.kind_of? Numeric then jd >= gs else gs end) then
jd -= b
end
jd
end
def Date.jd_to_civil(jd, gs = true)
unless
(if gs.kind_of? Numeric then jd >= gs else gs end) then
a = jd
else
x = ((jd - 1867216.25) / 36524.25).to_i
a = jd + 1 + x - (x / 4).to_i
end
b = a + 1524
c = ((b - 122.1) / 365.25).to_i
d = (365.25 * c).to_i
e = ((b - d) / 30.6001).to_i
dom = b - d - (30.6001 * e).to_i
if e <= 13 then
m = e - 1
y = c - 4716
else
m = e - 13
y = c - 4715
end
return y, m, dom
end
def Date.mjd_to_jd(mjd)
mjd + 2400000.5
end
def Date.jd_to_mjd(jd)
jd - 2400000.5
end
def Date.tjd_to_jd(tjd)
tjd + 2440000.5
end
def Date.jd_to_tjd(jd)
jd - 2440000.5
end
def Date.julian_leap? (y)
y % 4 == 0
end
def Date.gregorian_leap? (y)
y % 4 == 0 and y % 100 != 0 or y % 400 == 0
end
def Date.leap? (y)
Date.gregorian_leap?(y)
end
def initialize(jd = 0, gs = ITALY)
@jd, @gs = jd, gs
end
def Date.exist? (y, m, d, gs = true)
jd = Date.civil_to_jd(y, m, d, gs)
if [y, m, d] == Date.jd_to_civil(jd, gs) then
jd
end
end
def Date.new3(y = -4712, m = 1, d = 1, gs = ITALY)
unless jd = Date.exist?(y, m, d, gs) then
fail ArgumentError, 'invalid date'
end
Date.new(jd, gs)
end
def Date.today(gs = ITALY)
Date.new(Date.civil_to_jd(*(Time.now.to_a[3..5].reverse << gs)), gs)
end
def jd
@jd
end
def mjd
def self.mjd; @mjd end
@mjd = Date.jd_to_mjd(@jd)
end
def tjd
def self.tjd; @tjd end
@tjd = Date.jd_to_tjd(@jd)
end
def civil
def self.year; @year end
def self.mon; @mon end
def self.mday; @mday end
@year, @mon, @mday = Date.jd_to_civil(@jd, @gs)
end
private :civil
def year
civil
@year
end
def yday
def self.yday; @yday end
ns = if @gs.kind_of? Numeric then @jd >= @gs else @gs end
jd = Date.civil_to_jd(year - 1, 12, 31, ns)
@yday = @jd - jd
end
def mon
civil
@mon
end
def mday
civil
@mday
end
def wday
def self.wday; @wday end
@wday = (@jd + 1) % 7
end
def leap?
def self.leap?; @leap_p end
ns = if @gs.kind_of? Numeric then @jd >= @gs else @gs end
jd = Date.civil_to_jd(year, 2, 28, ns)
@leap_p = Date.jd_to_civil(jd + 1, ns)[1] == 2
end
def + (other)
if other.kind_of? Numeric then
return Date.new(@jd + other, @gs)
end
fail TypeError, 'expected numeric'
end
def - (other)
if other.kind_of? Numeric then
return Date.new(@jd - other, @gs)
elsif other.kind_of? Date then
return @jd - other.jd
end
fail TypeError, 'expected numeric or date'
end
def <=> (other)
if other.kind_of? Numeric then
return @jd <=> other
elsif other.kind_of? Date then
return @jd <=> other.jd
end
fail TypeError, 'expected numeric or date'
end
def downto(min)
@jd.downto(min.jd) do |jd|
yield Date.new(jd, @gs)
end
end
def upto(max)
@jd.upto(max.jd) do |jd|
yield Date.new(jd, @gs)
end
end
def step(max, step)
@jd.step(max.jd, step) do |jd|
yield Date.new(jd, @gs)
end
end
def eql? (other)
self == other
end
def hash
@jd
end
def to_s
format('%04d-%02d-%02d', year, mon, mday)
end
end

View file

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

View file

@ -1,26 +1,51 @@
# Delegation class that delegates even methods defined in super class,
# which can not be covered with normal method_missing hack.
#
# Delegater is the abstract delegation class. Need to redefine
# `__getobj__' method in the subclass. SimpleDelegater is the
# Delegator is the abstract delegation class. Need to redefine
# `__getobj__' method in the subclass. SimpleDelegator is the
# concrete subclass for simple delegation.
#
# Usage:
# foo = Object.new
# foo = SimpleDelegater.new(foo)
# foo.type # => Object
# foo2 = SimpleDelegator.new(foo)
# foo.hash == foo2.hash # => true
#
# Foo = DelegateClass(Array)
#
# class ExtArray<DelegateClass(Array)
# ...
# end
class Delegater
class Delegator
def initialize(obj)
preserved = ["id", "equal?", "__getobj__"]
preserved = ::Kernel.instance_methods
preserved -= ["to_s","to_a","inspect","==","=~","==="]
for t in self.type.ancestors
preserved |= t.instance_methods
break if t == Delegater
preserved |= t.private_instance_methods
preserved |= t.protected_instance_methods
break if t == Delegator
end
for method in obj.methods
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
@ -30,7 +55,7 @@ class Delegater
end
class SimpleDelegater<Delegater
class SimpleDelegator<Delegator
def initialize(obj)
super
@ -41,4 +66,61 @@ class SimpleDelegater<Delegater
@obj
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

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