diff --git a/src/apps/bin/gawk/missing_d/COPYING.LIB b/src/apps/bin/gawk/missing_d/COPYING.LIB new file mode 100644 index 0000000000..161a3d1d47 --- /dev/null +++ b/src/apps/bin/gawk/missing_d/COPYING.LIB @@ -0,0 +1,482 @@ + GNU LIBRARY GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 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. + +[This is the first released version of the library GPL. It is + numbered 2 because it goes with version 2 of the ordinary GPL.] + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +Licenses are intended to guarantee your freedom to share and change +free software--to make sure the software is free for all its users. + + This license, the Library General Public License, applies to some +specially designated Free Software Foundation software, and to any +other libraries whose authors decide to use it. You can use it for +your libraries, too. + + When we speak of free software, we are referring to freedom, not +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 library, or if you modify it. + + For example, if you distribute copies of the library, whether gratis +or for a fee, you must give the recipients all the rights that we gave +you. You must make sure that they, too, receive or can get the source +code. If you link a program with the library, you must provide +complete object files to the recipients so that they can relink them +with the library, after making changes to the library and recompiling +it. And you must show them these terms so they know their rights. + + Our method of protecting your rights has two steps: (1) copyright +the library, and (2) offer you this license which gives you legal +permission to copy, distribute and/or modify the library. + + Also, for each distributor's protection, we want to make certain +that everyone understands that there is no warranty for this free +library. If the library is modified by someone else and passed on, we +want its recipients to know that what they have is not the original +version, 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 companies distributing free +software will individually obtain patent licenses, thus in effect +transforming the program into proprietary software. To prevent this, +we have made it clear that any patent must be licensed for everyone's +free use or not licensed at all. + + Most GNU software, including some libraries, is covered by the ordinary +GNU General Public License, which was designed for utility programs. This +license, the GNU Library General Public License, applies to certain +designated libraries. This license is quite different from the ordinary +one; be sure to read it in full, and don't assume that anything in it is +the same as in the ordinary license. + + The reason we have a separate public license for some libraries is that +they blur the distinction we usually make between modifying or adding to a +program and simply using it. Linking a program with a library, without +changing the library, is in some sense simply using the library, and is +analogous to running a utility program or application program. However, in +a textual and legal sense, the linked executable is a combined work, a +derivative of the original library, and the ordinary General Public License +treats it as such. + + Because of this blurred distinction, using the ordinary General +Public License for libraries did not effectively promote software +sharing, because most developers did not use the libraries. We +concluded that weaker conditions might promote sharing better. + + However, unrestricted linking of non-free programs would deprive the +users of those programs of all benefit from the free status of the +libraries themselves. This Library General Public License is intended to +permit developers of non-free programs to use free libraries, while +preserving your freedom as a user of such programs to change the free +libraries that are incorporated in them. (We have not seen how to achieve +this as regards changes in header files, but we have achieved it as regards +changes in the actual functions of the Library.) The hope is that this +will lead to faster development of free libraries. + + The precise terms and conditions for copying, distribution and +modification follow. Pay close attention to the difference between a +"work based on the library" and a "work that uses the library". The +former contains code derived from the library, while the latter only +works together with the library. + + Note that it is possible for a library to be covered by the ordinary +General Public License rather than by this special one. + + GNU LIBRARY GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License Agreement applies to any software library which +contains a notice placed by the copyright holder or other authorized +party saying it may be distributed under the terms of this Library +General Public License (also called "this License"). Each licensee is +addressed as "you". + + A "library" means a collection of software functions and/or data +prepared so as to be conveniently linked with application programs +(which use some of those functions and data) to form executables. + + The "Library", below, refers to any such software library or work +which has been distributed under these terms. A "work based on the +Library" means either the Library or any derivative work under +copyright law: that is to say, a work containing the Library or a +portion of it, either verbatim or with modifications and/or translated +straightforwardly into another language. (Hereinafter, translation is +included without limitation in the term "modification".) + + "Source code" for a work means the preferred form of the work for +making modifications to it. For a library, 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 library. + + Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running a program using the Library is not restricted, and output from +such a program is covered only if its contents constitute a work based +on the Library (independent of the use of the Library in a tool for +writing it). Whether that is true depends on what the Library does +and what the program that uses the Library does. + + 1. You may copy and distribute verbatim copies of the Library's +complete 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 distribute a copy of this License along with the +Library. + + 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 Library or any portion +of it, thus forming a work based on the Library, 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) The modified work must itself be a software library. + + b) You must cause the files modified to carry prominent notices + stating that you changed the files and the date of any change. + + c) You must cause the whole of the work to be licensed at no + charge to all third parties under the terms of this License. + + d) If a facility in the modified Library refers to a function or a + table of data to be supplied by an application program that uses + the facility, other than as an argument passed when the facility + is invoked, then you must make a good faith effort to ensure that, + in the event an application does not supply such function or + table, the facility still operates, and performs whatever part of + its purpose remains meaningful. + + (For example, a function in a library to compute square roots has + a purpose that is entirely well-defined independent of the + application. Therefore, Subsection 2d requires that any + application-supplied function or table used by this function must + be optional: if the application does not supply it, the square + root function must still compute square roots.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Library, +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 Library, 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 Library. + +In addition, mere aggregation of another work not based on the Library +with the Library (or with a work based on the Library) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may opt to apply the terms of the ordinary GNU General Public +License instead of this License to a given copy of the Library. To do +this, you must alter all the notices that refer to this License, so +that they refer to the ordinary GNU General Public License, version 2, +instead of to this License. (If a newer version than version 2 of the +ordinary GNU General Public License has appeared, then you can specify +that version instead if you wish.) Do not make any other change in +these notices. + + Once this change is made in a given copy, it is irreversible for +that copy, so the ordinary GNU General Public License applies to all +subsequent copies and derivative works made from that copy. + + This option is useful when you wish to copy part of the code of +the Library into a program that is not a library. + + 4. You may copy and distribute the Library (or a portion or +derivative of it, under Section 2) in object code or executable form +under the terms of Sections 1 and 2 above provided that you 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. + + If distribution of 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 satisfies the requirement to +distribute the source code, even though third parties are not +compelled to copy the source along with the object code. + + 5. A program that contains no derivative of any portion of the +Library, but is designed to work with the Library by being compiled or +linked with it, is called a "work that uses the Library". Such a +work, in isolation, is not a derivative work of the Library, and +therefore falls outside the scope of this License. + + However, linking a "work that uses the Library" with the Library +creates an executable that is a derivative of the Library (because it +contains portions of the Library), rather than a "work that uses the +library". The executable is therefore covered by this License. +Section 6 states terms for distribution of such executables. + + When a "work that uses the Library" uses material from a header file +that is part of the Library, the object code for the work may be a +derivative work of the Library even though the source code is not. +Whether this is true is especially significant if the work can be +linked without the Library, or if the work is itself a library. The +threshold for this to be true is not precisely defined by law. + + If such an object file uses only numerical parameters, data +structure layouts and accessors, and small macros and small inline +functions (ten lines or less in length), then the use of the object +file is unrestricted, regardless of whether it is legally a derivative +work. (Executables containing this object code plus portions of the +Library will still fall under Section 6.) + + Otherwise, if the work is a derivative of the Library, you may +distribute the object code for the work under the terms of Section 6. +Any executables containing that work also fall under Section 6, +whether or not they are linked directly with the Library itself. + + 6. As an exception to the Sections above, you may also compile or +link a "work that uses the Library" with the Library to produce a +work containing portions of the Library, and distribute that work +under terms of your choice, provided that the terms permit +modification of the work for the customer's own use and reverse +engineering for debugging such modifications. + + You must give prominent notice with each copy of the work that the +Library is used in it and that the Library and its use are covered by +this License. You must supply a copy of this License. If the work +during execution displays copyright notices, you must include the +copyright notice for the Library among them, as well as a reference +directing the user to the copy of this License. Also, you must do one +of these things: + + a) Accompany the work with the complete corresponding + machine-readable source code for the Library including whatever + changes were used in the work (which must be distributed under + Sections 1 and 2 above); and, if the work is an executable linked + with the Library, with the complete machine-readable "work that + uses the Library", as object code and/or source code, so that the + user can modify the Library and then relink to produce a modified + executable containing the modified Library. (It is understood + that the user who changes the contents of definitions files in the + Library will not necessarily be able to recompile the application + to use the modified definitions.) + + b) Accompany the work with a written offer, valid for at + least three years, to give the same user the materials + specified in Subsection 6a, above, for a charge no more + than the cost of performing this distribution. + + c) If distribution of the work is made by offering access to copy + from a designated place, offer equivalent access to copy the above + specified materials from the same place. + + d) Verify that the user has already received a copy of these + materials or that you have already sent this user a copy. + + For an executable, the required form of the "work that uses the +Library" must include any data and utility programs needed for +reproducing the executable from it. 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. + + It may happen that this requirement contradicts the license +restrictions of other proprietary libraries that do not normally +accompany the operating system. Such a contradiction means you cannot +use both them and the Library together in an executable that you +distribute. + + 7. You may place library facilities that are a work based on the +Library side-by-side in a single library together with other library +facilities not covered by this License, and distribute such a combined +library, provided that the separate distribution of the work based on +the Library and of the other library facilities is otherwise +permitted, and provided that you do these two things: + + a) Accompany the combined library with a copy of the same work + based on the Library, uncombined with any other library + facilities. This must be distributed under the terms of the + Sections above. + + b) Give prominent notice with the combined library of the fact + that part of it is a work based on the Library, and explaining + where to find the accompanying uncombined form of the same work. + + 8. You may not copy, modify, sublicense, link with, or distribute +the Library except as expressly provided under this License. Any +attempt otherwise to copy, modify, sublicense, link with, or +distribute the Library 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. + + 9. 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 Library or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Library (or any work based on the +Library), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Library or works based on it. + + 10. Each time you redistribute the Library (or any work based on the +Library), the recipient automatically receives a license from the +original licensor to copy, distribute, link with or modify the Library +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. + + 11. 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 Library at all. For example, if a patent +license would not permit royalty-free redistribution of the Library 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 Library. + +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. + + 12. If the distribution and/or use of the Library is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Library 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. + + 13. The Free Software Foundation may publish revised and/or new +versions of the Library 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 Library +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 Library does not specify a +license version number, you may choose any version ever published by +the Free Software Foundation. + + 14. If you wish to incorporate parts of the Library into other free +programs whose distribution conditions are incompatible with these, +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 make exceptions for this. Our +decision will be guided by the two goals of preserving the free status +of all derivatives of our free software and of promoting the sharing +and reuse of software generally. + + NO WARRANTY + + 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO +WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. +EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR +OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY +KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE +LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME +THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. 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 LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU +FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR +CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE +LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING +RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A +FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF +SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH +DAMAGES. + + END OF TERMS AND CONDITIONS + + Appendix: How to Apply These Terms to Your New Libraries + + If you develop a new library, and you want it to be of the greatest +possible use to the public, we recommend making it free software that +everyone can redistribute and change. You can do so by permitting +redistribution under these terms (or, alternatively, under the terms of the +ordinary General Public License). + + To apply these terms, attach the following notices to the library. 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) + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software 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. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the library, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the + library `Frob' (a library for tweaking knobs) written by James Random Hacker. + + , 1 April 1990 + Ty Coon, President of Vice + +That's all there is to it! diff --git a/src/apps/bin/gawk/missing_d/ChangeLog b/src/apps/bin/gawk/missing_d/ChangeLog new file mode 100644 index 0000000000..da1d09a5c0 --- /dev/null +++ b/src/apps/bin/gawk/missing_d/ChangeLog @@ -0,0 +1,40 @@ +Mon Jul 7 11:01:43 2003 Arnold D. Robbins + + * Release 3.1.3: Release tar file made. + +Wed Mar 19 14:10:31 2003 Arnold D. Robbins + + This time for sure. + -- Bullwinkle + + * Release 3.1.2: Release tar file made. + +Mon Feb 3 20:37:09 2003 Pat Rankin + + * strftime.c: Restore use of TIME_T_IN_SYS_TYPES_H to control + inclusion of . + (TYPE_SIGNED): Add workaround to avoid diagnostic from Compaq C V6.4. + (my_strftime) [case 's']: Likewise; exclude negative number handling + if TIME_T_UNSIGNED is defined. + +Mon Jan 27 12:09:50 2003 Stepan Kasal + + * strtod.c (gawk_strtod): Cleanup, changing the logic + so that ptr is correct. Fixes the bug that 0e0 is not + recognized as numeric. + +Wed May 1 16:41:32 2002 Arnold D. Robbins + + * Release 3.1.1: Release tar file made. + +Tue Dec 4 17:56:46 2001 Arnold D. Robbins + + * strftime.c: Replaced with glibc version. + * strftime.3: Removed + +Fri Aug 3 09:01:19 2001 Arnold D. Robbins + + ChangeLog created. + + * strtod.c (strtod): Fixed test at end for failure to + be a little smarter. diff --git a/src/apps/bin/gawk/missing_d/memcmp.c b/src/apps/bin/gawk/missing_d/memcmp.c new file mode 100644 index 0000000000..63cb5f8f74 --- /dev/null +++ b/src/apps/bin/gawk/missing_d/memcmp.c @@ -0,0 +1,18 @@ +/* + * memcmp --- compare strings. + * + * We use our own routine since it has to act like strcmp() for return + * value, and the BSD manual says bcmp() only returns zero/non-zero. + */ + +int +memcmp (s1, s2, l) +register char *s1, *s2; +register int l; +{ + for (; l-- > 0; s1++, s2++) { + if (*s1 != *s2) + return (*s1 - *s2); + } + return (0); +} diff --git a/src/apps/bin/gawk/missing_d/memcpy.c b/src/apps/bin/gawk/missing_d/memcpy.c new file mode 100644 index 0000000000..3c4accdf6f --- /dev/null +++ b/src/apps/bin/gawk/missing_d/memcpy.c @@ -0,0 +1,18 @@ +/* + * memcpy --- copy strings. + * + * We supply this routine for those systems that aren't standard yet. + */ + +char * +memcpy (dest, src, l) +register char *dest, *src; +register int l; +{ + register char *ret = dest; + + while (l--) + *dest++ = *src++; + + return ret; +} diff --git a/src/apps/bin/gawk/missing_d/memset.c b/src/apps/bin/gawk/missing_d/memset.c new file mode 100644 index 0000000000..1ff4458b3e --- /dev/null +++ b/src/apps/bin/gawk/missing_d/memset.c @@ -0,0 +1,20 @@ +/* + * memset --- initialize memory + * + * We supply this routine for those systems that aren't standard yet. + */ + +void * +memset(dest, val, l) +void *dest; +register int val; +register size_t l; +{ + register char *ret = dest; + register char *d = dest; + + while (l--) + *d++ = val; + + return ((void *) ret); +} diff --git a/src/apps/bin/gawk/missing_d/mktime.c b/src/apps/bin/gawk/missing_d/mktime.c new file mode 100644 index 0000000000..fab599d862 --- /dev/null +++ b/src/apps/bin/gawk/missing_d/mktime.c @@ -0,0 +1,425 @@ +/* Copyright (C) 1993, 1994, 1995, 1996, 1997 Free Software Foundation, Inc. + This file is part of the GNU C Library. + Contributed by Paul Eggert (eggert@twinsun.com). + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with the GNU C Library; see the file COPYING.LIB. If not, + write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. */ + +/* Define this to have a standalone program to test this implementation of + mktime. */ +/* #define DEBUG 1 */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#ifdef _LIBC +# define HAVE_LIMITS_H 1 +# define HAVE_LOCALTIME_R 1 +# define STDC_HEADERS 1 +#endif + +/* Assume that leap seconds are possible, unless told otherwise. + If the host has a `zic' command with a `-L leapsecondfilename' option, + then it supports leap seconds; otherwise it probably doesn't. */ +#ifndef LEAP_SECONDS_POSSIBLE +#define LEAP_SECONDS_POSSIBLE 1 +#endif + +#ifndef VMS +#include /* Some systems define `time_t' here. */ +#else +#include +#endif +#include + +#if HAVE_LIMITS_H +#include +#endif + +#if DEBUG +#include +#if STDC_HEADERS +#include +#endif +/* Make it work even if the system's libc has its own mktime routine. */ +#define mktime my_mktime +#endif /* DEBUG */ + +#ifndef __P +#if defined (__GNUC__) || (defined (__STDC__) && __STDC__) +#define __P(args) args +#else +#define __P(args) () +#endif /* GCC. */ +#endif /* Not __P. */ + +#ifndef CHAR_BIT +#define CHAR_BIT 8 +#endif + +#ifndef INT_MIN +#define INT_MIN (~0 << (sizeof (int) * CHAR_BIT - 1)) +#endif +#ifndef INT_MAX +#define INT_MAX (~0 - INT_MIN) +#endif + +#ifndef TIME_T_MIN +#define TIME_T_MIN (0 < (time_t) -1 ? (time_t) 0 \ + : ~ (time_t) 0 << (sizeof (time_t) * CHAR_BIT - 1)) +#endif +#ifndef TIME_T_MAX +#define TIME_T_MAX (~ (time_t) 0 - TIME_T_MIN) +#endif + +#define TM_YEAR_BASE 1900 +#define EPOCH_YEAR 1970 + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +#define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + +/* How many days come before each month (0-12). */ +const unsigned short int __mon_yday[2][13] = + { + /* Normal years. */ + { 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, + /* Leap years. */ + { 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 } + }; + +static time_t ydhms_tm_diff __P ((int, int, int, int, int, const struct tm *)); +time_t __mktime_internal __P ((struct tm *, + struct tm *(*) (const time_t *, struct tm *), + time_t *)); + + +static struct tm *my_localtime_r __P ((const time_t *, struct tm *)); +static struct tm * +my_localtime_r (t, tp) + const time_t *t; + struct tm *tp; +{ + struct tm *l = localtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} + + +/* Yield the difference between (YEAR-YDAY HOUR:MIN:SEC) and (*TP), + measured in seconds, ignoring leap seconds. + YEAR uses the same numbering as TM->tm_year. + All values are in range, except possibly YEAR. + If overflow occurs, yield the low order bits of the correct answer. */ +static time_t +ydhms_tm_diff (year, yday, hour, min, sec, tp) + int year, yday, hour, min, sec; + const struct tm *tp; +{ + /* Compute intervening leap days correctly even if year is negative. + Take care to avoid int overflow. time_t overflow is OK, since + only the low order bits of the correct time_t answer are needed. + Don't convert to time_t until after all divisions are done, since + time_t might be unsigned. */ + int a4 = (year >> 2) + (TM_YEAR_BASE >> 2) - ! (year & 3); + int b4 = (tp->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (tp->tm_year & 3); + int a100 = a4 / 25 - (a4 % 25 < 0); + int b100 = b4 / 25 - (b4 % 25 < 0); + int a400 = a100 >> 2; + int b400 = b100 >> 2; + int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); + time_t years = year - (time_t) tp->tm_year; + time_t days = (365 * years + intervening_leap_days + + (yday - tp->tm_yday)); + return (60 * (60 * (24 * days + (hour - tp->tm_hour)) + + (min - tp->tm_min)) + + (sec - tp->tm_sec)); +} + + +static time_t localtime_offset; + +/* Convert *TP to a time_t value. */ +time_t +mktime (tp) + struct tm *tp; +{ +#ifdef _LIBC + /* POSIX.1 8.1.1 requires that whenever mktime() is called, the + time zone names contained in the external variable `tzname' shall + be set as if the tzset() function had been called. */ + __tzset (); +#endif + + return __mktime_internal (tp, my_localtime_r, &localtime_offset); +} + +/* Convert *TP to a time_t value, inverting + the monotonic and mostly-unit-linear conversion function CONVERT. + Use *OFFSET to keep track of a guess at the offset of the result, + compared to what the result would be for UTC without leap seconds. + If *OFFSET's guess is correct, only one CONVERT call is needed. */ +time_t +__mktime_internal (tp, convert, offset) + struct tm *tp; + struct tm *(*convert) __P ((const time_t *, struct tm *)); + time_t *offset; +{ + time_t t, dt, t0; + struct tm tm; + + /* The maximum number of probes (calls to CONVERT) should be enough + to handle any combinations of time zone rule changes, solar time, + and leap seconds. Posix.1 prohibits leap seconds, but some hosts + have them anyway. */ + int remaining_probes = 4; + + /* Time requested. Copy it in case CONVERT modifies *TP; this can + occur if TP is localtime's returned value and CONVERT is localtime. */ + int sec = tp->tm_sec; + int min = tp->tm_min; + int hour = tp->tm_hour; + int mday = tp->tm_mday; + int mon = tp->tm_mon; + int year_requested = tp->tm_year; + int isdst = tp->tm_isdst; + + /* Ensure that mon is in range, and set year accordingly. */ + int mon_remainder = mon % 12; + int negative_mon_remainder = mon_remainder < 0; + int mon_years = mon / 12 - negative_mon_remainder; + int year = year_requested + mon_years; + + /* The other values need not be in range: + the remaining code handles minor overflows correctly, + assuming int and time_t arithmetic wraps around. + Major overflows are caught at the end. */ + + /* Calculate day of year from year, month, and day of month. + The result need not be in range. */ + int yday = ((__mon_yday[__isleap (year + TM_YEAR_BASE)] + [mon_remainder + 12 * negative_mon_remainder]) + + mday - 1); + +#if LEAP_SECONDS_POSSIBLE + /* Handle out-of-range seconds specially, + since ydhms_tm_diff assumes every minute has 60 seconds. */ + int sec_requested = sec; + if (sec < 0) + sec = 0; + if (59 < sec) + sec = 59; +#endif + + /* Invert CONVERT by probing. First assume the same offset as last time. + Then repeatedly use the error to improve the guess. */ + + tm.tm_year = EPOCH_YEAR - TM_YEAR_BASE; + tm.tm_yday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0; + t0 = ydhms_tm_diff (year, yday, hour, min, sec, &tm); + + for (t = t0 + *offset; + (dt = ydhms_tm_diff (year, yday, hour, min, sec, (*convert) (&t, &tm))); + t += dt) + if (--remaining_probes == 0) + return -1; + + /* Check whether tm.tm_isdst has the requested value, if any. */ + if (0 <= isdst && 0 <= tm.tm_isdst) + { + int dst_diff = (isdst != 0) - (tm.tm_isdst != 0); + if (dst_diff) + { + /* Move two hours in the direction indicated by the disagreement, + probe some more, and switch to a new time if found. + The largest known fallback due to daylight savings is two hours: + once, in Newfoundland, 1988-10-30 02:00 -> 00:00. */ + time_t ot = t - 2 * 60 * 60 * dst_diff; + while (--remaining_probes != 0) + { + struct tm otm; + if (! (dt = ydhms_tm_diff (year, yday, hour, min, sec, + (*convert) (&ot, &otm)))) + { + t = ot; + tm = otm; + break; + } + if ((ot += dt) == t) + break; /* Avoid a redundant probe. */ + } + } + } + + *offset = t - t0; + +#if LEAP_SECONDS_POSSIBLE + if (sec_requested != tm.tm_sec) + { + /* Adjust time to reflect the tm_sec requested, not the normalized value. + Also, repair any damage from a false match due to a leap second. */ + t += sec_requested - sec + (sec == 0 && tm.tm_sec == 60); + (*convert) (&t, &tm); + } +#endif + + if (TIME_T_MAX / INT_MAX / 366 / 24 / 60 / 60 < 3) + { + /* time_t isn't large enough to rule out overflows in ydhms_tm_diff, + so check for major overflows. A gross check suffices, + since if t has overflowed, it is off by a multiple of + TIME_T_MAX - TIME_T_MIN + 1. So ignore any component of + the difference that is bounded by a small value. */ + + double dyear = (double) year_requested + mon_years - tm.tm_year; + double dday = 366 * dyear + mday; + double dsec = 60 * (60 * (24 * dday + hour) + min) + sec_requested; + + if (TIME_T_MAX / 3 - TIME_T_MIN / 3 < (dsec < 0 ? - dsec : dsec)) + return -1; + } + + *tp = tm; + return t; +} + +#ifdef weak_alias +weak_alias (mktime, timelocal) +#endif + +#if DEBUG + +static int +not_equal_tm (a, b) + struct tm *a; + struct tm *b; +{ + return ((a->tm_sec ^ b->tm_sec) + | (a->tm_min ^ b->tm_min) + | (a->tm_hour ^ b->tm_hour) + | (a->tm_mday ^ b->tm_mday) + | (a->tm_mon ^ b->tm_mon) + | (a->tm_year ^ b->tm_year) + | (a->tm_mday ^ b->tm_mday) + | (a->tm_yday ^ b->tm_yday) + | (a->tm_isdst ^ b->tm_isdst)); +} + +static void +print_tm (tp) + struct tm *tp; +{ + printf ("%04d-%02d-%02d %02d:%02d:%02d yday %03d wday %d isdst %d", + tp->tm_year + TM_YEAR_BASE, tp->tm_mon + 1, tp->tm_mday, + tp->tm_hour, tp->tm_min, tp->tm_sec, + tp->tm_yday, tp->tm_wday, tp->tm_isdst); +} + +static int +check_result (tk, tmk, tl, tml) + time_t tk; + struct tm tmk; + time_t tl; + struct tm tml; +{ + if (tk != tl || not_equal_tm (&tmk, &tml)) + { + printf ("mktime ("); + print_tm (&tmk); + printf (")\nyields ("); + print_tm (&tml); + printf (") == %ld, should be %ld\n", (long) tl, (long) tk); + return 1; + } + + return 0; +} + +int +main (argc, argv) + int argc; + char **argv; +{ + int status = 0; + struct tm tm, tmk, tml; + time_t tk, tl; + char trailer; + + if ((argc == 3 || argc == 4) + && (sscanf (argv[1], "%d-%d-%d%c", + &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &trailer) + == 3) + && (sscanf (argv[2], "%d:%d:%d%c", + &tm.tm_hour, &tm.tm_min, &tm.tm_sec, &trailer) + == 3)) + { + tm.tm_year -= TM_YEAR_BASE; + tm.tm_mon--; + tm.tm_isdst = argc == 3 ? -1 : atoi (argv[3]); + tmk = tm; + tl = mktime (&tmk); + tml = *localtime (&tl); + printf ("mktime returns %ld == ", (long) tl); + print_tm (&tmk); + printf ("\n"); + status = check_result (tl, tmk, tl, tml); + } + else if (argc == 4 || (argc == 5 && strcmp (argv[4], "-") == 0)) + { + time_t from = atol (argv[1]); + time_t by = atol (argv[2]); + time_t to = atol (argv[3]); + + if (argc == 4) + for (tl = from; tl <= to; tl += by) + { + tml = *localtime (&tl); + tmk = tml; + tk = mktime (&tmk); + status |= check_result (tk, tmk, tl, tml); + } + else + for (tl = from; tl <= to; tl += by) + { + /* Null benchmark. */ + tml = *localtime (&tl); + tmk = tml; + tk = tl; + status |= check_result (tk, tmk, tl, tml); + } + } + else + printf ("Usage:\ +\t%s YYYY-MM-DD HH:MM:SS [ISDST] # Test given time.\n\ +\t%s FROM BY TO # Test values FROM, FROM+BY, ..., TO.\n\ +\t%s FROM BY TO - # Do not test those values (for benchmark).\n", + argv[0], argv[0], argv[0]); + + return status; +} + +#endif /* DEBUG */ + +/* +Local Variables: +compile-command: "gcc -DDEBUG=1 -Wall -O -g mktime.c -o mktime" +End: +*/ diff --git a/src/apps/bin/gawk/missing_d/strchr.c b/src/apps/bin/gawk/missing_d/strchr.c new file mode 100644 index 0000000000..7da479fcc0 --- /dev/null +++ b/src/apps/bin/gawk/missing_d/strchr.c @@ -0,0 +1,47 @@ +/* + * strchr --- search a string for a character + * + * We supply this routine for those systems that aren't standard yet. + */ + +#if 0 +#include +#endif + +char * +strchr(str, c) +register const char *str, c; +{ + if (c == '\0') { + /* thanks to Mike Brennan ... */ + do { + if (*str == c) + return (char *) str; + } while (*str++); + } else { + for (; *str; str++) + if (*str == c) + return (char *) str; + } + + return NULL; +} + +/* + * strrchr --- find the last occurrence of a character in a string + * + * We supply this routine for those systems that aren't standard yet. + */ + +char * +strrchr(str, c) +register const char *str, c; +{ + register const char *save = NULL; + + for (; *str; str++) + if (*str == c) + save = str; + + return (char *) save; +} diff --git a/src/apps/bin/gawk/missing_d/strerror.c b/src/apps/bin/gawk/missing_d/strerror.c new file mode 100644 index 0000000000..6a7259951c --- /dev/null +++ b/src/apps/bin/gawk/missing_d/strerror.c @@ -0,0 +1,37 @@ +/* strerror.c --- ANSI C compatible system error routine + + Copyright (C) 1986, 1988, 1989, 1991 the Free Software Foundation, Inc. + + 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 2, 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +#if 0 +#include +#endif + +extern int sys_nerr; +extern char *sys_errlist[]; + +char * +strerror(n) +int n; +{ + static char mesg[30]; + + if (n < 0 || n >= sys_nerr) { + sprintf(mesg, "Unknown error (%d)", n); + return mesg; + } else + return sys_errlist[n]; +} diff --git a/src/apps/bin/gawk/missing_d/strftime.c b/src/apps/bin/gawk/missing_d/strftime.c new file mode 100644 index 0000000000..c1e1a1e228 --- /dev/null +++ b/src/apps/bin/gawk/missing_d/strftime.c @@ -0,0 +1,1473 @@ +/* Copyright (C) 1991-1999, 2000, 2001, 2002, 2003 + Free Software Foundation, Inc. + This file is part of the GNU C Library. + + The GNU C Library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2.1 of the License, or (at your option) any later version. + + The GNU C Library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with the GNU C Library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA + 02111-1307 USA. */ + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef _LIBC +# define HAVE_LIMITS_H 1 +# define HAVE_MBLEN 1 +# define HAVE_MBRLEN 1 +# define HAVE_STRUCT_ERA_ENTRY 1 +# define HAVE_TM_GMTOFF 1 +# define HAVE_TM_ZONE 1 +# define HAVE_TZNAME 1 +# define HAVE_TZSET 1 +# define MULTIBYTE_IS_FORMAT_SAFE 1 +# define STDC_HEADERS 1 +# include "../locale/localeinfo.h" +#endif + +#if defined emacs && !defined HAVE_BCOPY +# define HAVE_MEMCPY 1 +#endif + +#include +#ifdef TIME_T_IN_SYS_TYPES +#include /* Some systems define `time_t' here. */ +#endif + +#ifdef TIME_WITH_SYS_TIME +# include +# include +#else +# ifdef HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif +#if HAVE_TZNAME +extern char *tzname[]; +#endif + +/* Do multibyte processing if multibytes are supported, unless + multibyte sequences are safe in formats. Multibyte sequences are + safe if they cannot contain byte sequences that look like format + conversion specifications. The GNU C Library uses UTF8 multibyte + encoding, which is safe for formats, but strftime.c can be used + with other C libraries that use unsafe encodings. */ +#define DO_MULTIBYTE (HAVE_MBLEN && ! MULTIBYTE_IS_FORMAT_SAFE) + +#if DO_MULTIBYTE +# if HAVE_MBRLEN +# include +# else + /* Simulate mbrlen with mblen as best we can. */ +# define mbstate_t int +# define mbrlen(s, n, ps) mblen (s, n) +# define mbsinit(ps) (*(ps) == 0) +# endif + static const mbstate_t mbstate_zero; +#endif + +#if HAVE_LIMITS_H +# include +#endif + +#if STDC_HEADERS +# include +# include +# include +#else +# ifndef HAVE_MEMCPY +# define memcpy(d, s, n) bcopy ((s), (d), (n)) +# endif +#endif + +#ifdef COMPILE_WIDE +# include +# define CHAR_T wchar_t +# define UCHAR_T unsigned int +# define L_(Str) L##Str +# define NLW(Sym) _NL_W##Sym + +# define MEMCPY(d, s, n) __wmemcpy (d, s, n) +# define STRLEN(s) __wcslen (s) + +#else +# define CHAR_T char +# define UCHAR_T unsigned char +# define L_(Str) Str +# define NLW(Sym) Sym + +# if !defined STDC_HEADERS && !defined HAVE_MEMCPY +# define MEMCPY(d, s, n) bcopy ((s), (d), (n)) +# else +# define MEMCPY(d, s, n) memcpy ((d), (s), (n)) +# endif +# define STRLEN(s) strlen (s) + +# ifdef _LIBC +# define MEMPCPY(d, s, n) __mempcpy (d, s, n) +# else +# ifndef HAVE_MEMPCPY +# define MEMPCPY(d, s, n) ((void *) ((char *) memcpy (d, s, n) + (n))) +# endif +# endif +#endif + +#ifndef __P +# if defined __GNUC__ || (defined __STDC__ && __STDC__) +# define __P(args) args +# else +# define __P(args) () +# endif /* GCC. */ +#endif /* Not __P. */ + +#ifndef PTR +# ifdef __STDC__ +# define PTR void * +# else +# define PTR char * +# endif +#endif + +#ifndef CHAR_BIT +# define CHAR_BIT 8 +#endif + +#ifndef NULL +# define NULL 0 +#endif + +/* Test for checking whether a given type is signed or not. + Some compilers issue a diagnostic about suspicious construct for + a test that will always fail when comparing a value that can't be + negative against 0 using `<' or `<=' operator. */ +/* #define TYPE_SIGNED(t) ((t) -1 < 0) */ +#define TYPE_SIGNED(t) ((t) -1 < 1) + +#ifndef INT_STRLEN_BOUND +/* Bound on length of the string representing an integer value of type t. + Subtract one for the sign bit if t is signed; + 302 / 1000 is log10 (2) rounded up; + add one for integer division truncation; + add one more for a minus sign if t is signed. */ +#define INT_STRLEN_BOUND(t) \ + ((sizeof (t) * CHAR_BIT - TYPE_SIGNED (t)) * 302 / 1000 + 1 + TYPE_SIGNED (t)) +#endif + +#define TM_YEAR_BASE 1900 + +#ifndef __isleap +/* Nonzero if YEAR is a leap year (every 4 years, + except every 100th isn't, and every 400th is). */ +# define __isleap(year) \ + ((year) % 4 == 0 && ((year) % 100 != 0 || (year) % 400 == 0)) +#endif + + +#ifdef _LIBC +# define my_strftime_gmtime_r __gmtime_r +# define my_strftime_localtime_r __localtime_r +# define tzname __tzname +# define tzset __tzset +#else + +/* If we're a strftime substitute in a GNU program, then prefer gmtime + to gmtime_r, since many gmtime_r implementations are buggy. + Similarly for localtime_r. */ + +# if ! HAVE_TM_GMTOFF +static struct tm *my_strftime_gmtime_r __P ((const time_t *, struct tm *)); +static struct tm * +my_strftime_gmtime_r (t, tp) + const time_t *t; + struct tm *tp; +{ + struct tm *l = gmtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} +# endif /* ! HAVE_TM_GMTOFF */ + +static struct tm *my_strftime_localtime_r __P ((const time_t *, struct tm *)); +static struct tm * +my_strftime_localtime_r (t, tp) + const time_t *t; + struct tm *tp; +{ + struct tm *l = localtime (t); + if (! l) + return 0; + *tp = *l; + return tp; +} +#endif /* ! defined _LIBC */ + + +#if !defined memset && !defined HAVE_MEMSET && !defined _LIBC +/* Some systems lack the `memset' function and we don't want to + introduce additional dependencies. */ +/* The SGI compiler reportedly barfs on the trailing null + if we use a string constant as the initializer. 28 June 1997, rms. */ +static const CHAR_T spaces[16] = /* " " */ +{ + L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '), + L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' '),L_(' ') +}; +static const CHAR_T zeroes[16] = /* "0000000000000000" */ +{ + L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'), + L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0'),L_('0') +}; + +# define memset_space(P, Len) \ + do { \ + int _len = (Len); \ + \ + do \ + { \ + int _this = _len > 16 ? 16 : _len; \ + (P) = MEMPCPY ((P), spaces, _this * sizeof (CHAR_T)); \ + _len -= _this; \ + } \ + while (_len > 0); \ + } while (0) + +# define memset_zero(P, Len) \ + do { \ + int _len = (Len); \ + \ + do \ + { \ + int _this = _len > 16 ? 16 : _len; \ + (P) = MEMPCPY ((P), zeroes, _this * sizeof (CHAR_T)); \ + _len -= _this; \ + } \ + while (_len > 0); \ + } while (0) +#else +# ifdef COMPILE_WIDE +# define memset_space(P, Len) (wmemset ((P), L' ', (Len)), (P) += (Len)) +# define memset_zero(P, Len) (wmemset ((P), L'0', (Len)), (P) += (Len)) +# else +# define memset_space(P, Len) (memset ((P), ' ', (Len)), (P) += (Len)) +# define memset_zero(P, Len) (memset ((P), '0', (Len)), (P) += (Len)) +# endif +#endif + +#define add(n, f) \ + do \ + { \ + int _n = (n); \ + int _delta = width - _n; \ + int _incr = _n + (_delta > 0 ? _delta : 0); \ + if ((size_t) _incr >= maxsize - i) \ + return 0; \ + if (p) \ + { \ + if (_delta > 0) \ + { \ + if (pad == L_('0')) \ + memset_zero (p, _delta); \ + else \ + memset_space (p, _delta); \ + } \ + f; \ + p += _n; \ + } \ + i += _incr; \ + } while (0) + +#define cpy(n, s) \ + add ((n), \ + if (to_lowcase) \ + memcpy_lowcase (p, (s), _n LOCALE_ARG); \ + else if (to_uppcase) \ + memcpy_uppcase (p, (s), _n LOCALE_ARG); \ + else \ + MEMCPY ((PTR) p, (const PTR) (s), _n)) + +#ifdef COMPILE_WIDE +# ifndef USE_IN_EXTENDED_LOCALE_MODEL +# undef __mbsrtowcs_l +# define __mbsrtowcs_l(d, s, l, st, loc) __mbsrtowcs (d, s, l, st) +# endif +# define widen(os, ws, l) \ + { \ + mbstate_t __st; \ + const char *__s = os; \ + memset (&__st, '\0', sizeof (__st)); \ + l = __mbsrtowcs_l (NULL, &__s, 0, &__st, loc); \ + ws = alloca ((l + 1) * sizeof (wchar_t)); \ + (void) __mbsrtowcs_l (ws, &__s, l, &__st, loc); \ + } +#endif + +/* For gawk */ +#undef TOLOWER +#undef TOUPPER +#undef ISDIGIT + +#if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL +/* We use this code also for the extended locale handling where the + function gets as an additional argument the locale which has to be + used. To access the values we have to redefine the _NL_CURRENT + macro. */ +# define strftime __strftime_l +# define wcsftime __wcsftime_l +# undef _NL_CURRENT +# define _NL_CURRENT(category, item) \ + (current->values[_NL_ITEM_INDEX (item)].string) +# define LOCALE_PARAM , loc +# define LOCALE_ARG , loc +# define LOCALE_PARAM_DECL __locale_t loc; +# define LOCALE_PARAM_PROTO , __locale_t loc +# define HELPER_LOCALE_ARG , current +#else +# define LOCALE_PARAM +# define LOCALE_PARAM_PROTO +# define LOCALE_ARG +# define LOCALE_PARAM_DECL +# ifdef _LIBC +# define HELPER_LOCALE_ARG , _NL_CURRENT_DATA (LC_TIME) +# else +# define HELPER_LOCALE_ARG +# endif +#endif + +#ifdef COMPILE_WIDE +# ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define TOUPPER(Ch, L) __towupper_l (Ch, L) +# define TOLOWER(Ch, L) __towlower_l (Ch, L) +# else +# define TOUPPER(Ch, L) towupper (Ch) +# define TOLOWER(Ch, L) towlower (Ch) +# endif +#else +# ifdef _LIBC +# ifdef USE_IN_EXTENDED_LOCALE_MODEL +# define TOUPPER(Ch, L) __toupper_l (Ch, L) +# define TOLOWER(Ch, L) __tolower_l (Ch, L) +# else +# define TOUPPER(Ch, L) toupper (Ch) +# define TOLOWER(Ch, L) tolower (Ch) +# endif +# else +# define TOUPPER(Ch, L) (islower (Ch) ? toupper (Ch) : (Ch)) +# define TOLOWER(Ch, L) (isupper (Ch) ? tolower (Ch) : (Ch)) +# endif +#endif +/* We don't use `isdigit' here since the locale dependent + interpretation is not what we want here. We only need to accept + the arabic digits in the ASCII range. One day there is perhaps a + more reliable way to accept other sets of digits. */ +#define ISDIGIT(Ch) ((unsigned int) (Ch) - L_('0') <= 9) + +static CHAR_T *memcpy_lowcase __P ((CHAR_T *dest, const CHAR_T *src, + size_t len LOCALE_PARAM_PROTO)); + +static CHAR_T * +memcpy_lowcase (dest, src, len LOCALE_PARAM) + CHAR_T *dest; + const CHAR_T *src; + size_t len; + LOCALE_PARAM_DECL +{ + while (len-- > 0) + dest[len] = TOLOWER ((UCHAR_T) src[len], loc); + return dest; +} + +static CHAR_T *memcpy_uppcase __P ((CHAR_T *dest, const CHAR_T *src, + size_t len LOCALE_PARAM_PROTO)); + +static CHAR_T * +memcpy_uppcase (dest, src, len LOCALE_PARAM) + CHAR_T *dest; + const CHAR_T *src; + size_t len; + LOCALE_PARAM_DECL +{ + while (len-- > 0) + dest[len] = TOUPPER ((UCHAR_T) src[len], loc); + return dest; +} + + +#if ! HAVE_TM_GMTOFF +/* Yield the difference between *A and *B, + measured in seconds, ignoring leap seconds. */ +# define tm_diff ftime_tm_diff +static int tm_diff __P ((const struct tm *, const struct tm *)); +static int +tm_diff (a, b) + const struct tm *a; + const struct tm *b; +{ + /* Compute intervening leap days correctly even if year is negative. + Take care to avoid int overflow in leap day calculations, + but it's OK to assume that A and B are close to each other. */ + int a4 = (a->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (a->tm_year & 3); + int b4 = (b->tm_year >> 2) + (TM_YEAR_BASE >> 2) - ! (b->tm_year & 3); + int a100 = a4 / 25 - (a4 % 25 < 0); + int b100 = b4 / 25 - (b4 % 25 < 0); + int a400 = a100 >> 2; + int b400 = b100 >> 2; + int intervening_leap_days = (a4 - b4) - (a100 - b100) + (a400 - b400); + int years = a->tm_year - b->tm_year; + int days = (365 * years + intervening_leap_days + + (a->tm_yday - b->tm_yday)); + return (60 * (60 * (24 * days + (a->tm_hour - b->tm_hour)) + + (a->tm_min - b->tm_min)) + + (a->tm_sec - b->tm_sec)); +} +#endif /* ! HAVE_TM_GMTOFF */ + + + +/* The number of days from the first day of the first ISO week of this + year to the year day YDAY with week day WDAY. ISO weeks start on + Monday; the first ISO week has the year's first Thursday. YDAY may + be as small as YDAY_MINIMUM. */ +#define ISO_WEEK_START_WDAY 1 /* Monday */ +#define ISO_WEEK1_WDAY 4 /* Thursday */ +#define YDAY_MINIMUM (-366) +static int iso_week_days __P ((int, int)); +#ifdef __GNUC__ +__inline__ +#endif +static int +iso_week_days (yday, wday) + int yday; + int wday; +{ + /* Add enough to the first operand of % to make it nonnegative. */ + int big_enough_multiple_of_7 = (-YDAY_MINIMUM / 7 + 2) * 7; + return (yday + - (yday - wday + ISO_WEEK1_WDAY + big_enough_multiple_of_7) % 7 + + ISO_WEEK1_WDAY - ISO_WEEK_START_WDAY); +} + + +#if !(defined _NL_CURRENT || HAVE_STRFTIME) +static CHAR_T const weekday_name[][10] = + { + L_("Sunday"), L_("Monday"), L_("Tuesday"), L_("Wednesday"), + L_("Thursday"), L_("Friday"), L_("Saturday") + }; +static CHAR_T const month_name[][10] = + { + L_("January"), L_("February"), L_("March"), L_("April"), L_("May"), + L_("June"), L_("July"), L_("August"), L_("September"), L_("October"), + L_("November"), L_("December") + }; +#endif + + +#ifdef emacs +# define my_strftime emacs_strftimeu +# define ut_argument , ut +# define ut_argument_spec int ut; +# define ut_argument_spec_iso , int ut +#else +# ifdef COMPILE_WIDE +# define my_strftime wcsftime +# define nl_get_alt_digit _nl_get_walt_digit +# else +# define my_strftime strftime +# define nl_get_alt_digit _nl_get_alt_digit +# endif +# define ut_argument +# define ut_argument_spec +# define ut_argument_spec_iso +/* We don't have this information in general. */ +# define ut 0 +#endif + +#if !defined _LIBC && HAVE_TZNAME && HAVE_TZSET + /* Solaris 2.5 tzset sometimes modifies the storage returned by localtime. + Work around this bug by copying *tp before it might be munged. */ + size_t _strftime_copytm __P ((char *, size_t, const char *, + const struct tm * ut_argument_spec_iso)); + size_t + my_strftime (s, maxsize, format, tp ut_argument) + CHAR_T *s; + size_t maxsize; + const CHAR_T *format; + const struct tm *tp; + ut_argument_spec + { + struct tm tmcopy; + tmcopy = *tp; + return _strftime_copytm (s, maxsize, format, &tmcopy ut_argument); + } +# undef my_strftime +# define my_strftime _strftime_copytm +#endif + + +/* Write information from TP into S according to the format + string FORMAT, writing no more that MAXSIZE characters + (including the terminating '\0') and returning number of + characters written. If S is NULL, nothing will be written + anywhere, so to determine how many characters would be + written, use NULL for S and (size_t) UINT_MAX for MAXSIZE. */ +size_t +my_strftime (s, maxsize, format, tp ut_argument LOCALE_PARAM) + CHAR_T *s; + size_t maxsize; + const CHAR_T *format; + const struct tm *tp; + ut_argument_spec + LOCALE_PARAM_DECL +{ +#if defined _LIBC && defined USE_IN_EXTENDED_LOCALE_MODEL + struct locale_data *const current = loc->__locales[LC_TIME]; +#endif + + int hour12 = tp->tm_hour; +#ifdef _NL_CURRENT + /* We cannot make the following values variables since we must delay + the evaluation of these values until really needed since some + expressions might not be valid in every situation. The `struct tm' + might be generated by a strptime() call that initialized + only a few elements. Dereference the pointers only if the format + requires this. Then it is ok to fail if the pointers are invalid. */ +# define a_wkday \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABDAY_1) + tp->tm_wday)) +# define f_wkday \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(DAY_1) + tp->tm_wday)) +# define a_month \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ABMON_1) + tp->tm_mon)) +# define f_month \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(MON_1) + tp->tm_mon)) +# define ampm \ + ((const CHAR_T *) _NL_CURRENT (LC_TIME, tp->tm_hour > 11 \ + ? NLW(PM_STR) : NLW(AM_STR))) + +# define aw_len STRLEN (a_wkday) +# define am_len STRLEN (a_month) +# define ap_len STRLEN (ampm) +#else +# if !HAVE_STRFTIME +# define f_wkday (weekday_name[tp->tm_wday]) +# define f_month (month_name[tp->tm_mon]) +# define a_wkday f_wkday +# define a_month f_month +# define ampm (L_("AMPM") + 2 * (tp->tm_hour > 11)) + + size_t aw_len = 3; + size_t am_len = 3; + size_t ap_len = 2; +# endif +#endif + const char *zone; + size_t i = 0; + CHAR_T *p = s; + const CHAR_T *f; +#if DO_MULTIBYTE && !defined COMPILE_WIDE + const char *format_end = NULL; +#endif + + zone = NULL; +#if HAVE_TM_ZONE + /* The POSIX test suite assumes that setting + the environment variable TZ to a new value before calling strftime() + will influence the result (the %Z format) even if the information in + TP is computed with a totally different time zone. + This is bogus: though POSIX allows bad behavior like this, + POSIX does not require it. Do the right thing instead. */ + zone = (const char *) tp->tm_zone; +#endif +#if HAVE_TZNAME + if (ut) + { + if (! (zone && *zone)) + zone = "GMT"; + } + else + { + /* POSIX.1 requires that local time zone information is used as + though strftime called tzset. */ +# if HAVE_TZSET + tzset (); +# endif + } +#endif + + if (hour12 > 12) + hour12 -= 12; + else + if (hour12 == 0) + hour12 = 12; + + for (f = format; *f != '\0'; ++f) + { + int pad = 0; /* Padding for number ('-', '_', or 0). */ + int modifier; /* Field modifier ('E', 'O', or 0). */ + int digits; /* Max digits for numeric format. */ + int number_value; /* Numeric value to be printed. */ + int negative_number; /* 1 if the number is negative. */ + const CHAR_T *subfmt; + CHAR_T *bufp; + CHAR_T buf[1 + (sizeof (int) < sizeof (time_t) + ? INT_STRLEN_BOUND (time_t) + : INT_STRLEN_BOUND (int))]; + int width = -1; + int to_lowcase = 0; + int to_uppcase = 0; + int change_case = 0; + int format_char; + +#if DO_MULTIBYTE && !defined COMPILE_WIDE + switch (*f) + { + case L_('%'): + break; + + case L_('\b'): case L_('\t'): case L_('\n'): + case L_('\v'): case L_('\f'): case L_('\r'): + case L_(' '): case L_('!'): case L_('"'): case L_('#'): case L_('&'): + case L_('\''): case L_('('): case L_(')'): case L_('*'): case L_('+'): + case L_(','): case L_('-'): case L_('.'): case L_('/'): case L_('0'): + case L_('1'): case L_('2'): case L_('3'): case L_('4'): case L_('5'): + case L_('6'): case L_('7'): case L_('8'): case L_('9'): case L_(':'): + case L_(';'): case L_('<'): case L_('='): case L_('>'): case L_('?'): + case L_('A'): case L_('B'): case L_('C'): case L_('D'): case L_('E'): + case L_('F'): case L_('G'): case L_('H'): case L_('I'): case L_('J'): + case L_('K'): case L_('L'): case L_('M'): case L_('N'): case L_('O'): + case L_('P'): case L_('Q'): case L_('R'): case L_('S'): case L_('T'): + case L_('U'): case L_('V'): case L_('W'): case L_('X'): case L_('Y'): + case L_('Z'): case L_('['): case L_('\\'): case L_(']'): case L_('^'): + case L_('_'): case L_('a'): case L_('b'): case L_('c'): case L_('d'): + case L_('e'): case L_('f'): case L_('g'): case L_('h'): case L_('i'): + case L_('j'): case L_('k'): case L_('l'): case L_('m'): case L_('n'): + case L_('o'): case L_('p'): case L_('q'): case L_('r'): case L_('s'): + case L_('t'): case L_('u'): case L_('v'): case L_('w'): case L_('x'): + case L_('y'): case L_('z'): case L_('{'): case L_('|'): case L_('}'): + case L_('~'): + /* The C Standard requires these 98 characters (plus '%') to + be in the basic execution character set. None of these + characters can start a multibyte sequence, so they need + not be analyzed further. */ + add (1, *p = *f); + continue; + + default: + /* Copy this multibyte sequence until we reach its end, find + an error, or come back to the initial shift state. */ + { + mbstate_t mbstate = mbstate_zero; + size_t len = 0; + size_t fsize; + + if (! format_end) + format_end = f + strlen (f) + 1; + fsize = format_end - f; + + do + { + size_t bytes = mbrlen (f + len, fsize - len, &mbstate); + + if (bytes == 0) + break; + + if (bytes == (size_t) -2) + { + len += strlen (f + len); + break; + } + + if (bytes == (size_t) -1) + { + len++; + break; + } + + len += bytes; + } + while (! mbsinit (&mbstate)); + + cpy (len, f); + f += len - 1; + continue; + } + } + +#else /* ! DO_MULTIBYTE */ + + /* Either multibyte encodings are not supported, they are + safe for formats, so any non-'%' byte can be copied through, + or this is the wide character version. */ + if (*f != L_('%')) + { + add (1, *p = *f); + continue; + } + +#endif /* ! DO_MULTIBYTE */ + + /* Check for flags that can modify a format. */ + while (1) + { + switch (*++f) + { + /* This influences the number formats. */ + case L_('_'): + case L_('-'): + case L_('0'): + pad = *f; + continue; + + /* This changes textual output. */ + case L_('^'): + to_uppcase = 1; + continue; + case L_('#'): + change_case = 1; + continue; + + default: + break; + } + break; + } + + /* As a GNU extension we allow to specify the field width. */ + if (ISDIGIT (*f)) + { + width = 0; + do + { + if (width > INT_MAX / 10 + || (width == INT_MAX / 10 && *f - L_('0') > INT_MAX % 10)) + /* Avoid overflow. */ + width = INT_MAX; + else + { + width *= 10; + width += *f - L_('0'); + } + ++f; + } + while (ISDIGIT (*f)); + } + + /* Check for modifiers. */ + switch (*f) + { + case L_('E'): + case L_('O'): + modifier = *f++; + break; + + default: + modifier = 0; + break; + } + + /* Now do the specified format. */ + format_char = *f; + switch (format_char) + { +#define DO_NUMBER(d, v) \ + digits = d > width ? d : width; \ + number_value = v; goto do_number +#define DO_NUMBER_SPACEPAD(d, v) \ + digits = d > width ? d : width; \ + number_value = v; goto do_number_spacepad + + case L_('%'): + if (modifier != 0) + goto bad_format; + add (1, *p = *f); + break; + + case L_('a'): + if (modifier != 0) + goto bad_format; + if (change_case) + { + to_uppcase = 1; + to_lowcase = 0; + } +#if defined _NL_CURRENT || !HAVE_STRFTIME + cpy (aw_len, a_wkday); + break; +#else + goto underlying_strftime; +#endif + + case 'A': + if (modifier != 0) + goto bad_format; + if (change_case) + { + to_uppcase = 1; + to_lowcase = 0; + } +#if defined _NL_CURRENT || !HAVE_STRFTIME + cpy (STRLEN (f_wkday), f_wkday); + break; +#else + goto underlying_strftime; +#endif + + case L_('b'): + case L_('h'): + if (change_case) + { + to_uppcase = 1; + to_lowcase = 0; + } + if (modifier != 0) + goto bad_format; +#if defined _NL_CURRENT || !HAVE_STRFTIME + cpy (am_len, a_month); + break; +#else + goto underlying_strftime; +#endif + + case L_('B'): + if (modifier != 0) + goto bad_format; + if (change_case) + { + to_uppcase = 1; + to_lowcase = 0; + } +#if defined _NL_CURRENT || !HAVE_STRFTIME + cpy (STRLEN (f_month), f_month); + break; +#else + goto underlying_strftime; +#endif + + case L_('c'): + if (modifier == L_('O')) + goto bad_format; +#ifdef _NL_CURRENT + if (! (modifier == 'E' + && (*(subfmt = + (const CHAR_T *) _NL_CURRENT (LC_TIME, + NLW(ERA_D_T_FMT))) + != '\0'))) + subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_T_FMT)); +#else +# if HAVE_STRFTIME + goto underlying_strftime; +# else + subfmt = L_("%a %b %e %H:%M:%S %Y"); +# endif +#endif + + subformat: + { + CHAR_T *old_start = p; + size_t len = my_strftime (NULL, (size_t) -1, subfmt, + tp ut_argument LOCALE_ARG); + add (len, my_strftime (p, maxsize - i, subfmt, + tp ut_argument LOCALE_ARG)); + + if (to_uppcase) + while (old_start < p) + { + *old_start = TOUPPER ((UCHAR_T) *old_start, loc); + ++old_start; + } + } + break; + +#if HAVE_STRFTIME && ! (defined _NL_CURRENT && HAVE_STRUCT_ERA_ENTRY) + underlying_strftime: + { + /* The relevant information is available only via the + underlying strftime implementation, so use that. */ + char ufmt[4]; + char *u = ufmt; + char ubuf[1024]; /* enough for any single format in practice */ + size_t len; + /* Make sure we're calling the actual underlying strftime. + In some cases, config.h contains something like + "#define strftime rpl_strftime". */ +# ifdef strftime +# undef strftime + size_t strftime (); +# endif + + *u++ = '%'; + if (modifier != 0) + *u++ = modifier; + *u++ = format_char; + *u = '\0'; + len = strftime (ubuf, sizeof ubuf, ufmt, tp); + if (len == 0 && ubuf[0] != '\0') + return 0; + cpy (len, ubuf); + } + break; +#endif + + case L_('C'): + if (modifier == L_('O')) + goto bad_format; + if (modifier == L_('E')) + { +#if HAVE_STRUCT_ERA_ENTRY + struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); + if (era) + { +# ifdef COMPILE_WIDE + size_t len = __wcslen (era->era_wname); + cpy (len, era->era_wname); +# else + size_t len = strlen (era->era_name); + cpy (len, era->era_name); +# endif + break; + } +#else +# if HAVE_STRFTIME + goto underlying_strftime; +# endif +#endif + } + + { + int year = tp->tm_year + TM_YEAR_BASE; + DO_NUMBER (1, year / 100 - (year % 100 < 0)); + } + + case L_('x'): + if (modifier == L_('O')) + goto bad_format; +#ifdef _NL_CURRENT + if (! (modifier == L_('E') + && (*(subfmt = + (const CHAR_T *)_NL_CURRENT (LC_TIME, NLW(ERA_D_FMT))) + != L_('\0')))) + subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(D_FMT)); + goto subformat; +#else +# if HAVE_STRFTIME + goto underlying_strftime; +# else + /* Fall through. */ +# endif +#endif + case L_('D'): + if (modifier != 0) + goto bad_format; + subfmt = L_("%m/%d/%y"); + goto subformat; + + case L_('d'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (2, tp->tm_mday); + + case L_('e'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER_SPACEPAD (2, tp->tm_mday); + + /* All numeric formats set DIGITS and NUMBER_VALUE and then + jump to one of these two labels. */ + + do_number_spacepad: + /* Force `_' flag unless overwritten by `0' flag. */ + if (pad != L_('0')) + pad = L_('_'); + + do_number: + /* Format the number according to the MODIFIER flag. */ + + if (modifier == L_('O') && 0 <= number_value) + { +#ifdef _NL_CURRENT + /* Get the locale specific alternate representation of + the number NUMBER_VALUE. If none exist NULL is returned. */ + const CHAR_T *cp = nl_get_alt_digit (number_value + HELPER_LOCALE_ARG); + + if (cp != NULL) + { + size_t digitlen = STRLEN (cp); + if (digitlen != 0) + { + cpy (digitlen, cp); + break; + } + } +#else +# if HAVE_STRFTIME + goto underlying_strftime; +# endif +#endif + } + { + unsigned int u = number_value; + + bufp = buf + sizeof (buf) / sizeof (buf[0]); + negative_number = number_value < 0; + + if (negative_number) + u = -u; + + do + *--bufp = u % 10 + L_('0'); + while ((u /= 10) != 0); + } + + do_number_sign_and_padding: + if (negative_number) + *--bufp = L_('-'); + + if (pad != L_('-')) + { + int padding = digits - (buf + (sizeof (buf) / sizeof (buf[0])) + - bufp); + + if (padding > 0) + { + if (pad == L_('_')) + { + if ((size_t) padding >= maxsize - i) + return 0; + + if (p) + memset_space (p, padding); + i += padding; + width = width > padding ? width - padding : 0; + } + else + { + if ((size_t) digits >= maxsize - i) + return 0; + + if (negative_number) + { + ++bufp; + + if (p) + *p++ = L_('-'); + ++i; + } + + if (p) + memset_zero (p, padding); + i += padding; + width = 0; + } + } + } + + cpy (buf + sizeof (buf) / sizeof (buf[0]) - bufp, bufp); + break; + + case L_('F'): + if (modifier != 0) + goto bad_format; + subfmt = L_("%Y-%m-%d"); + goto subformat; + + case L_('H'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (2, tp->tm_hour); + + case L_('I'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (2, hour12); + + case L_('k'): /* GNU extension. */ + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER_SPACEPAD (2, tp->tm_hour); + + case L_('l'): /* GNU extension. */ + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER_SPACEPAD (2, hour12); + + case L_('j'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (3, 1 + tp->tm_yday); + + case L_('M'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (2, tp->tm_min); + + case L_('m'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (2, tp->tm_mon + 1); + + case L_('n'): + add (1, *p = L_('\n')); + break; + + case L_('P'): + to_lowcase = 1; +#if !defined _NL_CURRENT && HAVE_STRFTIME + format_char = L_('p'); +#endif + /* FALLTHROUGH */ + + case L_('p'): + if (change_case) + { + to_uppcase = 0; + to_lowcase = 1; + } +#if defined _NL_CURRENT || !HAVE_STRFTIME + cpy (ap_len, ampm); + break; +#else + goto underlying_strftime; +#endif + + case L_('R'): + subfmt = L_("%H:%M"); + goto subformat; + + case L_('r'): +#ifdef _NL_CURRENT + if (*(subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, + NLW(T_FMT_AMPM))) + == L_('\0')) +#endif + subfmt = L_("%I:%M:%S %p"); + goto subformat; + + case L_('S'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (2, tp->tm_sec); + + case L_('s'): /* GNU extension. */ + { + struct tm ltm; + time_t t; + + ltm = *tp; + t = mktime (<m); + + /* Generate string value for T using time_t arithmetic; + this works even if sizeof (long) < sizeof (time_t). */ + + bufp = buf + sizeof (buf) / sizeof (buf[0]); +#ifndef TIME_T_UNSIGNED + negative_number = t < 0; +#endif + + do + { + int d = t % 10; + t /= 10; + +#ifndef TIME_T_UNSIGNED + if (negative_number) + { + d = -d; + + /* Adjust if division truncates to minus infinity. */ + if (0 < -1 % 10 && d < 0) + { + t++; + d += 10; + } + } +#endif + + *--bufp = d + L_('0'); + } + while (t != 0); + + digits = 1; + goto do_number_sign_and_padding; + } + + case L_('X'): + if (modifier == L_('O')) + goto bad_format; +#ifdef _NL_CURRENT + if (! (modifier == L_('E') + && (*(subfmt = + (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(ERA_T_FMT))) + != L_('\0')))) + subfmt = (const CHAR_T *) _NL_CURRENT (LC_TIME, NLW(T_FMT)); + goto subformat; +#else +# if HAVE_STRFTIME + goto underlying_strftime; +# else + /* Fall through. */ +# endif +#endif + case L_('T'): + subfmt = L_("%H:%M:%S"); + goto subformat; + + case L_('t'): + add (1, *p = L_('\t')); + break; + + case L_('u'): + DO_NUMBER (1, (tp->tm_wday - 1 + 7) % 7 + 1); + + case L_('U'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (2, (tp->tm_yday - tp->tm_wday + 7) / 7); + + case L_('V'): + case L_('g'): + case L_('G'): + if (modifier == L_('E')) + goto bad_format; + { + int year = tp->tm_year + TM_YEAR_BASE; + int days = iso_week_days (tp->tm_yday, tp->tm_wday); + + if (days < 0) + { + /* This ISO week belongs to the previous year. */ + year--; + days = iso_week_days (tp->tm_yday + (365 + __isleap (year)), + tp->tm_wday); + } + else + { + int d = iso_week_days (tp->tm_yday - (365 + __isleap (year)), + tp->tm_wday); + if (0 <= d) + { + /* This ISO week belongs to the next year. */ + year++; + days = d; + } + } + + switch (*f) + { + case L_('g'): + DO_NUMBER (2, (year % 100 + 100) % 100); + + case L_('G'): + DO_NUMBER (1, year); + + default: + DO_NUMBER (2, days / 7 + 1); + } + } + + case L_('W'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (2, (tp->tm_yday - (tp->tm_wday - 1 + 7) % 7 + 7) / 7); + + case L_('w'): + if (modifier == L_('E')) + goto bad_format; + + DO_NUMBER (1, tp->tm_wday); + + case L_('Y'): + if (modifier == 'E') + { +#if HAVE_STRUCT_ERA_ENTRY + struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); + if (era) + { +# ifdef COMPILE_WIDE + subfmt = era->era_wformat; +# else + subfmt = era->era_format; +# endif + goto subformat; + } +#else +# if HAVE_STRFTIME + goto underlying_strftime; +# endif +#endif + } + if (modifier == L_('O')) + goto bad_format; + else + DO_NUMBER (1, tp->tm_year + TM_YEAR_BASE); + + case L_('y'): + if (modifier == L_('E')) + { +#if HAVE_STRUCT_ERA_ENTRY + struct era_entry *era = _nl_get_era_entry (tp HELPER_LOCALE_ARG); + if (era) + { + int delta = tp->tm_year - era->start_date[0]; + DO_NUMBER (1, (era->offset + + delta * era->absolute_direction)); + } +#else +# if HAVE_STRFTIME + goto underlying_strftime; +# endif +#endif + } + DO_NUMBER (2, (tp->tm_year % 100 + 100) % 100); + + case L_('Z'): + if (change_case) + { + to_uppcase = 0; + to_lowcase = 1; + } + +#if HAVE_TZNAME + /* The tzset() call might have changed the value. */ + if (!(zone && *zone) && tp->tm_isdst >= 0) + zone = tzname[tp->tm_isdst]; +#endif + if (! zone) + zone = ""; + +#ifdef COMPILE_WIDE + { + /* The zone string is always given in multibyte form. We have + to transform it first. */ + wchar_t *wczone; + size_t len; + widen (zone, wczone, len); + cpy (len, wczone); + } +#else + cpy (strlen (zone), zone); +#endif + break; + + case L_('z'): + if (tp->tm_isdst < 0) + break; + + { + int diff; +#if HAVE_TM_GMTOFF + diff = tp->tm_gmtoff; +#else + if (ut) + diff = 0; + else + { + struct tm gtm; + struct tm ltm; + time_t lt; + + ltm = *tp; + lt = mktime (<m); + + if (lt == (time_t) -1) + { + /* mktime returns -1 for errors, but -1 is also a + valid time_t value. Check whether an error really + occurred. */ + struct tm tm; + + if (! my_strftime_localtime_r (<, &tm) + || ((ltm.tm_sec ^ tm.tm_sec) + | (ltm.tm_min ^ tm.tm_min) + | (ltm.tm_hour ^ tm.tm_hour) + | (ltm.tm_mday ^ tm.tm_mday) + | (ltm.tm_mon ^ tm.tm_mon) + | (ltm.tm_year ^ tm.tm_year))) + break; + } + + if (! my_strftime_gmtime_r (<, >m)) + break; + + diff = tm_diff (<m, >m); + } +#endif + + if (diff < 0) + { + add (1, *p = L_('-')); + diff = -diff; + } + else + add (1, *p = L_('+')); + + diff /= 60; + DO_NUMBER (4, (diff / 60) * 100 + diff % 60); + } + + case L_('\0'): /* GNU extension: % at end of format. */ + --f; + /* Fall through. */ + default: + /* Unknown format; output the format, including the '%', + since this is most likely the right thing to do if a + multibyte string has been misparsed. */ + bad_format: + { + int flen; + for (flen = 1; f[1 - flen] != L_('%'); flen++) + continue; + cpy (flen, &f[1 - flen]); + } + break; + } + } + + if (p && maxsize != 0) + *p = L_('\0'); + return i; +} +#ifdef _LIBC +libc_hidden_def (my_strftime) +#endif + + +#ifdef emacs +/* For Emacs we have a separate interface which corresponds to the normal + strftime function and does not have the extra information whether the + TP arguments comes from a `gmtime' call or not. */ +size_t +emacs_strftime (s, maxsize, format, tp) + char *s; + size_t maxsize; + const char *format; + const struct tm *tp; +{ + return my_strftime (s, maxsize, format, tp, 0); +} +#endif diff --git a/src/apps/bin/gawk/missing_d/strncasecmp.c b/src/apps/bin/gawk/missing_d/strncasecmp.c new file mode 100644 index 0000000000..9d17c648cd --- /dev/null +++ b/src/apps/bin/gawk/missing_d/strncasecmp.c @@ -0,0 +1,102 @@ +/* + * Copyright (c) 1987 Regents of the University of California. + * All rights reserved. + * + * Redistribution and use in source and binary forms are permitted + * provided that the above copyright notice and this paragraph are + * duplicated in all such forms and that any documentation, + * advertising materials, and other materials related to such + * distribution and use acknowledge that the software was developed + * by the University of California, Berkeley. The name of the + * University may not be used to endorse or promote products derived + * from this software without specific prior written permission. + * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED + * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. + */ + +#if defined(LIBC_SCCS) && !defined(lint) +static char sccsid[] = "@(#)strcasecmp.c 5.6 (Berkeley) 6/27/88"; +#endif /* LIBC_SCCS and not lint */ + +#ifdef atarist +#include +#else +#define u_char unsigned char +#endif + +/* This rather ugly macro is for VMS C */ +#ifdef C +#undef C +#endif +#define C(c) ((u_char)c) +/* + * This array is designed for mapping upper and lower case letter + * together for a case independent comparison. The mappings are + * based upon ascii character sequences. + */ +static u_char charmap[] = { + '\000', '\001', '\002', '\003', '\004', '\005', '\006', '\007', + '\010', '\011', '\012', '\013', '\014', '\015', '\016', '\017', + '\020', '\021', '\022', '\023', '\024', '\025', '\026', '\027', + '\030', '\031', '\032', '\033', '\034', '\035', '\036', '\037', + '\040', '\041', '\042', '\043', '\044', '\045', '\046', '\047', + '\050', '\051', '\052', '\053', '\054', '\055', '\056', '\057', + '\060', '\061', '\062', '\063', '\064', '\065', '\066', '\067', + '\070', '\071', '\072', '\073', '\074', '\075', '\076', '\077', + '\100', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\133', '\134', '\135', '\136', '\137', + '\140', '\141', '\142', '\143', '\144', '\145', '\146', '\147', + '\150', '\151', '\152', '\153', '\154', '\155', '\156', '\157', + '\160', '\161', '\162', '\163', '\164', '\165', '\166', '\167', + '\170', '\171', '\172', '\173', '\174', '\175', '\176', '\177', + C('\200'), C('\201'), C('\202'), C('\203'), C('\204'), C('\205'), C('\206'), C('\207'), + C('\210'), C('\211'), C('\212'), C('\213'), C('\214'), C('\215'), C('\216'), C('\217'), + C('\220'), C('\221'), C('\222'), C('\223'), C('\224'), C('\225'), C('\226'), C('\227'), + C('\230'), C('\231'), C('\232'), C('\233'), C('\234'), C('\235'), C('\236'), C('\237'), + C('\240'), C('\241'), C('\242'), C('\243'), C('\244'), C('\245'), C('\246'), C('\247'), + C('\250'), C('\251'), C('\252'), C('\253'), C('\254'), C('\255'), C('\256'), C('\257'), + C('\260'), C('\261'), C('\262'), C('\263'), C('\264'), C('\265'), C('\266'), C('\267'), + C('\270'), C('\271'), C('\272'), C('\273'), C('\274'), C('\275'), C('\276'), C('\277'), + C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'), + C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'), + C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\327'), + C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\337'), + C('\340'), C('\341'), C('\342'), C('\343'), C('\344'), C('\345'), C('\346'), C('\347'), + C('\350'), C('\351'), C('\352'), C('\353'), C('\354'), C('\355'), C('\356'), C('\357'), + C('\360'), C('\361'), C('\362'), C('\363'), C('\364'), C('\365'), C('\366'), C('\367'), + C('\370'), C('\371'), C('\372'), C('\373'), C('\374'), C('\375'), C('\376'), C('\377'), +}; + +#undef C + +int +strcasecmp(s1, s2) + const char *s1, *s2; +{ + register u_char *cm = charmap, + *us1 = (u_char *)s1, + *us2 = (u_char *)s2; + + while (cm[*us1] == cm[*us2++]) + if (*us1++ == '\0') + return(0); + return(cm[*us1] - cm[*--us2]); +} + +int +strncasecmp(s1, s2, n) + const char *s1, *s2; + register size_t n; +{ + register u_char *cm = charmap, + *us1 = (u_char *)s1, + *us2 = (u_char *)s2; + + while ((long)(--n) >= 0 && cm[*us1] == cm[*us2++]) + if (*us1++ == '\0') + return(0); + return((long)n < 0 ? 0 : cm[*us1] - cm[*--us2]); +} diff --git a/src/apps/bin/gawk/missing_d/strtod.c b/src/apps/bin/gawk/missing_d/strtod.c new file mode 100644 index 0000000000..e33a5b5e56 --- /dev/null +++ b/src/apps/bin/gawk/missing_d/strtod.c @@ -0,0 +1,124 @@ +/* + * gawk wrapper for strtod + */ +/* + * Stupid version of System V strtod(3) library routine. + * Does no overflow/underflow checking. + * + * A real number is defined to be + * optional leading white space + * optional sign + * string of digits with optional decimal point + * optional 'e' or 'E' + * followed by optional sign or space + * followed by an integer + * + * if ptr is not NULL a pointer to the character terminating the + * scan is returned in *ptr. If no number formed, *ptr is set to str + * and 0 is returned. + * + * For speed, we don't do the conversion ourselves. Instead, we find + * the end of the number and then call atof() to do the dirty work. + * This bought us a 10% speedup on a sample program at uunet.uu.net. + * + * Fall 2000: Changed to enforce C89 semantics, so that 0x... returns 0. + * C99 has hexadecimal floating point numbers. + * + * Summer 2001. Try to make it smarter, so that a string like "0000" + * doesn't look like we failed. Sigh. + * + * Xmass 2002. Fix a bug in ptr determination, eg. for "0e0". + */ + +#if 0 +#include +#endif + +extern double atof(); + +double +gawk_strtod(s, ptr) +register const char *s; +register const char **ptr; +{ + const char *start = s; /* save original start of string */ + const char *begin = NULL; /* where the number really begins */ + int dig = 0; + int dig0 = 0; + + /* optional white space */ + while (isspace(*s)) + s++; + + begin = s; + + /* optional sign */ + if (*s == '+' || *s == '-') + s++; + + /* string of digits with optional decimal point */ + while (*s == '0') { + s++; + dig0++; + } + while (isdigit(*s)) { + s++; + dig++; + } + + if (*s == '.') { + s++; + while (*s == '0') { + s++; + dig0++; + } + while (isdigit(*s)) { + s++; + dig++; + } + } + + dig0 += dig; /* any digit has appeared */ + + /* + * optional 'e' or 'E' + * if a digit (or at least zero) was seen + * followed by optional sign + * followed by an integer + */ + if (dig0 + && (*s == 'e' || *s == 'E') + && (isdigit(s[1]) + || ((s[1] == '-' || s[1] == '+') && isdigit(s[2])))) { + s++; + if (*s == '+' || *s == '-') + s++; + while (isdigit(*s)) + s++; + } + + /* In case we haven't found a number, set ptr to start. */ + if (ptr) + *ptr = (dig0 ? s : start); + + /* Go for it. */ + return (dig ? atof(begin) : 0.0); +} + +#ifdef TEST +int +main(argc, argv) +int argc; +char **argv; +{ + double d; + char *p; + + for (argc--, argv++; argc; argc--, argv++) { + d = strtod (*argv, & p); + printf ("%lf [%s]\n", d, p); + } + + return 0; +} +#endif diff --git a/src/apps/bin/gawk/missing_d/system.c b/src/apps/bin/gawk/missing_d/system.c new file mode 100644 index 0000000000..11db99256a --- /dev/null +++ b/src/apps/bin/gawk/missing_d/system.c @@ -0,0 +1,27 @@ +/* system.c --- replacement system() for systems missing one + + Copyright (C) 1986, 1988, 1989, 1991 the Free Software Foundation, Inc. + + 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 2, 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +extern void fatal(); + +int +system(s) +char *s; +{ + fatal("system() not supported on this system"); + return 0; +} diff --git a/src/apps/bin/gawk/missing_d/tzset.c b/src/apps/bin/gawk/missing_d/tzset.c new file mode 100644 index 0000000000..678ec66db1 --- /dev/null +++ b/src/apps/bin/gawk/missing_d/tzset.c @@ -0,0 +1,39 @@ +/* + * tzset.c + * + * Quick and dirty emulation of tzset(), tzname[], and daylight + * for old BSD systems without it. + * + * Thanks to Rick Adams, rick@uunet.uu.net, for the basics. + * + * BUGS: + * Totally ignores the value of the TZ environment variable. + */ + +#if 0 +#include +#endif +#include + +static char tz1[1024]; +static char tz2[1024]; + +/* external variables */ +char *tzname[2] = { + tz1, tz2 +}; +int daylight; + +extern char *timezone(); + +void +tzset() +{ + struct timeval tp; + struct timezone tz; + + (void) gettimeofday(&tp, &tz); + (void) strcpy(tz1, timezone(tz.tz_minuteswest, 0)); + (void) strcpy(tz2, timezone(tz.tz_minuteswest, 1)); + daylight = tz.tz_dsttime; +} diff --git a/src/apps/bin/gawk/posix/ChangeLog b/src/apps/bin/gawk/posix/ChangeLog new file mode 100644 index 0000000000..b2bcfb1be9 --- /dev/null +++ b/src/apps/bin/gawk/posix/ChangeLog @@ -0,0 +1,99 @@ +Mon Jul 7 11:01:43 2003 Arnold D. Robbins + + * Release 3.1.3: Release tar file made. + +Sun May 25 16:23:43 2003 Corinna Vinschen + + * gawkmisc.c (cygwin_premain0): New function. + +Wed Mar 19 14:10:31 2003 Arnold D. Robbins + + This time for sure. + -- Bullwinkle + + * Release 3.1.2: Release tar file made. + +Tue Feb 4 14:28:06 2003 Arnold D. Robbins + + All relevant files: Copyright year updated to 2003. + +Tue Dec 17 11:05:11 2002 Arnold D. Robbins + + * gawkmisc.c (optimal_bufsize): Stat the file first, so that + stb is always valid for higher level code. + +Thu Nov 28 10:20:05 2002 Arnold D. Robbins + + * gawkmisc.c (optimal_bufsize): Enhance to use AWKBUFSIZE + environment variable for debugging. + +Tue Jun 11 22:18:42 2002 Stepan Kasal + + * gawkmisc.c (DEFBLKSIZE): Add check for st_blksize > 0, + fixes weird bug on some versions of HP-UX. + +Wed May 1 16:41:32 2002 Arnold D. Robbins + + * Release 3.1.1: Release tar file made. + +Tue Sep 25 15:19:53 2001 Arnold D. Robbins + + * gawkmisc.c (os_close_on_exec): If fd <= 2, return. + +Sun Jun 3 13:04:44 2001 Arnold D. Robbins + + * Release 3.1.0: Release tar file made. And there was + rejoicing. + +Sun Jan 28 15:50:02 2001 Eli Zaretskii + + * gawkmisc.c (os_restore_mode): New function. + +Sun Dec 3 16:53:37 2000 Arnold D. Robbins + + * gawkmisc.c (os_setbinmode): New function. + +Tue Nov 14 16:13:08 2000 Arnold D. Robbins + + * gawkmisc.c: Remove all includes. Done by ../gawkmisc.c. + +Tue Nov 7 14:09:14 2000 Arnold D. Robbins + + * gawkmisc.c (os_is_setuid): new function. + +Mon Aug 7 15:23:00 2000 Arnold D. Robbins + + * Release 3.0.6: Release tar file made. + +Sun Jun 25 15:08:19 2000 Arnold D. Robbins + + * Release 3.0.5: Release tar file made. + +Wed Jun 30 16:14:36 1999 Arnold D. Robbins + + * Release 3.0.4: Release tar file made. This time for sure. + +Wed Jul 30 19:53:52 1997 Arnold D. Robbins + + * Close-on-exec changes: + gawkmisc.c: (os_close_on_exec, os_isdir): new functions. + +Thu May 15 12:49:08 1997 Arnold D. Robbins + + * Release 3.0.3: Release tar file made. + +Fri Apr 18 07:55:47 1997 Arnold D. Robbins + + * BETA Release 3.0.34: Release tar file made. + +Wed Dec 25 11:25:22 1996 Arnold D. Robbins + + * Release 3.0.2: Release tar file made. + +Tue Dec 10 23:09:26 1996 Arnold D. Robbins + + * Release 3.0.1: Release tar file made. + +Wed Jan 10 22:58:55 1996 Arnold D. Robbins + + * ChangeLog created. diff --git a/src/apps/bin/gawk/posix/gawkmisc.c b/src/apps/bin/gawk/posix/gawkmisc.c new file mode 100644 index 0000000000..b421766ae5 --- /dev/null +++ b/src/apps/bin/gawk/posix/gawkmisc.c @@ -0,0 +1,238 @@ +/* gawkmisc.c --- miscellaneous gawk routines that are OS specific. + + Copyright (C) 1986, 1988, 1989, 1991 - 1998, 2001 - 2003 the Free Software Foundation, Inc. + + 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 2, 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 + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + +char quote = '\''; +char *defpath = DEFPATH; +char envsep = ':'; + +#ifndef INVALID_HANDLE +/* FIXME: is this value for INVALID_HANDLE correct? */ +#define INVALID_HANDLE -1 +#endif + +/* gawk_name --- pull out the "gawk" part from how the OS called us */ + +char * +gawk_name(filespec) +const char *filespec; +{ + char *p; + + /* "path/name" -> "name" */ + p = strrchr(filespec, '/'); + return (p == NULL ? (char *) filespec : p + 1); +} + +/* os_arg_fixup --- fixup the command line */ + +void +os_arg_fixup(argcp, argvp) +int *argcp; +char ***argvp; +{ + /* no-op */ + return; +} + +/* os_devopen --- open special per-OS devices */ + +int +os_devopen(name, flag) +const char *name; +int flag; +{ + /* no-op */ + return INVALID_HANDLE; +} + +/* optimal_bufsize --- determine optimal buffer size */ + +/* + * Enhance this for debugging purposes, as follows: + * + * Always stat the file, stat buffer is used by higher-level code. + * + * if (AWKBUFSIZE == "exact") + * return the file size + * else if (AWKBUFSIZE == a number) + * always return that number + * else + * if the size is < default_blocksize + * return the size + * else + * return default_blocksize + * end if + * endif + * + * Hair comes in an effort to only deal with AWKBUFSIZE + * once, the first time this routine is called, instead of + * every time. Performance, dontyaknow. + */ + +size_t +optimal_bufsize(fd, stb) +int fd; +struct stat *stb; +{ + char *val; + static size_t env_val = 0; + static short first = TRUE; + static short exact = FALSE; + + /* force all members to zero in case OS doesn't use all of them. */ + memset(stb, '\0', sizeof(struct stat)); + + /* always stat, in case stb is used by higher level code. */ + if (fstat(fd, stb) == -1) + fatal("can't stat fd %d (%s)", fd, strerror(errno)); + + if (first) { + first = FALSE; + + if ((val = getenv("AWKBUFSIZE")) != NULL) { + if (strcmp(val, "exact") == 0) + exact = TRUE; + else if (ISDIGIT(*val)) { + for (; *val && ISDIGIT(*val); val++) + env_val = (env_val * 10) + *val - '0'; + + return env_val; + } + } + } else if (! exact && env_val > 0) + return env_val; + /* else + fall through */ + + /* + * System V.n, n < 4, doesn't have the file system block size in the + * stat structure. So we have to make some sort of reasonable + * guess. We use stdio's BUFSIZ, since that is what it was + * meant for in the first place. + */ +#ifdef HAVE_ST_BLKSIZE +#define DEFBLKSIZE (stb->st_blksize > 0 ? stb->st_blksize : BUFSIZ) +#else +#define DEFBLKSIZE BUFSIZ +#endif + + if (S_ISREG(stb->st_mode) /* regular file */ + && 0 < stb->st_size /* non-zero size */ + && (stb->st_size < DEFBLKSIZE /* small file */ + || exact)) /* or debugging */ + return stb->st_size; /* use file size */ + + return DEFBLKSIZE; +} + +/* ispath --- return true if path has directory components */ + +int +ispath(file) +const char *file; +{ + return (strchr(file, '/') != NULL); +} + +/* isdirpunct --- return true if char is a directory separator */ + +int +isdirpunct(c) +int c; +{ + return (c == '/'); +} + +/* os_close_on_exec --- set close on exec flag, print warning if fails */ + +void +os_close_on_exec(fd, name, what, dir) +int fd; +const char *name, *what, *dir; +{ + if (fd <= 2) /* sanity */ + return; + + if (fcntl(fd, F_SETFD, 1) < 0) + warning(_("%s %s `%s': could not set close-on-exec: (fcntl: %s)"), + what, dir, name, strerror(errno)); +} + +/* os_isdir --- is this an fd on a directory? */ + +#if ! defined(S_ISDIR) && defined(S_IFDIR) +#define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) +#endif + +int +os_isdir(fd) +int fd; +{ + struct stat sbuf; + + return (fstat(fd, &sbuf) == 0 && S_ISDIR(sbuf.st_mode)); +} + +/* os_is_setuid --- true if running setuid root */ + +int +os_is_setuid() +{ + long uid, euid; + + uid = getuid(); + euid = geteuid(); + + return (euid == 0 && euid != uid); +} + +/* os_setbinmode --- set binary mode on file */ + +int +os_setbinmode (fd, mode) +int fd, mode; +{ + return 0; +} + +/* os_restore_mode --- restore the original mode of the console device */ + +void +os_restore_mode (fd) +int fd; +{ + /* no-op */ + return; +} + +#ifdef __CYGWIN__ +#include + +extern int _fmode; +void +cygwin_premain0 (int argc, char **argv, struct per_process *myself) +{ + static struct __cygwin_perfile pf[] = + { + {"", O_RDONLY | O_TEXT}, + /*{"", O_WRONLY | O_BINARY},*/ + {NULL, 0} + }; + cygwin_internal (CW_PERFILE, pf); +} +#endif