From ee5ab9cc136baf18756abc6bd5d136a0231f973e Mon Sep 17 00:00:00 2001 From: matz Date: Mon, 9 Nov 1998 09:11:52 +0000 Subject: 1.1c7 git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/v1_1r@316 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- COPYING | 358 +++++++++------ ChangeLog | 96 ++++ MANIFEST | 9 +- Makefile.in | 10 +- array.c | 25 +- config.dj | 42 -- config_h.dj | 64 +++ config_s.dj | 49 ++ configure.bat | 3 +- defines.h | 4 + dir.c | 11 + dln.c | 2 +- enum.c | 1 + eval.c | 42 +- ext/curses/curses.c | 8 +- ext/curses/extconf.rb | 2 +- ext/extmk.rb.in | 40 +- gc.c | 1 + instruby.rb | 22 +- intern.h | 1 + io.c | 24 +- lib/Env.rb | 1 + lib/README | 61 +++ lib/ping.rb | 25 +- lib/telnet.rb | 103 +++-- lib/timeout.rb | 42 ++ marshal.c | 8 +- missing/nt.h | 6 + missing/snprintf.c | 1197 ------------------------------------------------- missing/vsnprintf.c | 1150 +++++++++++++++++++++++++++++++++++++++++++++++ mkconfig.rb | 2 +- parse.y | 20 +- re.c | 18 +- regex.c | 55 +-- ruby.h | 92 ++-- sample/README | 60 +++ sample/mkproto.rb | 8 +- sample/ruby-mode.el | 9 +- sample/test.rb | 6 +- string.c | 22 +- time.c | 73 ++- top.sed | 96 ++-- version.h | 4 +- 43 files changed, 2200 insertions(+), 1672 deletions(-) delete mode 100644 config.dj create mode 100644 config_h.dj create mode 100644 config_s.dj create mode 100644 lib/README create mode 100644 lib/timeout.rb delete mode 100644 missing/snprintf.c create mode 100644 missing/vsnprintf.c create mode 100644 sample/README diff --git a/COPYING b/COPYING index 3c68f02bb4..eeb586b392 100644 --- a/COPYING +++ b/COPYING @@ -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". - - 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. - - 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: - - a) cause the modified files to carry prominent notices stating that - you changed the files and the date of any change; and - - 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). - - 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. - - 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. - -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. + 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". + +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. + + 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. + +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. + + 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: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + 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. + + 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: - - 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, - - 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, - - c) accompany it with the information you received as to where the - corresponding source code may be obtained. (This alternative is +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. + +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. + +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. + + 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.) - -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. - - 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. - - 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. + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +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. + +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. 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. Copyright (C) 19yy 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. , 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. diff --git a/ChangeLog b/ChangeLog index 87b4d2418d..14bc362df3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,99 @@ +Mon Nov 9 17:55:19 1998 Yukihiro Matsumoto + + * version 1.1c7 released. + +Fri Nov 6 19:25:27 1998 Takao KAWAMURA + + * sample/ruby-mode.el: font-lock patch. + +Thu Nov 5 15:42:22 1998 Yukihiro Matsumoto + + * sample/README, lib/README: simple description for each file. + +Wed Nov 4 18:14:19 1998 Yukihiro Matsumoto + + * eval.c (assign): attribute assignment should be called as public. + +Mon Nov 2 18:24:33 1998 Yukihiro Matsumoto + + * eval.c (thread_create): was accessing modified status. + +Sun Nov 1 01:18:52 1998 EGUCHI Osamu + + * gc.c (xrealloc): size 0 needs round up to 1. + +Sat Oct 31 23:18:34 1998 Yukihiro Matsumoto + + * string.c (rb_str_split_method): negative LIMIT means number of + splitted fields are unlimited, as in perl. + + * string.c (rb_str_split_method): if LIMIT is unspecified, + trailing null fields are stripped. + +Sat Oct 31 04:16:14 1998 Inaba Hiroto + + * string.c (str_aref): regexp index SEGVed. + +Fri Oct 30 14:33:47 1998 Yukihiro Matsumoto + + * re.c (reg_match): returns nil for unmatch. + + * dir.c (dir_entries): new method. + + * eval.c (block_pass): do not push block, substitute it. + +Wed Oct 28 11:37:42 1998 TAMITO + + * io.c (f_select): fd number comparison bug. + +Sun Oct 25 22:59:27 1998 Yukihiro Matsumoto + + * regex.c (set_list_bits): was using wrong offset. + +Mon Oct 19 11:50:00 1998 Motoyuki Kasahara + + * ext/extmk.rb: Load '@top_srcdir@/lib/find.rb', not + '../lib/find.rb'. + * ext/extmk.rb: Distinguish between `top_srcdir' and `topdir'. + * Makefile.in (CFLAGS): Add `-I.'. + * Makefile.in (lex.c): Give `@srcdir@/keywords' to gperf, not + `keywords'. + * instruby.rb: Use `CONFIG["bindir"]', instead of `prefix + "/bin"'. + * instruby.rb: Use `CONFIG["libdir"]', instead of `prefix + "/lib"'. + * instruby.rb Use `CONFIG["mandir"]', instead of `prefix + "/man"'. + * instruby.rb (wdir): Add the variable to preserve the current + working directory. + * instruby.rb: Chdir to wdir before install `config.h' and + `rbconfig.rb'. + +Mon Oct 19 10:07:01 1998 EGUCHI Osamu + + * eval.c (rb_eval): reduce recursive calls to rb_eval(). + +Thu Oct 15 13:54:48 1998 Yukihiro Matsumoto + + * parse.y (arg): local variabls can be accessed within right side + expression in assignment, notably in blocks. + +Mon Oct 12 13:27:15 1998 Yukihiro Matsumoto + + * eval.c (rb_call0): check stack depth more frequently. + +Fri Oct 9 17:01:14 1998 Yukihiro Matsumoto + + * io.c (read_all): read() returns "" at immediate EOF. + + * io.c (io_read): read(nil) read all until EOF. + +Thu Oct 8 13:32:13 1998 Yukihiro Matsumoto + + * time.c (time_dump): marshal can dump Time object now. + + * marshal.c (Init_marshal): rename marshal methods `_dump_to' to + `_dump', `_load_from' to `_load'. + + * parse.y (rb_intern): "+=".intern generates proper symbol. + Mon Oct 5 18:31:53 1998 Yukihiro Matsumoto * version 1.1c6 released. diff --git a/MANIFEST b/MANIFEST index 9826692850..95dc640c53 100644 --- a/MANIFEST +++ b/MANIFEST @@ -14,7 +14,8 @@ compar.c configure configure.bat configure.in -config.dj +config_h.dj +config_s.dj config.guess config.sub defines.h @@ -47,6 +48,7 @@ node.h numeric.c object.c pack.c +parse.c parse.y process.c random.c @@ -85,6 +87,7 @@ ext/extmk.rb.in ext/extmk.rb.nt lib/English.rb lib/Env.rb +lib/README lib/base64.rb lib/cgi-lib.rb lib/complex.rb @@ -125,6 +128,7 @@ lib/telnet.rb lib/tempfile.rb lib/thread.rb lib/thwait.rb +lib/timeout.rb lib/tk.rb lib/tkafter.rb lib/tkbgerror.rb @@ -153,7 +157,6 @@ missing/mkdir.c missing/nt.c missing/nt.h missing/setenv.c -missing/snprintf.c missing/strcasecmp.c missing/strchr.c missing/strdup.c @@ -162,7 +165,9 @@ 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 diff --git a/Makefile.in b/Makefile.in index 010f8dea33..f3ac3dd890 100644 --- a/Makefile.in +++ b/Makefile.in @@ -11,7 +11,7 @@ PURIFY = @SET_MAKE@ prefix = @prefix@ -CFLAGS = @CFLAGS@ -I@srcdir@ -I@includedir@ +CFLAGS = @CFLAGS@ -I. -I@srcdir@ -I@includedir@ LDFLAGS = @STATIC@ $(CFLAGS) @LDFLAGS@ EXTLIBS = LIBS = @LIBS@ $(EXTLIBS) @@ -84,7 +84,7 @@ ruby$(binsuffix): $(LIBRUBY) $(MAINOBJ) $(EXTOBJS) libruby.a: $(OBJS) dmyext.o @AR@ rcu $@ $(OBJS) dmyext.o - @-@RANLIB@ $(LIBRUBY) 2> /dev/null || true + @-@RANLIB@ $@ 2> /dev/null || true libruby.so: $(OBJS) dmyext.o $(LDSHARED) $(DLDFLAGS) $(SOLIBS) $(OBJS) dmyext.o -o $@ @@ -117,7 +117,7 @@ rbconfig.rb: config.status miniruby$(binsuffix) $(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) $< @@ -147,8 +147,8 @@ mkdir.o: @srcdir@/missing/mkdir.c setenv.o: @srcdir@/missing/setenv.c $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/setenv.c -snprintf.o: @srcdir@/missing/snprintf.c - $(CC) $(CFLAGS) $(CPPFLAGS) -c @srcdir@/missing/snprintf.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 diff --git a/array.c b/array.c index 6150d862dd..10d554ba2c 100644 --- a/array.c +++ b/array.c @@ -370,32 +370,29 @@ beg_len(range, begp, lenp, len) int len; { int beg, end; + int b, e; if (!range_beg_end(range, &beg, &end)) return FALSE; - - if ((beg > 0 && end > 0 || beg < 0 && end < 0) && beg > end) { - IndexError("end smaller than beg [%d..%d]", beg, end); - } + b = beg; e = end; if (beg < 0) { beg = len + beg; if (beg < 0) beg = 0; } + if (end < 0) { + end = len + end; + if (end < 0) end = -1; + } + if (beg > end) { + IndexError("end smaller than beg [%d..%d]", b, e); + } + *begp = beg; if (beg > len) { *lenp = 0; } else { - if (end < 0) { - end = len + end; - if (end < 0) end = -1; - } - if (beg > end) { - *lenp = 0; - } - else { - *lenp = end - beg +1; - } + *lenp = end - beg +1; } return TRUE; } diff --git a/config.dj b/config.dj deleted file mode 100644 index 896b00fdda..0000000000 --- a/config.dj +++ /dev/null @@ -1,42 +0,0 @@ -#define 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 HAVE_UNISTD_H 1 -#define HAVE_LIMITS_H 1 -#define HAVE_SYS_FILE_H 1 -#define HAVE_PWD_H 1 -#define HAVE_SYS_TIME_H 1 -#define HAVE_SYS_TIMES_H 1 -#define HAVE_SYS_PARAM_H 1 -#define HAVE_SYS_WAIT_H 1 -#define HAVE_STRING_H 1 -#define HAVE_UTIME_H 1 -#define HAVE_MEMORY_H 1 -#define HAVE_ST_BLKSIZE 1 -#define HAVE_ST_RDEV 1 -#define GETGROUPS_T gid_t -#define RETSIGTYPE void -#define HAVE_ALLOCA 1 -#define vfork fork -#define HAVE_FMOD 1 -#define HAVE_RANDOM 1 -#define HAVE_WAITPID 1 -#define HAVE_GETCWD 1 -#define HAVE_TRUNCATE 1 -#define HAVE_CHSIZE 1 -#define HAVE_TIMES 1 -#define HAVE_UTIMES 1 -/* #define HAVE_FCNTL 1 */ -/* #define HAVE_SETITIMER 1 */ -#define HAVE_GETGROUPS 1 -#define HAVE_SIGPROCMASK 1 -#define FILE_COUNT _cnt -#define DLEXT ".so" -#define RUBY_LIB ";/usr/local/lib/ruby;." -#define RUBY_ARCHLIB "/usr/local/lib/ruby/i386-djgpp" -#define RUBY_PLATFORM "i386-djgpp" diff --git a/config_h.dj b/config_h.dj new file mode 100644 index 0000000000..2a81c29594 --- /dev/null +++ b/config_h.dj @@ -0,0 +1,64 @@ +#define 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" diff --git a/config_s.dj b/config_s.dj new file mode 100644 index 0000000000..d6d3836613 --- /dev/null +++ b/config_s.dj @@ -0,0 +1,49 @@ +s%@CFLAGS@%-g -O2%g +s%@CPPFLAGS@%%g +s%@CXXFLAGS@%%g +s%@DEFS@% -DTHREAD=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%@arch@%i386-djgpp%g diff --git a/configure.bat b/configure.bat index 35f9d4893d..093d43549d 100644 --- a/configure.bat +++ b/configure.bat @@ -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 diff --git a/defines.h b/defines.h index 139d62efb4..1a857581fb 100644 --- a/defines.h +++ b/defines.h @@ -34,6 +34,10 @@ #include "missing/nt.h" #endif +#ifndef EXTERN +#define EXTERN extern +#endif + #ifdef sparc #define FLUSH_REGISTER_WINDOWS asm("ta 3") #else diff --git a/dir.c b/dir.c index 31524ddba5..44f662e2e8 100644 --- a/dir.c +++ b/dir.c @@ -426,6 +426,16 @@ dir_foreach(io, dirname) return rb_ensure(dir_each, dir, dir_close, dir); } +static VALUE +dir_entries(io, dirname) + VALUE io, dirname; +{ + VALUE dir; + + dir = rb_funcall(cDir, rb_intern("open"), 1, dirname); + return rb_ensure(rb_Array, dir, dir_close, dir); +} + void Init_Dir() { @@ -436,6 +446,7 @@ Init_Dir() rb_define_singleton_method(cDir, "new", dir_s_open, 1); rb_define_singleton_method(cDir, "open", dir_s_open, 1); rb_define_singleton_method(cDir, "foreach", dir_foreach, 1); + rb_define_singleton_method(cDir, "entries", dir_entries, 1); rb_define_method(cDir,"read", dir_read, 0); rb_define_method(cDir,"each", dir_each, 0); diff --git a/dln.c b/dln.c index c7f808983c..9fe4208f4c 100644 --- a/dln.c +++ b/dln.c @@ -78,7 +78,7 @@ int eaccess(); #endif #ifndef FUNCNAME_PATTERN -# if defined(__hp9000s300) || defined(__NetBSD__) || defined(__BORLANDC__) || defined(__FreeBSD__) || defined(NeXT) || defined(__WATCOMC__) +# 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" diff --git a/enum.c b/enum.c index 4cf490e4ca..ffc0734f44 100644 --- a/enum.c +++ b/enum.c @@ -377,6 +377,7 @@ Init_Enumerable() mEnumerable = rb_define_module("Enumerable"); rb_define_method(mEnumerable,"to_a", enum_to_a, 0); + rb_define_method(mEnumerable,"entries", enum_to_a, 0); rb_define_method(mEnumerable,"sort", enum_sort, 0); rb_define_method(mEnumerable,"grep", enum_grep, 1); diff --git a/eval.c b/eval.c index 2da03409ab..9cf23d3827 100644 --- a/eval.c +++ b/eval.c @@ -422,12 +422,6 @@ static struct BLOCK *the_block; _block.vmode = scope_vmode; \ the_block = &_block; -#define PUSH_BLOCK2(b) { \ - struct BLOCK _block; \ - _block = *b; \ - _block.prev = the_block; \ - the_block = &_block; - #define POP_BLOCK() \ the_block = _block.prev; \ } @@ -530,7 +524,7 @@ dvar_asgn_push(id, value) the_dyna_vars->next = vars; } else { - dyna_var_push(id, value); + dyna_var_asgn(id, value); } } @@ -704,10 +698,6 @@ rb_check_safe_str(x) Raise(eSecurityError, "Insecure operation - %s", rb_id2name(the_frame->last_func)); } - if (verbose) { - Warning("Insecure operation - %s", - rb_id2name(the_frame->last_func)); - } } } @@ -1611,7 +1601,11 @@ rb_eval(self, node) if (!node) RETURN(Qnil); switch (nd_type(node)) { - case NODE_BLOCK: + case NODE_BLOCK: + if (!node->nd_next) { + node = node->nd_head; + goto again; + } while (node) { result = rb_eval(self, node->nd_head); node = node->nd_next; @@ -2337,6 +2331,7 @@ rb_eval(self, node) } if (str2) { str_cat(str, RSTRING(str2)->ptr, RSTRING(str2)->len); + if (str_tainted(str2)) str_taint(str); } list = list->nd_next; } @@ -3050,7 +3045,7 @@ assign(self, lhs, val) recv = rb_eval(self, lhs->nd_recv); if (!lhs->nd_args->nd_head) { /* attr set */ - rb_funcall2(recv, lhs->nd_mid, 1, &val); + rb_call(CLASS_OF(recv), recv, lhs->nd_mid, 1, &val, 0); } else { /* array set */ @@ -3058,7 +3053,8 @@ assign(self, lhs, val) args = rb_eval(self, lhs->nd_args); RARRAY(args)->ptr[RARRAY(args)->len-1] = val; - rb_apply(recv, lhs->nd_mid, args); + rb_call(CLASS_OF(recv), recv, lhs->nd_mid, + RARRAY(args)->len, RARRAY(args)->ptr, 0); } } break; @@ -3353,7 +3349,7 @@ rb_call0(klass, recv, id, argc, argv, body, nosuper) break; } - if ((++tick & 0xfff) == 0 && stack_length() > STACK_LEVEL_MAX) + if ((++tick & 0x3ff) == 0 && stack_length() > STACK_LEVEL_MAX) Raise(eSysStackError, "stack level too deep"); PUSH_ITER(itr); @@ -5014,6 +5010,7 @@ static VALUE proc_call(proc, args) VALUE proc, args; /* OK */ { + struct BLOCK * volatile old_block; struct BLOCK *data; volatile VALUE result = Qnil; int state; @@ -5035,7 +5032,8 @@ proc_call(proc, args) orphan = blk_orphan(data); /* PUSH BLOCK from data */ - PUSH_BLOCK2(data); + old_block = the_block; + the_block = data; PUSH_ITER(ITER_CUR); the_frame->iter = ITER_CUR; @@ -5073,7 +5071,7 @@ proc_call(proc, args) if (the_block->tag->dst == state) { state &= TAG_MASK; } - POP_BLOCK(); + the_block = old_block; safe_level = safe; if (state) { @@ -5101,6 +5099,7 @@ block_pass(self, node) NODE *node; { VALUE block = rb_eval(self, node->nd_body); + struct BLOCK * volatile old_block; struct BLOCK *data; volatile VALUE result = Qnil; int state; @@ -5122,7 +5121,8 @@ block_pass(self, node) orphan = blk_orphan(data); /* PUSH BLOCK from data */ - PUSH_BLOCK2(data); + old_block = the_block; + the_block = data; PUSH_ITER(ITER_PRE); the_frame->iter = ITER_PRE; if (FL_TEST(block, PROC_TAINT)) { @@ -5151,7 +5151,7 @@ block_pass(self, node) state &= TAG_MASK; orphan = 2; } - POP_BLOCK(); + the_block = old_block; safe_level = safe; if (state) { @@ -6251,6 +6251,7 @@ thread_create(fn, arg) { thread_t th = thread_alloc(); int state; + enum thread_status status; #if defined(HAVE_SETITIMER) && !defined(__BOW__) static init = 0; @@ -6288,8 +6289,9 @@ thread_create(fn, arg) } } POP_TAG(); + status = th->status; thread_remove(); - if (state && th->status != THREAD_TO_KILL && !NIL_P(errinfo)) { + if (state && status != THREAD_TO_KILL && !NIL_P(errinfo)) { if (state == TAG_FATAL) { /* fatal error within this thread, need to stop whole script */ main_thread->errinfo = errinfo; diff --git a/ext/curses/curses.c b/ext/curses/curses.c index 69b5636a25..d8305a9db8 100644 --- a/ext/curses/curses.c +++ b/ext/curses/curses.c @@ -155,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; } @@ -252,7 +256,9 @@ static VALUE curses_flash(obj) VALUE obj; { +#ifdef HAVE_FLASH flash(); +#endif return Qnil; } diff --git a/ext/curses/extconf.rb b/ext/curses/extconf.rb index 720bccb8d2..244c9085c4 100644 --- a/ext/curses/extconf.rb +++ b/ext/curses/extconf.rb @@ -15,7 +15,7 @@ else end if make then - for f in ["isendwin", "ungetch", "beep"] + for f in ["isendwin", "ungetch", "beep", "doupdate", "flash"] have_func(f) end create_makefile("curses") diff --git a/ext/extmk.rb.in b/ext/extmk.rb.in index e8dc56604f..aaa3b6d3cf 100644 --- a/ext/extmk.rb.in +++ b/ext/extmk.rb.in @@ -1,7 +1,7 @@ #! /usr/local/bin/ruby $".push 'mkmf.rb' #" -load '../lib/find.rb' +load '@top_srcdir@/lib/find.rb' if ARGV[0] == 'static' $force_static = TRUE @@ -20,8 +20,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 @@ -63,8 +71,8 @@ CFLAGS = "@CFLAGS@".gsub(/-c..-stack=[0-9]+ */, '') else CFLAGS = "@CFLAGS@" end -LINK = "@CC@ -o conftest -I#{$topdir} -I@includedir@ " + CFLAGS + " %s @LDFLAGS@ %s conftest.c @LIBS@ %s" -CPP = "@CPP@ @CPPFLAGS@ -I#{$topdir} -I@includedir@ " + CFLAGS + " %s conftest.c" +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 /win32|djgpp|mingw32|m68k-human/i =~ PLATFORM $null = open("nul", "w") @@ -255,7 +263,7 @@ def create_makefile(target) $DLDFLAGS = $DLDFLAGS + " -L" + $topdir end - $srcdir = $topdir + "/ext/" + target + $srcdir = $top_srcdir + "/ext/" + target mfile = open("Makefile", "w") mfile.printf "\ SHELL = /bin/sh @@ -270,7 +278,7 @@ hdrdir = #{$topdir} CC = @CC@ prefix = @prefix@ -CFLAGS = %s -I#{$topdir} -I@includedir@ %s #$CFLAGS %s +CFLAGS = %s -I#{$topdir} -I#{$top_srcdir} -I@includedir@ %s #$CFLAGS %s DLDFLAGS = #$DLDFLAGS #$LDFLAGS LDSHARED = @LDSHARED@ ", if $static then "" else "@CCDLFLAGS@" end, CFLAGS, $defs.join(" ") @@ -294,7 +302,7 @@ archdir = $(libdir)/@arch@ mfile.printf "OBJS = " if !$objs then $objs = [] - for f in Dir["#{$topdir}/ext/#{target}/*.{c,cc}"] + for f in Dir["#{$top_srcdir}/ext/#{target}/*.{c,cc}"] f = File.basename(f) f.sub!(/\.(c|cc)$/, ".o") $objs.push f @@ -409,13 +417,13 @@ def extmake(target) Dir.chdir 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 @@ -445,7 +453,7 @@ 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() @@ -463,7 +471,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 @@ -511,7 +519,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 @@ -526,7 +534,7 @@ 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 diff --git a/gc.c b/gc.c index 3322352224..bf5124e66d 100644 --- a/gc.c +++ b/gc.c @@ -95,6 +95,7 @@ xrealloc(ptr, size) ArgError("negative re-allocation size"); } if (!ptr) return xmalloc(size); + if (size == 0) size = 1; malloc_memories += size; mem = realloc(ptr, size); if (!mem) { diff --git a/instruby.rb b/instruby.rb index 7dee03a6c1..6d82c3ba17 100644 --- a/instruby.rb +++ b/instruby.rb @@ -13,10 +13,11 @@ else prefix = CONFIG["prefix"] end ruby_install_name = CONFIG["ruby_install_name"] -bindir = prefix + "/bin" -libdir = prefix + "/lib/" + ruby_install_name +bindir = CONFIG["bindir"] +libdir = CONFIG["libdir"] + "/" + ruby_install_name archdir = libdir+"/"+CONFIG["arch"] -mandir = prefix + "/man/man1" +mandir = CONFIG["mandir"] + "/man1" +wdir = Dir.getwd File.makedirs bindir, TRUE File.install "ruby#{binsuffix}", @@ -24,10 +25,10 @@ File.install "ruby#{binsuffix}", for dll in Dir['*.dll'] File.install dll, "#{bindir}/#{dll}", 0755, TRUE end -File.makedirs "#{prefix}/lib", TRUE +File.makedirs "#{libdir}", TRUE for lib in ["libruby.so", "libruby.so.LIB"] if File.exist? lib - File.install lib, "#{prefix}/lib", 0644, TRUE + File.install lib, "#{libdir}", 0644, TRUE end end File.makedirs libdir, TRUE @@ -37,13 +38,14 @@ Dir.chdir CONFIG["srcdir"] IO.foreach 'MANIFEST' do |$_| $_.chop! if /^lib/ - File.install $_, libdir, 0644, TRUE + File.install $_, "#{libdir}", 0644, TRUE elsif /^[a-z]+\.h$/ - File.install $_, archdir, 0644, TRUE + File.install $_, "#{archdir}", 0644, TRUE end - File.install "config.h", archdir, 0644, TRUE end -File.install "rbconfig.rb", archdir, 0644, TRUE File.makedirs mandir, TRUE -File.install "ruby.1", mandir, 0644, TRUE +File.install "ruby.1", "#{mandir}", 0644, TRUE +Dir.chdir wdir +File.install "config.h", "#{archdir}", 0644, TRUE +File.install "rbconfig.rb", "#{archdir}", 0644, TRUE # vi:set sw=2: diff --git a/intern.h b/intern.h index 88ecb4cc75..e76a7a0c0f 100644 --- a/intern.h +++ b/intern.h @@ -100,6 +100,7 @@ int rb_method_boundp _((VALUE, ID, int)); VALUE dyna_var_defined _((ID)); VALUE dyna_var_ref _((ID)); VALUE dyna_var_asgn _((ID, VALUE)); +void dyna_var_push _((ID, VALUE)); void ruby_init _((void)); void ruby_options _((int, char**)); void ruby_run _((void)); diff --git a/io.c b/io.c index 04a8d67e5c..34f0ec3a95 100644 --- a/io.c +++ b/io.c @@ -370,13 +370,14 @@ read_all(port) GetOpenFile(port, fptr); io_readable(fptr); -#ifdef __BEOS__ + str = str_new(0, siz); if (fstat(fileno(fptr->f), &st) == 0 && S_ISREG(st.st_mode) - && (st.st_dev > 3)) { -#else - if (fstat(fileno(fptr->f), &st) == 0 && S_ISREG(st.st_mode)) { +#ifdef __BEOS__ + && (st.st_dev > 3) #endif - if (st.st_size == 0) return Qnil; + ) + { + if (st.st_size == 0) return str_new(0, 0); else { int pos = ftell(fptr->f); if (st.st_size > pos && pos >= 0) { @@ -384,7 +385,6 @@ read_all(port) } } } - str = str_new(0, siz); for (;;) { READ_CHECK(fptr->f); TRAP_BEG; @@ -392,14 +392,14 @@ read_all(port) TRAP_END; if (n <= 0) { if (ferror(fptr->f)) rb_sys_fail(fptr->path); - return Qnil; + return str_new(0, 0); } bytes += n; if (bytes < siz) break; siz += BUFSIZ; str_resize(str, siz); } - if (bytes == 0) return Qnil; + if (bytes == 0) return str_new(0, 0); if (bytes != siz) str_resize(str, bytes); return str_taint(str); } @@ -414,7 +414,7 @@ io_read(argc, argv, io) int n, len; VALUE length, str; - if (rb_scan_args(argc, argv, "01", &length) == 0) { + if (rb_scan_args(argc, argv, "01", &length) == 0 || NIL_P(length)) { return read_all(io); } @@ -2037,10 +2037,10 @@ f_select(argc, argv, obj) GetOpenFile(io, fptr); FD_SET(fileno(fptr->f), wp); - if (max > fileno(fptr->f)) max = fileno(fptr->f); + if (max < fileno(fptr->f)) max = fileno(fptr->f); if (fptr->f2) { FD_SET(fileno(fptr->f2), wp); - if (max < (int)fileno(fptr->f2)) max = fileno(fptr->f2); + if (max < fileno(fptr->f2)) max = fileno(fptr->f2); } } } @@ -2059,7 +2059,7 @@ f_select(argc, argv, obj) if (max < fileno(fptr->f)) max = fileno(fptr->f); if (fptr->f2) { FD_SET(fileno(fptr->f2), ep); - if (max > (int)fileno(fptr->f2)) max = fileno(fptr->f2); + if (max < fileno(fptr->f2)) max = fileno(fptr->f2); } } } diff --git a/lib/Env.rb b/lib/Env.rb index df14023f9e..b3ee3bae8a 100644 --- a/lib/Env.rb +++ b/lib/Env.rb @@ -2,6 +2,7 @@ # # Usage: # +# require 'Env' # p $USER # $USER = "matz" # p ENV["USER"] diff --git a/lib/README b/lib/README new file mode 100644 index 0000000000..09e5946ccb --- /dev/null +++ b/lib/README @@ -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 diff --git a/lib/ping.rb b/lib/ping.rb index d742a50f99..96919c004b 100644 --- a/lib/ping.rb +++ b/lib/ping.rb @@ -33,23 +33,26 @@ # #=end +require 'timeout' + module Ping require "socket" def pingecho(host, timeout=5) begin - x = Thread.current - y = Thread.start { - sleep timeout - x.raise RuntimeError if x.status - } - s = TCPsocket.new(host, "echo") - s.close - return TRUE + timeout(timeout) do + s = TCPsocket.new(host, "echo") + s.close + end rescue - return FALSE; - ensure - Thread.kill y if y.status + return false end + return true end module_function "pingecho" end + +if $0 == __FILE__ + host = ARGV[0] + host ||= "localhost" + printf("%s alive? - %s\n", host, Ping.pingecho(host, 5)) +end diff --git a/lib/telnet.rb b/lib/telnet.rb index e5a8aa6b7b..e3c590c35d 100644 --- a/lib/telnet.rb +++ b/lib/telnet.rb @@ -1,8 +1,17 @@ # # telnet.rb -# ver0.141 1998/09/22 +# ver0.16 1998/10/09 # Wakou Aoyama # +# ver0.16 1998/10/09 +# preprocess method change for the better +# add binmode method. +# change default Binmode +# TRUE --> FALSE +# +# ver0.15 1998/10/04 +# add telnetmode method. +# # ver0.141 1998/09/22 # change default prompt # /[$%#>] $/ --> /[$%#>] \Z/ @@ -33,7 +42,7 @@ # first release. # # == make new Telnet object -# host = Telnet.new({"Binmode" => TRUE, default: TRUE +# host = Telnet.new({"Binmode" => FALSE, default: FALSE # "Host" => "localhost", default: "localhost" # "Output_log" => "output_log", default: not output # "Dump_log" => "dump_log", default: not output @@ -76,6 +85,16 @@ # == send string # host.print("string") # +# == turn telnet command interpretation +# host.telnetmode # turn on/off +# host.telnetmode(TRUE) # on +# host.telnetmode(FALSE) # off +# +# == toggle newline translation +# host.binmode # turn TRUE/FALSE +# host.binmode(TRUE) # no translate newline +# host.binmode(FALSE) # translate newline +# # == login # host.login("username", "password") # host.login({"Name" => "username", @@ -204,6 +223,7 @@ class Telnet < SimpleDelegator OPT_AUTHENTICATION = 37.chr # Authentication Option OPT_ENCRYPT = 38.chr # Encryption Option OPT_NEW_ENVIRON = 39.chr # New Environment Option + OPT_EXOPL = 255.chr # Extended-Options-List NULL = "\000" CR = "\015" @@ -212,7 +232,7 @@ class Telnet < SimpleDelegator def initialize(options) @options = options - @options["Binmode"] = TRUE if not @options.include?("Binmode") + @options["Binmode"] = FALSE if not @options.include?("Binmode") @options["Host"] = "localhost" if not @options.include?("Host") @options["Port"] = 23 if not @options.include?("Port") @options["Prompt"] = /[$%#>] \Z/ if not @options.include?("Prompt") @@ -225,7 +245,7 @@ class Telnet < SimpleDelegator if @options.include?("Output_log") @log = File.open(@options["Output_log"], 'a+') @log.sync = TRUE - @log.binmode if @options["Binmode"] + @log.binmode end if @options.include?("Dump_log") @@ -250,7 +270,7 @@ class Telnet < SimpleDelegator } raise TimeOut, "timed-out; opening of the host" if is_timeout @sock.sync = TRUE - @sock.binmode if @options["Binmode"] + @sock.binmode message = "Connected to " + @options["Host"] + ".\n" STDOUT.write(message) @@ -260,46 +280,62 @@ class Telnet < SimpleDelegator super(@sock) end + def telnetmode(mode = 'turn') + if 'turn' == mode + @options["Telnetmode"] = @options["Telnetmode"] ? FALSE : TRUE + else + @options["Telnetmode"] = mode ? TRUE : FALSE + end + end + + def binmode(mode = 'turn') + if 'turn' == mode + @options["Binmode"] = @options["Binmode"] ? FALSE : TRUE + else + @options["Binmode"] = mode ? TRUE : FALSE + end + end + def preprocess(str) - str.gsub!(/#{CR}#{NULL}/no, CR) # combine CR+NULL into CR - str.gsub!(/#{EOL}/no, "\n") # combine EOL into "\n" + + if not @options["Binmode"] + str.gsub!(/#{CR}#{NULL}/no, CR) # combine CR+NULL into CR + str.gsub!(/#{EOL}/no, "\n") # combine EOL into "\n" + end # respond to "IAC DO x" - str.gsub!(/([^#{IAC}])?#{IAC}#{DO}(.|\n)/no){ - if OPT_BINARY == $2 + str.gsub!(/(?:(?!#{IAC}))?#{IAC}#{DO}([#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}])/no){ + if OPT_BINARY == $1 @telnet_option["BINARY"] = TRUE @sock.write(IAC + WILL + OPT_BINARY) - $1 else - @sock.write(IAC + WONT + $2) - $1 + @sock.write(IAC + WONT + $1) end + '' } # respond to "IAC DON'T x" with "IAC WON'T x" - str.gsub!(/([^#{IAC}])?#{IAC}#{DONT}(.|\n)/no){ - @sock.write(IAC + WONT + $2) - $1 + str.gsub!(/(?:(?!#{IAC}))?#{IAC}#{DONT}([#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}])/no){ + @sock.write(IAC + WONT + $1) + '' } # respond to "IAC WILL x" - str.gsub!(/([^#{IAC}])?#{IAC}#{WILL}(.|\n)/no){ - if OPT_SGA == $2 + str.gsub!(/(?:(?!#{IAC}))?#{IAC}#{WILL}([#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}])/no){ + if OPT_SGA == $1 @telnet_option["SGA"] = TRUE @sock.write(IAC + DO + OPT_SGA) - $1 - else - $1 end + '' } # ignore "IAC WON'T x" - str.gsub!(/([^#{IAC}])?#{IAC}#{WONT}(.|\n)/no, '\1') + str.gsub!(/(?:(?!#{IAC}))?#{IAC}#{WONT}[#{OPT_BINARY}-#{OPT_NEW_ENVIRON}#{OPT_EXOPL}]/no, '') # respond to "IAC AYT" (are you there) - str.gsub!(/([^#{IAC}])?#{IAC}#{AYT}/no){ + str.gsub!(/(?:(?!#{IAC}))?#{IAC}#{AYT}/no){ @sock.write("nobody here but us pigeons" + EOL) - $1 + '' } str.gsub(/#{IAC}#{IAC}/no, IAC) # handle escaped IAC characters @@ -340,15 +376,20 @@ class Telnet < SimpleDelegator end def print(string) - if @telnet_option["BINARY"] and @telnet_option["SGA"] - # IAC WILL SGA IAC DO BIN send EOL --> CR - @sock.write(string.gsub(/\n/, CR) + CR) - elsif @telnet_option["SGA"] - # IAC WILL SGA send EOL --> CR+NULL - @sock.write(string.gsub(/\n/, CR + NULL) + CR + NULL) + string.gsub!(/#{IAC}/no, IAC + IAC) if @options["Telnetmode"] + if @options["Binmode"] + @sock.write(string) else - # NONE send EOL --> LF - @sock.write(string.gsub(/\n/, LF) + LF) + if @telnet_option["BINARY"] and @telnet_option["SGA"] + # IAC WILL SGA IAC DO BIN send EOL --> CR + @sock.write(string.gsub(/\n/, CR) + CR) + elsif @telnet_option["SGA"] + # IAC WILL SGA send EOL --> CR+NULL + @sock.write(string.gsub(/\n/, CR + NULL) + CR + NULL) + else + # NONE send EOL --> LF + @sock.write(string.gsub(/\n/, LF) + LF) + end end end diff --git a/lib/timeout.rb b/lib/timeout.rb new file mode 100644 index 0000000000..d4ea758acd --- /dev/null +++ b/lib/timeout.rb @@ -0,0 +1,42 @@ +# +# timeout.rb -- execution timeout +# +#= SYNOPSIS +# +# require 'timeout' +# status = timeout(5) { +# # something may take time +# } +# +#= DESCRIPTION +# +# timeout executes the block. If the block execution terminates successfully +# before timeout, it returns true. If not, it terminates the execution and +# raise TimeoutError exception. +# +#== Parameters +# +# : timout +# +# The time in seconds to wait for block teminatation. +# +#=end + +class TimeoutErrorptr, RSTRING(v)->len, arg); return; @@ -753,7 +753,7 @@ r_object(arg) v = rb_funcall(klass, s_load, 1, r_string(arg)); return r_regist(v, arg); } - TypeError("class %s needs to have method `_load_from'", + TypeError("class %s needs to have method `_load'", rb_class2name(klass)); } break; @@ -859,8 +859,8 @@ Init_marshal() { VALUE mMarshal = rb_define_module("Marshal"); - s_dump = rb_intern("_dump_to"); - s_load = rb_intern("_load_from"); + s_dump = rb_intern("_dump"); + s_load = rb_intern("_load"); rb_define_module_function(mMarshal, "dump", marshal_dump, -1); rb_define_module_function(mMarshal, "load", marshal_load, -1); rb_define_module_function(mMarshal, "restore", marshal_load, 1); diff --git a/missing/nt.h b/missing/nt.h index be8d61fc41..a3d1f21aa5 100644 --- a/missing/nt.h +++ b/missing/nt.h @@ -9,6 +9,12 @@ * */ +#if defined(IMPORT) +#define EXTERN extern __declspec(dllimport) +#elif defined(EXPORT) +#define EXTERN extern __declspec(dllexport) +#endif + // // Definitions for NT port of Perl // diff --git a/missing/snprintf.c b/missing/snprintf.c deleted file mode 100644 index 750372e6f7..0000000000 --- a/missing/snprintf.c +++ /dev/null @@ -1,1197 +0,0 @@ -/*- - * Copyright (c) 1990, 1993 - * The Regents of the University of California. All rights reserved. - * - * This code is derived from software contributed to Berkeley by - * Chris Torek. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. All advertising materials mentioning features or use of this software - * must display the following acknowledgement: - * This product includes software developed by the University of - * California, Berkeley and its contributors. - * 4. Neither the name of the University nor the names of its contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - */ - -/* SNPRINTF.C - * fjc 7-31-97 Modified by Mib Software to be a standalone snprintf.c module. - * http://www.mibsoftware.com - * Mib Software does not warrant this software any differently than the - * University of California, Berkeley as described above. All warranties - * are disclaimed. Use this software at your own risk. - * - * All code referencing FILE * functions was eliminated, since it could - * never be called. All header files and necessary files are collapsed - * into one file, internal functions are declared static. This should - * allow inclusion into libraries with less chance of namespace collisions. - * - * snprintf should be the only externally visible item. - * - * As of 7-31-97 FLOATING_POINT is NOT provided. The code is somewhat - * non-portable, so it is disabled. - */ - -/* Define FLOATING_POINT to get floating point. */ -/* -#define FLOATING_POINT -*/ - -#include - -#undef __P -#if defined(__STDC__) -# include -# if !defined(__P) -# define __P(x) x -# endif -#else -# define __P(x) () -# if !defined(const) -# define const -# endif -# include -#endif -#ifndef _BSD_VA_LIST_ -#define _BSD_VA_LIST_ va_list -#endif - -#ifdef __STDC__ -# include -#else -# ifndef LONG_MAX -# ifdef HAVE_LIMITS_H -# include -# else - /* assuming 32bit(2's compliment) long */ -# define LONG_MAX 2147483647 -# endif -# endif -#endif - -#if defined(__hpux) && !defined(__GNUC__) -#define const -#endif - -#if defined(sgi) -#undef __const -#define __const -#endif /* People who don't like const sys_error */ - - -#ifndef NULL -#define NULL 0 -#endif - -/* - * This is fairly grotesque, but pure ANSI code must not inspect the - * innards of an fpos_t anyway. The library internally uses off_t, - * which we assume is exactly as big as eight chars. (When we switch - * to gcc 2.4 we will use __attribute__ here.) - * - * WARNING: the alignment constraints on an off_t and the struct below - * differ on (e.g.) the SPARC. Hence, the placement of an fpos_t object - * in a structure will change if fpos_t's are not aligned on 8-byte - * boundaries. THIS IS A CROCK, but for now there is no way around it. - */ -#if !defined(_ANSI_SOURCE) && !defined(__STRICT_ANSI__) -#if !defined(__hpux) -typedef off_t fpos_t; -#endif -#else -typedef struct __sfpos { - char _pos[8]; -} fpos_t; -#endif - -/* - * NB: to fit things in six character monocase externals, the stdio - * code uses the prefix `__s' for stdio objects, typically followed - * by a three-character attempt at a mnemonic. - */ - -/* stdio buffers */ -struct __sbuf { - unsigned char *_base; - int _size; -}; - - -/* - * stdio state variables. - * - * The following always hold: - * - * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR), - * _lbfsize is -_bf._size, else _lbfsize is 0 - * if _flags&__SRD, _w is 0 - * if _flags&__SWR, _r is 0 - * - * This ensures that the getc and putc macros (or inline functions) never - * try to write or read from a file that is in `read' or `write' mode. - * (Moreover, they can, and do, automatically switch from read mode to - * write mode, and back, on "r+" and "w+" files.) - * - * _lbfsize is used only to make the inline line-buffered output stream - * code as compact as possible. - * - * _ub, _up, and _ur are used when ungetc() pushes back more characters - * than fit in the current _bf, or when ungetc() pushes back a character - * that does not match the previous one in _bf. When this happens, - * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff - * _ub._base!=NULL) and _up and _ur save the current values of _p and _r. - * - * NB: see WARNING above before changing the layout of this structure! - */ -typedef struct __sFILE { - unsigned char *_p; /* current position in (some) buffer */ - int _r; /* read space left for getc() */ - int _w; /* write space left for putc() */ - short _flags; /* flags, below; this FILE is free if 0 */ - short _file; /* fileno, if Unix descriptor, else -1 */ - struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ - int _lbfsize; /* 0 or -_bf._size, for inline putc */ - - /* operations */ - void *_cookie; /* cookie passed to io functions */ - int (*_close) __P((void *)); - int (*_read) __P((void *, char *, int)); - fpos_t (*_seek) __P((void *, fpos_t, int)); - int (*_write) __P((void *, const char *, int)); - - /* separate buffer for long sequences of ungetc() */ - struct __sbuf _ub; /* ungetc buffer */ - unsigned char *_up; /* saved _p when _p is doing ungetc data */ - int _ur; /* saved _r when _r is counting ungetc data */ - - /* tricks to meet minimum requirements even when malloc() fails */ - unsigned char _ubuf[3]; /* guarantee an ungetc() buffer */ - unsigned char _nbuf[1]; /* guarantee a getc() buffer */ - - /* separate buffer for fgetln() when line crosses buffer boundary */ - struct __sbuf _lb; /* buffer for fgetln() */ - - /* Unix stdio files get aligned to block boundaries on fseek() */ - int _blksize; /* stat.st_blksize (may be != _bf._size) */ - fpos_t _offset; /* current lseek offset (see WARNING) */ -} FILE; - - -#define __SLBF 0x0001 /* line buffered */ -#define __SNBF 0x0002 /* unbuffered */ -#define __SRD 0x0004 /* OK to read */ -#define __SWR 0x0008 /* OK to write */ - /* RD and WR are never simultaneously asserted */ -#define __SRW 0x0010 /* open for reading & writing */ -#define __SEOF 0x0020 /* found EOF */ -#define __SERR 0x0040 /* found error */ -#define __SMBF 0x0080 /* _buf is from malloc */ -#define __SAPP 0x0100 /* fdopen()ed in append mode */ -#define __SSTR 0x0200 /* this is an sprintf/snprintf string */ -#define __SOPT 0x0400 /* do fseek() optimisation */ -#define __SNPT 0x0800 /* do not do fseek() optimisation */ -#define __SOFF 0x1000 /* set iff _offset is in fact correct */ -#define __SMOD 0x2000 /* true => fgetln modified _p text */ - - -#define EOF (-1) - - -/* - * The __sfoo macros are here so that we can - * define function versions in the C library. - */ -#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) -#if defined(__GNUC__) && defined(__STDC__) -static __inline int __sputc(int _c, FILE *_p) { - if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) - return (*_p->_p++ = _c); - else - return (__swbuf(_c, _p)); -} -#else -/* - * This has been tuned to generate reasonable code on the vax using pcc. - */ -#define __sputc(c, p) \ - (--(p)->_w < 0 ? \ - (p)->_w >= (p)->_lbfsize ? \ - (*(p)->_p = (c)), *(p)->_p != '\n' ? \ - (int)*(p)->_p++ : \ - __swbuf('\n', p) : \ - __swbuf((int)(c), p) : \ - (*(p)->_p = (c), (int)*(p)->_p++)) -#endif - -#define __sfeof(p) (((p)->_flags & __SEOF) != 0) -#define __sferror(p) (((p)->_flags & __SERR) != 0) -#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) -#define __sfileno(p) ((p)->_file) - -#define feof(p) __sfeof(p) -#define ferror(p) __sferror(p) -#define clearerr(p) __sclearerr(p) - -#ifndef _ANSI_SOURCE -#define fileno(p) __sfileno(p) -#endif - -#ifndef lint -#define getc(fp) __sgetc(fp) -#define putc(x, fp) __sputc(x, fp) -#endif /* lint */ - - -#if defined(__hpux) && !defined(__GNUC__) -#include -#endif - -/* - * I/O descriptors for __sfvwrite(). - */ -struct __siov { - void *iov_base; - size_t iov_len; -}; -struct __suio { - struct __siov *uio_iov; - int uio_iovcnt; - int uio_resid; -}; - -/* - * Write some memory regions. Return zero on success, EOF on error. - * - * This routine is large and unsightly, but most of the ugliness due - * to the three different kinds of output buffering is handled here. - */ -static BSD__sfvwrite(fp, uio) - register FILE *fp; - register struct __suio *uio; -{ - register size_t len; - register char *p; - register struct __siov *iov; - register int w, s; - char *nl; - int nlknown, nldist; - - if ((len = uio->uio_resid) == 0) - return (0); -#ifndef __hpux -#define MIN(a, b) ((a) < (b) ? (a) : (b)) -#endif -#define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n)) - - iov = uio->uio_iov; - p = iov->iov_base; - len = iov->iov_len; - iov++; -#define GETIOV(extra_work) \ - while (len == 0) { \ - extra_work; \ - p = iov->iov_base; \ - len = iov->iov_len; \ - iov++; \ - } - if (fp->_flags & __SNBF) { - /* fjc 7-31-97 Will never happen. We are working with - strings only - */ - } else if ((fp->_flags & __SLBF) == 0) { - /* - * Fully buffered: fill partially full buffer, if any, - * and then flush. If there is no partial buffer, write - * one _bf._size byte chunk directly (without copying). - * - * String output is a special case: write as many bytes - * as fit, but pretend we wrote everything. This makes - * snprintf() return the number of bytes needed, rather - * than the number used, and avoids its write function - * (so that the write function can be invalid). - */ - do { - GETIOV(;); - w = fp->_w; - if (fp->_flags & __SSTR) { - if (len < w) - w = len; - COPY(w); /* copy MIN(fp->_w,len), */ - fp->_w -= w; - fp->_p += w; - w = len; /* but pretend copied all */ - } else { - /* fjc 7-31-97 Will never happen. We are working with - strings only - */ - } - p += w; - len -= w; - } while ((uio->uio_resid -= w) != 0); - } else { - /* fjc 7-31-97 Will never happen. We are working with - strings only - */ - } - return (0); - -err: - fp->_flags |= __SERR; - return (EOF); -} - -/* - * Actual printf innards. - * - * This code is large and complicated... - */ - -#include -#define u_long unsigned long -#define u_short unsigned short -#define u_int unsigned int - -#if !defined(__CYGWIN32__) && defined(__hpux) && !defined(__GNUC__) -#include -#endif -#if defined(__hpux) && !defined(__GNUC__) -#include -#endif - -/* - * Flush out all the vectors defined by the given uio, - * then reset it so that it can be reused. - */ -static int -BSD__sprint(fp, uio) - FILE *fp; - register struct __suio *uio; -{ - register int err; - - if (uio->uio_resid == 0) { - uio->uio_iovcnt = 0; - return (0); - } - err = BSD__sfvwrite(fp, uio); - uio->uio_resid = 0; - uio->uio_iovcnt = 0; - return (err); -} - - -/* - * Helper function for `fprintf to unbuffered unix file': creates a - * temporary buffer. We only work on write-only files; this avoids - * worries about ungetc buffers and so forth. - */ -static int -BSD__sbprintf(fp, fmt, ap) - register FILE *fp; - const char *fmt; - va_list ap; -{ -/* We don't support files. */ - return 0; -} - - -/* - * Macros for converting digits to letters and vice versa - */ -#define to_digit(c) ((c) - '0') -#define is_digit(c) ((unsigned)to_digit(c) <= 9) -#define to_char(n) ((n) + '0') - -/* - * Convert an unsigned long to ASCII for printf purposes, returning - * a pointer to the first character of the string representation. - * Octal numbers can be forced to have a leading zero; hex numbers - * use the given digits. - */ -static char * -BSD__ultoa(val, endp, base, octzero, xdigs) - register u_long val; - char *endp; - int base, octzero; - char *xdigs; -{ - register char *cp = endp; - register long sval; - - /* - * Handle the three cases separately, in the hope of getting - * better/faster code. - */ - switch (base) { - case 10: - if (val < 10) { /* many numbers are 1 digit */ - *--cp = to_char(val); - return (cp); - } - /* - * On many machines, unsigned arithmetic is harder than - * signed arithmetic, so we do at most one unsigned mod and - * divide; this is sufficient to reduce the range of - * the incoming value to where signed arithmetic works. - */ - if (val > LONG_MAX) { - *--cp = to_char(val % 10); - sval = val / 10; - } else - sval = val; - do { - *--cp = to_char(sval % 10); - sval /= 10; - } while (sval != 0); - break; - - case 8: - do { - *--cp = to_char(val & 7); - val >>= 3; - } while (val); - if (octzero && *cp != '0') - *--cp = '0'; - break; - - case 16: - do { - *--cp = xdigs[val & 15]; - val >>= 4; - } while (val); - break; - - default: /* oops */ - /* - abort(); - */ - break; /* fjc 7-31-97. Don't reference abort() here */ - } - return (cp); -} - -#ifdef FLOATING_POINT -#include -#include "floatio.h" - -#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ -#define DEFPREC 6 - -static char *cvt __P((double, int, int, char *, int *, int, int *)); -static int exponent __P((char *, int, int)); - -#else /* no FLOATING_POINT */ - -#define BUF 68 - -#endif /* FLOATING_POINT */ - - -/* - * Flags used during conversion. - */ -#define ALT 0x001 /* alternate form */ -#define HEXPREFIX 0x002 /* add 0x or 0X prefix */ -#define LADJUST 0x004 /* left adjustment */ -#define LONGDBL 0x008 /* long double; unimplemented */ -#define LONGINT 0x010 /* long integer */ - -#ifdef _HAVE_SANE_QUAD_ -#define QUADINT 0x020 /* quad integer */ -#endif /* _HAVE_SANE_QUAD_ */ - -#define SHORTINT 0x040 /* short integer */ -#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ -#define FPT 0x100 /* Floating point number */ -static int -BSD_vfprintf(fp, fmt0, ap) - FILE *fp; - const char *fmt0; - va_list ap; -{ - register char *fmt; /* format string */ - register int ch; /* character from fmt */ - register int n; /* handy integer (short term usage) */ - register char *cp; /* handy char pointer (short term usage) */ - register struct __siov *iovp;/* for PRINT macro */ - register int flags; /* flags as above */ - int ret; /* return value accumulator */ - int width; /* width from format (%8d), or 0 */ - int prec; /* precision from format (%.3d), or -1 */ - char sign; /* sign prefix (' ', '+', '-', or \0) */ -#ifdef FLOATING_POINT - char softsign; /* temporary negative sign for floats */ - double _double; /* double precision arguments %[eEfgG] */ - int expt; /* integer value of exponent */ - int expsize; /* character count for expstr */ - int ndig; /* actual number of digits returned by cvt */ - char expstr[7]; /* buffer for exponent string */ -#endif - u_long ulval; /* integer arguments %[diouxX] */ -#ifdef _HAVE_SANE_QUAD_ - u_quad_t uqval; /* %q integers */ -#endif /* _HAVE_SANE_QUAD_ */ - int base; /* base for [diouxX] conversion */ - int dprec; /* a copy of prec if [diouxX], 0 otherwise */ - int fieldsz; /* field size expanded by sign, etc */ - int realsz; /* field size expanded by dprec */ - int size; /* size of converted field or string */ - char *xdigs; /* digits for [xX] conversion */ -#define NIOV 8 - struct __suio uio; /* output information: summary */ - struct __siov iov[NIOV];/* ... and individual io vectors */ - char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ - char ox[2]; /* space for 0x hex-prefix */ - - /* - * Choose PADSIZE to trade efficiency vs. size. If larger printf - * fields occur frequently, increase PADSIZE and make the initialisers - * below longer. - */ -#define PADSIZE 16 /* pad chunk size */ - static char blanks[PADSIZE] = - {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; - static char zeroes[PADSIZE] = - {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; - - /* - * BEWARE, these `goto error' on error, and PAD uses `n'. - */ -#define PRINT(ptr, len) { \ - iovp->iov_base = (ptr); \ - iovp->iov_len = (len); \ - uio.uio_resid += (len); \ - iovp++; \ - if (++uio.uio_iovcnt >= NIOV) { \ - if (BSD__sprint(fp, &uio)) \ - goto error; \ - iovp = iov; \ - } \ -} -#define PAD(howmany, with) { \ - if ((n = (howmany)) > 0) { \ - while (n > PADSIZE) { \ - PRINT(with, PADSIZE); \ - n -= PADSIZE; \ - } \ - PRINT(with, n); \ - } \ -} -#define FLUSH() { \ - if (uio.uio_resid && BSD__sprint(fp, &uio)) \ - goto error; \ - uio.uio_iovcnt = 0; \ - iovp = iov; \ -} - - /* - * To extend shorts properly, we need both signed and unsigned - * argument extraction methods. - */ -#define SARG() \ - (flags&LONGINT ? va_arg(ap, long) : \ - flags&SHORTINT ? (long)(short)va_arg(ap, int) : \ - (long)va_arg(ap, int)) -#define UARG() \ - (flags&LONGINT ? va_arg(ap, u_long) : \ - flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \ - (u_long)va_arg(ap, u_int)) - - /* optimise fprintf(stderr) (and other unbuffered Unix files) */ - if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && - fp->_file >= 0) - return (BSD__sbprintf(fp, fmt0, ap)); - - fmt = (char *)fmt0; - uio.uio_iov = iovp = iov; - uio.uio_resid = 0; - uio.uio_iovcnt = 0; - ret = 0; - - /* - * Scan the format for conversions (`%' character). - */ - for (;;) { - for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) - /* void */; - if ((n = fmt - cp) != 0) { - PRINT(cp, n); - ret += n; - } - if (ch == '\0') - goto done; - fmt++; /* skip over '%' */ - - flags = 0; - dprec = 0; - width = 0; - prec = -1; - sign = '\0'; - -rflag: ch = *fmt++; -reswitch: switch (ch) { - case ' ': - /* - * ``If the space and + flags both appear, the space - * flag will be ignored.'' - * -- ANSI X3J11 - */ - if (!sign) - sign = ' '; - goto rflag; - case '#': - flags |= ALT; - goto rflag; - case '*': - /* - * ``A negative field width argument is taken as a - * - flag followed by a positive field width.'' - * -- ANSI X3J11 - * They don't exclude field widths read from args. - */ - if ((width = va_arg(ap, int)) >= 0) - goto rflag; - width = -width; - /* FALLTHROUGH */ - case '-': - flags |= LADJUST; - goto rflag; - case '+': - sign = '+'; - goto rflag; - case '.': - if ((ch = *fmt++) == '*') { - n = va_arg(ap, int); - prec = n < 0 ? -1 : n; - goto rflag; - } - n = 0; - while (is_digit(ch)) { - n = 10 * n + to_digit(ch); - ch = *fmt++; - } - prec = n < 0 ? -1 : n; - goto reswitch; - case '0': - /* - * ``Note that 0 is taken as a flag, not as the - * beginning of a field width.'' - * -- ANSI X3J11 - */ - flags |= ZEROPAD; - goto rflag; - case '1': case '2': case '3': case '4': - case '5': case '6': case '7': case '8': case '9': - n = 0; - do { - n = 10 * n + to_digit(ch); - ch = *fmt++; - } while (is_digit(ch)); - width = n; - goto reswitch; -#ifdef FLOATING_POINT - case 'L': - flags |= LONGDBL; - goto rflag; -#endif - case 'h': - flags |= SHORTINT; - goto rflag; - case 'l': - flags |= LONGINT; - goto rflag; -#ifdef _HAVE_SANE_QUAD_ - case 'q': - flags |= QUADINT; - goto rflag; -#endif /* _HAVE_SANE_QUAD_ */ - case 'c': - *(cp = buf) = va_arg(ap, int); - size = 1; - sign = '\0'; - break; - case 'D': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'd': - case 'i': -#ifdef _HAVE_SANE_QUAD_ - if (flags & QUADINT) { - uqval = va_arg(ap, quad_t); - if ((quad_t)uqval < 0) { - uqval = -uqval; - sign = '-'; - } - } else { -#else /* _HAVE_SANE_QUAD_ */ - { -#endif /* _HAVE_SANE_QUAD_ */ - ulval = SARG(); - if ((long)ulval < 0) { - ulval = -ulval; - sign = '-'; - } - } - base = 10; - goto number; -#ifdef FLOATING_POINT - case 'e': /* anomalous precision */ - case 'E': - prec = (prec == -1) ? - DEFPREC + 1 : prec + 1; - /* FALLTHROUGH */ - goto fp_begin; - case 'f': /* always print trailing zeroes */ - if (prec != 0) - flags |= ALT; - case 'g': - case 'G': - if (prec == -1) - prec = DEFPREC; -fp_begin: _double = va_arg(ap, double); - /* do this before tricky precision changes */ - if (isinf(_double)) { - if (_double < 0) - sign = '-'; - cp = "Inf"; - size = 3; - break; - } - if (isnan(_double)) { - cp = "NaN"; - size = 3; - break; - } - flags |= FPT; - cp = cvt(_double, prec, flags, &softsign, - &expt, ch, &ndig); - if (ch == 'g' || ch == 'G') { - if (expt <= -4 || expt > prec) - ch = (ch == 'g') ? 'e' : 'E'; - else - ch = 'g'; - } - if (ch <= 'e') { /* 'e' or 'E' fmt */ - --expt; - expsize = exponent(expstr, expt, ch); - size = expsize + ndig; - if (ndig > 1 || flags & ALT) - ++size; - } else if (ch == 'f') { /* f fmt */ - if (expt > 0) { - size = expt; - if (prec || flags & ALT) - size += prec + 1; - } else /* "0.X" */ - size = prec + 2; - } else if (expt >= ndig) { /* fixed g fmt */ - size = expt; - if (flags & ALT) - ++size; - } else - size = ndig + (expt > 0 ? - 1 : 2 - expt); - - if (softsign) - sign = '-'; - break; -#endif /* FLOATING_POINT */ - case 'n': -#ifdef _HAVE_SANE_QUAD_ - if (flags & QUADINT) - *va_arg(ap, quad_t *) = ret; - else if (flags & LONGINT) -#else /* _HAVE_SANE_QUAD_ */ - if (flags & LONGINT) -#endif /* _HAVE_SANE_QUAD_ */ - *va_arg(ap, long *) = ret; - else if (flags & SHORTINT) - *va_arg(ap, short *) = ret; - else - *va_arg(ap, int *) = ret; - continue; /* no output */ - case 'O': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'o': -#ifdef _HAVE_SANE_QUAD_ - if (flags & QUADINT) - uqval = va_arg(ap, u_quad_t); - else -#endif /* _HAVE_SANE_QUAD_ */ - ulval = UARG(); - base = 8; - goto nosign; - case 'p': - /* - * ``The argument shall be a pointer to void. The - * value of the pointer is converted to a sequence - * of printable characters, in an implementation- - * defined manner.'' - * -- ANSI X3J11 - */ - ulval = (u_long)va_arg(ap, void *); - base = 16; - xdigs = "0123456789abcdef"; -#ifdef _HAVE_SANE_QUAD_ - flags = (flags & ~QUADINT) | HEXPREFIX; -#else /* _HAVE_SANE_QUAD_ */ - flags = (flags) | HEXPREFIX; -#endif /* _HAVE_SANE_QUAD_ */ - ch = 'x'; - goto nosign; - case 's': - if ((cp = va_arg(ap, char *)) == NULL) - cp = "(null)"; - if (prec >= 0) { - /* - * can't use strlen; can only look for the - * NUL in the first `prec' characters, and - * strlen() will go further. - */ - char *p = (char *)memchr(cp, 0, prec); - - if (p != NULL) { - size = p - cp; - if (size > prec) - size = prec; - } else - size = prec; - } else - size = strlen(cp); - sign = '\0'; - break; - case 'U': - flags |= LONGINT; - /*FALLTHROUGH*/ - case 'u': -#ifdef _HAVE_SANE_QUAD_ - if (flags & QUADINT) - uqval = va_arg(ap, u_quad_t); - else -#endif /* _HAVE_SANE_QUAD_ */ - ulval = UARG(); - base = 10; - goto nosign; - case 'X': - xdigs = "0123456789ABCDEF"; - goto hex; - case 'x': - xdigs = "0123456789abcdef"; -hex: -#ifdef _HAVE_SANE_QUAD_ - if (flags & QUADINT) - uqval = va_arg(ap, u_quad_t); - else -#endif /* _HAVE_SANE_QUAD_ */ - ulval = UARG(); - base = 16; - /* leading 0x/X only if non-zero */ - if (flags & ALT && -#ifdef _HAVE_SANE_QUAD_ - (flags & QUADINT ? uqval != 0 : ulval != 0)) -#else /* _HAVE_SANE_QUAD_ */ - ulval != 0) -#endif /* _HAVE_SANE_QUAD_ */ - flags |= HEXPREFIX; - - /* unsigned conversions */ -nosign: sign = '\0'; - /* - * ``... diouXx conversions ... if a precision is - * specified, the 0 flag will be ignored.'' - * -- ANSI X3J11 - */ -number: if ((dprec = prec) >= 0) - flags &= ~ZEROPAD; - - /* - * ``The result of converting a zero value with an - * explicit precision of zero is no characters.'' - * -- ANSI X3J11 - */ - cp = buf + BUF; -#ifdef _HAVE_SANE_QUAD_ - if (flags & QUADINT) { - if (uqval != 0 || prec != 0) - cp = __uqtoa(uqval, cp, base, - flags & ALT, xdigs); - } else { -#else /* _HAVE_SANE_QUAD_ */ - { -#endif /* _HAVE_SANE_QUAD_ */ - if (ulval != 0 || prec != 0) - cp = BSD__ultoa(ulval, cp, base, - flags & ALT, xdigs); - } - size = buf + BUF - cp; - break; - default: /* "%?" prints ?, unless ? is NUL */ - if (ch == '\0') - goto done; - /* pretend it was %c with argument ch */ - cp = buf; - *cp = ch; - size = 1; - sign = '\0'; - break; - } - - /* - * All reasonable formats wind up here. At this point, `cp' - * points to a string which (if not flags&LADJUST) should be - * padded out to `width' places. If flags&ZEROPAD, it should - * first be prefixed by any sign or other prefix; otherwise, - * it should be blank padded before the prefix is emitted. - * After any left-hand padding and prefixing, emit zeroes - * required by a decimal [diouxX] precision, then print the - * string proper, then emit zeroes required by any leftover - * floating precision; finally, if LADJUST, pad with blanks. - * - * Compute actual size, so we know how much to pad. - * fieldsz excludes decimal prec; realsz includes it. - */ - fieldsz = size; - if (sign) - fieldsz++; - else if (flags & HEXPREFIX) - fieldsz += 2; - realsz = dprec > fieldsz ? dprec : fieldsz; - - /* right-adjusting blank padding */ - if ((flags & (LADJUST|ZEROPAD)) == 0) - PAD(width - realsz, blanks); - - /* prefix */ - if (sign) { - PRINT(&sign, 1); - } else if (flags & HEXPREFIX) { - ox[0] = '0'; - ox[1] = ch; - PRINT(ox, 2); - } - - /* right-adjusting zero padding */ - if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) - PAD(width - realsz, zeroes); - - /* leading zeroes from decimal precision */ - PAD(dprec - fieldsz, zeroes); - - /* the string or number proper */ -#ifdef FLOATING_POINT - if ((flags & FPT) == 0) { - PRINT(cp, size); - } else { /* glue together f_p fragments */ - if (ch >= 'f') { /* 'f' or 'g' */ - if (_double == 0) { - /* kludge for __dtoa irregularity */ - if (prec == 0 || - (flags & ALT) == 0) { - PRINT("0", 1); - } else { - PRINT("0.", 2); - PAD(ndig - 1, zeroes); - } - } else if (expt <= 0) { - PRINT("0.", 2); - PAD(-expt, zeroes); - PRINT(cp, ndig); - } else if (expt >= ndig) { - PRINT(cp, ndig); - PAD(expt - ndig, zeroes); - if (flags & ALT) - PRINT(".", 1); - } else { - PRINT(cp, expt); - cp += expt; - PRINT(".", 1); - PRINT(cp, ndig-expt); - } - } else { /* 'e' or 'E' */ - if (ndig > 1 || flags & ALT) { - ox[0] = *cp++; - ox[1] = '.'; - PRINT(ox, 2); - if (_double || flags & ALT == 0) { - PRINT(cp, ndig-1); - } else /* 0.[0..] */ - /* __dtoa irregularity */ - PAD(ndig - 1, zeroes); - } else /* XeYYY */ - PRINT(cp, 1); - PRINT(expstr, expsize); - } - } -#else - PRINT(cp, size); -#endif - /* left-adjusting padding (always blank) */ - if (flags & LADJUST) - PAD(width - realsz, blanks); - - /* finally, adjust ret */ - ret += width > realsz ? width : realsz; - - FLUSH(); /* copy out the I/O vectors */ - } -done: - FLUSH(); -error: - return (__sferror(fp) ? EOF : ret); - /* NOTREACHED */ -} - -#ifdef FLOATING_POINT - -extern char *BSD__dtoa __P((double, int, int, int *, int *, char **)); - -static char * -cvt(value, ndigits, flags, sign, decpt, ch, length) - double value; - int ndigits, flags, *decpt, ch, *length; - char *sign; -{ - int mode, dsgn; - char *digits, *bp, *rve; - - if (ch == 'f') - mode = 3; - else { - mode = 2; - } - if (value < 0) { - value = -value; - *sign = '-'; - } else - *sign = '\000'; - digits = BSD__dtoa(value, mode, ndigits, decpt, &dsgn, &rve); - if (flags & ALT) { /* Print trailing zeros */ - bp = digits + ndigits; - if (ch == 'f') { - if (*digits == '0' && value) - *decpt = -ndigits + 1; - bp += *decpt; - } - if (value == 0) /* kludge for __dtoa irregularity */ - rve = bp; - while (rve < bp) - *rve++ = '0'; - } - *length = rve - digits; - return (digits); -} - -static int -exponent(p0, exp, fmtch) - char *p0; - int exp, fmtch; -{ - register char *p, *t; - char expbuf[MAXEXP]; - - p = p0; - *p++ = fmtch; - if (exp < 0) { - exp = -exp; - *p++ = '-'; - } - else - *p++ = '+'; - t = expbuf + MAXEXP; - if (exp > 9) { - do { - *--t = to_char(exp % 10); - } while ((exp /= 10) > 9); - *--t = to_char(exp); - for (; t < expbuf + MAXEXP; *p++ = *t++); - } - else { - *p++ = '0'; - *p++ = to_char(exp); - } - return (p - p0); -} -#endif /* FLOATING_POINT */ - -vsnprintf(str, n, fmt, ap) - char *str; - size_t n; - const char *fmt; - _BSD_VA_LIST_ ap; -{ - int ret; - FILE f; - - if ((int)n < 1) - return (EOF); - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = n - 1; - ret = BSD_vfprintf(&f, fmt, ap); - *f._p = 0; - return (ret); -} - -#if defined(LIBC_SCCS) && !defined(lint) -static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93"; -#endif /* LIBC_SCCS and not lint */ - -#include - -#if defined(__STDC__) -# include -#else -# include -#endif - -#if defined(__STDC__) -snprintf(char *str, size_t n, char const *fmt, ...) -#else -snprintf(str, n, fmt, va_alist) -char *str, *fmt; -size_t n; -va_dcl -#endif -{ - int ret; - va_list ap; - FILE f; - - if ((int)n < 1) - return (EOF); - -#if defined(__STDC__) - va_start(ap, fmt); -#else - va_start(ap); -#endif - f._flags = __SWR | __SSTR; - f._bf._base = f._p = (unsigned char *)str; - f._bf._size = f._w = n - 1; - ret = BSD_vfprintf(&f, fmt, ap); - *f._p = 0; - va_end(ap); - return (ret); -} diff --git a/missing/vsnprintf.c b/missing/vsnprintf.c new file mode 100644 index 0000000000..64076b5c01 --- /dev/null +++ b/missing/vsnprintf.c @@ -0,0 +1,1150 @@ +/*- + * Copyright (c) 1990, 1993 + * The Regents of the University of California. All rights reserved. + * + * This code is derived from software contributed to Berkeley by + * Chris Torek. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. All advertising materials mentioning features or use of this software + * must display the following acknowledgement: + * This product includes software developed by the University of + * California, Berkeley and its contributors. + * 4. Neither the name of the University nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* SNPRINTF.C + * fjc 7-31-97 Modified by Mib Software to be a standalone snprintf.c module. + * http://www.mibsoftware.com + * Mib Software does not warrant this software any differently than the + * University of California, Berkeley as described above. All warranties + * are disclaimed. Use this software at your own risk. + * + * All code referencing FILE * functions was eliminated, since it could + * never be called. All header files and necessary files are collapsed + * into one file, internal functions are declared static. This should + * allow inclusion into libraries with less chance of namespace collisions. + * + * snprintf should be the only externally visible item. + * + * As of 7-31-97 FLOATING_POINT is NOT provided. The code is somewhat + * non-portable, so it is disabled. + */ + +/* Define FLOATING_POINT to get floating point. */ +/* +#define FLOATING_POINT +*/ + +#include +#define u_long unsigned long +#define u_short unsigned short +#define u_int unsigned int + +#undef __P +#if defined(__STDC__) +# include +# if !defined(__P) +# define __P(x) x +# endif +#else +# define __P(x) () +# if !defined(const) +# define const +# endif +# include +#endif +#ifndef _BSD_VA_LIST_ +#define _BSD_VA_LIST_ va_list +#endif + +#ifdef __STDC__ +# include +#else +# ifndef LONG_MAX +# ifdef HAVE_LIMITS_H +# include +# else + /* assuming 32bit(2's compliment) long */ +# define LONG_MAX 2147483647 +# endif +# endif +#endif + +#if defined(__hpux) && !defined(__GNUC__) +#define const +#endif + +#if defined(sgi) +#undef __const +#define __const +#endif /* People who don't like const sys_error */ + + +#ifndef NULL +#define NULL 0 +#endif + +/* + * NB: to fit things in six character monocase externals, the stdio + * code uses the prefix `__s' for stdio objects, typically followed + * by a three-character attempt at a mnemonic. + */ + +/* stdio buffers */ +struct __sbuf { + unsigned char *_base; + int _size; +}; + + +/* + * stdio state variables. + * + * The following always hold: + * + * if (_flags&(__SLBF|__SWR)) == (__SLBF|__SWR), + * _lbfsize is -_bf._size, else _lbfsize is 0 + * if _flags&__SRD, _w is 0 + * if _flags&__SWR, _r is 0 + * + * This ensures that the getc and putc macros (or inline functions) never + * try to write or read from a file that is in `read' or `write' mode. + * (Moreover, they can, and do, automatically switch from read mode to + * write mode, and back, on "r+" and "w+" files.) + * + * _lbfsize is used only to make the inline line-buffered output stream + * code as compact as possible. + * + * _ub, _up, and _ur are used when ungetc() pushes back more characters + * than fit in the current _bf, or when ungetc() pushes back a character + * that does not match the previous one in _bf. When this happens, + * _ub._base becomes non-nil (i.e., a stream has ungetc() data iff + * _ub._base!=NULL) and _up and _ur save the current values of _p and _r. + * + * NB: see WARNING above before changing the layout of this structure! + */ +typedef struct __sFILE { + unsigned char *_p; /* current position in (some) buffer */ + int _r; /* read space left for getc() */ + int _w; /* write space left for putc() */ + short _flags; /* flags, below; this FILE is free if 0 */ + short _file; /* fileno, if Unix descriptor, else -1 */ + struct __sbuf _bf; /* the buffer (at least 1 byte, if !NULL) */ + int _lbfsize; /* 0 or -_bf._size, for inline putc */ +} FILE; + + +#define __SLBF 0x0001 /* line buffered */ +#define __SNBF 0x0002 /* unbuffered */ +#define __SRD 0x0004 /* OK to read */ +#define __SWR 0x0008 /* OK to write */ + /* RD and WR are never simultaneously asserted */ +#define __SRW 0x0010 /* open for reading & writing */ +#define __SEOF 0x0020 /* found EOF */ +#define __SERR 0x0040 /* found error */ +#define __SMBF 0x0080 /* _buf is from malloc */ +#define __SAPP 0x0100 /* fdopen()ed in append mode */ +#define __SSTR 0x0200 /* this is an sprintf/snprintf string */ +#define __SOPT 0x0400 /* do fseek() optimisation */ +#define __SNPT 0x0800 /* do not do fseek() optimisation */ +#define __SOFF 0x1000 /* set iff _offset is in fact correct */ +#define __SMOD 0x2000 /* true => fgetln modified _p text */ + + +#define EOF (-1) + + +/* + * The __sfoo macros are here so that we can + * define function versions in the C library. + */ +#define __sgetc(p) (--(p)->_r < 0 ? __srget(p) : (int)(*(p)->_p++)) +#if defined(__GNUC__) && defined(__STDC__) +static __inline int __sputc(int _c, FILE *_p) { + if (--_p->_w >= 0 || (_p->_w >= _p->_lbfsize && (char)_c != '\n')) + return (*_p->_p++ = _c); + else + return (__swbuf(_c, _p)); +} +#else +/* + * This has been tuned to generate reasonable code on the vax using pcc. + */ +#define __sputc(c, p) \ + (--(p)->_w < 0 ? \ + (p)->_w >= (p)->_lbfsize ? \ + (*(p)->_p = (c)), *(p)->_p != '\n' ? \ + (int)*(p)->_p++ : \ + __swbuf('\n', p) : \ + __swbuf((int)(c), p) : \ + (*(p)->_p = (c), (int)*(p)->_p++)) +#endif + +#define __sfeof(p) (((p)->_flags & __SEOF) != 0) +#define __sferror(p) (((p)->_flags & __SERR) != 0) +#define __sclearerr(p) ((void)((p)->_flags &= ~(__SERR|__SEOF))) +#define __sfileno(p) ((p)->_file) + +#define feof(p) __sfeof(p) +#define ferror(p) __sferror(p) +#define clearerr(p) __sclearerr(p) + +#ifndef _ANSI_SOURCE +#define fileno(p) __sfileno(p) +#endif + +#ifndef lint +#define getc(fp) __sgetc(fp) +#define putc(x, fp) __sputc(x, fp) +#endif /* lint */ + + +#if defined(__hpux) && !defined(__GNUC__) +#include +#endif + +/* + * I/O descriptors for __sfvwrite(). + */ +struct __siov { + void *iov_base; + size_t iov_len; +}; +struct __suio { + struct __siov *uio_iov; + int uio_iovcnt; + int uio_resid; +}; + +/* + * Write some memory regions. Return zero on success, EOF on error. + * + * This routine is large and unsightly, but most of the ugliness due + * to the three different kinds of output buffering is handled here. + */ +static BSD__sfvwrite(fp, uio) + register FILE *fp; + register struct __suio *uio; +{ + register size_t len; + register char *p; + register struct __siov *iov; + register int w, s; + char *nl; + int nlknown, nldist; + + if ((len = uio->uio_resid) == 0) + return (0); +#ifndef __hpux +#define MIN(a, b) ((a) < (b) ? (a) : (b)) +#endif +#define COPY(n) (void)memcpy((void *)fp->_p, (void *)p, (size_t)(n)) + + iov = uio->uio_iov; + p = iov->iov_base; + len = iov->iov_len; + iov++; +#define GETIOV(extra_work) \ + while (len == 0) { \ + extra_work; \ + p = iov->iov_base; \ + len = iov->iov_len; \ + iov++; \ + } + if (fp->_flags & __SNBF) { + /* fjc 7-31-97 Will never happen. We are working with + strings only + */ + } else if ((fp->_flags & __SLBF) == 0) { + /* + * Fully buffered: fill partially full buffer, if any, + * and then flush. If there is no partial buffer, write + * one _bf._size byte chunk directly (without copying). + * + * String output is a special case: write as many bytes + * as fit, but pretend we wrote everything. This makes + * snprintf() return the number of bytes needed, rather + * than the number used, and avoids its write function + * (so that the write function can be invalid). + */ + do { + GETIOV(;); + w = fp->_w; + if (fp->_flags & __SSTR) { + if (len < w) + w = len; + COPY(w); /* copy MIN(fp->_w,len), */ + fp->_w -= w; + fp->_p += w; + w = len; /* but pretend copied all */ + } else { + /* fjc 7-31-97 Will never happen. We are working with + strings only + */ + } + p += w; + len -= w; + } while ((uio->uio_resid -= w) != 0); + } else { + /* fjc 7-31-97 Will never happen. We are working with + strings only + */ + } + return (0); + +err: + fp->_flags |= __SERR; + return (EOF); +} + +/* + * Actual printf innards. + * + * This code is large and complicated... + */ + +#if !defined(__CYGWIN32__) && defined(__hpux) && !defined(__GNUC__) +#include +#endif + +/* + * Flush out all the vectors defined by the given uio, + * then reset it so that it can be reused. + */ +static int +BSD__sprint(fp, uio) + FILE *fp; + register struct __suio *uio; +{ + register int err; + + if (uio->uio_resid == 0) { + uio->uio_iovcnt = 0; + return (0); + } + err = BSD__sfvwrite(fp, uio); + uio->uio_resid = 0; + uio->uio_iovcnt = 0; + return (err); +} + + +/* + * Helper function for `fprintf to unbuffered unix file': creates a + * temporary buffer. We only work on write-only files; this avoids + * worries about ungetc buffers and so forth. + */ +static int +BSD__sbprintf(fp, fmt, ap) + register FILE *fp; + const char *fmt; + va_list ap; +{ +/* We don't support files. */ + return 0; +} + + +/* + * Macros for converting digits to letters and vice versa + */ +#define to_digit(c) ((c) - '0') +#define is_digit(c) ((unsigned)to_digit(c) <= 9) +#define to_char(n) ((n) + '0') + +/* + * Convert an unsigned long to ASCII for printf purposes, returning + * a pointer to the first character of the string representation. + * Octal numbers can be forced to have a leading zero; hex numbers + * use the given digits. + */ +static char * +BSD__ultoa(val, endp, base, octzero, xdigs) + register u_long val; + char *endp; + int base, octzero; + char *xdigs; +{ + register char *cp = endp; + register long sval; + + /* + * Handle the three cases separately, in the hope of getting + * better/faster code. + */ + switch (base) { + case 10: + if (val < 10) { /* many numbers are 1 digit */ + *--cp = to_char(val); + return (cp); + } + /* + * On many machines, unsigned arithmetic is harder than + * signed arithmetic, so we do at most one unsigned mod and + * divide; this is sufficient to reduce the range of + * the incoming value to where signed arithmetic works. + */ + if (val > LONG_MAX) { + *--cp = to_char(val % 10); + sval = val / 10; + } else + sval = val; + do { + *--cp = to_char(sval % 10); + sval /= 10; + } while (sval != 0); + break; + + case 8: + do { + *--cp = to_char(val & 7); + val >>= 3; + } while (val); + if (octzero && *cp != '0') + *--cp = '0'; + break; + + case 16: + do { + *--cp = xdigs[val & 15]; + val >>= 4; + } while (val); + break; + + default: /* oops */ + /* + abort(); + */ + break; /* fjc 7-31-97. Don't reference abort() here */ + } + return (cp); +} + +#ifdef FLOATING_POINT +#include +#include "floatio.h" + +#define BUF (MAXEXP+MAXFRACT+1) /* + decimal point */ +#define DEFPREC 6 + +static char *cvt __P((double, int, int, char *, int *, int, int *)); +static int exponent __P((char *, int, int)); + +#else /* no FLOATING_POINT */ + +#define BUF 68 + +#endif /* FLOATING_POINT */ + + +/* + * Flags used during conversion. + */ +#define ALT 0x001 /* alternate form */ +#define HEXPREFIX 0x002 /* add 0x or 0X prefix */ +#define LADJUST 0x004 /* left adjustment */ +#define LONGDBL 0x008 /* long double; unimplemented */ +#define LONGINT 0x010 /* long integer */ + +#ifdef _HAVE_SANE_QUAD_ +#define QUADINT 0x020 /* quad integer */ +#endif /* _HAVE_SANE_QUAD_ */ + +#define SHORTINT 0x040 /* short integer */ +#define ZEROPAD 0x080 /* zero (as opposed to blank) pad */ +#define FPT 0x100 /* Floating point number */ +static int +BSD_vfprintf(fp, fmt0, ap) + FILE *fp; + const char *fmt0; + va_list ap; +{ + register char *fmt; /* format string */ + register int ch; /* character from fmt */ + register int n; /* handy integer (short term usage) */ + register char *cp; /* handy char pointer (short term usage) */ + register struct __siov *iovp;/* for PRINT macro */ + register int flags; /* flags as above */ + int ret; /* return value accumulator */ + int width; /* width from format (%8d), or 0 */ + int prec; /* precision from format (%.3d), or -1 */ + char sign; /* sign prefix (' ', '+', '-', or \0) */ +#ifdef FLOATING_POINT + char softsign; /* temporary negative sign for floats */ + double _double; /* double precision arguments %[eEfgG] */ + int expt; /* integer value of exponent */ + int expsize; /* character count for expstr */ + int ndig; /* actual number of digits returned by cvt */ + char expstr[7]; /* buffer for exponent string */ +#endif + u_long ulval; /* integer arguments %[diouxX] */ +#ifdef _HAVE_SANE_QUAD_ + u_quad_t uqval; /* %q integers */ +#endif /* _HAVE_SANE_QUAD_ */ + int base; /* base for [diouxX] conversion */ + int dprec; /* a copy of prec if [diouxX], 0 otherwise */ + int fieldsz; /* field size expanded by sign, etc */ + int realsz; /* field size expanded by dprec */ + int size; /* size of converted field or string */ + char *xdigs; /* digits for [xX] conversion */ +#define NIOV 8 + struct __suio uio; /* output information: summary */ + struct __siov iov[NIOV];/* ... and individual io vectors */ + char buf[BUF]; /* space for %c, %[diouxX], %[eEfgG] */ + char ox[2]; /* space for 0x hex-prefix */ + + /* + * Choose PADSIZE to trade efficiency vs. size. If larger printf + * fields occur frequently, increase PADSIZE and make the initialisers + * below longer. + */ +#define PADSIZE 16 /* pad chunk size */ + static char blanks[PADSIZE] = + {' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '}; + static char zeroes[PADSIZE] = + {'0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'}; + + /* + * BEWARE, these `goto error' on error, and PAD uses `n'. + */ +#define PRINT(ptr, len) { \ + iovp->iov_base = (ptr); \ + iovp->iov_len = (len); \ + uio.uio_resid += (len); \ + iovp++; \ + if (++uio.uio_iovcnt >= NIOV) { \ + if (BSD__sprint(fp, &uio)) \ + goto error; \ + iovp = iov; \ + } \ +} +#define PAD(howmany, with) { \ + if ((n = (howmany)) > 0) { \ + while (n > PADSIZE) { \ + PRINT(with, PADSIZE); \ + n -= PADSIZE; \ + } \ + PRINT(with, n); \ + } \ +} +#define FLUSH() { \ + if (uio.uio_resid && BSD__sprint(fp, &uio)) \ + goto error; \ + uio.uio_iovcnt = 0; \ + iovp = iov; \ +} + + /* + * To extend shorts properly, we need both signed and unsigned + * argument extraction methods. + */ +#define SARG() \ + (flags&LONGINT ? va_arg(ap, long) : \ + flags&SHORTINT ? (long)(short)va_arg(ap, int) : \ + (long)va_arg(ap, int)) +#define UARG() \ + (flags&LONGINT ? va_arg(ap, u_long) : \ + flags&SHORTINT ? (u_long)(u_short)va_arg(ap, int) : \ + (u_long)va_arg(ap, u_int)) + + /* optimise fprintf(stderr) (and other unbuffered Unix files) */ + if ((fp->_flags & (__SNBF|__SWR|__SRW)) == (__SNBF|__SWR) && + fp->_file >= 0) + return (BSD__sbprintf(fp, fmt0, ap)); + + fmt = (char *)fmt0; + uio.uio_iov = iovp = iov; + uio.uio_resid = 0; + uio.uio_iovcnt = 0; + ret = 0; + + /* + * Scan the format for conversions (`%' character). + */ + for (;;) { + for (cp = fmt; (ch = *fmt) != '\0' && ch != '%'; fmt++) + /* void */; + if ((n = fmt - cp) != 0) { + PRINT(cp, n); + ret += n; + } + if (ch == '\0') + goto done; + fmt++; /* skip over '%' */ + + flags = 0; + dprec = 0; + width = 0; + prec = -1; + sign = '\0'; + +rflag: ch = *fmt++; +reswitch: switch (ch) { + case ' ': + /* + * ``If the space and + flags both appear, the space + * flag will be ignored.'' + * -- ANSI X3J11 + */ + if (!sign) + sign = ' '; + goto rflag; + case '#': + flags |= ALT; + goto rflag; + case '*': + /* + * ``A negative field width argument is taken as a + * - flag followed by a positive field width.'' + * -- ANSI X3J11 + * They don't exclude field widths read from args. + */ + if ((width = va_arg(ap, int)) >= 0) + goto rflag; + width = -width; + /* FALLTHROUGH */ + case '-': + flags |= LADJUST; + goto rflag; + case '+': + sign = '+'; + goto rflag; + case '.': + if ((ch = *fmt++) == '*') { + n = va_arg(ap, int); + prec = n < 0 ? -1 : n; + goto rflag; + } + n = 0; + while (is_digit(ch)) { + n = 10 * n + to_digit(ch); + ch = *fmt++; + } + prec = n < 0 ? -1 : n; + goto reswitch; + case '0': + /* + * ``Note that 0 is taken as a flag, not as the + * beginning of a field width.'' + * -- ANSI X3J11 + */ + flags |= ZEROPAD; + goto rflag; + case '1': case '2': case '3': case '4': + case '5': case '6': case '7': case '8': case '9': + n = 0; + do { + n = 10 * n + to_digit(ch); + ch = *fmt++; + } while (is_digit(ch)); + width = n; + goto reswitch; +#ifdef FLOATING_POINT + case 'L': + flags |= LONGDBL; + goto rflag; +#endif + case 'h': + flags |= SHORTINT; + goto rflag; + case 'l': + flags |= LONGINT; + goto rflag; +#ifdef _HAVE_SANE_QUAD_ + case 'q': + flags |= QUADINT; + goto rflag; +#endif /* _HAVE_SANE_QUAD_ */ + case 'c': + *(cp = buf) = va_arg(ap, int); + size = 1; + sign = '\0'; + break; + case 'D': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'd': + case 'i': +#ifdef _HAVE_SANE_QUAD_ + if (flags & QUADINT) { + uqval = va_arg(ap, quad_t); + if ((quad_t)uqval < 0) { + uqval = -uqval; + sign = '-'; + } + } else { +#else /* _HAVE_SANE_QUAD_ */ + { +#endif /* _HAVE_SANE_QUAD_ */ + ulval = SARG(); + if ((long)ulval < 0) { + ulval = -ulval; + sign = '-'; + } + } + base = 10; + goto number; +#ifdef FLOATING_POINT + case 'e': /* anomalous precision */ + case 'E': + prec = (prec == -1) ? + DEFPREC + 1 : prec + 1; + /* FALLTHROUGH */ + goto fp_begin; + case 'f': /* always print trailing zeroes */ + if (prec != 0) + flags |= ALT; + case 'g': + case 'G': + if (prec == -1) + prec = DEFPREC; +fp_begin: _double = va_arg(ap, double); + /* do this before tricky precision changes */ + if (isinf(_double)) { + if (_double < 0) + sign = '-'; + cp = "Inf"; + size = 3; + break; + } + if (isnan(_double)) { + cp = "NaN"; + size = 3; + break; + } + flags |= FPT; + cp = cvt(_double, prec, flags, &softsign, + &expt, ch, &ndig); + if (ch == 'g' || ch == 'G') { + if (expt <= -4 || expt > prec) + ch = (ch == 'g') ? 'e' : 'E'; + else + ch = 'g'; + } + if (ch <= 'e') { /* 'e' or 'E' fmt */ + --expt; + expsize = exponent(expstr, expt, ch); + size = expsize + ndig; + if (ndig > 1 || flags & ALT) + ++size; + } else if (ch == 'f') { /* f fmt */ + if (expt > 0) { + size = expt; + if (prec || flags & ALT) + size += prec + 1; + } else /* "0.X" */ + size = prec + 2; + } else if (expt >= ndig) { /* fixed g fmt */ + size = expt; + if (flags & ALT) + ++size; + } else + size = ndig + (expt > 0 ? + 1 : 2 - expt); + + if (softsign) + sign = '-'; + break; +#endif /* FLOATING_POINT */ + case 'n': +#ifdef _HAVE_SANE_QUAD_ + if (flags & QUADINT) + *va_arg(ap, quad_t *) = ret; + else if (flags & LONGINT) +#else /* _HAVE_SANE_QUAD_ */ + if (flags & LONGINT) +#endif /* _HAVE_SANE_QUAD_ */ + *va_arg(ap, long *) = ret; + else if (flags & SHORTINT) + *va_arg(ap, short *) = ret; + else + *va_arg(ap, int *) = ret; + continue; /* no output */ + case 'O': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'o': +#ifdef _HAVE_SANE_QUAD_ + if (flags & QUADINT) + uqval = va_arg(ap, u_quad_t); + else +#endif /* _HAVE_SANE_QUAD_ */ + ulval = UARG(); + base = 8; + goto nosign; + case 'p': + /* + * ``The argument shall be a pointer to void. The + * value of the pointer is converted to a sequence + * of printable characters, in an implementation- + * defined manner.'' + * -- ANSI X3J11 + */ + ulval = (u_long)va_arg(ap, void *); + base = 16; + xdigs = "0123456789abcdef"; +#ifdef _HAVE_SANE_QUAD_ + flags = (flags & ~QUADINT) | HEXPREFIX; +#else /* _HAVE_SANE_QUAD_ */ + flags = (flags) | HEXPREFIX; +#endif /* _HAVE_SANE_QUAD_ */ + ch = 'x'; + goto nosign; + case 's': + if ((cp = va_arg(ap, char *)) == NULL) + cp = "(null)"; + if (prec >= 0) { + /* + * can't use strlen; can only look for the + * NUL in the first `prec' characters, and + * strlen() will go further. + */ + char *p = (char *)memchr(cp, 0, prec); + + if (p != NULL) { + size = p - cp; + if (size > prec) + size = prec; + } else + size = prec; + } else + size = strlen(cp); + sign = '\0'; + break; + case 'U': + flags |= LONGINT; + /*FALLTHROUGH*/ + case 'u': +#ifdef _HAVE_SANE_QUAD_ + if (flags & QUADINT) + uqval = va_arg(ap, u_quad_t); + else +#endif /* _HAVE_SANE_QUAD_ */ + ulval = UARG(); + base = 10; + goto nosign; + case 'X': + xdigs = "0123456789ABCDEF"; + goto hex; + case 'x': + xdigs = "0123456789abcdef"; +hex: +#ifdef _HAVE_SANE_QUAD_ + if (flags & QUADINT) + uqval = va_arg(ap, u_quad_t); + else +#endif /* _HAVE_SANE_QUAD_ */ + ulval = UARG(); + base = 16; + /* leading 0x/X only if non-zero */ + if (flags & ALT && +#ifdef _HAVE_SANE_QUAD_ + (flags & QUADINT ? uqval != 0 : ulval != 0)) +#else /* _HAVE_SANE_QUAD_ */ + ulval != 0) +#endif /* _HAVE_SANE_QUAD_ */ + flags |= HEXPREFIX; + + /* unsigned conversions */ +nosign: sign = '\0'; + /* + * ``... diouXx conversions ... if a precision is + * specified, the 0 flag will be ignored.'' + * -- ANSI X3J11 + */ +number: if ((dprec = prec) >= 0) + flags &= ~ZEROPAD; + + /* + * ``The result of converting a zero value with an + * explicit precision of zero is no characters.'' + * -- ANSI X3J11 + */ + cp = buf + BUF; +#ifdef _HAVE_SANE_QUAD_ + if (flags & QUADINT) { + if (uqval != 0 || prec != 0) + cp = __uqtoa(uqval, cp, base, + flags & ALT, xdigs); + } else { +#else /* _HAVE_SANE_QUAD_ */ + { +#endif /* _HAVE_SANE_QUAD_ */ + if (ulval != 0 || prec != 0) + cp = BSD__ultoa(ulval, cp, base, + flags & ALT, xdigs); + } + size = buf + BUF - cp; + break; + default: /* "%?" prints ?, unless ? is NUL */ + if (ch == '\0') + goto done; + /* pretend it was %c with argument ch */ + cp = buf; + *cp = ch; + size = 1; + sign = '\0'; + break; + } + + /* + * All reasonable formats wind up here. At this point, `cp' + * points to a string which (if not flags&LADJUST) should be + * padded out to `width' places. If flags&ZEROPAD, it should + * first be prefixed by any sign or other prefix; otherwise, + * it should be blank padded before the prefix is emitted. + * After any left-hand padding and prefixing, emit zeroes + * required by a decimal [diouxX] precision, then print the + * string proper, then emit zeroes required by any leftover + * floating precision; finally, if LADJUST, pad with blanks. + * + * Compute actual size, so we know how much to pad. + * fieldsz excludes decimal prec; realsz includes it. + */ + fieldsz = size; + if (sign) + fieldsz++; + else if (flags & HEXPREFIX) + fieldsz += 2; + realsz = dprec > fieldsz ? dprec : fieldsz; + + /* right-adjusting blank padding */ + if ((flags & (LADJUST|ZEROPAD)) == 0) + PAD(width - realsz, blanks); + + /* prefix */ + if (sign) { + PRINT(&sign, 1); + } else if (flags & HEXPREFIX) { + ox[0] = '0'; + ox[1] = ch; + PRINT(ox, 2); + } + + /* right-adjusting zero padding */ + if ((flags & (LADJUST|ZEROPAD)) == ZEROPAD) + PAD(width - realsz, zeroes); + + /* leading zeroes from decimal precision */ + PAD(dprec - fieldsz, zeroes); + + /* the string or number proper */ +#ifdef FLOATING_POINT + if ((flags & FPT) == 0) { + PRINT(cp, size); + } else { /* glue together f_p fragments */ + if (ch >= 'f') { /* 'f' or 'g' */ + if (_double == 0) { + /* kludge for __dtoa irregularity */ + if (prec == 0 || + (flags & ALT) == 0) { + PRINT("0", 1); + } else { + PRINT("0.", 2); + PAD(ndig - 1, zeroes); + } + } else if (expt <= 0) { + PRINT("0.", 2); + PAD(-expt, zeroes); + PRINT(cp, ndig); + } else if (expt >= ndig) { + PRINT(cp, ndig); + PAD(expt - ndig, zeroes); + if (flags & ALT) + PRINT(".", 1); + } else { + PRINT(cp, expt); + cp += expt; + PRINT(".", 1); + PRINT(cp, ndig-expt); + } + } else { /* 'e' or 'E' */ + if (ndig > 1 || flags & ALT) { + ox[0] = *cp++; + ox[1] = '.'; + PRINT(ox, 2); + if (_double || flags & ALT == 0) { + PRINT(cp, ndig-1); + } else /* 0.[0..] */ + /* __dtoa irregularity */ + PAD(ndig - 1, zeroes); + } else /* XeYYY */ + PRINT(cp, 1); + PRINT(expstr, expsize); + } + } +#else + PRINT(cp, size); +#endif + /* left-adjusting padding (always blank) */ + if (flags & LADJUST) + PAD(width - realsz, blanks); + + /* finally, adjust ret */ + ret += width > realsz ? width : realsz; + + FLUSH(); /* copy out the I/O vectors */ + } +done: + FLUSH(); +error: + return (__sferror(fp) ? EOF : ret); + /* NOTREACHED */ +} + +#ifdef FLOATING_POINT + +extern char *BSD__dtoa __P((double, int, int, int *, int *, char **)); + +static char * +cvt(value, ndigits, flags, sign, decpt, ch, length) + double value; + int ndigits, flags, *decpt, ch, *length; + char *sign; +{ + int mode, dsgn; + char *digits, *bp, *rve; + + if (ch == 'f') + mode = 3; + else { + mode = 2; + } + if (value < 0) { + value = -value; + *sign = '-'; + } else + *sign = '\000'; + digits = BSD__dtoa(value, mode, ndigits, decpt, &dsgn, &rve); + if (flags & ALT) { /* Print trailing zeros */ + bp = digits + ndigits; + if (ch == 'f') { + if (*digits == '0' && value) + *decpt = -ndigits + 1; + bp += *decpt; + } + if (value == 0) /* kludge for __dtoa irregularity */ + rve = bp; + while (rve < bp) + *rve++ = '0'; + } + *length = rve - digits; + return (digits); +} + +static int +exponent(p0, exp, fmtch) + char *p0; + int exp, fmtch; +{ + register char *p, *t; + char expbuf[MAXEXP]; + + p = p0; + *p++ = fmtch; + if (exp < 0) { + exp = -exp; + *p++ = '-'; + } + else + *p++ = '+'; + t = expbuf + MAXEXP; + if (exp > 9) { + do { + *--t = to_char(exp % 10); + } while ((exp /= 10) > 9); + *--t = to_char(exp); + for (; t < expbuf + MAXEXP; *p++ = *t++); + } + else { + *p++ = '0'; + *p++ = to_char(exp); + } + return (p - p0); +} +#endif /* FLOATING_POINT */ + +int +vsnprintf(str, n, fmt, ap) + char *str; + size_t n; + const char *fmt; + _BSD_VA_LIST_ ap; +{ + int ret; + FILE f; + + if ((int)n < 1) + return (EOF); + f._flags = __SWR | __SSTR; + f._bf._base = f._p = (unsigned char *)str; + f._bf._size = f._w = n - 1; + ret = BSD_vfprintf(&f, fmt, ap); + *f._p = 0; + return (ret); +} + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)snprintf.c 8.1 (Berkeley) 6/4/93"; +#endif /* LIBC_SCCS and not lint */ + +#include + +#if defined(__STDC__) +# include +#else +# include +#endif + +int +#if defined(__STDC__) +snprintf(char *str, size_t n, char const *fmt, ...) +#else +snprintf(str, n, fmt, va_alist) +char *str, *fmt; +size_t n; +va_dcl +#endif +{ + int ret; + va_list ap; + FILE f; + + if ((int)n < 1) + return (EOF); + +#if defined(__STDC__) + va_start(ap, fmt); +#else + va_start(ap); +#endif + f._flags = __SWR | __SSTR; + f._bf._base = f._p = (unsigned char *)str; + f._bf._size = f._w = n - 1; + ret = BSD_vfprintf(&f, fmt, ap); + *f._p = 0; + va_end(ap); + return (ret); +} diff --git a/mkconfig.rb b/mkconfig.rb index cf5c1e13d5..8af3b0c175 100644 --- a/mkconfig.rb +++ b/mkconfig.rb @@ -33,7 +33,7 @@ File.foreach "config.status" do |$_| val = $2 || "" next if name =~ /^(INSTALL|DEFS|configure_input|srcdir|top_srcdir)$/ v = " CONFIG[\"" + name + "\"] = " + - val.sub(/^\s*(.*)\s*$/, '"\1"').gsub(/\$\{?([^}]*)\}?/) { + val.sub(/^\s*(.*)\s*$/, '"\1"').gsub(/\$[{(]?([^})]+)[})]?/) { "\#{CONFIG[\\\"#{$1}\\\"]}" } + "\n" if fast[name] diff --git a/parse.y b/parse.y index eac498a08c..3bf2bee981 100644 --- a/parse.y +++ b/parse.y @@ -569,10 +569,11 @@ reswords : k__LINE__ | k__FILE__ | klBEGIN | klEND | kTHEN | kTRUE | kUNDEF | kUNLESS_MOD | kUNTIL_MOD | kWHEN | kWHILE_MOD | kYIELD -arg : variable '=' arg +arg : variable '=' {$$ = assignable($1, 0);} arg { - $$ = assignable($1, $3); - fixpos($$, $3); + $$ = $3; + $$->nd_value = $4; + fixpos($$, $4); } | primary '[' aref_args ']' '=' arg { @@ -2384,6 +2385,9 @@ retry: case '=': if (lex_p == lex_pbeg + 1) { + if (!lex_input) { + Error("embedded document not available in eval"); + } /* skip embedded rd document */ if (strncmp(lex_p, "begin", 5) == 0 && ISSPACE(lex_p[5])) { for (;;) { @@ -2430,7 +2434,7 @@ retry: int c2 = nextc(); if (!ISSPACE(c2) && (strchr("\"'`", c2) || is_identchar(c2))) { if (!lex_input) { - ArgError("here document not available"); + ArgError("here document not available in eval"); } return here_document(c2); } @@ -4065,8 +4069,12 @@ rb_intern(name) strncpy(buf, name, last); buf[last] = '\0'; - id = id_attrset(rb_intern(buf)); - goto id_regist; + id = rb_intern(buf); + if (id > LAST_TOKEN) { + id = id_attrset(id); + goto id_regist; + } + id |= ID_ATTRSET; } else if (ISUPPER(name[0])) { id = ID_CONST; diff --git a/re.c b/re.c index c334397f00..1561c58e31 100644 --- a/re.c +++ b/re.c @@ -718,13 +718,11 @@ reg_match(re, str) { int start; - if (NIL_P(str)) return FALSE; + if (NIL_P(str)) return Qnil; str = str_to_str(str); start = reg_search(re, str, 0, 0); - if (start < 0) { - return FALSE; - } - return INT2FIX(start); + if (start >= 0) return INT2FIX(start); + return Qnil; } VALUE @@ -734,14 +732,10 @@ reg_match2(re) int start; VALUE line = lastline_get(); - if (TYPE(line) != T_STRING) - return FALSE; - + if (TYPE(line) != T_STRING) return Qnil; start = reg_search(re, line, 0, 0); - if (start < 0) { - return FALSE; - } - return INT2FIX(start); + if (start >= 0) return INT2FIX(start); + return Qnil; } static VALUE diff --git a/regex.c b/regex.c index 279297ad76..b3cbb77f2c 100644 --- a/regex.c +++ b/regex.c @@ -567,8 +567,8 @@ set_list_bits(c1, c2, b) if (beg != end) { if (c1 > EXTRACT_MBC(&b[beg*4])) c1 = EXTRACT_MBC(&b[beg*4]); - if (c2 < EXTRACT_MBC(&b[(end - 1)*4])) - c2 = EXTRACT_MBC(&b[(end - 1)*4]); + if (c2 < EXTRACT_MBC(&b[(end - 1)*4+2])) + c2 = EXTRACT_MBC(&b[(end - 1)*4+2]); } if (end < mbc_size && end != beg + 1) /* NOTE: memcpy() would not work here. */ @@ -2021,25 +2021,27 @@ re_compile_pattern(pattern, size, bufp) /* set optimize flags */ laststart = bufp->buffer; - if (*laststart == start_memory) laststart += 3; - if (*laststart == dummy_failure_jump) laststart += 3; - else if (*laststart == try_next) laststart += 3; - if (*laststart == on_failure_jump) { - int mcnt; - - laststart++; - EXTRACT_NUMBER_AND_INCR(mcnt, laststart); - if (mcnt == 4 && *laststart == anychar) { - bufp->options |= RE_OPTIMIZE_ANCHOR; - } - else if (*laststart == charset || *laststart == charset_not) { - p0 = laststart; - mcnt = *++p0 ; - p0 += mcnt+1; - mcnt = EXTRACT_UNSIGNED_AND_INCR(p0); - p0 += 4*mcnt; - if (*p0 == maybe_finalize_jump) { - bufp->stclass = laststart; + if (laststart != b) { + if (*laststart == start_memory) laststart += 3; + if (*laststart == dummy_failure_jump) laststart += 3; + else if (*laststart == try_next) laststart += 3; + if (*laststart == on_failure_jump) { + int mcnt; + + laststart++; + EXTRACT_NUMBER_AND_INCR(mcnt, laststart); + if (mcnt == 4 && *laststart == anychar) { + bufp->options |= RE_OPTIMIZE_ANCHOR; + } + else if (*laststart == charset || *laststart == charset_not) { + p0 = laststart; + mcnt = *++p0 ; + p0 += mcnt+1; + mcnt = EXTRACT_UNSIGNED_AND_INCR(p0); + p0 += 4*mcnt; + if (*p0 == maybe_finalize_jump) { + bufp->stclass = laststart; + } } } } @@ -2047,10 +2049,12 @@ re_compile_pattern(pattern, size, bufp) bufp->used = b - bufp->buffer; bufp->re_nsub = regnum; laststart = bufp->buffer; - if (*laststart == start_memory) laststart += 3; - if (*laststart == exactn) { - bufp->options |= RE_OPTIMIZE_EXACTN; - bufp->must = laststart+1; + if (laststart != b) { + if (*laststart == start_memory) laststart += 3; + if (*laststart == exactn) { + bufp->options |= RE_OPTIMIZE_EXACTN; + bufp->must = laststart+1; + } } else { bufp->must = calculate_must_string(bufp->buffer, b); @@ -3917,6 +3921,7 @@ re_match(bufp, string_arg, size, pos, regs) EXTRACT_NUMBER_AND_INCR (mcnt, p1); p1 += mcnt; + if (p1 >= pend) break; if ((is_a_jump_n && (enum regexpcode) *p1 == succeed_n) || (!is_a_jump_n && (enum regexpcode) *p1 == on_failure_jump)) diff --git a/ruby.h b/ruby.h index 4d7ee52c88..76de6764fe 100644 --- a/ruby.h +++ b/ruby.h @@ -287,7 +287,7 @@ struct RData { void *data; }; -extern VALUE cData; +EXTERN VALUE cData; #define DATA_PTR(dta) (RDATA(dta)->data) @@ -458,7 +458,7 @@ void rb_const_set _((VALUE, ID, VALUE)); VALUE rb_equal _((VALUE,VALUE)); -extern VALUE verbose, debug; +EXTERN VALUE verbose, debug; int rb_safe_level _((void)); void rb_set_safe_level _((int)); @@ -487,54 +487,54 @@ VALUE rb_ensure _((VALUE(*)(),VALUE,VALUE(*)(),VALUE)); VALUE rb_catch _((char*,VALUE(*)(),VALUE)); void rb_throw _((char*,VALUE)) NORETURN; -extern VALUE mKernel; -extern VALUE mComparable; -extern VALUE mEnumerable; -extern VALUE mErrno; -extern VALUE mFileTest; -extern VALUE mGC; -extern VALUE mMath; -extern VALUE mProcess; +EXTERN VALUE mKernel; +EXTERN VALUE mComparable; +EXTERN VALUE mEnumerable; +EXTERN VALUE mErrno; +EXTERN VALUE mFileTest; +EXTERN VALUE mGC; +EXTERN VALUE mMath; +EXTERN VALUE mProcess; #ifdef __MACOS__ /* name conflict, AERegistory.h */ -extern VALUE cRubyObject; +EXTERN VALUE cRubyObject; #else -extern VALUE cObject; +EXTERN VALUE cObject; #endif -extern VALUE cArray; -extern VALUE cBignum; -extern VALUE cClass; -extern VALUE cData; -extern VALUE cFile; -extern VALUE cFixnum; -extern VALUE cFloat; -extern VALUE cHash; -extern VALUE cInteger; -extern VALUE cIO; -extern VALUE cModule; -extern VALUE cNumeric; -extern VALUE cProc; -extern VALUE cRegexp; -extern VALUE cString; -extern VALUE cThread; -extern VALUE cStruct; - -extern VALUE eException; -extern VALUE eStandardError; -extern VALUE eSystemExit, eInterrupt, eFatal; -extern VALUE eArgError; -extern VALUE eEOFError; -extern VALUE eIndexError; -extern VALUE eIOError; -extern VALUE eLoadError; -extern VALUE eNameError; -extern VALUE eRuntimeError; -extern VALUE eSecurityError; -extern VALUE eSyntaxError; -extern VALUE eSystemCallError; -extern VALUE eTypeError; -extern VALUE eZeroDiv; -extern VALUE eNotImpError; +EXTERN VALUE cArray; +EXTERN VALUE cBignum; +EXTERN VALUE cClass; +EXTERN VALUE cData; +EXTERN VALUE cFile; +EXTERN VALUE cFixnum; +EXTERN VALUE cFloat; +EXTERN VALUE cHash; +EXTERN VALUE cInteger; +EXTERN VALUE cIO; +EXTERN VALUE cModule; +EXTERN VALUE cNumeric; +EXTERN VALUE cProc; +EXTERN VALUE cRegexp; +EXTERN VALUE cString; +EXTERN VALUE cThread; +EXTERN VALUE cStruct; + +EXTERN VALUE eException; +EXTERN VALUE eStandardError; +EXTERN VALUE eSystemExit, eInterrupt, eFatal; +EXTERN VALUE eArgError; +EXTERN VALUE eEOFError; +EXTERN VALUE eIndexError; +EXTERN VALUE eIOError; +EXTERN VALUE eLoadError; +EXTERN VALUE eNameError; +EXTERN VALUE eRuntimeError; +EXTERN VALUE eSecurityError; +EXTERN VALUE eSyntaxError; +EXTERN VALUE eSystemCallError; +EXTERN VALUE eTypeError; +EXTERN VALUE eZeroDiv; +EXTERN VALUE eNotImpError; #include "intern.h" diff --git a/sample/README b/sample/README new file mode 100644 index 0000000000..90ac0c7220 --- /dev/null +++ b/sample/README @@ -0,0 +1,60 @@ +README this file +biorhythm.rb biorhythm calculator +cal.rb cal(1) clone +cbreak.rb no echo done by ioctl +clnt.rb socket client +dbmtest.rb test for dbm +dir.rb directory access +dstore.rb object database on dbm +eval.rb simple evaluator +export.rb method access example +exyacc.rb extrace BNF from yacc file +fact.rb factorial calculator +fib.awk Fibonacci number (AWK) +fib.pl Fibonacci number (Perl) +fib.py Fibonacci number (Python) +fib.rb Fibonacci number (Ruby) +fib.scm Fibonacci number (Scheme) +freq.rb count word occurrence +from.rb scan mail spool +fullpath.rb convert ls -lR to fullpath format +getopts.test test fot getopt.rb +goodfriday.rb print various christian calendar event. +inf-ruby.el program to run ruby under emacs +io.rb io test +less.rb front end for less +list.rb stupid object sample +list2.rb stupid object sample +list3.rb stupid object sample +mine.rb simple mine sweeper +mkproto.rb extract protptype from C +mpart.rb split file int multi part +mrshtest.rb test marshal +observ.rb observer design pattern sample +occur.pl count word occurrence (Perl) +occur.rb count word occurrence (Ruby) +occur2.rb count word occurrence - another style +philos.rb famous dining philosophers +pi.rb calculate PI +rbc.rb interactive ruby, to be removed by irb +rcs.awk random character stereogram (AWK) +rcs.rb random character stereogram (Ruby) +rcs.dat data for random character stereogram +regx.rb regular expression tester +ruby-mode.el ruby mode for emacs +rubydb2x.el ruby debugger support for emacs 19.2x or before +rubydb3x.el ruby debugger support for emacs 19.3x or later +sieve.rb sieve of Eratosthenes +svr.rb socket server +test.rb test suite used by `make test' +time.rb /usr/bin/time clone +tkbiff.rb mail notifier using Tk +tkbrowse.rb directory browser using Tk +tkdialog.rb dialog example +tkfrom.rb scan mail spool using Tk +tkhello.rb simple Tk example +tkline.rb simple Tk example +tktimer.rb stopwatch +trojan.rb simple tool to find file that may be trojan horse. +tsvr.rb socket server using thread +uumerge.rb merge files and uudecode them diff --git a/sample/mkproto.rb b/sample/mkproto.rb index 97006f9f54..8661240085 100644 --- a/sample/mkproto.rb +++ b/sample/mkproto.rb @@ -8,17 +8,17 @@ while gets() arg.gsub! ' +', ' ' if arg =~ /,/ if arg =~ /(([^*]+) *\** *[\w\d_]+),/ - type = $2.strip! - args.push $1.strip! + type = $2.strip + args.push $1.strip arg = $' else type = "" end while arg.sub!(/(\** *[\w\d_]+)(,|$)/, "") - args.push type + " " + $1.strip! + args.push type + " " + $1.strip end else - args.push arg.strip! + args.push arg.strip end end printf "%s);\n", args.join(', ') diff --git a/sample/ruby-mode.el b/sample/ruby-mode.el index 204654013f..f4c5ce98f0 100644 --- a/sample/ruby-mode.el +++ b/sample/ruby-mode.el @@ -253,7 +253,7 @@ The variable ruby-indent-level controls the amount of indentation. ((looking-at "%") (cond ((and (not (eobp)) (ruby-expr-beg) - (looking-at "%[Qqrx]?\\(.\\)")) + (looking-at "%[Qqrxw]?\\(.\\)")) (setq w (buffer-substring (match-beginning 1) (match-end 1))) (cond @@ -618,6 +618,7 @@ An end of a defun is found by moving forward from the beginning of one." "break" "case" "class" + "def" "do" "elsif" "else" @@ -646,7 +647,7 @@ An end of a defun is found by moving forward from the beginning of one." "while" ) "\\|") - "\\)[ \n\t()]") + "\\)\\b") 2) ;; variables '("\\(^\\|[^_]\\)\\b\\(nil\\|self\\|true\\|false\\)\\b\\([^_]\\|$\\)" @@ -658,8 +659,8 @@ An end of a defun is found by moving forward from the beginning of one." '("\\(^\\|[^_]\\)\\b\\([A-Z]+[a-zA-Z0-9_]*\\)" 2 font-lock-type-face) ;; functions - '("^\\s *def[ \t]+[^ \t(]*" - 0 font-lock-function-name-face t)) + '("^\\s *def[ \t]+\\([^ \t(]*\\)" + 1 font-lock-function-name-face t)) "*Additional expressions to highlight in ruby mode.") (if (and (>= (string-to-int emacs-version) 19) (not (featurep 'xemacs))) diff --git a/sample/test.rb b/sample/test.rb index 0adcb22307..55893cfc61 100644 --- a/sample/test.rb +++ b/sample/test.rb @@ -546,9 +546,9 @@ check "string & char" ok("abcd" == "abcd") ok("abcd" =~ "abcd") ok("abcd" === "abcd") -ok(("abc" =~ /^$/) == false) -ok(("abc\n" =~ /^$/) == false) -ok(("abc" =~ /^d*$/) == false) +ok("abc" !~ /^$/) +ok("abc\n" !~ /^$/) +ok("abc" !~ /^d*$/) ok(("abc" =~ /d*$/) == 3) ok("" =~ /^$/) ok("\n" =~ /^$/) diff --git a/string.c b/string.c index 0c9f5fb23a..b57c7175e7 100644 --- a/string.c +++ b/string.c @@ -802,8 +802,8 @@ str_aref(str, indx) return INT2FIX(RSTRING(str)->ptr[idx] & 0xff); case T_REGEXP: - if (str_match(str, indx)) - return reg_last_match(0); + if (reg_match(indx, str)) + return reg_last_match(backref_get()); return Qnil; case T_STRING: @@ -1551,7 +1551,7 @@ str_dump(str) } else { *q++ = '\\'; - sprintf(q, "%03o", c); + sprintf(q, "%03o", c&0xff); q += 3; } } @@ -2011,12 +2011,12 @@ str_split_method(argc, argv, str) VALUE spat; VALUE limit; int char_sep = -1; - int beg, end, lim, i; + int beg, end, i, lim = 0; VALUE result, tmp; if (rb_scan_args(argc, argv, "02", &spat, &limit) == 2) { lim = NUM2INT(limit); - if (lim == 0) limit = Qnil; + if (lim <= 0) limit = Qnil; else if (lim == 1) return ary_new3(1, str); i = 1; } @@ -2119,8 +2119,9 @@ str_split_method(argc, argv, str) last_null = 0; for (idx=1; idx < regs->num_regs; idx++) { - if (BEG(idx) == -1) continue; - if (BEG(idx) == END(idx)) + if (BEG(idx) == -1) + tmp = Qnil; + else if (BEG(idx) == END(idx)) tmp = str_new(0, 0); else tmp = str_subseq(str, BEG(idx), END(idx)-1); @@ -2129,9 +2130,14 @@ str_split_method(argc, argv, str) if (!NIL_P(limit) && lim <= ++i) break; } } - if (RSTRING(str)->len > beg) { + if (!NIL_P(limit) || RSTRING(str)->len > beg || lim < 0) { ary_push(result, str_subseq(str, beg, -1)); } + if (NIL_P(limit) && lim == 0) { + while (RARRAY(result)->len > 0 && + RSTRING(RARRAY(result)->ptr[RARRAY(result)->len-1])->len == 0) + ary_pop(result); + } return result; } diff --git a/time.c b/time.c index b906bb59e6..298c5a14d5 100644 --- a/time.c +++ b/time.c @@ -103,23 +103,13 @@ time_timeval(time) switch (TYPE(time)) { case T_FIXNUM: - t.tv_sec = FIX2UINT(time); - if (t.tv_sec < 0) - ArgError("time must be positive"); + t.tv_sec = FIX2INT(time); t.tv_usec = 0; break; case T_FLOAT: - { - double seconds, microseconds; - - if (RFLOAT(time)->value < 0.0) - ArgError("time must be positive"); - seconds = floor(RFLOAT(time)->value); - microseconds = (RFLOAT(time)->value - seconds) * 1000000.0; - t.tv_sec = seconds; - t.tv_usec = microseconds; - } + t.tv_sec = RFLOAT(time)->value; + t.tv_usec = (RFLOAT(time)->value - t.tv_sec) * 1000000.0; break; case T_BIGNUM: @@ -231,8 +221,8 @@ time_arg(argc, argv, args) || args[1] < 0 || args[1] > 11 || args[2] < 1 || args[2] > 31 || args[3] < 0 || args[3] > 23 - || args[4] < 0 || args[4] > 60 - || args[5] < 0 || args[5] > 61) + || args[4] < 0 || args[4] > 59 + || args[5] < 0 || args[5] > 60) ArgError("argument out of range"); } @@ -800,6 +790,55 @@ time_s_times(obj) #endif } +static VALUE +time_dump(time, limit) + VALUE time, limit; +{ + struct time_object *tobj; + int sec, usec; + unsigned char buf[8]; + int i; + + GetTimeval(time, tobj); + sec = tobj->tv.tv_sec; + usec = tobj->tv.tv_usec; + + for (i=0; i<4; i++) { + buf[i] = sec & 0xff; + sec = RSHIFT(sec, 8); + } + printf("::"); + for (i=4; i<8; i++) { + buf[i] = usec & 0xff; + usec = RSHIFT(usec, 8); + } + return str_new(buf, 8); +} + +static VALUE +time_load(klass, str) + VALUE klass, str; +{ + int sec, usec; + unsigned char *buf; + int i; + + buf = str2cstr(str, &i); + if (i != 8) { + TypeError("marshaled time format differ"); + } + + sec = usec = 0; + for (i=0; i<4; i++) { + sec |= buf[i]<<(8*i); + } + for (i=4; i<8; i++) { + usec |= buf[i]<<(8*(i-4)); + } + + return time_new_internal(klass, sec, usec); +} + void Init_Time() { @@ -854,4 +893,8 @@ Init_Time() #if defined(HAVE_TIMES) || defined(NT) S_Tms = struct_define("Tms", "utime", "stime", "cutime", "cstime", 0); #endif + + /* methods for marshaling */ + rb_define_singleton_method(cTime, "_load", time_load, 1); + rb_define_method(cTime, "_dump", time_dump, 1); } diff --git a/top.sed b/top.sed index 934f60142d..bb9a96c146 100644 --- a/top.sed +++ b/top.sed @@ -1,52 +1,58 @@ /^SHELL/s,/bin/sh,$(COMPSEC), s/@srcdir@/./g s/@top_srcdir@/../ -s/@CC@/gcc/ -s/@CPP@/gcc -E/ -s/@CPPFLAGS@// -s/@AR@/ar/ -s/@RANLIB@/ranlib/ -s/@YACC@/bison -y/ -s/@INSTALL@/ginstall -c/ -s/@INSTALL_PROGRAM@/${INSTALL}/ -s/@INSTALL_DATA@/${INSTALL} -m 644/ -s/@SET_MAKE@// -s/@CFLAGS@/-g -O2 -I./ -s/@STATIC@// -s/@LDFLAGS@// -s/@LIBS@// -s/@LIBOBJS@/crypt.o flock.o/ -s/@ALLOCA@// -s!@prefix@!/usr/local! -s/@exec_prefix@/${prefix}/ -s!@bindir@!${exec_prefix}/bin! -s!@libdir@!${exec_prefix}/lib! -s/@STRIP@/strip/ -s!/bin/rm!rm! -s/@DLEXT@/o/ -s/@CCDLFLAGS@/-fpic/ -s/@DLDFLAGS@// -s/@LDSHARED@// -s/@binsuffix@/.exe/g -s/@setup@/Setup/g -s/|| true// -s!@archlib@!/usr/local/lib/ruby/i386-djgpp! +s%@CFLAGS@%-g -O2%g +s%@CPPFLAGS@%%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.dj%g +s%@LIBRUBY@%libruby.a%g +s%@LIBRUBYARG@%libruby.a%g +s%@SOLIBS@%%g +s%@arch@%i386-djgpp%g +s%/bin/rm%rm% +s%|| true%% +s%@archlib@%/usr/local/lib/ruby/i386-djgpp% /\/dev\/null/ { s,/dev/null 2>&1, nul, s,2> /dev/null,, } -s/y\.tab\.c/y_tab.c/ -#/if older/s/"ruby"/"ruby.exe"/g -#/`rm -f ruby`/s//`rm -f ruby.exe`/ -#/`cp miniruby ruby`/s//`cp miniruby.exe ruby.exe`/ -/^all:.*miniruby/ { - n;c\ - cd ext\ - ../miniruby ./extmk.rb\ - cd .. -} -/^clean:;/ { - n;n;s!cd.*!cd ext\ - ../miniruby ./extmk.rb clean\ - cd ..! -} +s%y\.tab\.c%y_tab.c% diff --git a/version.h b/version.h index 5d4bd534bc..5582f46a4f 100644 --- a/version.h +++ b/version.h @@ -1,2 +1,2 @@ -#define RUBY_VERSION "1.1c6" -#define VERSION_DATE "98/10/05" +#define RUBY_VERSION "1.1c7" +#define VERSION_DATE "98/11/09" -- cgit v1.2.3