diff --git a/build/jam/OptionalPackages b/build/jam/OptionalPackages index ac8feeafb5..94a35cfa6b 100644 --- a/build/jam/OptionalPackages +++ b/build/jam/OptionalPackages @@ -118,7 +118,7 @@ if [ IsOptionalHaikuImagePackageAdded DevelopmentBase ] { } # other commonly used tools - AddHaikuImagePackages bison cdrtools flex jam m4 make mkdepend nasm ; + AddHaikuImagePackages bison cdrtools flex jam m4 make mkdepend nasm patch ; } diff --git a/build/jam/images/definitions/minimum b/build/jam/images/definitions/minimum index 11061d5947..095f82bf76 100644 --- a/build/jam/images/definitions/minimum +++ b/build/jam/images/definitions/minimum @@ -20,7 +20,7 @@ SYSTEM_BIN = [ FFilterByBuildFeatures modifiers mount mountvolume netcat netstat notify open - package package_repo passwd patch pc ping ping6 pkgman + package package_repo passwd pc ping ping6 pkgman prio profile ps query quit rc reindex release renice rmattr rmindex roster diff --git a/src/bin/Jamfile b/src/bin/Jamfile index e5b4b79d2d..bd8b59494e 100644 --- a/src/bin/Jamfile +++ b/src/bin/Jamfile @@ -279,7 +279,6 @@ SubInclude HAIKU_TOP src bin mkfs ; SubInclude HAIKU_TOP src bin multiuser ; SubInclude HAIKU_TOP src bin package ; SubInclude HAIKU_TOP src bin package_repo ; -SubInclude HAIKU_TOP src bin patch ; SubInclude HAIKU_TOP src bin pc ; SubInclude HAIKU_TOP src bin pcmcia-cs ; SubInclude HAIKU_TOP src bin pkgman ; diff --git a/src/bin/patch/COPYING b/src/bin/patch/COPYING deleted file mode 100644 index 60549be514..0000000000 --- a/src/bin/patch/COPYING +++ /dev/null @@ -1,340 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -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 - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -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 PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (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 PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - 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 - - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/src/bin/patch/Jamfile b/src/bin/patch/Jamfile deleted file mode 100644 index 6ceb05c27e..0000000000 --- a/src/bin/patch/Jamfile +++ /dev/null @@ -1,24 +0,0 @@ -SubDir HAIKU_TOP src bin patch ; - -SubDirSysHdrs [ FDirName $(SUBDIR) ] ; - -SubDirCcFlags -DHAVE_CONFIG_H -Ded_PROGRAM='\"ed\"' -w ; - -BinCommand patch : - addext.c - argmatch.c - backupfile.c - basename.c - error.c - inp.c - maketime.c - partime.c - patch.c - pch.c - quotearg.c - quotesys.c - util.c - version.c - xmalloc.c - : - : patch.rdef ; diff --git a/src/bin/patch/addext.c b/src/bin/patch/addext.c deleted file mode 100644 index a075ea3b1e..0000000000 --- a/src/bin/patch/addext.c +++ /dev/null @@ -1,105 +0,0 @@ -/* addext.c -- add an extension to a file name - Copyright (C) 1990, 1997, 1998, 1999 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by David MacKenzie and Paul Eggert */ - -#if HAVE_CONFIG_H -# include -#endif - -#ifndef HAVE_DOS_FILE_NAMES -# define HAVE_DOS_FILE_NAMES 0 -#endif -#ifndef HAVE_LONG_FILE_NAMES -# define HAVE_LONG_FILE_NAMES 0 -#endif - -#include - -#if HAVE_LIMITS_H -# include -#endif -#ifndef _POSIX_NAME_MAX -# define _POSIX_NAME_MAX 14 -#endif - -#include -#if HAVE_STRING_H -# include -#else -# include -#endif - -#if HAVE_UNISTD_H -# include -#endif - -char *base_name PARAMS ((char const *)); - -/* Append to FILENAME the extension EXT, unless the result would be too long, - in which case just append the character E. */ - -void -addext (char *filename, char const *ext, int e) -{ - char *s = base_name (filename); - size_t slen = strlen (s), extlen = strlen (ext); - long slen_max = -1; - -#if HAVE_PATHCONF && defined _PC_NAME_MAX - if (slen + extlen <= _POSIX_NAME_MAX && ! HAVE_DOS_FILE_NAMES) - /* The file name is so short there's no need to call pathconf. */ - slen_max = _POSIX_NAME_MAX; - else if (s == filename) - slen_max = pathconf (".", _PC_NAME_MAX); - else - { - char c = *s; - *s = 0; - slen_max = pathconf (filename, _PC_NAME_MAX); - *s = c; - } -#endif - if (slen_max < 0) - slen_max = HAVE_LONG_FILE_NAMES ? 255 : 14; - - if (HAVE_DOS_FILE_NAMES && slen_max <= 12) - { - /* Live within DOS's 8.3 limit. */ - char *dot = strchr (s, '.'); - if (dot) - { - slen -= dot + 1 - s; - s = dot + 1; - slen_max = 3; - } - else - slen_max = 8; - extlen = 9; /* Don't use EXT. */ - } - - if (slen + extlen <= slen_max) - strcpy (s + slen, ext); - else - { - if (slen_max <= slen) - slen = slen_max - 1; - s[slen] = e; - s[slen + 1] = 0; - } -} diff --git a/src/bin/patch/argmatch.c b/src/bin/patch/argmatch.c deleted file mode 100644 index 964270650c..0000000000 --- a/src/bin/patch/argmatch.c +++ /dev/null @@ -1,306 +0,0 @@ -/* argmatch.c -- find a match for a string in an array - Copyright (C) 1990, 1998, 1999 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. */ - -/* Written by David MacKenzie - Modified by Akim Demaille */ - -#include "argmatch.h" - -#include -#ifdef STDC_HEADERS -# include -#endif - -#if HAVE_LOCALE_H -# include -#endif - -#if ENABLE_NLS -# include -# define _(Text) gettext (Text) -#else -# define _(Text) Text -#endif - -#include "error.h" -#include "quotearg.h" - -/* When reporting an invalid argument, show nonprinting characters - by using the quoting style ARGMATCH_QUOTING_STYLE. Do not use - literal_quoting_style. */ -#ifndef ARGMATCH_QUOTING_STYLE -# define ARGMATCH_QUOTING_STYLE locale_quoting_style -#endif - -/* The following test is to work around the gross typo in - systems like Sony NEWS-OS Release 4.0C, whereby EXIT_FAILURE - is defined to 0, not 1. */ -#if !EXIT_FAILURE -# undef EXIT_FAILURE -# define EXIT_FAILURE 1 -#endif - -/* Non failing version of argmatch call this function after failing. */ -#ifndef ARGMATCH_DIE -# define ARGMATCH_DIE exit (EXIT_FAILURE) -#endif - -#ifdef ARGMATCH_DIE_DECL -ARGMATCH_DIE_DECL; -#endif - -static void -__argmatch_die (void) -{ - ARGMATCH_DIE; -} - -/* Used by XARGMATCH and XARGCASEMATCH. See description in argmatch.h. - Default to __argmatch_die, but allow caller to change this at run-time. */ -argmatch_exit_fn argmatch_die = __argmatch_die; - - -/* If ARG is an unambiguous match for an element of the - null-terminated array ARGLIST, return the index in ARGLIST - of the matched element, else -1 if it does not match any element - or -2 if it is ambiguous (is a prefix of more than one element). - If SENSITIVE, comparison is case sensitive. - - If VALLIST is none null, use it to resolve ambiguities limited to - synonyms, i.e., for - "yes", "yop" -> 0 - "no", "nope" -> 1 - "y" is a valid argument, for `0', and "n" for `1'. */ - -static int -__argmatch_internal (const char *arg, const char *const *arglist, - const char *vallist, size_t valsize, - int case_sensitive) -{ - int i; /* Temporary index in ARGLIST. */ - size_t arglen; /* Length of ARG. */ - int matchind = -1; /* Index of first nonexact match. */ - int ambiguous = 0; /* If nonzero, multiple nonexact match(es). */ - - arglen = strlen (arg); - - /* Test all elements for either exact match or abbreviated matches. */ - for (i = 0; arglist[i]; i++) - { - if (case_sensitive - ? !strncmp (arglist[i], arg, arglen) - : !strncasecmp (arglist[i], arg, arglen)) - { - if (strlen (arglist[i]) == arglen) - /* Exact match found. */ - return i; - else if (matchind == -1) - /* First nonexact match found. */ - matchind = i; - else - { - /* Second nonexact match found. */ - if (vallist == NULL - || memcmp (vallist + valsize * matchind, - vallist + valsize * i, valsize)) - { - /* There is a real ambiguity, or we could not - disambiguate. */ - ambiguous = 1; - } - } - } - } - if (ambiguous) - return -2; - else - return matchind; -} - -/* argmatch - case sensitive version */ -int -argmatch (const char *arg, const char *const *arglist, - const char *vallist, size_t valsize) -{ - return __argmatch_internal (arg, arglist, vallist, valsize, 1); -} - -/* argcasematch - case insensitive version */ -int -argcasematch (const char *arg, const char *const *arglist, - const char *vallist, size_t valsize) -{ - return __argmatch_internal (arg, arglist, vallist, valsize, 0); -} - -/* Error reporting for argmatch. - CONTEXT is a description of the type of entity that was being matched. - VALUE is the invalid value that was given. - PROBLEM is the return value from argmatch. */ - -void -argmatch_invalid (const char *context, const char *value, int problem) -{ - char const *format = (problem == -1 - ? _("invalid argument %s for `%s'") - : _("ambiguous argument %s for `%s'")); - - error (0, 0, format, quotearg_style (ARGMATCH_QUOTING_STYLE, value), context); -} - -/* List the valid arguments for argmatch. - ARGLIST is the same as in argmatch. - VALLIST is a pointer to an array of values. - VALSIZE is the size of the elements of VALLIST */ -void -argmatch_valid (const char *const *arglist, - const char *vallist, size_t valsize) -{ - int i; - const char *last_val = NULL; - - /* We try to put synonyms on the same line. The assumption is that - synonyms follow each other */ - fprintf (stderr, _("Valid arguments are:")); - for (i = 0; arglist[i]; i++) - if ((i == 0) - || memcmp (last_val, vallist + valsize * i, valsize)) - { - fprintf (stderr, "\n - `%s'", arglist[i]); - last_val = vallist + valsize * i; - } - else - { - fprintf (stderr, ", `%s'", arglist[i]); - } - putc ('\n', stderr); -} - -/* Never failing versions of the previous functions. - - CONTEXT is the context for which argmatch is called (e.g., - "--version-control", or "$VERSION_CONTROL" etc.). Upon failure, - calls the (supposed never to return) function EXIT_FN. */ - -int -__xargmatch_internal (const char *context, - const char *arg, const char *const *arglist, - const char *vallist, size_t valsize, - int case_sensitive, - argmatch_exit_fn exit_fn) -{ - int res = __argmatch_internal (arg, arglist, - vallist, valsize, - case_sensitive); - if (res >= 0) - /* Success. */ - return res; - - /* We failed. Explain why. */ - argmatch_invalid (context, arg, res); - argmatch_valid (arglist, vallist, valsize); - (*exit_fn) (); - - return -1; /* To please the compilers. */ -} - -/* Look for VALUE in VALLIST, an array of objects of size VALSIZE and - return the first corresponding argument in ARGLIST */ -const char * -argmatch_to_argument (const char *value, - const char *const *arglist, - const char *vallist, size_t valsize) -{ - int i; - - for (i = 0; arglist[i]; i++) - if (!memcmp (value, vallist + valsize * i, valsize)) - return arglist[i]; - return NULL; -} - -#ifdef TEST -/* - * Based on "getversion.c" by David MacKenzie - */ -char *program_name; -extern const char *getenv (); - -/* When to make backup files. */ -enum backup_type -{ - /* Never make backups. */ - none, - - /* Make simple backups of every file. */ - simple, - - /* Make numbered backups of files that already have numbered backups, - and simple backups of the others. */ - numbered_existing, - - /* Make numbered backups of every file. */ - numbered -}; - -/* Two tables describing arguments (keys) and their corresponding - values */ -static const char *const backup_args[] = -{ - "no", "none", "off", - "simple", "never", - "existing", "nil", - "numbered", "t", - 0 -}; - -static const enum backup_type backup_vals[] = -{ - none, none, none, - simple, simple, - numbered_existing, numbered_existing, - numbered, numbered -}; - -int -main (int argc, const char *const *argv) -{ - const char *cp; - enum backup_type backup_type = none; - - program_name = (char *) argv[0]; - - if (argc > 2) - { - fprintf (stderr, "Usage: %s [VERSION_CONTROL]\n", program_name); - exit (1); - } - - if ((cp = getenv ("VERSION_CONTROL"))) - backup_type = XARGCASEMATCH ("$VERSION_CONTROL", cp, - backup_args, backup_vals); - - if (argc == 2) - backup_type = XARGCASEMATCH (program_name, argv[1], - backup_args, backup_vals); - - printf ("The version control is `%s'\n", - ARGMATCH_TO_ARGUMENT (backup_type, backup_args, backup_vals)); - - return 0; -} -#endif diff --git a/src/bin/patch/argmatch.h b/src/bin/patch/argmatch.h deleted file mode 100644 index d3f25cc333..0000000000 --- a/src/bin/patch/argmatch.h +++ /dev/null @@ -1,129 +0,0 @@ -/* argmatch.h -- definitions and prototypes for argmatch.c - Copyright (C) 1990, 1998, 1999 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. */ - -/* Written by David MacKenzie - Modified by Akim Demaille */ - -#ifndef ARGMATCH_H_ -# define ARGMATCH_H_ 1 - -# if HAVE_CONFIG_H -# include -# endif - -# include - -# ifndef PARAMS -# if PROTOTYPES || (defined (__STDC__) && __STDC__) -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif /* GCC. */ -# endif /* Not PARAMS. */ - -/* Assert there are as many real arguments as there are values - (argument list ends with a NULL guard). There is no execution - cost, since it will be statically evalauted to `assert (0)' or - `assert (1)'. Unfortunately there is no -Wassert-0. */ - -# undef ARRAY_CARDINALITY -# define ARRAY_CARDINALITY(Array) (sizeof ((Array)) / sizeof (*(Array))) - -# define ARGMATCH_ASSERT(Arglist, Vallist) \ - assert (ARRAY_CARDINALITY ((Arglist)) == ARRAY_CARDINALITY ((Vallist)) + 1) - -/* Return the index of the element of ARGLIST (NULL terminated) that - matches with ARG. If VALLIST is not NULL, then use it to resolve - false ambiguities (i.e., different matches of ARG but corresponding - to the same values in VALLIST). */ - -int argmatch - PARAMS ((const char *arg, const char *const *arglist, - const char *vallist, size_t valsize)); -int argcasematch - PARAMS ((const char *arg, const char *const *arglist, - const char *vallist, size_t valsize)); - -# define ARGMATCH(Arg, Arglist, Vallist) \ - argmatch ((Arg), (Arglist), (const char *) (Vallist), sizeof (*(Vallist))) - -# define ARGCASEMATCH(Arg, Arglist, Vallist) \ - argcasematch ((Arg), (Arglist), (const char *) (Vallist), sizeof (*(Vallist))) - -/* xargmatch calls this function when it fails. This function should not - return. By default, this is a function that calls ARGMATCH_DIE which - in turn defaults to `exit (EXIT_FAILURE)'. */ -typedef void (*argmatch_exit_fn) PARAMS ((void)); -extern argmatch_exit_fn argmatch_die; - -/* Report on stderr why argmatch failed. Report correct values. */ - -void argmatch_invalid - PARAMS ((const char *context, const char *value, int problem)); - -/* Left for compatibility with the old name invalid_arg */ - -# define invalid_arg(Context, Value, Problem) \ - argmatch_invalid ((Context), (Value), (Problem)) - - - -/* Report on stderr the list of possible arguments. */ - -void argmatch_valid - PARAMS ((const char *const *arglist, - const char *vallist, size_t valsize)); - -# define ARGMATCH_VALID(Arglist, Vallist) \ - argmatch_valid (Arglist, (const char *) Vallist, sizeof (*(Vallist))) - - - -/* Same as argmatch, but upon failure, reports a explanation on the - failure, and exits using the function EXIT_FN. */ - -int __xargmatch_internal - PARAMS ((const char *context, - const char *arg, const char *const *arglist, - const char *vallist, size_t valsize, - int case_sensitive, argmatch_exit_fn exit_fn)); - -/* Programmer friendly interface to __xargmatch_internal. */ - -# define XARGMATCH(Context, Arg, Arglist, Vallist) \ - (Vallist [__xargmatch_internal ((Context), (Arg), (Arglist), \ - (const char *) (Vallist), \ - sizeof (*(Vallist)), \ - 1, argmatch_die)]) - -# define XARGCASEMATCH(Context, Arg, Arglist, Vallist) \ - (Vallist [__xargmatch_internal ((Context), (Arg), (Arglist), \ - (const char *) (Vallist), \ - sizeof (*(Vallist)), \ - 0, argmatch_die)]) - -/* Convert a value into a corresponding argument. */ - -const char *argmatch_to_argument - PARAMS ((char const *value, const char *const *arglist, - const char *vallist, size_t valsize)); - -# define ARGMATCH_TO_ARGUMENT(Value, Arglist, Vallist) \ - argmatch_to_argument ((char const *) &(Value), (Arglist), \ - (const char *) (Vallist), sizeof (*(Vallist))) - -#endif /* ARGMATCH_H_ */ diff --git a/src/bin/patch/backupfile.c b/src/bin/patch/backupfile.c deleted file mode 100644 index 7f4da17fca..0000000000 --- a/src/bin/patch/backupfile.c +++ /dev/null @@ -1,268 +0,0 @@ -/* backupfile.c -- make Emacs style backup file names - Copyright (C) 1990-1997, 1998, 1999 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by David MacKenzie . - Some algorithms adapted from GNU Emacs. */ - -#if HAVE_CONFIG_H -# include -#endif - -#include -#include - -#include -#include -#if HAVE_STRING_H -# include -#else -# include -#endif - -#if HAVE_DIRENT_H -# include -# define NLENGTH(direct) strlen ((direct)->d_name) -#else -# define dirent direct -# define NLENGTH(direct) ((size_t) (direct)->d_namlen) -# if HAVE_SYS_NDIR_H -# include -# endif -# if HAVE_SYS_DIR_H -# include -# endif -# if HAVE_NDIR_H -# include -# endif -#endif - -#if CLOSEDIR_VOID -/* Fake a return value. */ -# define CLOSEDIR(d) (closedir (d), 0) -#else -# define CLOSEDIR(d) closedir (d) -#endif - -#if STDC_HEADERS -# include -#else -char *malloc (); -#endif - -#ifndef HAVE_DECL_GETENV -char *getenv (); -#endif - -char *base_name PARAMS ((char const *)); - -#if HAVE_DIRENT_H || HAVE_NDIR_H || HAVE_SYS_DIR_H || HAVE_SYS_NDIR_H -# define HAVE_DIR 1 -#else -# define HAVE_DIR 0 -#endif - -#if HAVE_LIMITS_H -# include -#endif -#ifndef CHAR_BIT -# define CHAR_BIT 8 -#endif -/* Upper bound on the string length of an integer converted to string. - 302 / 1000 is ceil (log10 (2.0)). Subtract 1 for the sign bit; - add 1 for integer division truncation; add 1 more for a minus sign. */ -#define INT_STRLEN_BOUND(t) ((sizeof (t) * CHAR_BIT - 1) * 302 / 1000 + 2) - -/* ISDIGIT differs from isdigit, as follows: - - Its arg may be any int or unsigned int; it need not be an unsigned char. - - It's guaranteed to evaluate its argument exactly once. - - It's typically faster. - Posix 1003.2-1992 section 2.5.2.1 page 50 lines 1556-1558 says that - only '0' through '9' are digits. Prefer ISDIGIT to isdigit unless - it's important to use the locale's definition of `digit' even when the - host does not conform to Posix. */ -#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) - -#if D_INO_IN_DIRENT -# define REAL_DIR_ENTRY(dp) ((dp)->d_ino != 0) -#else -# define REAL_DIR_ENTRY(dp) 1 -#endif - -/* The extension added to file names to produce a simple (as opposed - to numbered) backup file name. */ -const char *simple_backup_suffix = "~"; - -static int max_backup_version PARAMS ((const char *, const char *)); -static int version_number PARAMS ((const char *, const char *, size_t)); - -/* Return the name of the new backup file for file FILE, - allocated with malloc. Return 0 if out of memory. - FILE must not end with a '/' unless it is the root directory. - Do not call this function if backup_type == none. */ - -char * -find_backup_file_name (const char *file, enum backup_type backup_type) -{ - size_t backup_suffix_size_max; - size_t file_len = strlen (file); - size_t numbered_suffix_size_max = INT_STRLEN_BOUND (int) + 4; - char *s; - const char *suffix = simple_backup_suffix; - - /* Allow room for simple or `.~N~' backups. */ - backup_suffix_size_max = strlen (simple_backup_suffix) + 1; - if (HAVE_DIR && backup_suffix_size_max < numbered_suffix_size_max) - backup_suffix_size_max = numbered_suffix_size_max; - - s = malloc (file_len + backup_suffix_size_max + numbered_suffix_size_max); - if (s) - { - strcpy (s, file); - -#if HAVE_DIR - if (backup_type != simple) - { - int highest_backup; - size_t dir_len = base_name (s) - s; - - strcpy (s + dir_len, "."); - highest_backup = max_backup_version (file + dir_len, s); - if (! (backup_type == numbered_existing && highest_backup == 0)) - { - char *numbered_suffix = s + (file_len + backup_suffix_size_max); - sprintf (numbered_suffix, ".~%d~", highest_backup + 1); - suffix = numbered_suffix; - } - strcpy (s, file); - } -#endif /* HAVE_DIR */ - - addext (s, suffix, '~'); - } - return s; -} - -#if HAVE_DIR - -/* Return the number of the highest-numbered backup file for file - FILE in directory DIR. If there are no numbered backups - of FILE in DIR, or an error occurs reading DIR, return 0. - */ - -static int -max_backup_version (const char *file, const char *dir) -{ - DIR *dirp; - struct dirent *dp; - int highest_version; - int this_version; - size_t file_name_length; - - dirp = opendir (dir); - if (!dirp) - return 0; - - highest_version = 0; - file_name_length = strlen (file); - - while ((dp = readdir (dirp)) != 0) - { - if (!REAL_DIR_ENTRY (dp) || NLENGTH (dp) < file_name_length + 4) - continue; - - this_version = version_number (file, dp->d_name, file_name_length); - if (this_version > highest_version) - highest_version = this_version; - } - if (CLOSEDIR (dirp)) - return 0; - return highest_version; -} - -/* If BACKUP is a numbered backup of BASE, return its version number; - otherwise return 0. BASE_LENGTH is the length of BASE. - */ - -static int -version_number (const char *base, const char *backup, size_t base_length) -{ - int version; - const char *p; - - version = 0; - if (strncmp (base, backup, base_length) == 0 - && backup[base_length] == '.' - && backup[base_length + 1] == '~') - { - for (p = &backup[base_length + 2]; ISDIGIT (*p); ++p) - version = version * 10 + *p - '0'; - if (p[0] != '~' || p[1]) - version = 0; - } - return version; -} -#endif /* HAVE_DIR */ - -static const char * const backup_args[] = -{ - /* In a series of synonyms, present the most meaning full first, so - that argmatch_valid be more readable. */ - "none", "off", - "simple", "never", - "existing", "nil", - "numbered", "t", - 0 -}; - -static const enum backup_type backup_types[] = -{ - none, none, - simple, simple, - numbered_existing, numbered_existing, - numbered, numbered -}; - -/* Return the type of backup specified by VERSION. - If VERSION is NULL or the empty string, return numbered_existing. - If VERSION is invalid or ambiguous, fail with a diagnostic appropriate - for the specified CONTEXT. Unambiguous abbreviations are accepted. */ - -enum backup_type -get_version (const char *context, const char *version) -{ - if (version == 0 || *version == 0) - return numbered_existing; - else - return XARGMATCH (context, version, backup_args, backup_types); -} - - -/* Return the type of backup specified by VERSION. - If VERSION is NULL, use the value of the envvar VERSION_CONTROL. - If the specified string is invalid or ambiguous, fail with a diagnostic - appropriate for the specified CONTEXT. - Unambiguous abbreviations are accepted. */ - -enum backup_type -xget_version (const char *context, const char *version) -{ - if (version && *version) - return get_version (context, version); - else - return get_version ("$VERSION_CONTROL", getenv ("VERSION_CONTROL")); -} diff --git a/src/bin/patch/backupfile.h b/src/bin/patch/backupfile.h deleted file mode 100644 index b9b973c2dd..0000000000 --- a/src/bin/patch/backupfile.h +++ /dev/null @@ -1,60 +0,0 @@ -/* backupfile.h -- declarations for making Emacs style backup file names - Copyright (C) 1990-1992, 1997-1999 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef BACKUPFILE_H_ -# define BACKUPFILE_H_ - -/* When to make backup files. */ -enum backup_type -{ - /* Never make backups. */ - none, - - /* Make simple backups of every file. */ - simple, - - /* Make numbered backups of files that already have numbered backups, - and simple backups of the others. */ - numbered_existing, - - /* Make numbered backups of every file. */ - numbered -}; - -# define VALID_BACKUP_TYPE(Type) \ - ((Type) == none \ - || (Type) == simple \ - || (Type) == numbered_existing \ - || (Type) == numbered) - -extern char const *simple_backup_suffix; - -# ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -# endif - -char *find_backup_file_name PARAMS ((char const *, enum backup_type)); -enum backup_type get_version PARAMS ((char const *context, char const *arg)); -enum backup_type xget_version PARAMS ((char const *context, char const *arg)); -void addext PARAMS ((char *, char const *, int)); - -#endif /* ! BACKUPFILE_H_ */ diff --git a/src/bin/patch/basename.c b/src/bin/patch/basename.c deleted file mode 100644 index e648b1a7e2..0000000000 --- a/src/bin/patch/basename.c +++ /dev/null @@ -1,55 +0,0 @@ -/* basename.c -- return the last element in a path - Copyright (C) 1990, 1998, 1999 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 HAVE_CONFIG_H -# include -#endif - -#ifndef FILESYSTEM_PREFIX_LEN -# define FILESYSTEM_PREFIX_LEN(Filename) 0 -#endif - -#ifndef ISSLASH -# define ISSLASH(C) ((C) == '/') -#endif - -/* In general, we can't use the builtin `basename' function if available, - since it has different meanings in different environments. - In some environments the builtin `basename' modifies its argument. - If NAME is all slashes, be sure to return `/'. */ - -char * -base_name (char const *name) -{ - char const *base = name += FILESYSTEM_PREFIX_LEN (name); - int all_slashes = 1; - char const *p; - - for (p = name; *p; p++) - { - if (ISSLASH (*p)) - base = p + 1; - else - all_slashes = 0; - } - - /* If NAME is all slashes, arrange to return `/'. */ - if (*base == '\0' && ISSLASH (*name) && all_slashes) - --base; - - return (char *) base; -} diff --git a/src/bin/patch/basename.h b/src/bin/patch/basename.h deleted file mode 100644 index 90f765428d..0000000000 --- a/src/bin/patch/basename.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -#endif - -char *base_name PARAMS ((char const *name)); diff --git a/src/bin/patch/common.h b/src/bin/patch/common.h deleted file mode 100644 index f381d479f1..0000000000 --- a/src/bin/patch/common.h +++ /dev/null @@ -1,328 +0,0 @@ -/* common definitions for `patch' */ - -/* $Id: common.h 8008 2004-06-16 21:22:10Z korli $ */ - -/* Copyright 1986, 1988 Larry Wall - Copyright 1990, 1991-1993, 1997-1998, 1999 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#ifndef DEBUGGING -#define DEBUGGING 1 -#endif - -/* We must define `volatile' and `const' first (the latter inside config.h), - so that they're used consistently in all system includes. */ -#ifndef __STDC__ -# ifndef volatile -# define volatile -# endif -#endif - -#include - -#include -#include -#include -#include - -#include -#if ! defined S_ISDIR && defined S_IFDIR -# define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR) -#endif -#if ! defined S_ISREG && defined S_IFREG -# define S_ISREG(m) (((m) & S_IFMT) == S_IFREG) -#endif -#ifndef S_IXOTH -#define S_IXOTH 1 -#endif -#ifndef S_IWOTH -#define S_IWOTH 2 -#endif -#ifndef S_IROTH -#define S_IROTH 4 -#endif -#ifndef S_IXGRP -#define S_IXGRP (S_IXOTH << 3) -#endif -#ifndef S_IWGRP -#define S_IWGRP (S_IWOTH << 3) -#endif -#ifndef S_IRGRP -#define S_IRGRP (S_IROTH << 3) -#endif -#ifndef S_IXUSR -#define S_IXUSR (S_IXOTH << 6) -#endif -#ifndef S_IWUSR -#define S_IWUSR (S_IWOTH << 6) -#endif -#ifndef S_IRUSR -#define S_IRUSR (S_IROTH << 6) -#endif - -#if HAVE_LIMITS_H -# include -#endif -#ifndef CHAR_BIT -#define CHAR_BIT 8 -#endif -/* The extra casts work around common compiler bugs, - e.g. Cray C 5.0.3.0 time_t. */ -#define TYPE_SIGNED(t) ((t) -1 < (t) 0) -#define TYPE_MINIMUM(t) ((t) (TYPE_SIGNED (t) \ - ? (t) (~ (t) 0 << (sizeof (t) * CHAR_BIT - 1)) \ - : (t) 0)) -#define TYPE_MAXIMUM(t) ((t) ((t) ~ (t) 0 - TYPE_MINIMUM (t))) -#ifndef CHAR_MAX -#define CHAR_MAX TYPE_MAXIMUM (char) -#endif -#ifndef INT_MAX -#define INT_MAX TYPE_MAXIMUM (int) -#endif -#ifndef LONG_MIN -#define LONG_MIN TYPE_MINIMUM (long) -#endif - -#if HAVE_INTTYPES_H -# include -#endif -#ifndef SIZE_MAX -/* On some nonstandard hosts, size_t is signed, - so SIZE_MAX != (size_t) -1. */ -#define SIZE_MAX TYPE_MAXIMUM (size_t) -#endif - -#include -/* CTYPE_DOMAIN (C) is nonzero if the unsigned char C can safely be given - as an argument to macros like `isspace'. */ -#if STDC_HEADERS -#define CTYPE_DOMAIN(c) 1 -#else -#define CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177) -#endif -#ifndef ISSPACE -#define ISSPACE(c) (CTYPE_DOMAIN (c) && isspace (c)) -#endif - -#ifndef ISDIGIT -#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) -#endif - - -#ifndef FILESYSTEM_PREFIX_LEN -#define FILESYSTEM_PREFIX_LEN(f) 0 -#endif - -#ifndef ISSLASH -#define ISSLASH(c) ((c) == '/') -#endif - - -/* constants */ - -/* AIX predefines these. */ -#ifdef TRUE -#undef TRUE -#endif -#ifdef FALSE -#undef FALSE -#endif -#define TRUE 1 -#define FALSE 0 - -/* handy definitions */ - -#define strEQ(s1,s2) (!strcmp(s1, s2)) -#define strnEQ(s1,s2,l) (!strncmp(s1, s2, l)) - -/* typedefs */ - -typedef int bool; /* must promote to itself */ -typedef off_t LINENUM; /* must be signed */ - -/* globals */ - -extern char const program_name[]; - -XTERN char *buf; /* general purpose buffer */ -XTERN size_t bufsize; /* allocated size of buf */ - -XTERN bool using_plan_a; /* try to keep everything in memory */ - -XTERN char *inname; -XTERN char *outfile; -XTERN int inerrno; -XTERN int invc; -XTERN struct stat instat; -XTERN bool dry_run; -XTERN bool posixly_correct; - -XTERN char const *origprae; -XTERN char const *origbase; - -XTERN char const * volatile TMPINNAME; -XTERN char const * volatile TMPOUTNAME; -XTERN char const * volatile TMPPATNAME; - -XTERN int volatile TMPINNAME_needs_removal; -XTERN int volatile TMPOUTNAME_needs_removal; -XTERN int volatile TMPPATNAME_needs_removal; - -#ifdef DEBUGGING -XTERN int debug; -#else -# define debug 0 -#endif -XTERN bool force; -XTERN bool batch; -XTERN bool noreverse; -XTERN int reverse; -XTERN enum { DEFAULT_VERBOSITY, SILENT, VERBOSE } verbosity; -XTERN bool skip_rest_of_patch; -XTERN int strippath; -XTERN bool canonicalize; -XTERN int patch_get; -XTERN int set_time; -XTERN int set_utc; - -enum diff - { - NO_DIFF, - CONTEXT_DIFF, - NORMAL_DIFF, - ED_DIFF, - NEW_CONTEXT_DIFF, - UNI_DIFF - }; - -XTERN enum diff diff_type; - -XTERN char *revision; /* prerequisite revision, if any */ - -#ifdef __STDC__ -# define GENERIC_OBJECT void -#else -# define GENERIC_OBJECT char -#endif - -#if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 6) || __STRICT_ANSI__ -# define __attribute__(x) -#endif - -#ifndef PARAMS -# ifdef __STDC__ -# define PARAMS(args) args -# else -# define PARAMS(args) () -# endif -#endif - -void fatal_exit PARAMS ((int)) __attribute__ ((noreturn)); - -#include -#if !STDC_HEADERS && !defined errno -extern int errno; -#endif - -#if STDC_HEADERS || HAVE_STRING_H -# include -#else -# if !HAVE_MEMCHR -# define memcmp(s1, s2, n) bcmp (s1, s2, n) -# define memcpy(d, s, n) bcopy (s, d, n) -GENERIC_OBJECT *memchr (); -# endif -#endif - -#if STDC_HEADERS -# include -#else -char *getenv (); -GENERIC_OBJECT *malloc (); -GENERIC_OBJECT *realloc (); -#endif - -#if HAVE_UNISTD_H -# include -#else -# ifndef lseek - off_t lseek (); -# endif -#endif -#ifndef SEEK_SET -#define SEEK_SET 0 -#endif -#ifndef STDIN_FILENO -#define STDIN_FILENO 0 -#endif -#ifndef STDOUT_FILENO -#define STDOUT_FILENO 1 -#endif -#ifndef STDERR_FILENO -#define STDERR_FILENO 2 -#endif -#if HAVE_FSEEKO - typedef off_t file_offset; -# define file_seek fseeko -# define file_tell ftello -#else - typedef long file_offset; -# define file_seek fseek -# define file_tell ftell -#endif - -#if HAVE_FCNTL_H -# include -#endif -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif -#ifndef O_WRONLY -#define O_WRONLY 1 -#endif -#ifndef O_RDWR -#define O_RDWR 2 -#endif -#ifndef _O_BINARY -#define _O_BINARY 0 -#endif -#ifndef O_BINARY -#define O_BINARY _O_BINARY -#endif -#ifndef O_CREAT -#define O_CREAT 0 -#endif -#ifndef O_EXCL -#define O_EXCL 0 -#endif -#ifndef O_TRUNC -#define O_TRUNC 0 -#endif - -#if HAVE_SETMODE - XTERN int binary_transput; /* O_BINARY if binary i/o is desired */ -#else -# define binary_transput 0 -#endif - -#ifndef NULL_DEVICE -#define NULL_DEVICE "/dev/null" -#endif - -#ifndef TTY_DEVICE -#define TTY_DEVICE "/dev/tty" -#endif diff --git a/src/bin/patch/config.h b/src/bin/patch/config.h deleted file mode 100644 index c44585188b..0000000000 --- a/src/bin/patch/config.h +++ /dev/null @@ -1,170 +0,0 @@ -/* config.h. Generated automatically by configure. */ -/* config.hin. Generated automatically from configure.in by autoheader. */ - -/* Define if on AIX 3. - System headers sometimes define this. - We just want to avoid a redefinition error message. */ -#ifndef _ALL_SOURCE -/* #undef _ALL_SOURCE */ -#endif - -/* Define if the closedir function returns void instead of int. */ -/* #undef CLOSEDIR_VOID */ - -/* Define to empty if the keyword does not work. */ -/* #undef const */ - -/* Define if you don't have vprintf but do have _doprnt. */ -/* #undef HAVE_DOPRNT */ - -/* Define if you support file names longer than 14 characters. */ -#define HAVE_LONG_FILE_NAMES 1 - -/* Define if you have the vprintf function. */ -#define HAVE_VPRINTF 1 - -/* Define if on MINIX. */ -/* #undef _MINIX */ - -/* Define to `int' if doesn't define. */ -/* #undef mode_t */ - -/* Define to `long' if doesn't define. */ -/* #undef off_t */ - -/* Define to `int' if doesn't define. */ -/* #undef pid_t */ - -/* Define if the system does not provide POSIX.1 features except - with this defined. */ -/* #undef _POSIX_1_SOURCE */ - -/* Define if you need to in order for stat and other things to work. */ -/* #undef _POSIX_SOURCE */ - -/* Define as the return type of signal handlers (int or void). */ -#define RETSIGTYPE void - -/* Define to `unsigned' if doesn't define. */ -/* #undef size_t */ - -/* Define if you have the ANSI C header files. */ -#define STDC_HEADERS 1 - -/* Define if you can safely include both and . */ -#define TIME_WITH_SYS_TIME 1 - -/* Define if you have the _doprintf function. */ -/* #undef HAVE__DOPRINTF */ - -/* Define if you have the fseeko function. */ -#define HAVE_FSEEKO 1 - -/* Define if you have the isascii function. */ -#define HAVE_ISASCII 1 - -/* Define if you have the memchr function. */ -#define HAVE_MEMCHR 1 - -/* Define if you have the memcmp function. */ -#define HAVE_MEMCMP 1 - -/* Define if you have the mkdir function. */ -#define HAVE_MKDIR 1 - -/* Define if you have the mktemp function. */ -#define HAVE_MKTEMP 1 - -/* Define if you have the pathconf function. */ -#define HAVE_PATHCONF 1 - -/* Define if you have the raise function. */ -#define HAVE_RAISE 1 - -/* Define if you have the rename function. */ -#define HAVE_RENAME 1 - -/* Define if you have the rmdir function. */ -#define HAVE_RMDIR 1 - -/* Define if you have the setmode function. */ -/* #undef HAVE_SETMODE */ - -/* Define if you have the sigaction function. */ -#define HAVE_SIGACTION 1 - -/* Define if you have the sigprocmask function. */ -#define HAVE_SIGPROCMASK 1 - -/* Define if you have the sigsetmask function. */ -/* #undef HAVE_SIGSETMASK */ - -/* Define if you have the strerror function. */ -#define HAVE_STRERROR 1 - -/* Define if you have the header file. */ -#define HAVE_DIRENT_H 1 - -/* Define if you have the header file. */ -#define HAVE_FCNTL_H 1 - -/* Define if you have the header file. */ -#define HAVE_LIMITS_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_NDIR_H */ - -/* Define if you have the header file. */ -#define HAVE_STRING_H 1 - -/* Define if you have the header file. */ -/* #undef HAVE_SYS_DIR_H */ - -/* Define if you have the header file. */ -/* #undef HAVE_SYS_NDIR_H */ - -/* Define if you have the header file. */ -#define HAVE_UNISTD_H 1 - -/* Define if you have the header file. */ -#define HAVE_UTIME_H 1 - -/* Define if you have the header file. */ -#define HAVE_VARARGS_H 1 - -/* Number of bits in a file offset, on hosts where this is settable. */ -/* #undef _FILE_OFFSET_BITS */ - -/* Define to make fseeko etc. visible, on some hosts. */ -/* #undef _LARGEFILE_SOURCE */ - -/* Define for large files, on AIX-style hosts. */ -/* #undef _LARGE_FILES */ - -/* Define if compiler has function prototypes */ -#define PROTOTYPES 1 - -/* Define if exists, doesn't clash with , - and declares uintmax_t. */ -#define HAVE_INTTYPES_H 1 - -/* Define if struct utimbuf is declared -- usually in . - Some systems have utime.h but don't declare the struct anywhere. */ -#define HAVE_STRUCT_UTIMBUF 1 - -/* Define if the malloc check has been performed. */ -#define HAVE_DONE_WORKING_MALLOC_CHECK 1 - -/* Define to rpl_malloc if the replacement function should be used. */ -/* #undef malloc */ - -/* Define if the realloc check has been performed. */ -#define HAVE_DONE_WORKING_REALLOC_CHECK 1 - -/* Define to rpl_realloc if the replacement function should be used. */ -/* #undef realloc */ - -/* Define if there is a member named d_ino in the struct describing - directory headers. */ -#define D_INO_IN_DIRENT 1 - diff --git a/src/bin/patch/error.c b/src/bin/patch/error.c deleted file mode 100644 index 4eff5d0f9d..0000000000 --- a/src/bin/patch/error.c +++ /dev/null @@ -1,250 +0,0 @@ -/* Error handler for noninteractive utilities - Copyright (C) 1990,91,92,93,94,95,96,97,98 Free Software Foundation, Inc. - - This file is part of the GNU C Library. Its master source is NOT part of - the C library, however. The master source lives in /gd/gnu/lib. - - 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. */ - -/* Written by David MacKenzie . */ - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#if HAVE_VPRINTF || HAVE_DOPRNT || _LIBC -# if __STDC__ -# include -# define VA_START(args, lastarg) va_start(args, lastarg) -# else -# include -# define VA_START(args, lastarg) va_start(args) -# endif -#else -# define va_alist a1, a2, a3, a4, a5, a6, a7, a8 -# define va_dcl char *a1, *a2, *a3, *a4, *a5, *a6, *a7, *a8; -#endif - -#if STDC_HEADERS || _LIBC -# include -# include -#else -void exit (); -#endif - -#include "error.h" - -#ifndef _ -# define _(String) String -#endif - -/* If NULL, error will flush stdout, then print on stderr the program - name, a colon and a space. Otherwise, error will call this - function without parameters instead. */ -void (*error_print_progname) ( -#if __STDC__ - 0 - void -#endif - ); - -/* This variable is incremented each time `error' is called. */ -unsigned int error_message_count; - -#ifdef _LIBC -/* In the GNU C library, there is a predefined variable for this. */ - -# define program_name program_invocation_name -# include - -/* In GNU libc we want do not want to use the common name `error' directly. - Instead make it a weak alias. */ -# define error __error -# define error_at_line __error_at_line - -#else /* not _LIBC */ - -/* The calling program should define program_name and set it to the - name of the executing program. */ -extern char *program_name; - -# ifdef HAVE_STRERROR_R -# define __strerror_r strerror_r -# else -# if HAVE_STRERROR -# ifndef strerror /* On some systems, strerror is a macro */ -char *strerror (); -# endif -# else -static char * -private_strerror (errnum) - int errnum; -{ - extern char *sys_errlist[]; - extern int sys_nerr; - - if (errnum > 0 && errnum <= sys_nerr) - return _(sys_errlist[errnum]); - return _("Unknown system error"); -} -# define strerror private_strerror -# endif /* HAVE_STRERROR */ -# endif /* HAVE_STRERROR_R */ -#endif /* not _LIBC */ - -/* Print the program name and error message MESSAGE, which is a printf-style - format string with optional args. - If ERRNUM is nonzero, print its corresponding system error message. - Exit with status STATUS if it is nonzero. */ -/* VARARGS */ - -void -#if defined VA_START && __STDC__ -error (int status, int errnum, const char *message, ...) -#else -error (status, errnum, message, va_alist) - int status; - int errnum; - char *message; - va_dcl -#endif -{ -#ifdef VA_START - va_list args; -#endif - - if (error_print_progname) - (*error_print_progname) (); - else - { - fflush (stdout); - fprintf (stderr, "%s: ", program_name); - } - -#ifdef VA_START - VA_START (args, message); -# if HAVE_VPRINTF || _LIBC - vfprintf (stderr, message, args); -# else - _doprnt (message, args, stderr); -# endif - va_end (args); -#else - fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); -#endif - - ++error_message_count; - if (errnum) - { -#if defined HAVE_STRERROR_R || defined _LIBC - char errbuf[1024]; - /* Don't use __strerror_r's return value because on some systems - (at least DEC UNIX 4.0[A-D]) strerror_r returns `int'. */ - __strerror_r (errnum, errbuf, sizeof errbuf); - fprintf (stderr, ": %s", errbuf); -#else - fprintf (stderr, ": %s", strerror (errnum)); -#endif - } - putc ('\n', stderr); - fflush (stderr); - if (status) - exit (status); -} - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -int error_one_per_line; - -void -#if defined VA_START && __STDC__ -error_at_line (int status, int errnum, const char *file_name, - unsigned int line_number, const char *message, ...) -#else -error_at_line (status, errnum, file_name, line_number, message, va_alist) - int status; - int errnum; - const char *file_name; - unsigned int line_number; - char *message; - va_dcl -#endif -{ -#ifdef VA_START - va_list args; -#endif - - if (error_one_per_line) - { - static const char *old_file_name; - static unsigned int old_line_number; - - if (old_line_number == line_number && - (file_name == old_file_name || !strcmp (old_file_name, file_name))) - /* Simply return and print nothing. */ - return; - - old_file_name = file_name; - old_line_number = line_number; - } - - if (error_print_progname) - (*error_print_progname) (); - else - { - fflush (stdout); - fprintf (stderr, "%s:", program_name); - } - - if (file_name != NULL) - fprintf (stderr, "%s:%d: ", file_name, line_number); - -#ifdef VA_START - VA_START (args, message); -# if HAVE_VPRINTF || _LIBC - vfprintf (stderr, message, args); -# else - _doprnt (message, args, stderr); -# endif - va_end (args); -#else - fprintf (stderr, message, a1, a2, a3, a4, a5, a6, a7, a8); -#endif - - ++error_message_count; - if (errnum) - { -#if defined HAVE_STRERROR_R || defined _LIBC - char errbuf[1024]; - fprintf (stderr, ": %s", __strerror_r (errnum, errbuf, sizeof errbuf)); -#else - fprintf (stderr, ": %s", strerror (errnum)); -#endif - } - putc ('\n', stderr); - fflush (stderr); - if (status) - exit (status); -} - -#ifdef _LIBC -/* Make the weak alias. */ -# undef error -# undef error_at_line -weak_alias (__error, error) -weak_alias (__error_at_line, error_at_line) -#endif diff --git a/src/bin/patch/error.h b/src/bin/patch/error.h deleted file mode 100644 index 20f75824d6..0000000000 --- a/src/bin/patch/error.h +++ /dev/null @@ -1,78 +0,0 @@ -/* Declaration for error-reporting function - Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. - - - NOTE: The canonical source of this file is maintained with the GNU C Library. - Bugs can be reported to bug-glibc@prep.ai.mit.edu. - - 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. */ - -#ifndef _ERROR_H -#define _ERROR_H 1 - -#ifndef __attribute__ -/* This feature is available in gcc versions 2.5 and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__ -# define __attribute__(Spec) /* empty */ -# endif -/* The __-protected variants of `format' and `printf' attributes - are accepted by gcc versions 2.6.4 (effectively 2.7) and later. */ -# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7) -# define __format__ format -# define __printf__ printf -# endif -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -#if defined (__STDC__) && __STDC__ - -/* Print a message with `fprintf (stderr, FORMAT, ...)'; - if ERRNUM is nonzero, follow it with ": " and strerror (ERRNUM). - If STATUS is nonzero, terminate the program with `exit (STATUS)'. */ - -extern void error (int status, int errnum, const char *format, ...) - __attribute__ ((__format__ (__printf__, 3, 4))); - -extern void error_at_line (int status, int errnum, const char *fname, - unsigned int lineno, const char *format, ...) - __attribute__ ((__format__ (__printf__, 5, 6))); - -/* If NULL, error will flush stdout, then print on stderr the program - name, a colon and a space. Otherwise, error will call this - function without parameters instead. */ -extern void (*error_print_progname) (void); - -#else -void error (); -void error_at_line (); -extern void (*error_print_progname) (); -#endif - -/* This variable is incremented each time `error' is called. */ -extern unsigned int error_message_count; - -/* Sometimes we want to have at most one error per line. This - variable controls whether this mode is selected or not. */ -extern int error_one_per_line; - -#ifdef __cplusplus -} -#endif - -#endif /* error.h */ diff --git a/src/bin/patch/inp.c b/src/bin/patch/inp.c deleted file mode 100644 index b64559147f..0000000000 --- a/src/bin/patch/inp.c +++ /dev/null @@ -1,467 +0,0 @@ -/* inputting files to be patched */ - -/* $Id: inp.c 8008 2004-06-16 21:22:10Z korli $ */ - -/* Copyright 1986, 1988 Larry Wall - Copyright 1991, 1992-1993, 1997-1998, 1999 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define XTERN extern -#include -#include -#include -#include -#include -#include -#undef XTERN -#define XTERN -#include - -/* Input-file-with-indexable-lines abstract type */ - -static char *i_buffer; /* plan A buffer */ -static char const **i_ptr; /* pointers to lines in plan A buffer */ - -static size_t tibufsize; /* size of plan b buffers */ -#ifndef TIBUFSIZE_MINIMUM -#define TIBUFSIZE_MINIMUM (8 * 1024) /* minimum value for tibufsize */ -#endif -static int tifd = -1; /* plan b virtual string array */ -static char *tibuf[2]; /* plan b buffers */ -static LINENUM tiline[2] = {-1, -1}; /* 1st line in each buffer */ -static LINENUM lines_per_buf; /* how many lines per buffer */ -static size_t tireclen; /* length of records in tmp file */ -static size_t last_line_size; /* size of last input line */ - -static bool plan_a PARAMS ((char const *));/* yield FALSE if memory runs out */ -static void plan_b PARAMS ((char const *)); -static void report_revision PARAMS ((int)); -static void too_many_lines PARAMS ((char const *)) __attribute__((noreturn)); - -/* New patch--prepare to edit another file. */ - -void -re_input (void) -{ - if (using_plan_a) { - if (i_buffer) - { - free (i_buffer); - i_buffer = 0; - free (i_ptr); - } - } - else { - close (tifd); - tifd = -1; - if (tibuf[0]) - { - free (tibuf[0]); - tibuf[0] = 0; - } - tiline[0] = tiline[1] = -1; - tireclen = 0; - } -} - -/* Construct the line index, somehow or other. */ - -void -scan_input (char *filename) -{ - using_plan_a = ! (debug & 16) && plan_a (filename); - if (!using_plan_a) - plan_b(filename); - - if (verbosity != SILENT) - { - filename = quotearg (filename); - - if (verbosity == VERBOSE) - say ("Patching file %s using Plan %s...\n", - filename, using_plan_a ? "A" : "B"); - else - say ("patching file %s\n", filename); - } -} - -/* Report whether a desired revision was found. */ - -static void -report_revision (int found_revision) -{ - revision = quotearg (revision); - - if (found_revision) - { - if (verbosity == VERBOSE) - say ("Good. This file appears to be the %s version.\n", revision); - } - else if (force) - { - if (verbosity != SILENT) - say ("Warning: this file doesn't appear to be the %s version -- patching anyway.\n", - revision); - } - else if (batch) - fatal ("This file doesn't appear to be the %s version -- aborting.", - revision); - else - { - ask ("This file doesn't appear to be the %s version -- patch anyway? [n] ", - revision); - if (*buf != 'y') - fatal ("aborted"); - } -} - - -static void -too_many_lines (char const *filename) -{ - fatal ("File %s has too many lines", quotearg (filename)); -} - - -void -get_input_file (char const *filename, char const *outname) -{ - int elsewhere = strcmp (filename, outname); - char const *cs; - char *diffbuf; - char *getbuf; - - if (inerrno == -1) - inerrno = stat (inname, &instat) == 0 ? 0 : errno; - - /* Perhaps look for RCS or SCCS versions. */ - if (patch_get - && invc != 0 - && (inerrno - || (! elsewhere - && (/* No one can write to it. */ - (instat.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) == 0 - /* Only the owner (who's not me) can write to it. */ - || ((instat.st_mode & (S_IWGRP|S_IWOTH)) == 0 - && instat.st_uid != geteuid ())))) - && (invc = !! (cs = (version_controller - (filename, elsewhere, - inerrno ? (struct stat *) 0 : &instat, - &getbuf, &diffbuf))))) { - - if (!inerrno) { - if (!elsewhere - && (instat.st_mode & (S_IWUSR|S_IWGRP|S_IWOTH)) != 0) - /* Somebody can write to it. */ - fatal ("File %s seems to be locked by somebody else under %s", - quotearg (filename), cs); - if (diffbuf) - { - /* It might be checked out unlocked. See if it's safe to - check out the default version locked. */ - - if (verbosity == VERBOSE) - say ("Comparing file %s to default %s version...\n", - quotearg (filename), cs); - - if (systemic (diffbuf) != 0) - { - say ("warning: Patching file %s, which does not match default %s version\n", - quotearg (filename), cs); - cs = 0; - } - } - } - - if (cs && version_get (filename, cs, ! inerrno, elsewhere, getbuf, - &instat)) - inerrno = 0; - - free (getbuf); - if (diffbuf) - free (diffbuf); - - } else if (inerrno && !pch_says_nonexistent (reverse)) - { - errno = inerrno; - pfatal ("Can't find file %s", quotearg (filename)); - } - - if (inerrno) - { - instat.st_mode = S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP|S_IROTH|S_IWOTH; - instat.st_size = 0; - } - else if (! S_ISREG (instat.st_mode)) - fatal ("File %s is not a regular file -- can't patch", - quotearg (filename)); -} - - -/* Try keeping everything in memory. */ - -static bool -plan_a (char const *filename) -{ - register char const *s; - register char const *lim; - register char const **ptr; - register char *buffer; - register LINENUM iline; - size_t size = instat.st_size; - - /* Fail if the file size doesn't fit in a size_t, - or if storage isn't available. */ - if (! (size == instat.st_size - && (buffer = malloc (size ? size : (size_t) 1)))) - return FALSE; - - /* Read the input file, but don't bother reading it if it's empty. - When creating files, the files do not actually exist. */ - if (size) - { - int ifd = open (filename, O_RDONLY|binary_transput); - size_t buffered = 0, n; - if (ifd < 0) - pfatal ("can't open file %s", quotearg (filename)); - - while (size - buffered != 0) - { - n = read (ifd, buffer + buffered, size - buffered); - if (n == 0) - { - /* Some non-POSIX hosts exaggerate st_size in text mode; - or the file may have shrunk! */ - size = buffered; - break; - } - if (n == (size_t) -1) - { - /* Perhaps size is too large for this host. */ - close (ifd); - free (buffer); - return FALSE; - } - buffered += n; - } - - if (close (ifd) != 0) - read_fatal (); - } - - /* Scan the buffer and build array of pointers to lines. */ - lim = buffer + size; - iline = 3; /* 1 unused, 1 for SOF, 1 for EOF if last line is incomplete */ - for (s = buffer; (s = (char *) memchr (s, '\n', lim - s)); s++) - if (++iline < 0) - too_many_lines (filename); - if (! (iline == (size_t) iline - && (size_t) iline * sizeof *ptr / sizeof *ptr == (size_t) iline - && (ptr = (char const **) malloc ((size_t) iline * sizeof *ptr)))) - { - free (buffer); - return FALSE; - } - iline = 0; - for (s = buffer; ; s++) - { - ptr[++iline] = s; - if (! (s = (char *) memchr (s, '\n', lim - s))) - break; - } - if (size && lim[-1] != '\n') - ptr[++iline] = lim; - input_lines = iline - 1; - - if (revision) - { - char const *rev = revision; - int rev0 = rev[0]; - int found_revision = 0; - size_t revlen = strlen (rev); - - if (revlen <= size) - { - char const *limrev = lim - revlen; - - for (s = buffer; (s = (char *) memchr (s, rev0, limrev - s)); s++) - if (memcmp (s, rev, revlen) == 0 - && (s == buffer || ISSPACE ((unsigned char) s[-1])) - && (s + 1 == limrev || ISSPACE ((unsigned char) s[revlen]))) - { - found_revision = 1; - break; - } - } - - report_revision (found_revision); - } - - /* Plan A will work. */ - i_buffer = buffer; - i_ptr = ptr; - return TRUE; -} - -/* Keep (virtually) nothing in memory. */ - -static void -plan_b (char const *filename) -{ - register FILE *ifp; - register int c; - register size_t len; - register size_t maxlen; - register int found_revision; - register size_t i; - register char const *rev; - register size_t revlen; - register LINENUM line = 1; - int exclusive; - - if (instat.st_size == 0) - filename = NULL_DEVICE; - if (! (ifp = fopen (filename, binary_transput ? "rb" : "r"))) - pfatal ("Can't open file %s", quotearg (filename)); - exclusive = TMPINNAME_needs_removal ? 0 : O_EXCL; - TMPINNAME_needs_removal = 1; - tifd = create_file (TMPINNAME, O_RDWR | O_BINARY | exclusive, (mode_t) 0); - i = 0; - len = 0; - maxlen = 1; - rev = revision; - found_revision = !rev; - revlen = rev ? strlen (rev) : 0; - - while ((c = getc (ifp)) != EOF) - { - len++; - - if (c == '\n') - { - if (++line < 0) - too_many_lines (filename); - if (maxlen < len) - maxlen = len; - len = 0; - } - - if (!found_revision) - { - if (i == revlen) - { - found_revision = ISSPACE ((unsigned char) c); - i = (size_t) -1; - } - else if (i != (size_t) -1) - i = rev[i]==c ? i + 1 : (size_t) -1; - - if (i == (size_t) -1 && ISSPACE ((unsigned char) c)) - i = 0; - } - } - - if (revision) - report_revision (found_revision); - Fseek (ifp, (off_t) 0, SEEK_SET); /* rewind file */ - for (tibufsize = TIBUFSIZE_MINIMUM; tibufsize < maxlen; tibufsize <<= 1) - continue; - lines_per_buf = tibufsize / maxlen; - tireclen = maxlen; - tibuf[0] = xmalloc (2 * tibufsize); - tibuf[1] = tibuf[0] + tibufsize; - - for (line = 1; ; line++) - { - char *p = tibuf[0] + maxlen * (line % lines_per_buf); - char const *p0 = p; - if (! (line % lines_per_buf)) /* new block */ - if (write (tifd, tibuf[0], tibufsize) != tibufsize) - write_fatal (); - if ((c = getc (ifp)) == EOF) - break; - - for (;;) - { - *p++ = c; - if (c == '\n') - { - last_line_size = p - p0; - break; - } - - if ((c = getc (ifp)) == EOF) - { - last_line_size = p - p0; - line++; - goto EOF_reached; - } - } - } - EOF_reached: - if (ferror (ifp) || fclose (ifp) != 0) - read_fatal (); - - if (line % lines_per_buf != 0) - if (write (tifd, tibuf[0], tibufsize) != tibufsize) - write_fatal (); - input_lines = line - 1; -} - -/* Fetch a line from the input file. - WHICHBUF is ignored when the file is in memory. */ - -char const * -ifetch (LINENUM line, int whichbuf, size_t *psize) -{ - register char const *q; - register char const *p; - - if (line < 1 || line > input_lines) { - *psize = 0; - return ""; - } - if (using_plan_a) { - p = i_ptr[line]; - *psize = i_ptr[line + 1] - p; - return p; - } else { - LINENUM offline = line % lines_per_buf; - LINENUM baseline = line - offline; - - if (tiline[0] == baseline) - whichbuf = 0; - else if (tiline[1] == baseline) - whichbuf = 1; - else { - tiline[whichbuf] = baseline; - if (lseek (tifd, (off_t) (baseline/lines_per_buf * tibufsize), - SEEK_SET) == -1 - || read (tifd, tibuf[whichbuf], tibufsize) < 0) - read_fatal (); - } - p = tibuf[whichbuf] + (tireclen*offline); - if (line == input_lines) - *psize = last_line_size; - else { - for (q = p; *q++ != '\n'; ) - continue; - *psize = q - p; - } - return p; - } -} diff --git a/src/bin/patch/inp.h b/src/bin/patch/inp.h deleted file mode 100644 index 6a4f41d521..0000000000 --- a/src/bin/patch/inp.h +++ /dev/null @@ -1,10 +0,0 @@ -/* inputting files to be patched */ - -/* $Id: inp.h 8008 2004-06-16 21:22:10Z korli $ */ - -XTERN LINENUM input_lines; /* how long is input file in lines */ - -char const *ifetch PARAMS ((LINENUM, int, size_t *)); -void get_input_file PARAMS ((char const *, char const *)); -void re_input PARAMS ((void)); -void scan_input PARAMS ((char *)); diff --git a/src/bin/patch/maketime.c b/src/bin/patch/maketime.c deleted file mode 100644 index 2cb9eef4da..0000000000 --- a/src/bin/patch/maketime.c +++ /dev/null @@ -1,501 +0,0 @@ -/* Convert struct partime into time_t. */ - -/* Copyright 1992, 1993, 1994, 1995, 1997 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - - This file is part of RCS. - - RCS 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. - - RCS 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 RCS; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - - */ - -/* For maximum portability, use only localtime and gmtime. - Make no assumptions about the time_t epoch or the range of time_t values. - Avoid mktime because it's not universal and because there's no easy, - portable way for mktime to yield the inverse of gmtime. */ - -#if has_conf_h -# include -#else -# if HAVE_CONFIG_H -# include -# else -# ifndef __STDC__ -# define const -# endif -# endif - /* MIPS RISCOS4.52 defines time_t in not . */ -# include -# if HAVE_LIMITS_H -# include -# endif -# ifndef LONG_MIN -# define LONG_MIN (-1-2147483647L) -# endif -# if STDC_HEADERS -# include -# endif -# include -# ifdef __STDC__ -# define P(x) x -# else -# define P(x) () -# endif -#endif - -#include -#include - -char const maket_id[] = - "$Id: maketime.c 8008 2004-06-16 21:22:10Z korli $"; - -static int isleap P ((int)); -static int month_days P ((struct tm const *)); -static time_t maketime P ((struct partime const *, time_t)); - -/* Suppose A1 + B1 = SUM1, using 2's complement arithmetic ignoring overflow. - Suppose A, B and SUM have the same respective signs as A1, B1, and SUM1. - Then this yields nonzero if overflow occurred during the addition. - Overflow occurs if A and B have the same sign, but A and SUM differ in sign. - Use `^' to test whether signs differ, and `< 0' to isolate the sign. */ -#define overflow_sum_sign(a, b, sum) ((~((a) ^ (b)) & ((a) ^ (sum))) < 0) - -/* Quotient and remainder when dividing A by B, - truncating towards minus infinity, where B is positive. */ -#define DIV(a, b) ((a) / (b) - ((a) % (b) < 0)) -#define MOD(a, b) ((a) % (b) + (b) * ((a) % (b) < 0)) - -/* Number of days in 400 consecutive Gregorian years. */ -#define Y400_DAYS (365 * 400L + 100 - 4 + 1) - -/* Number of years to add to tm_year to get Gregorian year. */ -#define TM_YEAR_ORIGIN 1900 - -static int -isleap (y) - int y; -{ - return (y & 3) == 0 && (y % 100 != 0 || y % 400 == 0); -} - -/* days in year before start of months 0-12 */ -static int const month_yday[] = -{ - 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 -}; - -/* Yield the number of days in TM's month. */ -static int -month_days (tm) - struct tm const *tm; -{ - int m = tm->tm_mon; - return (month_yday[m + 1] - month_yday[m] - + (m == 1 && isleap (tm->tm_year + TM_YEAR_ORIGIN))); -} - -/* Convert UNIXTIME to struct tm form. - Use gmtime if available and if !LOCALZONE, localtime otherwise. */ -struct tm * -time2tm (unixtime, localzone) - time_t unixtime; - int localzone; -{ - struct tm *tm; -#ifdef TZ_is_unset - static char const *TZ; - if (!TZ && !(TZ = getenv ("TZ"))) - TZ_is_unset ("The TZ environment variable is not set; please set it to your timezone"); -#endif - if (localzone || !(tm = gmtime (&unixtime))) - tm = localtime (&unixtime); - return tm; -} - -/* Yield A - B, measured in seconds. */ -time_t -difftm (a, b) - struct tm const *a; - struct tm const *b; -{ - int ay = a->tm_year + (TM_YEAR_ORIGIN - 1); - int by = b->tm_year + (TM_YEAR_ORIGIN - 1); - int ac = DIV (ay, 100); - int bc = DIV (by, 100); - int difference_in_day_of_year = a->tm_yday - b->tm_yday; - int intervening_leap_days = (((ay >> 2) - (by >> 2)) - - (ac - bc) - + ((ac >> 2) - (bc >> 2))); - time_t difference_in_years = ay - by; - time_t difference_in_days - = (difference_in_years * 365 - + (intervening_leap_days + difference_in_day_of_year)); - return (((((difference_in_days * 24 - + (a->tm_hour - b->tm_hour)) - * 60) - + (a->tm_min - b->tm_min)) - * 60) - + (a->tm_sec - b->tm_sec)); -} - -/* Adjust time T by adding SECONDS. - The absolute value of SECONDS cannot exceed 59 * INT_MAX, - and also cannot exceed one month's worth of seconds; - this is enough to handle any POSIX or real-life daylight-saving offset. - Adjust only T's year, mon, mday, hour, min and sec members; - plus adjust wday if it is defined. */ -void -adjzone (t, seconds) - register struct tm *t; - long seconds; -{ - int days = 0; - - /* This code can be off by a second if SECONDS is not a multiple of 60, - if T is local time, and if a leap second happens during this minute. - But this bug has never occurred, and most likely will not ever occur. - Liberia, the last country for which SECONDS % 60 was nonzero, - switched to UTC in May 1972; the first leap second was in June 1972. */ - int leap_second = t->tm_sec == 60; - long sec = seconds + (t->tm_sec - leap_second); - if (sec < 0) - { - if ((t->tm_min -= (59 - sec) / 60) < 0 - && (t->tm_hour -= (59 - t->tm_min) / 60) < 0) - { - days = - ((23 - t->tm_hour) / 24); - if ((t->tm_mday += days) <= 0) - { - if (--t->tm_mon < 0) - { - --t->tm_year; - t->tm_mon = 11; - } - t->tm_mday += month_days (t); - } - } - } - else - { - if (60 <= (t->tm_min += sec / 60) - && (24 <= (t->tm_hour += t->tm_min / 60))) - { - days = t->tm_hour / 24; - if (month_days (t) < (t->tm_mday += days)) - { - if (11 < ++t->tm_mon) - { - ++t->tm_year; - t->tm_mon = 0; - } - t->tm_mday = 1; - } - } - } - if (TM_DEFINED (t->tm_wday)) - t->tm_wday = MOD (t->tm_wday + days, 7); - t->tm_hour = MOD (t->tm_hour, 24); - t->tm_min = MOD (t->tm_min, 60); - t->tm_sec = (int) MOD (sec, 60) + leap_second; -} - -/* Convert TM to time_t, using localtime if LOCALZONE and gmtime otherwise. - Use only TM's year, mon, mday, hour, min, and sec members. - Ignore TM's old tm_yday and tm_wday, but fill in their correct values. - Yield -1 on failure (e.g. a member out of range). - POSIX 1003.1 doesn't allow leap seconds, but some implementations - have them anyway, so allow them if localtime/gmtime does. */ -time_t -tm2time (tm, localzone) - struct tm *tm; - int localzone; -{ - /* Cache the most recent t,tm pairs; 1 for gmtime, 1 for localtime. */ - static time_t t_cache[2]; - static struct tm tm_cache[2]; - - time_t d, gt; - struct tm const *gtm; - /* The maximum number of iterations should be enough to handle any - combinations of leap seconds, time zone rule changes, and solar time. - 4 is probably enough; we use a bigger number just to be safe. */ - int remaining_tries = 8; - - /* Avoid subscript errors. */ - if (12 <= (unsigned) tm->tm_mon) - return -1; - - tm->tm_yday = month_yday[tm->tm_mon] + tm->tm_mday - - (tm->tm_mon < 2 || !isleap (tm->tm_year + TM_YEAR_ORIGIN)); - - /* Make a first guess. */ - gt = t_cache[localzone]; - gtm = gt ? &tm_cache[localzone] : time2tm (gt, localzone); - - /* Repeatedly use the error from the guess to improve the guess. */ - while ((d = difftm (tm, gtm)) != 0) - { - if (--remaining_tries == 0) - return -1; - gt += d; - gtm = time2tm (gt, localzone); - } - - /* Check that the guess actually matches; - overflow can cause difftm to yield 0 even on differing times, - or tm may have members out of range (e.g. bad leap seconds). */ -#define TM_DIFFER(a,b) \ - ( \ - ((a)->tm_year ^ (b)->tm_year) | \ - ((a)->tm_mon ^ (b)->tm_mon) | \ - ((a)->tm_mday ^ (b)->tm_mday) | \ - ((a)->tm_hour ^ (b)->tm_hour) | \ - ((a)->tm_min ^ (b)->tm_min) | \ - ((a)->tm_sec ^ (b)->tm_sec) \ - ) - if (TM_DIFFER (tm, gtm)) - { - /* If gt is a leap second, try gt+1; if it is one greater than - a leap second, try gt-1; otherwise, it doesn't matter. - Leap seconds always fall at month end. */ - int yd = tm->tm_year - gtm->tm_year; - gt += yd + (yd ? 0 : tm->tm_mon - gtm->tm_mon); - gtm = time2tm (gt, localzone); - if (TM_DIFFER (tm, gtm)) - return -1; - } - t_cache[localzone] = gt; - tm_cache[localzone] = *gtm; - - tm->tm_wday = gtm->tm_wday; - return gt; -} - -/* Check *PT and convert it to time_t. - If it is incompletely specified, use DEFAULT_TIME to fill it out. - Use localtime if PT->zone is the special value TM_LOCAL_ZONE. - Yield -1 on failure. - ISO 8601 day-of-year and week numbers are not yet supported. */ -static time_t -maketime (pt, default_time) - struct partime const *pt; - time_t default_time; -{ - int localzone, wday, year; - struct tm tm; - struct tm *tm0 = 0; - time_t r; - int use_ordinal_day; - - tm0 = 0; /* Keep gcc -Wall happy. */ - localzone = pt->zone == TM_LOCAL_ZONE; - - tm = pt->tm; - year = tm.tm_year; - wday = tm.tm_wday; - use_ordinal_day = (!TM_DEFINED (tm.tm_mday) - && TM_DEFINED (wday) && TM_DEFINED (pt->wday_ordinal)); - - if (use_ordinal_day || TM_DEFINED (pt->ymodulus) || !TM_DEFINED (year)) - { - /* Get tm corresponding to default time. */ - tm0 = time2tm (default_time, localzone); - if (!localzone) - adjzone (tm0, pt->zone); - } - - if (use_ordinal_day) - tm.tm_mday = (tm0->tm_mday - + ((wday - tm0->tm_wday + 7) % 7 - + 7 * (pt->wday_ordinal - (pt->wday_ordinal != 0)))); - - if (TM_DEFINED (pt->ymodulus)) - { - /* Yield a year closest to the default that has the given modulus. */ - int year0 = tm0->tm_year + TM_YEAR_ORIGIN; - int y0 = MOD (year0, pt->ymodulus); - int d = 2 * (year - y0); - year += (((year0 - y0) / pt->ymodulus - + (pt->ymodulus < d ? -1 : d < -pt->ymodulus)) - * pt->ymodulus); - } - else if (!TM_DEFINED (year)) - { - /* Set default year, month, day from current time. */ - year = tm0->tm_year + TM_YEAR_ORIGIN; - if (!TM_DEFINED (tm.tm_mon)) - { - tm.tm_mon = tm0->tm_mon; - if (!TM_DEFINED (tm.tm_mday)) - tm.tm_mday = tm0->tm_mday; - } - } - - /* Set remaining default fields to be their minimum values. */ - if (!TM_DEFINED (tm.tm_mon)) - tm.tm_mon = 0; - if (!TM_DEFINED (tm.tm_mday)) - tm.tm_mday = 1; - if (!TM_DEFINED (tm.tm_hour)) - tm.tm_hour = 0; - if (!TM_DEFINED (tm.tm_min)) - tm.tm_min = 0; - if (!TM_DEFINED (tm.tm_sec)) - tm.tm_sec = 0; - - tm.tm_year = year - TM_YEAR_ORIGIN; - if ((year < tm.tm_year) != (TM_YEAR_ORIGIN < 0)) - return -1; - - if (!localzone) - { - adjzone (&tm, -pt->zone); - wday = tm.tm_wday; - } - - /* Convert and fill in the rest of the tm. */ - r = tm2time (&tm, localzone); - if (r == -1) - return r; - - /* Check weekday. */ - if (TM_DEFINED (wday) && wday != tm.tm_wday) - return -1; - - /* Add relative time, except for seconds. - We handle seconds separately, at the end, - so that leap seconds are handled properly. */ - if (pt->tmr.tm_year | pt->tmr.tm_mon | pt->tmr.tm_mday - | pt->tmr.tm_hour | pt->tmr.tm_min) - { - int years = tm.tm_year + pt->tmr.tm_year; - int mons = tm.tm_mon + pt->tmr.tm_mon; - int mdays = tm.tm_mday + pt->tmr.tm_mday; - int hours = tm.tm_hour + pt->tmr.tm_hour; - int mins = tm.tm_min + pt->tmr.tm_min; - - int carried_hours = DIV (mins, 60); - int hours1 = hours + carried_hours; - int carried_days = DIV (hours1, 24); - int mdays1 = mdays + carried_days; - - int mon0 = MOD (mons, 12); - int carried_years0 = DIV (mons, 12); - int year0 = years + carried_years0; - int yday0 = (month_yday[mon0] - - (mon0 < 2 || !isleap (year0 + TM_YEAR_ORIGIN))); - - int yday1 = yday0 + mdays1; - int carried_years1 = DIV (yday1, Y400_DAYS) * 400; - int year1 = year0 + carried_years1; - int yday2 = MOD (yday1, Y400_DAYS); - int leap; - - if (overflow_sum_sign (tm.tm_year, pt->tmr.tm_year, years) - | overflow_sum_sign (tm.tm_mon, pt->tmr.tm_mon, mons) - | overflow_sum_sign (tm.tm_mday, pt->tmr.tm_mday, mdays) - | overflow_sum_sign (tm.tm_hour, pt->tmr.tm_hour, hours) - | overflow_sum_sign (tm.tm_min, pt->tmr.tm_min, mins) - | overflow_sum_sign (hours, carried_hours, hours1) - | overflow_sum_sign (mdays, carried_days, mdays1) - | overflow_sum_sign (years, carried_years0, year0) - | overflow_sum_sign (yday0, mdays1, yday1) - | overflow_sum_sign (year0, carried_years1, year1)) - return -1; - - for (;;) - { - int days_per_year = 365 + (leap = isleap (year1 + TM_YEAR_ORIGIN)); - if (yday2 < days_per_year) - break; - yday2 -= days_per_year; - year1++; - } - - tm.tm_year = year1; - - { - int mon; - for (mon = 11; - (tm.tm_mday = (yday2 - month_yday[mon] + (mon < 2 || !leap))) <= 0; - mon--) - continue; - tm.tm_mon = mon; - } - - tm.tm_hour = MOD (hours1, 24); - tm.tm_min = MOD (mins, 60); - - r = tm2time (&tm, localzone); - if (r == -1) - return r; - } - - /* Add the seconds' part of relative time. */ - { - time_t rs = r + pt->tmr.tm_sec; - if ((pt->tmr.tm_sec < 0) != (rs < r)) - return -1; - return rs; - } -} - -/* Parse a free-format date in *SOURCE, yielding a Unix format time. - Update *SOURCE to point to the first character after the date. - If *SOURCE is missing some information, take defaults from - DEFAULT_TIME and DEFAULT_ZONE. *SOURCE may even be the empty - string or an immediately invalid string, in which case the default - time and zone is used. - Return (time_t) -1 if the time is invalid or cannot be represented. */ -time_t -str2time (source, default_time, default_zone) - char const **source; - time_t default_time; - long default_zone; -{ - struct partime pt; - - *source = partime (*source, &pt); - if (pt.zone == TM_UNDEFINED_ZONE) - pt.zone = default_zone; - return maketime (&pt, default_time); -} - -#ifdef TEST -#include -int -main (argc, argv) - int argc; - char **argv; -{ - time_t default_time = time ((time_t *) 0); - long default_zone = argv[1] ? atol (argv[1]) : TM_LOCAL_ZONE; - char buf[1000]; - while (fgets (buf, sizeof (buf), stdin)) - { - char const *p = buf; - time_t t = str2time (&p, default_time, default_zone); - printf ("`%.*s' -> %s", - (int) (p - buf - (p[0] == '\0' && p[-1] == '\n')), buf, - asctime ((argv[1] ? gmtime : localtime) (&t))); - } - return 0; -} -#endif diff --git a/src/bin/patch/maketime.h b/src/bin/patch/maketime.h deleted file mode 100644 index 2f977c452c..0000000000 --- a/src/bin/patch/maketime.h +++ /dev/null @@ -1,39 +0,0 @@ -/* Yield time_t from struct partime yielded by partime. */ - -/* Copyright 1993, 1994, 1995 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - - This file is part of RCS. - - RCS 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. - - RCS 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 RCS; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - - */ - -#if defined __STDC__ || has_prototypes -# define __MAKETIME_P(x) x -#else -# define __MAKETIME_P(x) () -#endif - -struct tm *time2tm __MAKETIME_P ((time_t, int)); -time_t difftm __MAKETIME_P ((struct tm const *, struct tm const *)); -time_t str2time __MAKETIME_P ((char const **, time_t, long)); -time_t tm2time __MAKETIME_P ((struct tm *, int)); -void adjzone __MAKETIME_P ((struct tm *, long)); diff --git a/src/bin/patch/partime.c b/src/bin/patch/partime.c deleted file mode 100644 index e905e25c7d..0000000000 --- a/src/bin/patch/partime.c +++ /dev/null @@ -1,956 +0,0 @@ -/* Parse a string, yielding a struct partime that describes it. */ - -/* Copyright 1993, 1994, 1995, 1997 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - - This file is part of RCS. - - RCS 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. - - RCS 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 RCS; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - - */ - -#if has_conf_h -# include -#else -# if HAVE_CONFIG_H -# include -# else -# ifndef __STDC__ -# define const -# endif -# endif -# if HAVE_LIMITS_H -# include -# endif -# ifndef LONG_MIN -# define LONG_MIN (-1-2147483647L) -# endif -# if HAVE_STDDEF_H -# include -# endif -# if STDC_HEADERS -# include -# endif -# include -# ifdef __STDC__ -# define P(x) x -# else -# define P(x) () -# endif -#endif - -#ifndef offsetof -#define offsetof(aggregate, member) ((size_t) &((aggregate *) 0)->member) -#endif - -#include -#if STDC_HEADERS -# define CTYPE_DOMAIN(c) 1 -#else -# define CTYPE_DOMAIN(c) ((unsigned) (c) <= 0177) -#endif -#define ISALNUM(c) (CTYPE_DOMAIN (c) && isalnum (c)) -#define ISALPHA(c) (CTYPE_DOMAIN (c) && isalpha (c)) -#define ISSPACE(c) (CTYPE_DOMAIN (c) && isspace (c)) -#define ISUPPER(c) (CTYPE_DOMAIN (c) && isupper (c)) -#define ISDIGIT(c) ((unsigned) (c) - '0' <= 9) - -#include - -char const partime_id[] = - "$Id: partime.c 8008 2004-06-16 21:22:10Z korli $"; - - -/* Lookup tables for names of months, weekdays, time zones. */ - -#define NAME_LENGTH_MAXIMUM 4 - -struct name_val - { - char name[NAME_LENGTH_MAXIMUM]; - int val; - }; - - -static char const *parse_decimal P ((char const *, int, int, int, int, int *, int *)); -static char const *parse_fixed P ((char const *, int, int *)); -static char const *parse_pattern_letter P ((char const *, int, struct partime *)); -static char const *parse_prefix P ((char const *, char const **, struct partime *)); -static char const *parse_ranged P ((char const *, int, int, int, int *)); -static char const *parse_varying P ((char const *, int *)); -static int lookup P ((char const *, struct name_val const[])); -static int merge_partime P ((struct partime *, struct partime const *)); -static void undefine P ((struct partime *)); - - -static struct name_val const month_names[] = -{ - {"jan", 0}, - {"feb", 1}, - {"mar", 2}, - {"apr", 3}, - {"may", 4}, - {"jun", 5}, - {"jul", 6}, - {"aug", 7}, - {"sep", 8}, - {"oct", 9}, - {"nov", 10}, - {"dec", 11}, - {"", TM_UNDEFINED} -}; - -static struct name_val const weekday_names[] = -{ - {"sun", 0}, - {"mon", 1}, - {"tue", 2}, - {"wed", 3}, - {"thu", 4}, - {"fri", 5}, - {"sat", 6}, - {"", TM_UNDEFINED} -}; - -#define RELATIVE_CONS(member, multiplier) \ - (offsetof (struct tm, member) + (multiplier) * sizeof (struct tm)) -#define RELATIVE_OFFSET(c) ((c) % sizeof (struct tm)) -#define RELATIVE_MULTIPLIER(c) ((c) / sizeof (struct tm)) -static struct name_val const relative_units[] = -{ - {"year", RELATIVE_CONS (tm_year, 1) }, - {"mont", RELATIVE_CONS (tm_mon , 1) }, - {"fort", RELATIVE_CONS (tm_mday, 14) }, - {"week", RELATIVE_CONS (tm_mday, 7) }, - {"day" , RELATIVE_CONS (tm_mday, 1) }, - {"hour", RELATIVE_CONS (tm_hour, 1) }, - {"min" , RELATIVE_CONS (tm_min , 1) }, - {"sec" , RELATIVE_CONS (tm_sec , 1) }, - {"", TM_UNDEFINED} -}; - -static struct name_val const ago[] = -{ - {"ago", 0}, - {"", TM_UNDEFINED} -}; - -static struct name_val const dst_names[] = -{ - {"dst", 1}, - {"", 0} -}; - -#define hr60nonnegative(t) ((t)/100 * 60 + (t)%100) -#define hr60(t) ((t) < 0 ? - hr60nonnegative (-(t)) : hr60nonnegative (t)) -#define zs(t, s) {s, hr60 (t)} -#define zd(t, s, d) zs (t, s), zs ((t) + 100, d) - -static struct name_val const zone_names[] = -{ - zs (-1000, "hst"), /* Hawaii */ - zd (-1000, "hast", "hadt"), /* Hawaii-Aleutian */ - zd (- 900, "akst", "akdt"), /* Alaska */ - zd (- 800, "pst" , "pdt" ), /* Pacific */ - zd (- 700, "mst" , "mdt" ), /* Mountain */ - zd (- 600, "cst" , "cdt" ), /* Central */ - zd (- 500, "est" , "edt" ), /* Eastern */ - zd (- 400, "ast" , "adt" ), /* Atlantic */ - zd (- 330, "nst" , "ndt" ), /* Newfoundland */ - zs ( 000, "utc" ), /* Coordinated Universal */ - zs ( 000, "uct" ), /* " */ - zs ( 000, "cut" ), /* " */ - zs ( 000, "ut"), /* Universal */ - zs ( 000, "z"), /* Zulu (required by ISO 8601) */ - zd ( 000, "gmt" , "bst" ), /* Greenwich Mean, British Summer */ - zd ( 000, "wet" , "west"), /* Western European */ - zd ( 100, "cet" , "cest"), /* Central European */ - zd ( 100, "met" , "mest"), /* Middle European (bug in old tz versions) */ - zd ( 100, "mez" , "mesz"), /* Mittel-Europaeische Zeit */ - zd ( 200, "eet" , "eest"), /* Eastern European */ - zs ( 530, "ist" ), /* India */ - zd ( 900, "jst" , "jdt" ), /* Japan */ - zd ( 900, "kst" , "kdt" ), /* Korea */ - zd ( 1200, "nzst", "nzdt"), /* New Zealand */ - {"lt", 1}, -#if 0 - /* The following names are duplicates or are not well attested. - It's not worth keeping a complete list, since alphabetic time zone names - are deprecated and there are lots more where these came from. */ - zs (-1100, "sst" ), /* Samoan */ - zd (- 900, "yst" , "ydt" ), /* Yukon - name is no longer used */ - zd (- 500, "ast" , "adt" ), /* Acre */ - zd (- 400, "wst" , "wdt" ), /* Western Brazil */ - zd (- 400, "cst" , "cdt" ), /* Chile */ - zd (- 200, "fst" , "fdt" ), /* Fernando de Noronha */ - zs ( 000, "wat" ), /* West African */ - zs ( 100, "cat" ), /* Central African */ - zs ( 200, "sat" ), /* South African */ - zd ( 200, "ist" , "idt" ), /* Israel */ - zs ( 300, "eat" ), /* East African */ - zd ( 300, "msk" , "msd" ), /* Moscow */ - zd ( 330, "ist" , "idt" ), /* Iran */ - zs ( 800, "hkt" ), /* Hong Kong */ - zs ( 800, "sgt" ), /* Singapore */ - zd ( 800, "cst" , "cdt" ), /* China */ - zd ( 800, "wst" , "wst" ), /* Western Australia */ - zd ( 930, "cst" , "cst" ), /* Central Australia */ - zs ( 1000, "gst" ), /* Guam */ - zd ( 1000, "est" , "est" ), /* Eastern Australia */ -#endif - {"", -1} -}; - -/* Look for a prefix of S in TABLE, returning val for first matching entry. */ -static int -lookup (s, table) - char const *s; - struct name_val const table[]; -{ - int j; - char buf[NAME_LENGTH_MAXIMUM]; - - for (j = 0; j < NAME_LENGTH_MAXIMUM; j++) - { - unsigned char c = *s; - if (! ISALPHA (c)) - { - buf[j] = '\0'; - break; - } - buf[j] = ISUPPER (c) ? tolower (c) : c; - s++; - s += *s == '.'; - } - - for (;; table++) - for (j = 0; ; j++) - if (j == NAME_LENGTH_MAXIMUM || ! table[0].name[j]) - return table[0].val; - else if (buf[j] != table[0].name[j]) - break; -} - - -/* Set *T to ``undefined'' values. */ -static void -undefine (t) - struct partime *t; -{ - t->tm.tm_sec = t->tm.tm_min = t->tm.tm_hour = t->tm.tm_mday = t->tm.tm_mon - = t->tm.tm_year = t->tm.tm_wday = t->tm.tm_yday - = t->wday_ordinal = t->ymodulus = t->yweek - = TM_UNDEFINED; - t->tmr.tm_sec = t->tmr.tm_min = t->tmr.tm_hour = - t->tmr.tm_mday = t->tmr.tm_mon = t->tmr.tm_year = 0; - t->zone = TM_UNDEFINED_ZONE; -} - -/* Patterns to look for in a time string. - Order is important: we look for the first matching pattern - whose values do not contradict values that we already know about. - See `parse_pattern_letter' below for the meaning of the pattern codes. */ -static char const time_patterns[] = -{ - /* Traditional patterns come first, - to prevent an ISO 8601 format from misinterpreting their prefixes. */ - - /* RFC 822, extended */ - 'E', '_', 'N', '_', 'y', '$', 0, - 'x', 0, - - /* traditional */ - '4', '_', 'M', '_', 'D', '_', 'h', '_', 'm', '_', 's', '$', 0, - 'R', '_', 'M', '_', 'D', '_', 'h', '_', 'm', '_', 's', '$', 0, - 'E', '_', 'N', 0, - 'N', '_', 'E', '_', 'y', ';', 0, - 'N', '_', 'E', ';', 0, - 'N', 0, - 't', ':', 'm', ':', 's', '_', 'A', 0, - 't', ':', 'm', '_', 'A', 0, - 't', '_', 'A', 0, - - /* traditional get_date */ - 'i', '_', 'x', 0, - 'Y', '/', 'n', '/', 'E', ';', 0, - 'n', '/', 'E', '/', 'y', ';', 0, - 'n', '/', 'E', ';', 0, - 'u', 0, - - /* ISO 8601:1988 formats, generalized a bit. */ - 'y', '-', 'M', '-', 'D', '$', 0, - '4', 'M', 'D', '$', 0, - 'Y', '-', 'M', '$', 0, - 'R', 'M', 'D', '$', 0, - '-', 'R', '=', 'M', '$', 0, - '-', 'R', '$', 0, - '-', '-', 'M', '=', 'D', '$', 0, - 'M', '=', 'D', 'T', 0, - '-', '-', 'M', '$', 0, - '-', '-', '-', 'D', '$', 0, - 'D', 'T', 0, - 'Y', '-', 'd', '$', 0, - '4', 'd', '$', 0, - 'R', '=', 'd', '$', 0, - '-', 'd', '$', 0, - 'd', 'T', 0, - 'y', '-', 'W', '-', 'X', 0, - 'y', 'W', 'X', 0, - 'y', '=', 'W', 0, - '-', 'r', '-', 'W', '-', 'X', 0, - 'r', '-', 'W', '-', 'X', 'T', 0, - '-', 'r', 'W', 'X', 0, - 'r', 'W', 'X', 'T', 0, - '-', 'W', '=', 'X', 0, - 'W', '=', 'X', 'T', 0, - '-', 'W', 0, - '-', 'w', '-', 'X', 0, - 'w', '-', 'X', 'T', 0, - '-', '-', '-', 'X', '$', 0, - 'X', 'T', 0, - '4', '$', 0, - 'T', 0, - 'h', ':', 'm', ':', 's', '$', 0, - 'h', 'm', 's', '$', 0, - 'h', ':', 'L', '$', 0, - 'h', 'L', '$', 0, - 'H', '$', 0, - '-', 'm', ':', 's', '$', 0, - '-', 'm', 's', '$', 0, - '-', 'L', '$', 0, - '-', '-', 's', '$', 0, - 'Y', 0, - 'Z', 0, - - 0 -}; - -/* Parse an initial prefix of STR according to *PATTERNS, setting *T. - Return the first character after the prefix, or 0 if it couldn't be parsed. - *PATTERNS is a character array containing one pattern string after another; - it is terminated by an empty string. - If success, set *PATTERNS to the next pattern to try. - Set *PATTERNS to 0 if we know there are no more patterns to try; - if *PATTERNS is initially 0, give up immediately. */ -static char const * -parse_prefix (str, patterns, t) - char const *str; - char const **patterns; - struct partime *t; -{ - char const *pat = *patterns; - unsigned char c; - - if (! pat) - return 0; - - /* Remove initial noise. */ - while (! ISALNUM (c = *str) && c != '-' && c != '+') - { - if (! c) - { - undefine (t); - *patterns = 0; - return str; - } - - str++; - } - - /* Try a pattern until one succeeds. */ - while (*pat) - { - char const *s = str; - undefine (t); - - do - { - if (! (c = *pat++)) - { - *patterns = pat; - return s; - } - } - while ((s = parse_pattern_letter (s, c, t)) != 0); - - while (*pat++) - continue; - } - - return 0; -} - -/* Parse an initial prefix of S of length DIGITS; it must be a number. - Store the parsed number into *RES. - Return the first character after the prefix, or 0 if it wasn't parsed. */ -static char const * -parse_fixed (s, digits, res) - char const *s; - int digits, *res; -{ - int n = 0; - char const *lim = s + digits; - while (s < lim) - { - unsigned d = *s++ - '0'; - if (9 < d) - return 0; - n = 10 * n + d; - } - *res = n; - return s; -} - -/* Parse a possibly empty initial prefix of S. - Store the parsed number into *RES. - Return the first character after the prefix. */ -static char const * -parse_varying (s, res) - char const *s; - int *res; -{ - int n = 0; - for (;;) - { - unsigned d = *s - '0'; - if (9 < d) - break; - s++; - n = 10 * n + d; - } - *res = n; - return s; -} - -/* Parse an initial prefix of S of length DIGITS; - it must be a number in the range LO through HI. - Store the parsed number into *RES. - Return the first character after the prefix, or 0 if it wasn't parsed. */ -static char const * -parse_ranged (s, digits, lo, hi, res) - char const *s; - int digits, lo, hi, *res; -{ - s = parse_fixed (s, digits, res); - return s && lo <= *res && *res <= hi ? s : 0; -} - -/* Parse an initial prefix of S of length DIGITS; - it must be a number in the range LO through HI - and it may be followed by a fraction to be computed using RESOLUTION. - Store the parsed number into *RES; store the fraction times RESOLUTION, - rounded to the nearest integer, into *FRES. - Return the first character after the prefix, or 0 if it wasn't parsed. */ -static char const * -parse_decimal (s, digits, lo, hi, resolution, res, fres) - char const *s; - int digits, lo, hi, resolution, *res, *fres; -{ - s = parse_fixed (s, digits, res); - if (s && lo <= *res && *res <= hi) - { - int f = 0; - if ((s[0] == ',' || s[0] == '.') && ISDIGIT (s[1])) - { - char const *s1 = ++s; - int num10 = 0, denom10 = 10, product; - while (ISDIGIT (*++s)) - { - int d = denom10 * 10; - if (d / 10 != denom10) - return 0; /* overflow */ - denom10 = d; - } - s = parse_fixed (s1, (int) (s - s1), &num10); - product = num10 * resolution; - f = (product + (denom10 >> 1)) / denom10; - f -= f & (product % denom10 == denom10 >> 1); /* round to even */ - if (f < 0 || product/resolution != num10) - return 0; /* overflow */ - } - *fres = f; - return s; - } - return 0; -} - -/* Parse an initial prefix of S; it must denote a time zone. - Set *ZONE to the number of seconds east of GMT, - or to TM_LOCAL_ZONE if it is the local time zone. - Return the first character after the prefix, or 0 if it wasn't parsed. */ -char * -parzone (s, zone) - char const *s; - long *zone; -{ - char const *s1; - char sign; - int hh, mm, ss; - int minutes_east_of_UTC; - int trailing_DST; - long offset, z; - - /* The formats are LT, n, n DST, nDST, no, o - where n is a time zone name - and o is a time zone offset of the form [-+]hh[:mm[:ss]]. */ - switch (*s) - { - case '-': - case '+': - z = 0; - break; - - default: - minutes_east_of_UTC = lookup (s, zone_names); - if (minutes_east_of_UTC == -1) - return 0; - - /* Don't bother to check rest of spelling, - but look for an embedded "DST". */ - trailing_DST = 0; - while (ISALPHA ((unsigned char) *s)) - { - if ((*s == 'D' || *s == 'd') && lookup (s, dst_names)) - trailing_DST = 1; - s++; - s += *s == '.'; - } - - /* Don't modify LT. */ - if (minutes_east_of_UTC == 1) - { - *zone = TM_LOCAL_ZONE; - return (char *) s; - } - - z = minutes_east_of_UTC * 60L; - s1 = s; - - /* Look for trailing "DST" or " DST". */ - while (ISSPACE ((unsigned char) *s)) - s++; - if (lookup (s, dst_names)) - { - while (ISALPHA ((unsigned char) *s)) - { - s++; - s += *s == '.'; - } - trailing_DST = 1; - } - - if (trailing_DST) - { - *zone = z + 60*60; - return (char *) s; - } - - s = s1; - - switch (*s) - { - case '-': - case '+': - break; - - default: - *zone = z; - return (char *) s; - } - - break; - } - - sign = *s++; - - if (! (s = parse_ranged (s, 2, 0, 23, &hh))) - return 0; - mm = ss = 0; - if (*s == ':') - s++; - if (ISDIGIT (*s)) - { - if (! (s = parse_ranged (s, 2, 0, 59, &mm))) - return 0; - if (*s == ':' && s[-3] == ':' && ISDIGIT (s[1]) - && ! (s = parse_ranged (s + 1, 2, 0, 59, &ss))) - return 0; - } - if (ISDIGIT (*s)) - return 0; - offset = (hh * 60 + mm) * 60L + ss; - *zone = z + (sign == '-' ? -offset : offset); - /* ?? Are fractions allowed here? If so, they're not implemented. */ - return (char *) s; -} - -/* Parse an initial prefix of S, matching the pattern whose code is C. - Set *T accordingly. - Return the first character after the prefix, or 0 if it wasn't parsed. */ -static char const * -parse_pattern_letter (s, c, t) - char const *s; - int c; - struct partime *t; -{ - char const *s0 = s; - - switch (c) - { - case '$': /* The next character must be a non-digit. */ - if (ISDIGIT (*s)) - return 0; - break; - - case '-': - case '/': - case ':': - /* These characters stand for themselves. */ - if (*s++ != c) - return 0; - break; - - case '4': /* 4-digit year */ - s = parse_fixed (s, 4, &t->tm.tm_year); - break; - - case ';': /* The next character must be a non-digit, and cannot be ':'. */ - if (ISDIGIT (*s) || *s == ':') - return 0; - break; - - case '=': /* optional '-' */ - s += *s == '-'; - break; - - case 'A': /* AM or PM */ - /* This matches the regular expression [AaPp]\.?([Mm]\.?)?. - It must not be followed by a letter or digit; - otherwise it would match prefixes of strings like "PST". */ - switch (*s) - { - case 'A': - case 'a': - if (t->tm.tm_hour == 12) - t->tm.tm_hour = 0; - break; - - case 'P': - case 'p': - if (t->tm.tm_hour != 12) - t->tm.tm_hour += 12; - break; - - default: - return 0; - } - s++; - s += *s == '.'; - switch (*s) - { - case 'M': - case 'm': - s++; - s += *s == '.'; - break; - } - if (ISALNUM ((unsigned char) *s)) - return 0; - break; - - case 'D': /* day of month [01-31] */ - s = parse_ranged (s, 2, 1, 31, &t->tm.tm_mday); - break; - - case 'd': /* day of year [001-366] */ - s = parse_ranged (s, 3, 1, 366, &t->tm.tm_yday); - t->tm.tm_yday--; - break; - - case 'E': /* traditional day of month [1-9, 01-31] */ - s = parse_ranged (s, (ISDIGIT (s[0]) && ISDIGIT (s[1])) + 1, 1, 31, - &t->tm.tm_mday); - break; - - case 'h': /* hour [00-23] */ - s = parse_ranged (s, 2, 0, 23, &t->tm.tm_hour); - break; - - case 'H': /* hour [00-23 followed by optional fraction] */ - { - int frac; - s = parse_decimal (s, 2, 0, 23, 60 * 60, &t->tm.tm_hour, &frac); - t->tm.tm_min = frac / 60; - t->tm.tm_sec = frac % 60; - } - break; - - case 'i': /* ordinal day number, e.g. "3rd" */ - s = parse_varying (s, &t->wday_ordinal); - if (s == s0) - return 0; - while (ISALPHA ((unsigned char) *s)) - s++; - break; - - case 'L': /* minute [00-59 followed by optional fraction] */ - s = parse_decimal (s, 2, 0, 59, 60, &t->tm.tm_min, &t->tm.tm_sec); - break; - - case 'm': /* minute [00-59] */ - s = parse_ranged (s, 2, 0, 59, &t->tm.tm_min); - break; - - case 'M': /* month [01-12] */ - s = parse_ranged (s, 2, 1, 12, &t->tm.tm_mon); - t->tm.tm_mon--; - break; - - case 'n': /* traditional month [1-9, 01-12] */ - s = parse_ranged (s, (ISDIGIT (s[0]) && ISDIGIT (s[1])) + 1, 1, 12, - &t->tm.tm_mon); - t->tm.tm_mon--; - break; - - case 'N': /* month name [e.g. "Jan"] */ - if (! TM_DEFINED (t->tm.tm_mon = lookup (s, month_names))) - return 0; - /* Don't bother to check rest of spelling. */ - while (ISALPHA ((unsigned char) *s)) - s++; - break; - - case 'r': /* year % 10 (remainder in origin-0 decade) [0-9] */ - s = parse_fixed (s, 1, &t->tm.tm_year); - t->ymodulus = 10; - break; - - case_R: - case 'R': /* year % 100 (remainder in origin-0 century) [00-99] */ - s = parse_fixed (s, 2, &t->tm.tm_year); - t->ymodulus = 100; - break; - - case 's': /* second [00-60 followed by optional fraction] */ - { - int frac; - s = parse_decimal (s, 2, 0, 60, 1, &t->tm.tm_sec, &frac); - t->tm.tm_sec += frac; - } - break; - - case 'T': /* 'T' or 't' */ - switch (*s++) - { - case 'T': - case 't': - break; - default: - return 0; - } - break; - - case 't': /* traditional hour [1-9 or 01-12] */ - s = parse_ranged (s, (ISDIGIT (s[0]) && ISDIGIT (s[1])) + 1, 1, 12, - &t->tm.tm_hour); - break; - - case 'u': /* relative unit */ - { - int i; - int n; - int negative = 0; - switch (*s) - { - case '-': negative = 1; - /* Fall through. */ - case '+': s++; - } - if (ISDIGIT (*s)) - s = parse_varying (s, &n); - else if (s == s0) - n = 1; - else - return 0; - if (negative) - n = -n; - while (!ISALNUM ((unsigned char) *s)) - s++; - i = lookup (s, relative_units); - if (!TM_DEFINED (i)) - return 0; - * (int *) ((char *) &t->tmr + RELATIVE_OFFSET (i)) - += n * RELATIVE_MULTIPLIER (i); - while (ISALPHA ((unsigned char) *s)) - s++; - while (! ISALNUM ((unsigned char) *s) && *s) - s++; - if (TM_DEFINED (lookup (s, ago))) - { - t->tmr.tm_sec = - t->tmr.tm_sec; - t->tmr.tm_min = - t->tmr.tm_min; - t->tmr.tm_hour = - t->tmr.tm_hour; - t->tmr.tm_mday = - t->tmr.tm_mday; - t->tmr.tm_mon = - t->tmr.tm_mon; - t->tmr.tm_year = - t->tmr.tm_year; - while (ISALPHA ((unsigned char) *s)) - s++; - } - break; - } - - case 'w': /* 'W' or 'w' only (stands for current week) */ - switch (*s++) - { - case 'W': - case 'w': - break; - default: - return 0; - } - break; - - case 'W': /* 'W' or 'w', followed by a week of year [00-53] */ - switch (*s++) - { - case 'W': - case 'w': - break; - default: - return 0; - } - s = parse_ranged (s, 2, 0, 53, &t->yweek); - break; - - case 'X': /* weekday (1=Mon ... 7=Sun) [1-7] */ - s = parse_ranged (s, 1, 1, 7, &t->tm.tm_wday); - t->tm.tm_wday--; - break; - - case 'x': /* weekday name [e.g. "Sun"] */ - if (! TM_DEFINED (t->tm.tm_wday = lookup (s, weekday_names))) - return 0; - /* Don't bother to check rest of spelling. */ - while (ISALPHA ((unsigned char) *s)) - s++; - break; - - case 'y': /* either R or Y */ - if (ISDIGIT (s[0]) && ISDIGIT (s[1]) && ! ISDIGIT (s[2])) - goto case_R; - /* fall into */ - case 'Y': /* year in full [4 or more digits] */ - s = parse_varying (s, &t->tm.tm_year); - if (s - s0 < 4) - return 0; - break; - - case 'Z': /* time zone */ - s = parzone (s, &t->zone); - break; - - case '_': /* possibly empty sequence of non-alphanumerics */ - while (! ISALNUM ((unsigned char) *s) && *s) - s++; - break; - - default: /* bad pattern */ - return 0; - } - - return s; -} - -/* If there is no conflict, merge into *T the additional information in *U - and return 0. Otherwise do nothing and return -1. */ -static int -merge_partime (t, u) - struct partime *t; - struct partime const *u; -{ -# define conflict(a,b) ((a) != (b) && TM_DEFINED (a) && TM_DEFINED (b)) - if (conflict (t->tm.tm_sec, u->tm.tm_sec) - || conflict (t->tm.tm_min, u->tm.tm_min) - || conflict (t->tm.tm_hour, u->tm.tm_hour) - || conflict (t->tm.tm_mday, u->tm.tm_mday) - || conflict (t->tm.tm_mon, u->tm.tm_mon) - || conflict (t->tm.tm_year, u->tm.tm_year) - || conflict (t->tm.tm_wday, u->tm.tm_wday) - || conflict (t->tm.tm_yday, u->tm.tm_yday) - || conflict (t->ymodulus, u->ymodulus) - || conflict (t->yweek, u->yweek) - || (t->zone != u->zone - && t->zone != TM_UNDEFINED_ZONE - && u->zone != TM_UNDEFINED_ZONE)) - return -1; -# undef conflict -# define merge_(a,b) if (TM_DEFINED (b)) (a) = (b); - merge_ (t->tm.tm_sec, u->tm.tm_sec) - merge_ (t->tm.tm_min, u->tm.tm_min) - merge_ (t->tm.tm_hour, u->tm.tm_hour) - merge_ (t->tm.tm_mday, u->tm.tm_mday) - merge_ (t->tm.tm_mon, u->tm.tm_mon) - merge_ (t->tm.tm_year, u->tm.tm_year) - merge_ (t->tm.tm_wday, u->tm.tm_wday) - merge_ (t->tm.tm_yday, u->tm.tm_yday) - merge_ (t->ymodulus, u->ymodulus) - merge_ (t->yweek, u->yweek) -# undef merge_ - t->tmr.tm_sec += u->tmr.tm_sec; - t->tmr.tm_min += u->tmr.tm_min; - t->tmr.tm_hour += u->tmr.tm_hour; - t->tmr.tm_mday += u->tmr.tm_mday; - t->tmr.tm_mon += u->tmr.tm_mon; - t->tmr.tm_year += u->tmr.tm_year; - if (u->zone != TM_UNDEFINED_ZONE) - t->zone = u->zone; - return 0; -} - -/* Parse a date/time prefix of S, putting the parsed result into *T. - Return the first character after the prefix. - The prefix may contain no useful information; - in that case, *T will contain only undefined values. */ -char * -partime (s, t) - char const *s; - struct partime *t; -{ - struct partime p; - - undefine (t); - - while (*s) - { - char const *patterns = time_patterns; - char const *s1; - - do - { - if (! (s1 = parse_prefix (s, &patterns, &p))) - return (char *) s; - } - while (merge_partime (t, &p) != 0); - - s = s1; - } - - return (char *) s; -} diff --git a/src/bin/patch/partime.h b/src/bin/patch/partime.h deleted file mode 100644 index 1f4d31a8b1..0000000000 --- a/src/bin/patch/partime.h +++ /dev/null @@ -1,77 +0,0 @@ -/* Parse a string, yielding a struct partime that describes it. */ - -/* Copyright 1993, 1994, 1995, 1997 Paul Eggert - Distributed under license by the Free Software Foundation, Inc. - - This file is part of RCS. - - RCS 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. - - RCS 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 RCS; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - - Report problems and direct all questions to: - - rcs-bugs@cs.purdue.edu - - */ - -#define TM_UNDEFINED (-1) -#define TM_DEFINED(x) (0 <= (x)) - -/* #include if you want to use these symbols. */ -#define TM_LOCAL_ZONE LONG_MIN -#define TM_UNDEFINED_ZONE (LONG_MIN + 1) - -struct partime - { - /* This structure describes the parsed time. - Only the following tm_* members are used: - sec, min, hour, mday, mon, year, wday, yday. - If ! TM_DEFINED (value), the parser never found the value. - The tm_year field is the actual year, not the year - 1900; - but see ymodulus below. */ - struct tm tm; - - /* Like tm, but values are relative to the value in tm, - and values are initialized to 0 rather than to TM_UNDEFINED. - Only the following tm_* members are used: - sec, min, hour, mday, mon, year. */ - struct tm tmr; - - /* If TM_DEFINED (wday_ordinal), - then day number (e.g. 3 in "3rd Sunday"). */ - int wday_ordinal; - - /* If TM_DEFINED (ymodulus), - then tm.tm_year is actually modulo ymodulus. */ - int ymodulus; - - /* Week of year, ISO 8601 style. - If ! TM_DEFINED (yweek), the parser never found yweek. - Weeks start on Mondays. - Week 1 includes Jan 4. */ - int yweek; - - /* Seconds east of UTC; or TM_LOCAL_ZONE or TM_UNDEFINED_ZONE. */ - long zone; - }; - -#if defined __STDC__ || has_prototypes -# define __PARTIME_P(x) x -#else -# define __PARTIME_P(x) () -#endif - -char *partime __PARTIME_P ((char const *, struct partime *)); -char *parzone __PARTIME_P ((char const *, long *)); diff --git a/src/bin/patch/patch.c b/src/bin/patch/patch.c deleted file mode 100644 index 44d9c85e4d..0000000000 --- a/src/bin/patch/patch.c +++ /dev/null @@ -1,1366 +0,0 @@ -/* patch - a program to apply diffs to original files */ - -/* $Id: patch.c 8008 2004-06-16 21:22:10Z korli $ */ - -/* Copyright 1984, 1985-1987, 1988 Larry Wall - Copyright 1989, 1990-1993, 1997-1998, 1999 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define XTERN -#include -#undef XTERN -#define XTERN extern -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#if HAVE_UTIME_H -# include -#endif -/* Some nonstandard hosts don't declare this structure even in . */ -#if ! HAVE_STRUCT_UTIMBUF -struct utimbuf -{ - time_t actime; - time_t modtime; -}; -#endif - -/* Output stream state. */ -struct outstate -{ - FILE *ofp; - int after_newline; - int zero_output; -}; - -/* procedures */ - -static FILE *create_output_file PARAMS ((char const *, int)); -static LINENUM locate_hunk PARAMS ((LINENUM)); -static bool apply_hunk PARAMS ((struct outstate *, LINENUM)); -static bool copy_till PARAMS ((struct outstate *, LINENUM)); -static bool patch_match PARAMS ((LINENUM, LINENUM, LINENUM, LINENUM)); -static bool similar PARAMS ((char const *, size_t, char const *, size_t)); -static bool spew_output PARAMS ((struct outstate *)); -static char const *make_temp PARAMS ((int)); -static int numeric_string PARAMS ((char const *, int, char const *)); -static void abort_hunk PARAMS ((void)); -static void cleanup PARAMS ((void)); -static void get_some_switches PARAMS ((void)); -static void init_output PARAMS ((char const *, int, struct outstate *)); -static void init_reject PARAMS ((void)); -static void reinitialize_almost_everything PARAMS ((void)); -static void remove_if_needed PARAMS ((char const *, int volatile *)); -static void usage PARAMS ((FILE *, int)) __attribute__((noreturn)); - -static int make_backups; -static int backup_if_mismatch; -static char const *version_control; -static char const *version_control_context; -static int remove_empty_files; - -/* TRUE if -R was specified on command line. */ -static int reverse_flag_specified; - -/* how many input lines have been irretractably output */ -static LINENUM last_frozen_line; - -static char const *do_defines; /* symbol to patch using ifdef, ifndef, etc. */ -static char const if_defined[] = "\n#ifdef %s\n"; -static char const not_defined[] = "#ifndef %s\n"; -static char const else_defined[] = "\n#else\n"; -static char const end_defined[] = "\n#endif /* %s */\n"; - -static int Argc; -static char * const *Argv; - -static FILE *rejfp; /* reject file pointer */ - -static char const *patchname; -static char *rejname; -static char const * volatile TMPREJNAME; -static int volatile TMPREJNAME_needs_removal; - -static LINENUM last_offset; -static LINENUM maxfuzz = 2; - -static char serrbuf[BUFSIZ]; - -char const program_name[] = "patch"; - -/* Apply a set of diffs as appropriate. */ - -int main PARAMS ((int, char **)); - -int -main (int argc, char **argv) -{ - char const *val; - bool somefailed = FALSE; - struct outstate outstate; - char numbuf[LINENUM_LENGTH_BOUND + 1]; - - init_time (); - - setbuf(stderr, serrbuf); - - xalloc_fail_func = memory_fatal; - bufsize = 8 * 1024; - buf = xmalloc (bufsize); - - strippath = -1; - - val = getenv ("QUOTING_STYLE"); - { - int i = val ? argmatch (val, quoting_style_args, 0, 0) : -1; - set_quoting_style ((struct quoting_options *) 0, - i < 0 ? shell_quoting_style : (enum quoting_style) i); - } - - posixly_correct = getenv ("POSIXLY_CORRECT") != 0; - backup_if_mismatch = ! posixly_correct; - patch_get = ((val = getenv ("PATCH_GET")) - ? numeric_string (val, 1, "PATCH_GET value") - : posixly_correct - 1); - - val = getenv ("SIMPLE_BACKUP_SUFFIX"); - if (val && *val) - simple_backup_suffix = val; - - if ((version_control = getenv ("PATCH_VERSION_CONTROL"))) - version_control_context = "$PATCH_VERSION_CONTROL"; - else if ((version_control = getenv ("VERSION_CONTROL"))) - version_control_context = "$VERSION_CONTROL"; - - /* Cons up the names of the global temporary files. - Do this before `cleanup' can possibly be called (e.g. by `pfatal'). */ - TMPOUTNAME = make_temp ('o'); - TMPINNAME = make_temp ('i'); - TMPREJNAME = make_temp ('r'); - TMPPATNAME = make_temp ('p'); - - /* parse switches */ - Argc = argc; - Argv = argv; - get_some_switches(); - - if (make_backups | backup_if_mismatch) - backup_type = get_version (version_control_context, version_control); - - init_output (outfile, 0, &outstate); - - /* Make sure we clean up in case of disaster. */ - set_signals(0); - - for ( - open_patch_file (patchname); - there_is_another_patch(); - reinitialize_almost_everything() - ) { /* for each patch in patch file */ - int hunk = 0; - int failed = 0; - int mismatch = 0; - char *outname = outfile ? outfile : inname; - - if (!skip_rest_of_patch) - get_input_file (inname, outname); - - if (diff_type == ED_DIFF) { - outstate.zero_output = 0; - if (! dry_run) - { - do_ed_script (outstate.ofp); - if (! outfile) - { - struct stat statbuf; - if (stat (TMPOUTNAME, &statbuf) != 0) - pfatal ("%s", TMPOUTNAME); - outstate.zero_output = statbuf.st_size == 0; - } - } - } else { - int got_hunk; - int apply_anyway = 0; - - /* initialize the patched file */ - if (! skip_rest_of_patch && ! outfile) - { - int exclusive = TMPOUTNAME_needs_removal ? 0 : O_EXCL; - TMPOUTNAME_needs_removal = 1; - init_output (TMPOUTNAME, exclusive, &outstate); - } - - /* initialize reject file */ - init_reject (); - - /* find out where all the lines are */ - if (!skip_rest_of_patch) - scan_input (inname); - - /* from here on, open no standard i/o files, because malloc */ - /* might misfire and we can't catch it easily */ - - /* apply each hunk of patch */ - while (0 < (got_hunk = another_hunk (diff_type, reverse))) { - LINENUM where = 0; /* Pacify `gcc -Wall'. */ - LINENUM newwhere; - LINENUM fuzz = 0; - LINENUM prefix_context = pch_prefix_context (); - LINENUM suffix_context = pch_suffix_context (); - LINENUM context = (prefix_context < suffix_context - ? suffix_context : prefix_context); - LINENUM mymaxfuzz = (maxfuzz < context ? maxfuzz : context); - hunk++; - if (!skip_rest_of_patch) { - do { - where = locate_hunk(fuzz); - if (! where || fuzz || last_offset) - mismatch = 1; - if (hunk == 1 && ! where && ! (force | apply_anyway) - && reverse == reverse_flag_specified) { - /* dwim for reversed patch? */ - if (!pch_swap()) { - say ( -"Not enough memory to try swapped hunk! Assuming unswapped.\n"); - continue; - } - /* Try again. */ - where = locate_hunk (fuzz); - if (where - && (ok_to_reverse - ("%s patch detected!", - (reverse - ? "Unreversed" - : "Reversed (or previously applied)")))) - reverse ^= 1; - else - { - /* Put it back to normal. */ - if (! pch_swap ()) - fatal ("lost hunk on alloc error!"); - if (where) - { - apply_anyway = 1; - fuzz--; /* Undo `++fuzz' below. */ - where = 0; - } - } - } - } while (!skip_rest_of_patch && !where - && ++fuzz <= mymaxfuzz); - - if (skip_rest_of_patch) { /* just got decided */ - if (outstate.ofp && ! outfile) - { - fclose (outstate.ofp); - outstate.ofp = 0; - } - } - } - - newwhere = pch_newfirst() + last_offset; - if (skip_rest_of_patch) { - abort_hunk(); - failed++; - if (verbosity == VERBOSE) - say ("Hunk #%d ignored at %s.\n", hunk, - format_linenum (numbuf, newwhere)); - } - else if (!where - || (where == 1 && pch_says_nonexistent (reverse) == 2 - && instat.st_size)) { - - if (where) - say ("Patch attempted to create file %s, which already exists.\n", - quotearg (inname)); - - abort_hunk(); - failed++; - if (verbosity != SILENT) - say ("Hunk #%d FAILED at %s.\n", hunk, - format_linenum (numbuf, newwhere)); - } - else if (! apply_hunk (&outstate, where)) { - abort_hunk (); - failed++; - if (verbosity != SILENT) - say ("Hunk #%d FAILED at %s.\n", hunk, - format_linenum (numbuf, newwhere)); - } else { - if (verbosity == VERBOSE - || (verbosity != SILENT && (fuzz || last_offset))) { - say ("Hunk #%d succeeded at %s", hunk, - format_linenum (numbuf, newwhere)); - if (fuzz) - say (" with fuzz %s", format_linenum (numbuf, fuzz)); - if (last_offset) - say (" (offset %s line%s)", - format_linenum (numbuf, last_offset), - "s" + (last_offset == 1)); - say (".\n"); - } - } - } - - if (!skip_rest_of_patch) - { - if (got_hunk < 0 && using_plan_a) - { - if (outfile) - fatal ("out of memory using Plan A"); - say ("\n\nRan out of memory using Plan A -- trying again...\n\n"); - if (outstate.ofp) - { - fclose (outstate.ofp); - outstate.ofp = 0; - } - fclose (rejfp); - continue; - } - - /* Finish spewing out the new file. */ - assert (hunk); - if (! spew_output (&outstate)) - { - say ("Skipping patch.\n"); - skip_rest_of_patch = TRUE; - } - } - } - - /* and put the output where desired */ - ignore_signals (); - if (! skip_rest_of_patch && ! outfile) { - if (outstate.zero_output - && (remove_empty_files - || (pch_says_nonexistent (reverse ^ 1) == 2 - && ! posixly_correct))) - { - if (verbosity == VERBOSE) - say ("Removing file %s%s\n", quotearg (outname), - dry_run ? " and any empty ancestor directories" : ""); - if (! dry_run) - { - move_file ((char *) 0, (int *) 0, outname, (mode_t) 0, - (make_backups - || (backup_if_mismatch && (mismatch | failed)))); - removedirs (outname); - } - } - else - { - if (! outstate.zero_output - && pch_says_nonexistent (reverse ^ 1)) - { - mismatch = 1; - if (verbosity != SILENT) - say ("File %s is not empty after patch, as expected\n", - quotearg (outname)); - } - - if (! dry_run) - { - time_t t; - - move_file (TMPOUTNAME, &TMPOUTNAME_needs_removal, - outname, instat.st_mode, - (make_backups - || (backup_if_mismatch && (mismatch | failed)))); - - if ((set_time | set_utc) - && (t = pch_timestamp (reverse ^ 1)) != (time_t) -1) - { - struct utimbuf utimbuf; - utimbuf.actime = utimbuf.modtime = t; - - if (! force && ! inerrno - && pch_says_nonexistent (reverse) != 2 - && (t = pch_timestamp (reverse)) != (time_t) -1 - && t != instat.st_mtime) - say ("Not setting time of file %s (time mismatch)\n", - quotearg (outname)); - else if (! force && (mismatch | failed)) - say ("Not setting time of file %s (contents mismatch)\n", - quotearg (outname)); - else if (utime (outname, &utimbuf) != 0) - pfatal ("Can't set timestamp on file %s", - quotearg (outname)); - } - - if (! inerrno && chmod (outname, instat.st_mode) != 0) - pfatal ("Can't set permissions on file %s", - quotearg (outname)); - } - } - } - if (diff_type != ED_DIFF) { - if (fclose (rejfp) != 0) - write_fatal (); - if (failed) { - somefailed = TRUE; - say ("%d out of %d hunk%s %s", failed, hunk, "s" + (hunk == 1), - skip_rest_of_patch ? "ignored" : "FAILED"); - if (outname) { - char *rej = rejname; - if (!rejname) { - rej = xmalloc (strlen (outname) + 5); - strcpy (rej, outname); - addext (rej, ".rej", '#'); - } - say (" -- saving rejects to file %s", quotearg (rej)); - if (! dry_run) - { - move_file (TMPREJNAME, &TMPREJNAME_needs_removal, - rej, instat.st_mode, FALSE); - if (! inerrno - && (chmod (rej, (instat.st_mode - & ~(S_IXUSR|S_IXGRP|S_IXOTH))) - != 0)) - pfatal ("can't set permissions on file %s", - quotearg (rej)); - } - if (!rejname) - free (rej); - } - say ("\n"); - } - } - set_signals (1); - } - if (outstate.ofp && (ferror (outstate.ofp) || fclose (outstate.ofp) != 0)) - write_fatal (); - cleanup (); - if (somefailed) - exit (1); - return 0; -} - -/* Prepare to find the next patch to do in the patch file. */ - -static void -reinitialize_almost_everything (void) -{ - re_patch(); - re_input(); - - input_lines = 0; - last_frozen_line = 0; - - if (inname) { - free (inname); - inname = 0; - } - - last_offset = 0; - - diff_type = NO_DIFF; - - if (revision) { - free(revision); - revision = 0; - } - - reverse = reverse_flag_specified; - skip_rest_of_patch = FALSE; -} - -static char const shortopts[] = "bB:cd:D:eEfF:g:i:lnNo:p:r:RstTuvV:x:Y:z:Z"; -static struct option const longopts[] = -{ - {"backup", no_argument, NULL, 'b'}, - {"prefix", required_argument, NULL, 'B'}, - {"context", no_argument, NULL, 'c'}, - {"directory", required_argument, NULL, 'd'}, - {"ifdef", required_argument, NULL, 'D'}, - {"ed", no_argument, NULL, 'e'}, - {"remove-empty-files", no_argument, NULL, 'E'}, - {"force", no_argument, NULL, 'f'}, - {"fuzz", required_argument, NULL, 'F'}, - {"get", no_argument, NULL, 'g'}, - {"input", required_argument, NULL, 'i'}, - {"ignore-whitespace", no_argument, NULL, 'l'}, - {"normal", no_argument, NULL, 'n'}, - {"forward", no_argument, NULL, 'N'}, - {"output", required_argument, NULL, 'o'}, - {"strip", required_argument, NULL, 'p'}, - {"reject-file", required_argument, NULL, 'r'}, - {"reverse", no_argument, NULL, 'R'}, - {"quiet", no_argument, NULL, 's'}, - {"silent", no_argument, NULL, 's'}, - {"batch", no_argument, NULL, 't'}, - {"set-time", no_argument, NULL, 'T'}, - {"unified", no_argument, NULL, 'u'}, - {"version", no_argument, NULL, 'v'}, - {"version-control", required_argument, NULL, 'V'}, - {"debug", required_argument, NULL, 'x'}, - {"basename-prefix", required_argument, NULL, 'Y'}, - {"suffix", required_argument, NULL, 'z'}, - {"set-utc", no_argument, NULL, 'Z'}, - {"dry-run", no_argument, NULL, CHAR_MAX + 1}, - {"verbose", no_argument, NULL, CHAR_MAX + 2}, - {"binary", no_argument, NULL, CHAR_MAX + 3}, - {"help", no_argument, NULL, CHAR_MAX + 4}, - {"backup-if-mismatch", no_argument, NULL, CHAR_MAX + 5}, - {"no-backup-if-mismatch", no_argument, NULL, CHAR_MAX + 6}, - {"posix", no_argument, NULL, CHAR_MAX + 7}, - {"quoting-style", required_argument, NULL, CHAR_MAX + 8}, - {NULL, no_argument, NULL, 0} -}; - -static char const *const option_help[] = -{ -"Input options:", -"", -" -p NUM --strip=NUM Strip NUM leading components from file names.", -" -F LINES --fuzz LINES Set the fuzz factor to LINES for inexact matching.", -" -l --ignore-whitespace Ignore white space changes between patch and input.", -"", -" -c --context Interpret the patch as a context difference.", -" -e --ed Interpret the patch as an ed script.", -" -n --normal Interpret the patch as a normal difference.", -" -u --unified Interpret the patch as a unified difference.", -"", -" -N --forward Ignore patches that appear to be reversed or already applied.", -" -R --reverse Assume patches were created with old and new files swapped.", -"", -" -i PATCHFILE --input=PATCHFILE Read patch from PATCHFILE instead of stdin.", -"", -"Output options:", -"", -" -o FILE --output=FILE Output patched files to FILE.", -" -r FILE --reject-file=FILE Output rejects to FILE.", -"", -" -D NAME --ifdef=NAME Make merged if-then-else output using NAME.", -" -E --remove-empty-files Remove output files that are empty after patching.", -"", -" -Z --set-utc Set times of patched files, assuming diff uses UTC (GMT).", -" -T --set-time Likewise, assuming local time.", -"", -" --quoting-style=WORD output file names using quoting style WORD.", -" Valid WORDs are: literal, shell, shell-always, c, escape.", -" Default is taken from QUOTING_STYLE env variable, or 'shell' if unset.", -"", -"Backup and version control options:", -"", -" -b --backup Back up the original contents of each file.", -" --backup-if-mismatch Back up if the patch does not match exactly.", -" --no-backup-if-mismatch Back up mismatches only if otherwise requested.", -"", -" -V STYLE --version-control=STYLE Use STYLE version control.", -" STYLE is either 'simple', 'numbered', or 'existing'.", -" -B PREFIX --prefix=PREFIX Prepend PREFIX to backup file names.", -" -Y PREFIX --basename-prefix=PREFIX Prepend PREFIX to backup file basenames.", -" -z SUFFIX --suffix=SUFFIX Append SUFFIX to backup file names.", -"", -" -g NUM --get=NUM Get files from RCS etc. if positive; ask if negative.", -"", -"Miscellaneous options:", -"", -" -t --batch Ask no questions; skip bad-Prereq patches; assume reversed.", -" -f --force Like -t, but ignore bad-Prereq patches, and assume unreversed.", -" -s --quiet --silent Work silently unless an error occurs.", -" --verbose Output extra information about the work being done.", -" --dry-run Do not actually change any files; just print what would happen.", -" --posix Conform to the POSIX standard.", -"", -" -d DIR --directory=DIR Change the working directory to DIR first.", -#if HAVE_SETMODE -" --binary Read and write data in binary mode.", -#else -" --binary Read and write data in binary mode (no effect on this platform).", -#endif -"", -" -v --version Output version info.", -" --help Output this help.", -"", -"Report bugs to .", -0 -}; - -static void -usage (FILE *stream, int status) -{ - char const * const *p; - - if (status != 0) - { - fprintf (stream, "%s: Try `%s --help' for more information.\n", - program_name, Argv[0]); - } - else - { - fprintf (stream, "Usage: %s [OPTION]... [ORIGFILE [PATCHFILE]]\n\n", - Argv[0]); - for (p = option_help; *p; p++) - fprintf (stream, "%s\n", *p); - } - - exit (status); -} - -/* Process switches and filenames. */ - -static void -get_some_switches (void) -{ - register int optc; - - if (rejname) - free (rejname); - rejname = 0; - if (optind == Argc) - return; - while ((optc = getopt_long (Argc, Argv, shortopts, longopts, (int *) 0)) - != -1) { - switch (optc) { - case 'b': - make_backups = 1; - /* Special hack for backward compatibility with CVS 1.9. - If the last 4 args are `-b SUFFIX ORIGFILE PATCHFILE', - treat `-b' as if it were `-b -z'. */ - if (Argc - optind == 3 - && strcmp (Argv[optind - 1], "-b") == 0 - && ! (Argv[optind + 0][0] == '-' && Argv[optind + 0][1]) - && ! (Argv[optind + 1][0] == '-' && Argv[optind + 1][1]) - && ! (Argv[optind + 2][0] == '-' && Argv[optind + 2][1])) - { - optarg = Argv[optind++]; - if (verbosity != SILENT) - say ("warning: the `-b %s' option is obsolete; use `-b -z %s' instead\n", - optarg, optarg); - goto case_z; - } - break; - case 'B': - if (!*optarg) - fatal ("backup prefix is empty"); - origprae = savestr (optarg); - break; - case 'c': - diff_type = CONTEXT_DIFF; - break; - case 'd': - if (chdir(optarg) < 0) - pfatal ("Can't change to directory %s", quotearg (optarg)); - break; - case 'D': - do_defines = savestr (optarg); - break; - case 'e': - diff_type = ED_DIFF; - break; - case 'E': - remove_empty_files = TRUE; - break; - case 'f': - force = TRUE; - break; - case 'F': - maxfuzz = numeric_string (optarg, 0, "fuzz factor"); - break; - case 'g': - patch_get = numeric_string (optarg, 1, "get option value"); - break; - case 'i': - patchname = savestr (optarg); - break; - case 'l': - canonicalize = TRUE; - break; - case 'n': - diff_type = NORMAL_DIFF; - break; - case 'N': - noreverse = TRUE; - break; - case 'o': - if (strcmp (optarg, "-") == 0) - fatal ("can't output patches to standard output"); - outfile = savestr (optarg); - break; - case 'p': - strippath = numeric_string (optarg, 0, "strip count"); - break; - case 'r': - rejname = savestr (optarg); - break; - case 'R': - reverse = 1; - reverse_flag_specified = 1; - break; - case 's': - verbosity = SILENT; - break; - case 't': - batch = TRUE; - break; - case 'T': - set_time = 1; - break; - case 'u': - diff_type = UNI_DIFF; - break; - case 'v': - version(); - exit (0); - break; - case 'V': - version_control = optarg; - version_control_context = "--version-control or -V option"; - break; -#if DEBUGGING - case 'x': - debug = numeric_string (optarg, 1, "debugging option"); - break; -#endif - case 'Y': - if (!*optarg) - fatal ("backup basename prefix is empty"); - origbase = savestr (optarg); - break; - case 'z': - case_z: - if (!*optarg) - fatal ("backup suffix is empty"); - simple_backup_suffix = savestr (optarg); - break; - case 'Z': - set_utc = 1; - break; - case CHAR_MAX + 1: - dry_run = TRUE; - break; - case CHAR_MAX + 2: - verbosity = VERBOSE; - break; - case CHAR_MAX + 3: -#if HAVE_SETMODE - binary_transput = O_BINARY; -#endif - break; - case CHAR_MAX + 4: - usage (stdout, 0); - case CHAR_MAX + 5: - backup_if_mismatch = 1; - break; - case CHAR_MAX + 6: - backup_if_mismatch = 0; - break; - case CHAR_MAX + 7: - posixly_correct = 1; - break; - case CHAR_MAX + 8: - { - int i = argmatch (optarg, quoting_style_args, 0, 0); - if (i < 0) - { - invalid_arg ("quoting style", optarg, i); - usage (stderr, 2); - } - set_quoting_style ((struct quoting_options *) 0, - (enum quoting_style) i); - } - break; - default: - usage (stderr, 2); - } - } - - /* Process any filename args. */ - if (optind < Argc) - { - inname = savestr (Argv[optind++]); - invc = -1; - if (optind < Argc) - { - patchname = savestr (Argv[optind++]); - if (optind < Argc) - { - fprintf (stderr, "%s: %s: extra operand\n", - program_name, quotearg (Argv[optind])); - usage (stderr, 2); - } - } - } -} - -/* Handle STRING (possibly negative if NEGATIVE_ALLOWED is nonzero) - of type ARGTYPE_MSGID by converting it to an integer, - returning the result. */ -static int -numeric_string (char const *string, - int negative_allowed, - char const *argtype_msgid) -{ - int value = 0; - char const *p = string; - int sign = *p == '-' ? -1 : 1; - - p += *p == '-' || *p == '+'; - - do - { - int v10 = value * 10; - int digit = *p - '0'; - int signed_digit = sign * digit; - int next_value = v10 + signed_digit; - - if (9 < (unsigned) digit) - fatal ("%s %s is not a number", argtype_msgid, quotearg (string)); - - if (v10 / 10 != value || (next_value < v10) != (signed_digit < 0)) - fatal ("%s %s is too large", argtype_msgid, quotearg (string)); - - value = next_value; - } - while (*++p); - - if (value < 0 && ! negative_allowed) - fatal ("%s %s is negative", argtype_msgid, quotearg (string)); - - return value; -} - -/* Attempt to find the right place to apply this hunk of patch. */ - -static LINENUM -locate_hunk (LINENUM fuzz) -{ - register LINENUM first_guess = pch_first () + last_offset; - register LINENUM offset; - LINENUM pat_lines = pch_ptrn_lines(); - LINENUM prefix_context = pch_prefix_context (); - LINENUM suffix_context = pch_suffix_context (); - LINENUM context = (prefix_context < suffix_context - ? suffix_context : prefix_context); - LINENUM prefix_fuzz = fuzz + prefix_context - context; - LINENUM suffix_fuzz = fuzz + suffix_context - context; - LINENUM max_where = input_lines - (pat_lines - suffix_fuzz) + 1; - LINENUM min_where = last_frozen_line + 1 - (prefix_context - prefix_fuzz); - LINENUM max_pos_offset = max_where - first_guess; - LINENUM max_neg_offset = first_guess - min_where; - LINENUM max_offset = (max_pos_offset < max_neg_offset - ? max_neg_offset : max_pos_offset); - - if (!pat_lines) /* null range matches always */ - return first_guess; - - /* Do not try lines <= 0. */ - if (first_guess <= max_neg_offset) - max_neg_offset = first_guess - 1; - - if (prefix_fuzz < 0) - { - /* Can only match start of file. */ - - if (suffix_fuzz < 0) - /* Can only match entire file. */ - if (pat_lines != input_lines || prefix_context < last_frozen_line) - return 0; - - offset = 1 - first_guess; - if (last_frozen_line <= prefix_context - && offset <= max_pos_offset - && patch_match (first_guess, offset, (LINENUM) 0, suffix_fuzz)) - { - last_offset = offset; - return first_guess + offset; - } - else - return 0; - } - - if (suffix_fuzz < 0) - { - /* Can only match end of file. */ - offset = first_guess - (input_lines - pat_lines + 1); - if (offset <= max_neg_offset - && patch_match (first_guess, -offset, prefix_fuzz, (LINENUM) 0)) - { - last_offset = - offset; - return first_guess - offset; - } - else - return 0; - } - - for (offset = 0; offset <= max_offset; offset++) { - char numbuf0[LINENUM_LENGTH_BOUND + 1]; - char numbuf1[LINENUM_LENGTH_BOUND + 1]; - if (offset <= max_pos_offset - && patch_match (first_guess, offset, prefix_fuzz, suffix_fuzz)) { - if (debug & 1) - say ("Offset changing from %s to %s\n", - format_linenum (numbuf0, last_offset), - format_linenum (numbuf1, offset)); - last_offset = offset; - return first_guess+offset; - } - if (0 < offset && offset <= max_neg_offset - && patch_match (first_guess, -offset, prefix_fuzz, suffix_fuzz)) { - if (debug & 1) - say ("Offset changing from %s to %s\n", - format_linenum (numbuf0, last_offset), - format_linenum (numbuf1, -offset)); - last_offset = -offset; - return first_guess-offset; - } - } - return 0; -} - -/* We did not find the pattern, dump out the hunk so they can handle it. */ - -static void -abort_hunk (void) -{ - register LINENUM i; - register LINENUM pat_end = pch_end (); - /* add in last_offset to guess the same as the previous successful hunk */ - LINENUM oldfirst = pch_first() + last_offset; - LINENUM newfirst = pch_newfirst() + last_offset; - LINENUM oldlast = oldfirst + pch_ptrn_lines() - 1; - LINENUM newlast = newfirst + pch_repl_lines() - 1; - char const *stars = - (int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ****" : ""; - char const *minuses = - (int) NEW_CONTEXT_DIFF <= (int) diff_type ? " ----" : " -----"; - - fprintf(rejfp, "***************\n"); - for (i=0; i<=pat_end; i++) { - char numbuf0[LINENUM_LENGTH_BOUND + 1]; - char numbuf1[LINENUM_LENGTH_BOUND + 1]; - switch (pch_char(i)) { - case '*': - if (oldlast < oldfirst) - fprintf(rejfp, "*** 0%s\n", stars); - else if (oldlast == oldfirst) - fprintf (rejfp, "*** %s%s\n", - format_linenum (numbuf0, oldfirst), stars); - else - fprintf (rejfp, "*** %s,%s%s\n", - format_linenum (numbuf0, oldfirst), - format_linenum (numbuf1, oldlast), stars); - break; - case '=': - if (newlast < newfirst) - fprintf(rejfp, "--- 0%s\n", minuses); - else if (newlast == newfirst) - fprintf (rejfp, "--- %s%s\n", - format_linenum (numbuf0, newfirst), minuses); - else - fprintf (rejfp, "--- %s,%s%s\n", - format_linenum (numbuf0, newfirst), - format_linenum (numbuf1, newlast), minuses); - break; - case ' ': case '-': case '+': case '!': - fprintf (rejfp, "%c ", pch_char (i)); - /* fall into */ - case '\n': - pch_write_line (i, rejfp); - break; - default: - fatal ("fatal internal error in abort_hunk"); - } - if (ferror (rejfp)) - write_fatal (); - } -} - -/* We found where to apply it (we hope), so do it. */ - -static bool -apply_hunk (struct outstate *outstate, LINENUM where) -{ - register LINENUM old = 1; - register LINENUM lastline = pch_ptrn_lines (); - register LINENUM new = lastline+1; - register enum {OUTSIDE, IN_IFNDEF, IN_IFDEF, IN_ELSE} def_state = OUTSIDE; - register char const *R_do_defines = do_defines; - register LINENUM pat_end = pch_end (); - register FILE *fp = outstate->ofp; - - where--; - while (pch_char(new) == '=' || pch_char(new) == '\n') - new++; - - while (old <= lastline) { - if (pch_char(old) == '-') { - assert (outstate->after_newline); - if (! copy_till (outstate, where + old - 1)) - return FALSE; - if (R_do_defines) { - if (def_state == OUTSIDE) { - fprintf (fp, outstate->after_newline + if_defined, - R_do_defines); - def_state = IN_IFNDEF; - } - else if (def_state == IN_IFDEF) { - fprintf (fp, outstate->after_newline + else_defined); - def_state = IN_ELSE; - } - if (ferror (fp)) - write_fatal (); - outstate->after_newline = pch_write_line (old, fp); - outstate->zero_output = 0; - } - last_frozen_line++; - old++; - } - else if (new > pat_end) { - break; - } - else if (pch_char(new) == '+') { - if (! copy_till (outstate, where + old - 1)) - return FALSE; - if (R_do_defines) { - if (def_state == IN_IFNDEF) { - fprintf (fp, outstate->after_newline + else_defined); - def_state = IN_ELSE; - } - else if (def_state == OUTSIDE) { - fprintf (fp, outstate->after_newline + if_defined, - R_do_defines); - def_state = IN_IFDEF; - } - if (ferror (fp)) - write_fatal (); - } - outstate->after_newline = pch_write_line (new, fp); - outstate->zero_output = 0; - new++; - } - else if (pch_char(new) != pch_char(old)) { - char numbuf0[LINENUM_LENGTH_BOUND + 1]; - char numbuf1[LINENUM_LENGTH_BOUND + 1]; - if (debug & 1) - say ("oldchar = '%c', newchar = '%c'\n", - pch_char (old), pch_char (new)); - fatal ("Out-of-sync patch, lines %s,%s -- mangled text or line numbers, maybe?", - format_linenum (numbuf0, pch_hunk_beg() + old), - format_linenum (numbuf1, pch_hunk_beg() + new)); - } - else if (pch_char(new) == '!') { - assert (outstate->after_newline); - if (! copy_till (outstate, where + old - 1)) - return FALSE; - assert (outstate->after_newline); - if (R_do_defines) { - fprintf (fp, not_defined, R_do_defines); - if (ferror (fp)) - write_fatal (); - def_state = IN_IFNDEF; - } - - do - { - if (R_do_defines) { - outstate->after_newline = pch_write_line (old, fp); - } - last_frozen_line++; - old++; - } - while (pch_char (old) == '!'); - - if (R_do_defines) { - fprintf (fp, outstate->after_newline + else_defined); - if (ferror (fp)) - write_fatal (); - def_state = IN_ELSE; - } - - do - { - outstate->after_newline = pch_write_line (new, fp); - new++; - } - while (pch_char (new) == '!'); - outstate->zero_output = 0; - } - else { - assert(pch_char(new) == ' '); - old++; - new++; - if (R_do_defines && def_state != OUTSIDE) { - fprintf (fp, outstate->after_newline + end_defined, - R_do_defines); - if (ferror (fp)) - write_fatal (); - outstate->after_newline = 1; - def_state = OUTSIDE; - } - } - } - if (new <= pat_end && pch_char(new) == '+') { - if (! copy_till (outstate, where + old - 1)) - return FALSE; - if (R_do_defines) { - if (def_state == OUTSIDE) { - fprintf (fp, outstate->after_newline + if_defined, - R_do_defines); - def_state = IN_IFDEF; - } - else if (def_state == IN_IFNDEF) { - fprintf (fp, outstate->after_newline + else_defined); - def_state = IN_ELSE; - } - if (ferror (fp)) - write_fatal (); - outstate->zero_output = 0; - } - - do - { - if (! outstate->after_newline && putc ('\n', fp) == EOF) - write_fatal (); - outstate->after_newline = pch_write_line (new, fp); - outstate->zero_output = 0; - new++; - } - while (new <= pat_end && pch_char (new) == '+'); - } - if (R_do_defines && def_state != OUTSIDE) { - fprintf (fp, outstate->after_newline + end_defined, R_do_defines); - if (ferror (fp)) - write_fatal (); - outstate->after_newline = 1; - } - return TRUE; -} - -/* Create an output file. */ - -static FILE * -create_output_file (char const *name, int open_flags) -{ - int fd = create_file (name, O_WRONLY | binary_transput | open_flags, - instat.st_mode); - FILE *f = fdopen (fd, binary_transput ? "wb" : "w"); - if (! f) - pfatal ("Can't create file %s", quotearg (name)); - return f; -} - -/* Open the new file. */ - -static void -init_output (char const *name, int open_flags, struct outstate *outstate) -{ - outstate->ofp = name ? create_output_file (name, open_flags) : (FILE *) 0; - outstate->after_newline = 1; - outstate->zero_output = 1; -} - -/* Open a file to put hunks we can't locate. */ - -static void -init_reject (void) -{ - int exclusive = TMPREJNAME_needs_removal ? 0 : O_EXCL; - TMPREJNAME_needs_removal = 1; - rejfp = create_output_file (TMPREJNAME, exclusive); -} - -/* Copy input file to output, up to wherever hunk is to be applied. */ - -static bool -copy_till (register struct outstate *outstate, register LINENUM lastline) -{ - register LINENUM R_last_frozen_line = last_frozen_line; - register FILE *fp = outstate->ofp; - register char const *s; - size_t size; - - if (R_last_frozen_line > lastline) - { - say ("misordered hunks! output would be garbled\n"); - return FALSE; - } - while (R_last_frozen_line < lastline) - { - s = ifetch (++R_last_frozen_line, 0, &size); - if (size) - { - if ((! outstate->after_newline && putc ('\n', fp) == EOF) - || ! fwrite (s, sizeof *s, size, fp)) - write_fatal (); - outstate->after_newline = s[size - 1] == '\n'; - outstate->zero_output = 0; - } - } - last_frozen_line = R_last_frozen_line; - return TRUE; -} - -/* Finish copying the input file to the output file. */ - -static bool -spew_output (struct outstate *outstate) -{ - if (debug & 256) - { - char numbuf0[LINENUM_LENGTH_BOUND + 1]; - char numbuf1[LINENUM_LENGTH_BOUND + 1]; - say ("il=%s lfl=%s\n", - format_linenum (numbuf0, input_lines), - format_linenum (numbuf1, last_frozen_line)); - } - - if (last_frozen_line < input_lines) - if (! copy_till (outstate, input_lines)) - return FALSE; - - if (outstate->ofp && ! outfile) - { - if (fclose (outstate->ofp) != 0) - write_fatal (); - outstate->ofp = 0; - } - - return TRUE; -} - -/* Does the patch pattern match at line base+offset? */ - -static bool -patch_match (LINENUM base, LINENUM offset, - LINENUM prefix_fuzz, LINENUM suffix_fuzz) -{ - register LINENUM pline = 1 + prefix_fuzz; - register LINENUM iline; - register LINENUM pat_lines = pch_ptrn_lines () - suffix_fuzz; - size_t size; - register char const *p; - - for (iline=base+offset+prefix_fuzz; pline <= pat_lines; pline++,iline++) { - p = ifetch (iline, offset >= 0, &size); - if (canonicalize) { - if (!similar(p, size, - pfetch(pline), - pch_line_len(pline) )) - return FALSE; - } - else if (size != pch_line_len (pline) - || memcmp (p, pfetch (pline), size) != 0) - return FALSE; - } - return TRUE; -} - -/* Do two lines match with canonicalized white space? */ - -static bool -similar (register char const *a, register size_t alen, - register char const *b, register size_t blen) -{ - /* Ignore presence or absence of trailing newlines. */ - alen -= alen && a[alen - 1] == '\n'; - blen -= blen && b[blen - 1] == '\n'; - - for (;;) - { - if (!blen || (*b == ' ' || *b == '\t')) - { - while (blen && (*b == ' ' || *b == '\t')) - b++, blen--; - if (alen) - { - if (!(*a == ' ' || *a == '\t')) - return FALSE; - do a++, alen--; - while (alen && (*a == ' ' || *a == '\t')); - } - if (!alen || !blen) - return alen == blen; - } - else if (!alen || *a++ != *b++) - return FALSE; - else - alen--, blen--; - } -} - -/* Make a temporary file. */ - -#if HAVE_MKTEMP -char *mktemp PARAMS ((char *)); -#endif - -#ifndef TMPDIR -#define TMPDIR "/tmp" -#endif - -static char const * -make_temp (int letter) -{ - char *r; -#if HAVE_MKTEMP - char const *tmpdir = getenv ("TMPDIR"); /* Unix tradition */ - if (!tmpdir) tmpdir = getenv ("TMP"); /* DOS tradition */ - if (!tmpdir) tmpdir = getenv ("TEMP"); /* another DOS tradition */ - if (!tmpdir) tmpdir = TMPDIR; - r = xmalloc (strlen (tmpdir) + 10); - sprintf (r, "%s/p%cXXXXXX", tmpdir, letter); - mktemp (r); - if (!*r) - pfatal ("mktemp"); -#else - r = xmalloc (L_tmpnam); - if (! (tmpnam (r) == r && *r)) - pfatal ("tmpnam"); -#endif - return r; -} - -/* Fatal exit with cleanup. */ - -void -fatal_exit (int sig) -{ - cleanup (); - - if (sig) - exit_with_signal (sig); - - exit (2); -} - -static void -remove_if_needed (char const *name, int volatile *needs_removal) -{ - if (*needs_removal) - { - unlink (name); - *needs_removal = 0; - } -} - -static void -cleanup (void) -{ - remove_if_needed (TMPINNAME, &TMPINNAME_needs_removal); - remove_if_needed (TMPOUTNAME, &TMPOUTNAME_needs_removal); - remove_if_needed (TMPPATNAME, &TMPPATNAME_needs_removal); - remove_if_needed (TMPREJNAME, &TMPREJNAME_needs_removal); -} diff --git a/src/bin/patch/patch.man b/src/bin/patch/patch.man deleted file mode 100644 index 6a21c3d15b..0000000000 --- a/src/bin/patch/patch.man +++ /dev/null @@ -1,1149 +0,0 @@ -.\" patch man page -.de Id -.ds Dt \\$4 -.. -.Id $Id: patch.man 8008 2004-06-16 21:22:10Z korli $ -.ds = \-\^\- -.de Sp -.if t .sp .3 -.if n .sp -.. -.TH PATCH 1 \*(Dt GNU -.ta 3n -.SH NAME -patch \- apply a diff file to an original -.SH SYNOPSIS -.B patch -.RI [ options ] -.RI [ originalfile -.RI [ patchfile ]] -.Sp -but usually just -.Sp -.BI "patch \-p" "num" -.BI < patchfile -.SH DESCRIPTION -.B patch -takes a patch file -.I patchfile -containing a difference listing produced by the -.B diff -program and applies those differences to one or more original files, -producing patched versions. -Normally the patched versions are put in place of the originals. -Backups can be made; see the -.B \-b -or -.B \*=backup -option. -The names of the files to be patched are usually taken from the patch file, -but if there's just one file to be patched it can specified on the -command line as -.IR originalfile . -.PP -Upon startup, patch attempts to determine the type of the diff listing, -unless overruled by a -\fB\-c\fP (\fB\*=context\fP), -\fB\-e\fP (\fB\*=ed\fP), -\fB\-n\fP (\fB\*=normal\fP), -or -\fB\-u\fP (\fB\*=unified\fP) -option. -Context diffs (old-style, new-style, and unified) and -normal diffs are applied by the -.B patch -program itself, while -.B ed -diffs are simply fed to the -.BR ed (1) -editor via a pipe. -.PP -.B patch -tries to skip any leading garbage, apply the diff, -and then skip any trailing garbage. -Thus you could feed an article or message containing a -diff listing to -.BR patch , -and it should work. -If the entire diff is indented by a consistent amount, -or if a context diff contains lines ending in \s-1CRLF\s0 -or is encapsulated one or more times by prepending -"\fB\- \fP" to lines starting with "\fB\-\fP" as specified by Internet RFC 934, -this is taken into account. -.PP -With context diffs, and to a lesser extent with normal diffs, -.B patch -can detect when the line numbers mentioned in the patch are incorrect, -and attempts to find the correct place to apply each hunk of the patch. -As a first guess, it takes the line number mentioned for the hunk, plus or -minus any offset used in applying the previous hunk. -If that is not the correct place, -.B patch -scans both forwards and backwards for a set of lines matching the context -given in the hunk. -First -.B patch -looks for a place where all lines of the context match. -If no such place is found, and it's a context diff, and the maximum fuzz factor -is set to 1 or more, then another scan takes place ignoring the first and last -line of context. -If that fails, and the maximum fuzz factor is set to 2 or more, -the first two and last two lines of context are ignored, -and another scan is made. -(The default maximum fuzz factor is 2.) -If -.B patch -cannot find a place to install that hunk of the patch, it puts the -hunk out to a reject file, which normally is the name of the output file -plus a -.B \&.rej -suffix, or -.B # -if -.B \&.rej -would generate a file name that is too long -(if even appending the single character -.B # -makes the file name too long, then -.B # -replaces the file name's last character). -(The rejected hunk comes out in ordinary context diff form regardless of -the input patch's form. -If the input was a normal diff, many of the contexts are simply null.) -The line numbers on the hunks in the reject file may be different than -in the patch file: they reflect the approximate location patch thinks the -failed hunks belong in the new file rather than the old one. -.PP -As each hunk is completed, you are told if the hunk -failed, and if so which line (in the new file) -.B patch -thought the hunk should go on. -If the hunk is installed at a different line -from the line number specified in the diff you -are told the offset. -A single large offset -.I may -indicate that a hunk was installed in the -wrong place. -You are also told if a fuzz factor was used to make the match, in which -case you should also be slightly suspicious. -If the -.B \*=verbose -option is given, you are also told about hunks that match exactly. -.PP -If no original file -.I origfile -is specified on the command line, -.B patch -tries to figure out from the leading garbage what the name of the file -to edit is, using the following rules. -.LP -First, -.B patch -takes an ordered list of candidate file names as follows: -.TP 3 -.B " \(bu" -If the header is that of a context diff, -.B patch -takes the old and new file names in the header. -A name is ignored if it does not have enough slashes to satisfy the -.BI \-p num -or -.BI \*=strip= num -option. -The name -.B /dev/null -is also ignored. -.TP -.B " \(bu" -If there is an -.B Index:\& -line in the leading garbage -and if either the old and new names are both absent or if -.B patch -is conforming to \s-1POSIX\s0, -.B patch -takes the name in the -.B Index:\& -line. -.TP -.B " \(bu" -For the purpose of the following rules, -the candidate file names are considered to be in the order (old, new, index), -regardless of the order that they appear in the header. -.LP -Then -.B patch -selects a file name from the candidate list as follows: -.TP 3 -.B " \(bu" -If some of the named files exist, -.B patch -selects the first name if conforming to \s-1POSIX\s0, -and the best name otherwise. -.TP -.B " \(bu" -If -.B patch -is not ignoring \s-1RCS\s0, ClearCase, and \s-1SCCS\s0 (see the -.BI "\-g\ " num -or -.BI \*=get= num -option), and no named files exist -but an \s-1RCS\s0, ClearCase, or \s-1SCCS\s0 master is found, -.B patch -selects the first named file -with an \s-1RCS\s0, ClearCase, or \s-1SCCS\s0 master. -.TP -.B " \(bu" -If no named files exist, -no \s-1RCS\s0, ClearCase, or \s-1SCCS\s0 master was found, -some names are given, -.B patch -is not conforming to \s-1POSIX\s0, -and the patch appears to create a file, -.B patch -selects the best name requiring the creation of the fewest directories. -.TP -.B " \(bu" -If no file name results from the above heuristics, you are asked -for the name of the file to patch, and -.B patch -selects that name. -.LP -To determine the -.I best -of a nonempty list of file names, -.B patch -first takes all the names with the fewest path name components; -of those, it then takes all the names with the shortest basename; -of those, it then takes all the shortest names; -finally, it takes the first remaining name. -.PP -Additionally, if the leading garbage contains a -.B Prereq:\& -line, -.B patch -takes the first word from the prerequisites line (normally a version -number) and checks the original file to see if that word can be found. -If not, -.B patch -asks for confirmation before proceeding. -.PP -The upshot of all this is that you should be able to say, while in a news -interface, something like the following: -.Sp - \fB| patch \-d /usr/src/local/blurfl\fP -.Sp -and patch a file in the -.B blurfl -directory directly from the article containing -the patch. -.PP -If the patch file contains more than one patch, -.B patch -tries to apply each of them as if they came from separate patch files. -This means, among other things, that it is assumed that the name of the file -to patch must be determined for each diff listing, -and that the garbage before each diff listing -contains interesting things such as file names and revision level, as -mentioned previously. -.SH OPTIONS -.TP 3 -\fB\-b\fP or \fB\*=backup\fP -Make backup files. -That is, when patching a file, -rename or copy the original instead of removing it. -When backing up a file that does not exist, -an empty, unreadable backup file is created -as a placeholder to represent the nonexistent file. -See the -.B \-V -or -.B \*=version\-control -option for details about how backup file names are determined. -.TP -.B \*=backup\-if\-mismatch -Back up a file if the patch does not match the file exactly -and if backups are not otherwise requested. -This is the default unless -.B patch -is conforming to \s-1POSIX\s0. -.TP -.B \*=no\-backup\-if\-mismatch -Do not back up a file if the patch does not match the file exactly -and if backups are not otherwise requested. -This is the default if -.B patch -is conforming to \s-1POSIX\s0. -.TP -\fB\-B\fP \fIpref\fP or \fB\*=prefix=\fP\fIpref\fP -Prefix -.I pref -to a file name when generating its simple backup file name. -For example, with -.B "\-B\ /junk/" -the simple backup file name for -.B src/patch/util.c -is -.BR /junk/src/patch/util.c . -.TP -\fB\*=binary\fP -Read and write all files in binary mode, -except for standard output and -.BR /dev/tty . -This option has no effect on \s-1POSIX\s0-conforming systems. -On systems like \s-1DOS\s0 where this option makes a difference, -the patch should be generated by -.BR "diff\ \-a\ \*=binary" . -.TP -\fB\-c\fP or \fB\*=context\fP -Interpret the patch file as a ordinary context diff. -.TP -\fB\-d\fP \fIdir\fP or \fB\*=directory=\fP\fIdir\fP -Change to the directory -.I dir -immediately, before doing -anything else. -.TP -\fB\-D\fP \fIdefine\fP or \fB\*=ifdef=\fP\fIdefine\fP -Use the -.BR #ifdef " .\|.\|. " #endif -construct to mark changes, with -.I define -as the differentiating symbol. -.TP -.B "\*=dry\-run" -Print the results of applying the patches without actually changing any files. -.TP -\fB\-e\fP or \fB\*=ed\fP -Interpret the patch file as an -.B ed -script. -.TP -\fB\-E\fP or \fB\*=remove\-empty\-files\fP -Remove output files that are empty after the patches have been applied. -Normally this option is unnecessary, since -.B patch -can examine the time stamps on the header to determine whether a file -should exist after patching. -However, if the input is not a context diff or if -.B patch -is conforming to \s-1POSIX\s0, -.B patch -does not remove empty patched files unless this option is given. -When -.B patch -removes a file, it also attempts to remove any empty ancestor directories. -.TP -\fB\-f\fP or \fB\*=force\fP -Assume that the user knows exactly what he or she is doing, and do not -ask any questions. Skip patches whose headers -do not say which file is to be patched; patch files even though they have the -wrong version for the -.B Prereq:\& -line in the patch; and assume that -patches are not reversed even if they look like they are. -This option does not suppress commentary; use -.B \-s -for that. -.TP -\fB\-F\fP \fInum\fP or \fB\*=fuzz=\fP\fInum\fP -Set the maximum fuzz factor. -This option only applies to diffs that have context, and causes -.B patch -to ignore up to that many lines in looking for places to install a hunk. -Note that a larger fuzz factor increases the odds of a faulty patch. -The default fuzz factor is 2, and it may not be set to more than -the number of lines of context in the context diff, ordinarily 3. -.TP -\fB\-g\fP \fInum\fP or \fB\*=get=\fP\fInum\fP -This option controls -.BR patch 's -actions when a file is under \s-1RCS\s0 or \s-1SCCS\s0 control, -and does not exist or is read-only and matches the default version, -or when a file is under ClearCase control and does not exist. -If -.I num -is positive, -.B patch -gets (or checks out) the file from the revision control system; if zero, -.B patch -ignores \s-1RCS\s0, ClearCase, and \s-1SCCS\s0 -and does not get the file; and if negative, -.B patch -asks the user whether to get the file. -The default value of this option is given by the value of the -.B PATCH_GET -environment variable if it is set; if not, the default value is zero if -.B patch -is conforming to \s-1POSIX\s0, negative otherwise. -.TP -.B "\*=help" -Print a summary of options and exit. -.TP -\fB\-i\fP \fIpatchfile\fP or \fB\*=input=\fP\fIpatchfile\fP -Read the patch from -.IR patchfile . -If -.I patchfile -is -.BR \- , -read from standard input, the default. -.TP -\fB\-l\fP or \fB\*=ignore\-whitespace\fP -Match patterns loosely, in case tabs or spaces -have been munged in your files. -Any sequence of one or more blanks in the patch file matches any sequence -in the original file, and sequences of blanks at the ends of lines are ignored. -Normal characters must still match exactly. -Each line of the context must still match a line in the original file. -.TP -\fB\-n\fP or \fB\*=normal\fP -Interpret the patch file as a normal diff. -.TP -\fB\-N\fP or \fB\*=forward\fP -Ignore patches that seem to be reversed or already applied. -See also -.BR \-R . -.TP -\fB\-o\fP \fIoutfile\fP or \fB\*=output=\fP\fIoutfile\fP -Send output to -.I outfile -instead of patching files in place. -.TP -\fB\-p\fP\fInum\fP or \fB\*=strip\fP\fB=\fP\fInum\fP -Strip the smallest prefix containing -.I num -leading slashes from each file name found in the patch file. -A sequence of one or more adjacent slashes is counted as a single slash. -This controls how file names found in the patch file are treated, in case -you keep your files in a different directory than the person who sent -out the patch. -For example, supposing the file name in the patch file was -.Sp - \fB/u/howard/src/blurfl/blurfl.c\fP -.Sp -setting -.B \-p0 -gives the entire file name unmodified, -.B \-p1 -gives -.Sp - \fBu/howard/src/blurfl/blurfl.c\fP -.Sp -without the leading slash, -.B \-p4 -gives -.Sp - \fBblurfl/blurfl.c\fP -.Sp -and not specifying -.B \-p -at all just gives you \fBblurfl.c\fP. -Whatever you end up with is looked for either in the current directory, -or the directory specified by the -.B \-d -option. -.TP -.B \*=posix -Conform more strictly to the \s-1POSIX\s0 standard, as follows. -.RS -.TP 3 -.B " \(bu" -Take the first existing file from the list (old, new, index) -when intuiting file names from diff headers. -.TP -.B " \(bu" -Do not remove files that are empty after patching. -.TP -.B " \(bu" -Do not ask whether to get files from \s-1RCS\s0, ClearCase, or \s-1SCCS\s0. -.TP -.B " \(bu" -Require that all options precede the files in the command line. -.TP -.B " \(bu" -Do not backup files when there is a mismatch. -.RE -.TP -.BI \*=quoting\-style= word -Use style -.I word -to quote output names. -The -.I word -should be one of the following: -.RS -.TP -.B literal -Output names as-is. -.TP -.B shell -Quote names for the shell if they contain shell metacharacters or would -cause ambiguous output. -.TP -.B shell-always -Quote names for the shell, even if they would normally not require quoting. -.TP -.B c -Quote names as for a C language string. -.TP -.B escape -Quote as with -.B c -except omit the surrounding double-quote characters. -.LP -You can specify the default value of the -.B \*=quoting\-style -option with the environment variable -.BR QUOTING_STYLE . -If that environment variable is not set, the default value is -.BR shell . -.RE -.TP -\fB\-r\fP \fIrejectfile\fP or \fB\*=reject\-file=\fP\fIrejectfile\fP -Put rejects into -.I rejectfile -instead of the default -.B \&.rej -file. -.TP -\fB\-R\fP or \fB\*=reverse\fP -Assume that this patch was created with the old and new files swapped. -(Yes, I'm afraid that does happen occasionally, human nature being what it -is.) -.B patch -attempts to swap each hunk around before applying it. -Rejects come out in the swapped format. -The -.B \-R -option does not work with -.B ed -diff scripts because there is too little -information to reconstruct the reverse operation. -.Sp -If the first hunk of a patch fails, -.B patch -reverses the hunk to see if it can be applied that way. -If it can, you are asked if you want to have the -.B \-R -option set. -If it can't, the patch continues to be applied normally. -(Note: this method cannot detect a reversed patch if it is a normal diff -and if the first command is an append (i.e. it should have been a delete) -since appends always succeed, due to the fact that a null context matches -anywhere. -Luckily, most patches add or change lines rather than delete them, so most -reversed normal diffs begin with a delete, which fails, triggering -the heuristic.) -.TP -\fB\-s\fP or \fB\*=silent\fP or \fB\*=quiet\fP -Work silently, unless an error occurs. -.TP -\fB\-t\fP or \fB\*=batch\fP -Suppress questions like -.BR \-f , -but make some different assumptions: -skip patches whose headers do not contain file names (the same as \fB\-f\fP); -skip patches for which the file has the wrong version for the -.B Prereq:\& -line -in the patch; and assume that patches are reversed if they look like -they are. -.TP -\fB\-T\fP or \fB\*=set\-time\fP -Set the modification and access times of patched files from time stamps -given in context diff headers, assuming that the context diff headers -use local time. This option is not recommended, because patches using -local time cannot easily be used by people in other time zones, and -because local time stamps are ambiguous when local clocks move backwards -during daylight-saving time adjustments. Instead of using this option, -generate patches with \s-1UTC\s0 and use the -.B \-Z -or -.B \*=set\-utc -option instead. -.TP -\fB\-u\fP or \fB\*=unified\fP -Interpret the patch file as a unified context diff. -.TP -\fB\-v\fP or \fB\*=version\fP -Print out -.BR patch 's -revision header and patch level, and exit. -.TP -\fB\-V\fP \fImethod\fP or \fB\*=version\-control=\fP\fImethod\fP -Use -.I method -to determine -backup file names. The method can also be given by the -.B PATCH_VERSION_CONTROL -(or, if that's not set, the -.BR VERSION_CONTROL ) -environment variable, which is overridden by this option. -The method does not affect whether backup files are made; -it affects only the names of any backup files that are made. -.Sp -The value of -.I method -is like the \s-1GNU\s0 -Emacs `version-control' variable; -.B patch -also recognizes synonyms that -are more descriptive. The valid values for -.I method -are (unique abbreviations are -accepted): -.RS -.TP 3 -\fBexisting\fP or \fBnil\fP -Make numbered backups of files that already have them, -otherwise simple backups. -This is the default. -.TP -\fBnumbered\fP or \fBt\fP -Make numbered backups. The numbered backup file name for -.I F -is -.IB F .~ N ~ -where -.I N -is the version number. -.TP -\fBsimple\fP or \fBnever\fP -Make simple backups. -The -.B \-B -or -.BR \*=prefix , -.B \-Y -or -.BR \*=basename\-prefix , -and -.B \-z -or -.BR \*=suffix -options specify the simple backup file name. -If none of these options are given, then a simple backup suffix is used; -it is the value of the -.B SIMPLE_BACKUP_SUFFIX -environment variable if set, and is -.B \&.orig -otherwise. -.PP -With numbered or simple backups, -if the backup file name is too long, the backup suffix -.B ~ -is used instead; if even appending -.B ~ -would make the name too long, then -.B ~ -replaces the last character of the file name. -.RE -.TP -\fB\*=verbose\fP -Output extra information about the work being done. -.TP -\fB\-x\fP \fInum\fP or \fB\*=debug=\fP\fInum\fP -Set internal debugging flags of interest only to -.B patch -patchers. -.TP -\fB\-Y\fP \fIpref\fP or \fB\*=basename\-prefix=\fP\fIpref\fP -Prefix -.I pref -to the basename of a file name when generating its simple backup file name. -For example, with -.B "\-Y\ .del/" -the simple backup file name for -.B src/patch/util.c -is -.BR src/patch/.del/util.c . -.TP -\fB\-z\fP \fIsuffix\fP or \fB\*=suffix=\fP\fIsuffix\fP -Use -.I suffix -as the simple backup suffix. -For example, with -.B "\-z\ -" -the simple backup file name for -.B src/patch/util.c -is -.BR src/patch/util.c- . -The backup suffix may also be specified by the -.B SIMPLE_BACKUP_SUFFIX -environment variable, which is overridden by this option. -.TP -\fB\-Z\fP or \fB\*=set\-utc\fP -Set the modification and access times of patched files from time stamps -given in context diff headers, assuming that the context diff headers -use Coordinated Universal Time (\s-1UTC\s0, often known as \s-1GMT\s0). -Also see the -.B \-T -or -.B \*=set\-time -option. -.Sp -The -.B \-Z -or -.B \*=set\-utc -and -.B \-T -or -.B \*=set\-time -options normally refrain from setting a file's time if the file's original time -does not match the time given in the patch header, or if its -contents do not match the patch exactly. However, if the -.B \-f -or -.B \*=force -option is given, the file time is set regardless. -.Sp -Due to the limitations of -.B diff -output format, these options cannot update the times of files whose -contents have not changed. Also, if you use these options, you should remove -(e.g. with -.BR "make\ clean" ) -all files that depend on the patched files, so that later invocations of -.B make -do not get confused by the patched files' times. -.SH ENVIRONMENT -.TP 3 -.B PATCH_GET -This specifies whether -.B patch -gets missing or read-only files from \s-1RCS\s0, ClearCase, or \s-1SCCS\s0 -by default; see the -.B \-g -or -.B \*=get -option. -.TP -.B POSIXLY_CORRECT -If set, -.B patch -conforms more strictly to the \s-1POSIX\s0 standard by default: -see the -.B \*=posix -option. -.TP -.B QUOTING_STYLE -Default value of the -.B \*=quoting\-style -option. -.TP -.B SIMPLE_BACKUP_SUFFIX -Extension to use for simple backup file names instead of -.BR \&.orig . -.TP -\fBTMPDIR\fP, \fBTMP\fP, \fBTEMP\fP -Directory to put temporary files in; -.B patch -uses the first environment variable in this list that is set. -If none are set, the default is system-dependent; -it is normally -.B /tmp -on Unix hosts. -.TP -\fBVERSION_CONTROL\fP or \fBPATCH_VERSION_CONTROL\fP -Selects version control style; see the -.B \-v -or -.B \*=version\-control -option. -.SH FILES -.TP 3 -.IB $TMPDIR "/p\(**" -temporary files -.TP -.B /dev/tty -controlling terminal; used to get answers to questions asked of the user -.SH "SEE ALSO" -.BR diff (1), -.BR ed (1) -.Sp -Marshall T. Rose and Einar A. Stefferud, -Proposed Standard for Message Encapsulation, -Internet RFC 934 (1985-01). -.SH "NOTES FOR PATCH SENDERS" -There are several things you should bear in mind if you are going to -be sending out patches. -.PP -Create your patch systematically. -A good method is the command -.BI "diff\ \-Naur\ " "old\ new" -where -.I old -and -.I new -identify the old and new directories. -The names -.I old -and -.I new -should not contain any slashes. -The -.B diff -command's headers should have dates -and times in Universal Time using traditional Unix format, -so that patch recipients can use the -.B \-Z -or -.B \*=set\-utc -option. -Here is an example command, using Bourne shell syntax: -.Sp - \fBLC_ALL=C TZ=UTC0 diff \-Naur gcc\-2.7 gcc\-2.8\fP -.PP -Tell your recipients how to apply the patch -by telling them which directory to -.B cd -to, and which -.B patch -options to use. The option string -.B "\-Np1" -is recommended. -Test your procedure by pretending to be a recipient and applying -your patch to a copy of the original files. -.PP -You can save people a lot of grief by keeping a -.B patchlevel.h -file which is patched to increment the patch level -as the first diff in the patch file you send out. -If you put a -.B Prereq:\& -line in with the patch, it won't let them apply -patches out of order without some warning. -.PP -You can create a file by sending out a diff that compares -.B /dev/null -or an empty file dated the Epoch (1970-01-01 00:00:00 \s-1UTC\s0) -to the file you want to create. -This only works if the file you want to create doesn't exist already in -the target directory. -Conversely, you can remove a file by sending out a context diff that compares -the file to be deleted with an empty file dated the Epoch. -The file will be removed unless -.B patch -is conforming to \s-1POSIX\s0 and the -.B \-E -or -.B \*=remove\-empty\-files -option is not given. -An easy way to generate patches that create and remove files -is to use \s-1GNU\s0 -.BR diff 's -.B \-N -or -.B \*=new\-file -option. -.PP -If the recipient is supposed to use the -.BI \-p N -option, do not send output that looks like this: -.Sp -.ft B -.ne 3 - diff \-Naur v2.0.29/prog/README prog/README -.br - \-\^\-\^\- v2.0.29/prog/README Mon Mar 10 15:13:12 1997 -.br - +\^+\^+ prog/README Mon Mar 17 14:58:22 1997 -.ft -.Sp -because the two file names have different numbers of slashes, -and different versions of -.B patch -interpret the file names differently. -To avoid confusion, send output that looks like this instead: -.Sp -.ft B -.ne 3 - diff \-Naur v2.0.29/prog/README v2.0.30/prog/README -.br - \-\^\-\^\- v2.0.29/prog/README Mon Mar 10 15:13:12 1997 -.br - +\^+\^+ v2.0.30/prog/README Mon Mar 17 14:58:22 1997 -.ft -.Sp -.PP -Avoid sending patches that compare backup file names like -.BR README.orig , -since this might confuse -.B patch -into patching a backup file instead of the real file. -Instead, send patches that compare the same base file names -in different directories, e.g.\& -.B old/README -and -.BR new/README . -.PP -Take care not to send out reversed patches, since it makes people wonder -whether they already applied the patch. -.PP -Try not to have your patch modify derived files -(e.g. the file -.B configure -where there is a line -.B "configure: configure.in" -in your makefile), since the recipient should be -able to regenerate the derived files anyway. -If you must send diffs of derived files, -generate the diffs using \s-1UTC\s0, -have the recipients apply the patch with the -.B \-Z -or -.B \*=set\-utc -option, and have them remove any unpatched files that depend on patched files -(e.g. with -.BR "make\ clean" ). -.PP -While you may be able to get away with putting 582 diff listings into -one file, it may be wiser to group related patches into separate files in -case something goes haywire. -.SH DIAGNOSTICS -Diagnostics generally indicate that -.B patch -couldn't parse your patch file. -.PP -If the -.B \*=verbose -option is given, the message -.B Hmm.\|.\|.\& -indicates that there is unprocessed text in -the patch file and that -.B patch -is attempting to intuit whether there is a patch in that text and, if so, -what kind of patch it is. -.PP -.BR patch 's -exit status is -0 if all hunks are applied successfully, -1 if some hunks cannot be applied, -and 2 if there is more serious trouble. -When applying a set of patches in a loop it behooves you to check this -exit status so you don't apply a later patch to a partially patched file. -.SH CAVEATS -Context diffs cannot reliably represent the creation or deletion of -empty files, empty directories, or special files such as symbolic links. -Nor can they represent changes to file metadata like ownership, permissions, -or whether one file is a hard link to another. -If changes like these are also required, separate instructions -(e.g. a shell script) to accomplish them should accompany the patch. -.PP -.B patch -cannot tell if the line numbers are off in an -.B ed -script, and can detect -bad line numbers in a normal diff only when it finds a change or deletion. -A context diff using fuzz factor 3 may have the same problem. -Until a suitable interactive interface is added, you should probably do -a context diff in these cases to see if the changes made sense. -Of course, compiling without errors is a pretty good indication that the patch -worked, but not always. -.PP -.B patch -usually produces the correct results, even when it has to do a lot of -guessing. -However, the results are guaranteed to be correct only when the patch is -applied to exactly the same version of the file that the patch was -generated from. -.SH "COMPATIBILITY ISSUES" -The \s-1POSIX\s0 standard specifies behavior that differs from -.BR patch 's -traditional behavior. -You should be aware of these differences if you must interoperate with -.B patch -versions 2.1 and earlier, which do not conform to \s-1POSIX\s0. -.TP 3 -.B " \(bu" -In traditional -.BR patch , -the -.B \-p -option's operand was optional, and a bare -.B \-p -was equivalent to -.BR \-p0. -The -.B \-p -option now requires an operand, and -.B "\-p\ 0" -is now equivalent to -.BR \-p0 . -For maximum compatibility, use options like -.B \-p0 -and -.BR \-p1 . -.Sp -Also, -traditional -.B patch -simply counted slashes when stripping path prefixes; -.B patch -now counts pathname components. -That is, a sequence of one or more adjacent slashes -now counts as a single slash. -For maximum portability, avoid sending patches containing -.B // -in file names. -.TP -.B " \(bu" -In traditional -.BR patch , -backups were enabled by default. -This behavior is now enabled with the -.B \-b -or -.B \*=backup -option. -.Sp -Conversely, in \s-1POSIX\s0 -.BR patch , -backups are never made, even when there is a mismatch. -In \s-1GNU\s0 -.BR patch , -this behavior is enabled with the -.B \*=no\-backup\-if\-mismatch -option, or by conforming to \s-1POSIX\s0 with the -.B \*=posix -option or by setting the -.B POSIXLY_CORRECT -environment variable. -.Sp -The -.BI \-b "\ suffix" -option -of traditional -.B patch -is equivalent to the -.BI "\-b\ \-z" "\ suffix" -options of \s-1GNU\s0 -.BR patch . -.TP -.B " \(bu" -Traditional -.B patch -used a complicated (and incompletely documented) method -to intuit the name of the file to be patched from the patch header. -This method did not conform to \s-1POSIX\s0, and had a few gotchas. -Now -.B patch -uses a different, equally complicated (but better documented) method -that is optionally \s-1POSIX\s0-conforming; we hope it has -fewer gotchas. The two methods are compatible if the -file names in the context diff header and the -.B Index:\& -line are all identical after prefix-stripping. -Your patch is normally compatible if each header's file names -all contain the same number of slashes. -.TP -.B " \(bu" -When traditional -.B patch -asked the user a question, it sent the question to standard error -and looked for an answer from -the first file in the following list that was a terminal: -standard error, standard output, -.BR /dev/tty , -and standard input. -Now -.B patch -sends questions to standard output and gets answers from -.BR /dev/tty . -Defaults for some answers have been changed so that -.B patch -never goes into an infinite loop when using default answers. -.TP -.B " \(bu" -Traditional -.B patch -exited with a status value that counted the number of bad hunks, -or with status 1 if there was real trouble. -Now -.B patch -exits with status 1 if some hunks failed, -or with 2 if there was real trouble. -.TP -.B " \(bu" -Limit yourself to the following options when sending instructions -meant to be executed by anyone running \s-1GNU\s0 -.BR patch , -traditional -.BR patch , -or a -.B patch -that conforms to \s-1POSIX\s0. -Spaces are significant in the following list, and operands are required. -.Sp -.nf -.in +3 -.ne 11 -.B \-c -.BI \-d " dir" -.BI \-D " define" -.B \-e -.B \-l -.B \-n -.B \-N -.BI \-o " outfile" -.BI \-p num -.B \-R -.BI \-r " rejectfile" -.in -.fi -.SH BUGS -Please report bugs via email to -.BR . -.PP -.B patch -could be smarter about partial matches, excessively deviant offsets and -swapped code, but that would take an extra pass. -.PP -If code has been duplicated (for instance with -\fB#ifdef OLDCODE\fP .\|.\|. \fB#else .\|.\|. #endif\fP), -.B patch -is incapable of patching both versions, and, if it works at all, will likely -patch the wrong one, and tell you that it succeeded to boot. -.PP -If you apply a patch you've already applied, -.B patch -thinks it is a reversed patch, and offers to un-apply the patch. -This could be construed as a feature. -.SH COPYING -Copyright -.if t \(co -1984, 1985, 1986, 1988 Larry Wall. -.br -Copyright -.if t \(co -1989, 1990, 1991, 1992, 1993, 1994, 1995, 1996, 1997, 1998 -Free Software Foundation, Inc. -.PP -Permission is granted to make and distribute verbatim copies of -this manual provided the copyright notice and this permission notice -are preserved on all copies. -.PP -Permission is granted to copy and distribute modified versions of this -manual under the conditions for verbatim copying, provided that the -entire resulting derived work is distributed under the terms of a -permission notice identical to this one. -.PP -Permission is granted to copy and distribute translations of this -manual into another language, under the above conditions for modified -versions, except that this permission notice may be included in -translations approved by the copyright holders instead of in -the original English. -.SH AUTHORS -Larry Wall wrote the original version of -.BR patch . -Paul Eggert removed -.BR patch 's -arbitrary limits; added support for binary files, -setting file times, and deleting files; -and made it conform better to \s-1POSIX\s0. -Other contributors include Wayne Davison, who added unidiff support, -and David MacKenzie, who added configuration and backup support. diff --git a/src/bin/patch/patch.rdef b/src/bin/patch/patch.rdef deleted file mode 100644 index 969d56db9e..0000000000 --- a/src/bin/patch/patch.rdef +++ /dev/null @@ -1,11 +0,0 @@ -resource app_version -{ - major = 2, - middle = 5, - minor = 4, - variety = 5, - internal = 0, - short_info = "2.5.4", - long_info = "2.5.4 ©1999 The Free Software Foundation" -}; - diff --git a/src/bin/patch/patchlevel.h b/src/bin/patch/patchlevel.h deleted file mode 100644 index 5fa53213cc..0000000000 --- a/src/bin/patch/patchlevel.h +++ /dev/null @@ -1 +0,0 @@ -#define PATCH_VERSION "2.5.4" diff --git a/src/bin/patch/pch.c b/src/bin/patch/pch.c deleted file mode 100644 index ef7c8e5af4..0000000000 --- a/src/bin/patch/pch.c +++ /dev/null @@ -1,1913 +0,0 @@ -/* reading patches */ - -/* $Id: pch.c 8008 2004-06-16 21:22:10Z korli $ */ - -/* Copyright 1986, 1987, 1988 Larry Wall - Copyright 1990, 1991-1993, 1997-1998, 1999 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define XTERN extern -#include -#include -#include -#include -#include -#include -#undef XTERN -#define XTERN -#include - -#define INITHUNKMAX 125 /* initial dynamic allocation size */ - -/* Patch (diff listing) abstract type. */ - -static FILE *pfp; /* patch file pointer */ -static int p_says_nonexistent[2]; /* [0] for old file, [1] for new: - 0 for existent and nonempty, - 1 for existent and probably (but not necessarily) empty, - 2 for nonexistent */ -static int p_rfc934_nesting; /* RFC 934 nesting level */ -static time_t p_timestamp[2]; /* timestamps in patch headers */ -static off_t p_filesize; /* size of the patch file */ -static LINENUM p_first; /* 1st line number */ -static LINENUM p_newfirst; /* 1st line number of replacement */ -static LINENUM p_ptrn_lines; /* # lines in pattern */ -static LINENUM p_repl_lines; /* # lines in replacement text */ -static LINENUM p_end = -1; /* last line in hunk */ -static LINENUM p_max; /* max allowed value of p_end */ -static LINENUM p_prefix_context; /* # of prefix context lines */ -static LINENUM p_suffix_context; /* # of suffix context lines */ -static LINENUM p_input_line; /* current line # from patch file */ -static char **p_line; /* the text of the hunk */ -static size_t *p_len; /* line length including \n if any */ -static char *p_Char; /* +, -, and ! */ -static LINENUM hunkmax = INITHUNKMAX; /* size of above arrays */ -static int p_indent; /* indent to patch */ -static int p_strip_trailing_cr; /* nonzero if stripping trailing \r */ -static file_offset p_base; /* where to intuit this time */ -static LINENUM p_bline; /* line # of p_base */ -static file_offset p_start; /* where intuit found a patch */ -static LINENUM p_sline; /* and the line number for it */ -static LINENUM p_hunk_beg; /* line number of current hunk */ -static LINENUM p_efake = -1; /* end of faked up lines--don't free */ -static LINENUM p_bfake = -1; /* beg of faked up lines */ - -enum nametype { OLD, NEW, INDEX, NONE }; - -static char *scan_linenum PARAMS ((char *, LINENUM *)); -static enum diff intuit_diff_type PARAMS ((void)); -static enum nametype best_name PARAMS ((char * const *, int const *)); -static int prefix_components PARAMS ((char *, int)); -static size_t pget_line PARAMS ((int, int, int)); -static size_t get_line PARAMS ((void)); -static bool incomplete_line PARAMS ((void)); -static bool grow_hunkmax PARAMS ((void)); -static void malformed PARAMS ((void)) __attribute__ ((noreturn)); -static void next_intuit_at PARAMS ((file_offset, LINENUM)); -static void skip_to PARAMS ((file_offset, LINENUM)); - -/* Prepare to look for the next patch in the patch file. */ - -void -re_patch (void) -{ - p_first = 0; - p_newfirst = 0; - p_ptrn_lines = 0; - p_repl_lines = 0; - p_end = -1; - p_max = 0; - p_indent = 0; - p_strip_trailing_cr = 0; -} - -/* Open the patch file at the beginning of time. */ - -void -open_patch_file (char const *filename) -{ - file_offset file_pos = 0; - struct stat st; - if (!filename || !*filename || strEQ (filename, "-")) - { - file_offset stdin_pos; -#if HAVE_SETMODE - if (binary_transput) - { - if (isatty (STDIN_FILENO)) - fatal ("cannot read binary data from tty on this platform"); - setmode (STDIN_FILENO, O_BINARY); - } -#endif - if (fstat (STDIN_FILENO, &st) != 0) - pfatal ("fstat"); - if (S_ISREG (st.st_mode) && (stdin_pos = file_tell (stdin)) != -1) - { - pfp = stdin; - file_pos = stdin_pos; - } - else - { - size_t charsread; - int exclusive = TMPPATNAME_needs_removal ? 0 : O_EXCL; - TMPPATNAME_needs_removal = 1; - pfp = fdopen (create_file (TMPPATNAME, - O_RDWR | O_BINARY | exclusive, - (mode_t) 0), - "w+b"); - if (!pfp) - pfatal ("Can't open stream for file %s", quotearg (TMPPATNAME)); - for (st.st_size = 0; - (charsread = fread (buf, 1, bufsize, stdin)) != 0; - st.st_size += charsread) - if (fwrite (buf, 1, charsread, pfp) != charsread) - write_fatal (); - if (ferror (stdin) || fclose (stdin) != 0) - read_fatal (); - if (fflush (pfp) != 0 - || file_seek (pfp, (file_offset) 0, SEEK_SET) != 0) - write_fatal (); - } - } - else - { - pfp = fopen (filename, binary_transput ? "rb" : "r"); - if (!pfp) - pfatal ("Can't open patch file %s", quotearg (filename)); - if (fstat (fileno (pfp), &st) != 0) - pfatal ("fstat"); - } - p_filesize = st.st_size; - if (p_filesize != (file_offset) p_filesize) - fatal ("patch file is too long"); - next_intuit_at (file_pos, (LINENUM) 1); - set_hunkmax(); -} - -/* Make sure our dynamically realloced tables are malloced to begin with. */ - -void -set_hunkmax (void) -{ - if (!p_line) - p_line = (char **) malloc (hunkmax * sizeof *p_line); - if (!p_len) - p_len = (size_t *) malloc (hunkmax * sizeof *p_len); - if (!p_Char) - p_Char = malloc (hunkmax * sizeof *p_Char); -} - -/* Enlarge the arrays containing the current hunk of patch. */ - -static bool -grow_hunkmax (void) -{ - hunkmax *= 2; - assert (p_line && p_len && p_Char); - if ((p_line = (char **) realloc (p_line, hunkmax * sizeof (*p_line))) - && (p_len = (size_t *) realloc (p_len, hunkmax * sizeof (*p_len))) - && (p_Char = realloc (p_Char, hunkmax * sizeof (*p_Char)))) - return TRUE; - if (!using_plan_a) - memory_fatal (); - /* Don't free previous values of p_line etc., - since some broken implementations free them for us. - Whatever is null will be allocated again from within plan_a (), - of all places. */ - return FALSE; -} - -/* True if the remainder of the patch file contains a diff of some sort. */ - -bool -there_is_another_patch (void) -{ - if (p_base != 0 && p_base >= p_filesize) { - if (verbosity == VERBOSE) - say ("done\n"); - return FALSE; - } - if (verbosity == VERBOSE) - say ("Hmm..."); - diff_type = intuit_diff_type(); - if (diff_type == NO_DIFF) { - if (verbosity == VERBOSE) - say (p_base - ? " Ignoring the trailing garbage.\ndone\n" - : " I can't seem to find a patch in there anywhere.\n"); - if (! p_base && p_filesize) - fatal ("Only garbage was found in the patch input."); - return FALSE; - } - if (skip_rest_of_patch) - { - Fseek (pfp, p_start, SEEK_SET); - p_input_line = p_sline - 1; - return TRUE; - } - if (verbosity == VERBOSE) - say (" %sooks like %s to me...\n", - (p_base == 0 ? "L" : "The next patch l"), - diff_type == UNI_DIFF ? "a unified diff" : - diff_type == CONTEXT_DIFF ? "a context diff" : - diff_type == NEW_CONTEXT_DIFF ? "a new-style context diff" : - diff_type == NORMAL_DIFF ? "a normal diff" : - "an ed script" ); - - if (verbosity != SILENT) - { - if (p_indent) - say ("(Patch is indented %d space%s.)\n", p_indent, p_indent==1?"":"s"); - if (p_strip_trailing_cr) - say ("(Stripping trailing CRs from patch.)\n"); - if (! inname) - { - char numbuf[LINENUM_LENGTH_BOUND + 1]; - say ("can't find file to patch at input line %s\n", - format_linenum (numbuf, p_sline)); - say (strippath == -1 - ? "Perhaps you should have used the -p or --strip option?\n" - : "Perhaps you used the wrong -p or --strip option?\n"); - } - } - - skip_to(p_start,p_sline); - while (!inname) { - if (force || batch) { - say ("No file to patch. Skipping patch.\n"); - skip_rest_of_patch = TRUE; - return TRUE; - } - ask ("File to patch: "); - inname = fetchname (buf, 0, (time_t *) 0); - if (inname) - { - if (stat (inname, &instat) == 0) - { - inerrno = 0; - invc = -1; - } - else - { - perror (inname); - free (inname); - inname = 0; - } - } - if (!inname) { - ask ("Skip this patch? [y] "); - if (*buf != 'n') { - if (verbosity != SILENT) - say ("Skipping patch.\n"); - skip_rest_of_patch = TRUE; - return TRUE; - } - } - } - return TRUE; -} - -/* Determine what kind of diff is in the remaining part of the patch file. */ - -static enum diff -intuit_diff_type (void) -{ - register file_offset this_line = 0; - register file_offset first_command_line = -1; - LINENUM fcl_line = 0; /* Pacify `gcc -W'. */ - register bool this_is_a_command = FALSE; - register bool stars_this_line = FALSE; - enum nametype i; - char *name[3]; - struct stat st[3]; - int stat_errno[3]; - int version_controlled[3]; - register enum diff retval; - - name[OLD] = name[NEW] = name[INDEX] = 0; - version_controlled[OLD] = -1; - version_controlled[NEW] = -1; - version_controlled[INDEX] = -1; - p_rfc934_nesting = 0; - p_timestamp[OLD] = p_timestamp[NEW] = (time_t) -1; - p_says_nonexistent[OLD] = p_says_nonexistent[NEW] = 0; - Fseek (pfp, p_base, SEEK_SET); - p_input_line = p_bline - 1; - for (;;) { - register char *s; - register char *t; - register file_offset previous_line = this_line; - register bool last_line_was_command = this_is_a_command; - register bool stars_last_line = stars_this_line; - register int indent = 0; - int strip_trailing_cr; - size_t chars_read; - - this_line = file_tell (pfp); - chars_read = pget_line (0, 0, 0); - if (chars_read == (size_t) -1) - memory_fatal (); - if (! chars_read) { - if (first_command_line >= 0) { - /* nothing but deletes!? */ - p_start = first_command_line; - p_sline = fcl_line; - retval = ED_DIFF; - goto scan_exit; - } - else { - p_start = this_line; - p_sline = p_input_line; - return NO_DIFF; - } - } - strip_trailing_cr = 2 <= chars_read && buf[chars_read - 2] == '\r'; - for (s = buf; *s == ' ' || *s == '\t' || *s == 'X'; s++) { - if (*s == '\t') - indent = (indent + 8) & ~7; - else - indent++; - } - for (t = s; ISDIGIT (*t) || *t == ','; t++) - continue; - this_is_a_command = (ISDIGIT (*s) && - (*t == 'd' || *t == 'c' || *t == 'a') ); - if (first_command_line < 0 && this_is_a_command) { - first_command_line = this_line; - fcl_line = p_input_line; - p_indent = indent; /* assume this for now */ - p_strip_trailing_cr = strip_trailing_cr; - } - if (!stars_last_line && strnEQ(s, "*** ", 4)) - name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]); - else if (strnEQ(s, "+++ ", 4)) - /* Swap with NEW below. */ - name[OLD] = fetchname (s+4, strippath, &p_timestamp[OLD]); - else if (strnEQ(s, "Index:", 6)) - name[INDEX] = fetchname (s+6, strippath, (time_t *) 0); - else if (strnEQ(s, "Prereq:", 7)) { - for (t = s + 7; ISSPACE ((unsigned char) *t); t++) - continue; - revision = t; - for (t = revision; *t && !ISSPACE ((unsigned char) *t); t++) - continue; - if (t == revision) - revision = 0; - else { - char oldc = *t; - *t = '\0'; - revision = savestr (revision); - *t = oldc; - } - } else - { - for (t = s; t[0] == '-' && t[1] == ' '; t += 2) - continue; - if (strnEQ(t, "--- ", 4)) - { - time_t timestamp = (time_t) -1; - name[NEW] = fetchname (t+4, strippath, ×tamp); - if (timestamp != (time_t) -1) - { - p_timestamp[NEW] = timestamp; - p_rfc934_nesting = (t - s) >> 1; - } - } - } - if ((diff_type == NO_DIFF || diff_type == ED_DIFF) && - first_command_line >= 0 && - strEQ(s, ".\n") ) { - p_indent = indent; - p_strip_trailing_cr = strip_trailing_cr; - p_start = first_command_line; - p_sline = fcl_line; - retval = ED_DIFF; - goto scan_exit; - } - if ((diff_type == NO_DIFF || diff_type == UNI_DIFF) - && strnEQ(s, "@@ -", 4)) { - - /* `name' and `p_timestamp' are backwards; swap them. */ - time_t ti = p_timestamp[OLD]; - p_timestamp[OLD] = p_timestamp[NEW]; - p_timestamp[NEW] = ti; - t = name[OLD]; - name[OLD] = name[NEW]; - name[NEW] = t; - - s += 4; - if (s[0] == '0' && !ISDIGIT (s[1])) - p_says_nonexistent[OLD] = 1 + ! p_timestamp[OLD]; - while (*s != ' ' && *s != '\n') - s++; - while (*s == ' ') - s++; - if (s[0] == '+' && s[1] == '0' && !ISDIGIT (s[2])) - p_says_nonexistent[NEW] = 1 + ! p_timestamp[NEW]; - p_indent = indent; - p_strip_trailing_cr = strip_trailing_cr; - p_start = this_line; - p_sline = p_input_line; - retval = UNI_DIFF; - if (! ((name[OLD] || ! p_timestamp[OLD]) - && (name[NEW] || ! p_timestamp[NEW]))) - { - char numbuf[LINENUM_LENGTH_BOUND + 1]; - say ("missing header for unified diff at line %s of patch\n", - format_linenum (numbuf, p_sline)); - } - goto scan_exit; - } - stars_this_line = strnEQ(s, "********", 8); - if ((diff_type == NO_DIFF - || diff_type == CONTEXT_DIFF - || diff_type == NEW_CONTEXT_DIFF) - && stars_last_line && strnEQ (s, "*** ", 4)) { - s += 4; - if (s[0] == '0' && !ISDIGIT (s[1])) - p_says_nonexistent[OLD] = 1 + ! p_timestamp[OLD]; - /* if this is a new context diff the character just before */ - /* the newline is a '*'. */ - while (*s != '\n') - s++; - p_indent = indent; - p_strip_trailing_cr = strip_trailing_cr; - p_start = previous_line; - p_sline = p_input_line - 1; - retval = (*(s-1) == '*' ? NEW_CONTEXT_DIFF : CONTEXT_DIFF); - - { - /* Scan the first hunk to see whether the file contents - appear to have been deleted. */ - file_offset saved_p_base = p_base; - LINENUM saved_p_bline = p_bline; - Fseek (pfp, previous_line, SEEK_SET); - p_input_line -= 2; - if (another_hunk (retval, 0) - && ! p_repl_lines && p_newfirst == 1) - p_says_nonexistent[NEW] = 1 + ! p_timestamp[NEW]; - next_intuit_at (saved_p_base, saved_p_bline); - } - - if (! ((name[OLD] || ! p_timestamp[OLD]) - && (name[NEW] || ! p_timestamp[NEW]))) - { - char numbuf[LINENUM_LENGTH_BOUND + 1]; - say ("missing header for context diff at line %s of patch\n", - format_linenum (numbuf, p_sline)); - } - goto scan_exit; - } - if ((diff_type == NO_DIFF || diff_type == NORMAL_DIFF) && - last_line_was_command && - (strnEQ(s, "< ", 2) || strnEQ(s, "> ", 2)) ) { - p_start = previous_line; - p_sline = p_input_line - 1; - p_indent = indent; - p_strip_trailing_cr = strip_trailing_cr; - retval = NORMAL_DIFF; - goto scan_exit; - } - } - - scan_exit: - - /* To intuit `inname', the name of the file to patch, - use the algorithm specified by POSIX 1003.2b/D11 section 5.22.7.2 - (with some modifications if posixly_correct is zero): - - - Take the old and new names from the context header if present, - and take the index name from the `Index:' line if present and - if either the old and new names are both absent - or posixly_correct is nonzero. - Consider the file names to be in the order (old, new, index). - - If some named files exist, use the first one if posixly_correct - is nonzero, the best one otherwise. - - If patch_get is nonzero, and no named files exist, - but an RCS or SCCS master file exists, - use the first named file with an RCS or SCCS master. - - If no named files exist, no RCS or SCCS master was found, - some names are given, posixly_correct is zero, - and the patch appears to create a file, then use the best name - requiring the creation of the fewest directories. - - Otherwise, report failure by setting `inname' to 0; - this causes our invoker to ask the user for a file name. */ - - i = NONE; - - if (!inname) - { - enum nametype i0 = NONE; - - if (! posixly_correct && (name[OLD] || name[NEW]) && name[INDEX]) - { - free (name[INDEX]); - name[INDEX] = 0; - } - - for (i = OLD; i <= INDEX; i++) - if (name[i]) - { - if (i0 != NONE && strcmp (name[i0], name[i]) == 0) - { - /* It's the same name as before; reuse stat results. */ - stat_errno[i] = stat_errno[i0]; - if (! stat_errno[i]) - st[i] = st[i0]; - } - else if (stat (name[i], &st[i]) != 0) - stat_errno[i] = errno; - else - { - stat_errno[i] = 0; - if (posixly_correct) - break; - } - i0 = i; - } - - if (! posixly_correct) - { - int is_empty; - - i = best_name (name, stat_errno); - - if (i == NONE && patch_get) - { - enum nametype nope = NONE; - - for (i = OLD; i <= INDEX; i++) - if (name[i]) - { - char const *cs; - char *getbuf; - char *diffbuf; - int readonly = outfile && strcmp (outfile, name[i]) != 0; - - if (nope == NONE || strcmp (name[nope], name[i]) != 0) - { - cs = (version_controller - (name[i], readonly, (struct stat *) 0, - &getbuf, &diffbuf)); - version_controlled[i] = !! cs; - if (cs) - { - if (version_get (name[i], cs, 0, readonly, - getbuf, &st[i])) - stat_errno[i] = 0; - else - version_controlled[i] = 0; - - free (getbuf); - if (diffbuf) - free (diffbuf); - - if (! stat_errno[i]) - break; - } - } - - nope = i; - } - } - - is_empty = i == NONE || st[i].st_size == 0; - if ((! is_empty) < p_says_nonexistent[reverse ^ is_empty]) - { - assert (i0 != NONE); - if (ok_to_reverse - ("The next patch%s would %s the file %s,\nwhich %s!", - reverse ? ", when reversed," : "", - (i == NONE ? "delete" - : st[i].st_size == 0 ? "empty out" - : "create"), - quotearg (name[i == NONE || st[i].st_size == 0 ? i0 : i]), - (i == NONE ? "does not exist" - : st[i].st_size == 0 ? "is already empty" - : "already exists"))) - reverse ^= 1; - } - - if (i == NONE && p_says_nonexistent[reverse]) - { - int newdirs[3]; - int newdirs_min = INT_MAX; - int distance_from_minimum[3]; - - for (i = OLD; i <= INDEX; i++) - if (name[i]) - { - newdirs[i] = (prefix_components (name[i], 0) - - prefix_components (name[i], 1)); - if (newdirs[i] < newdirs_min) - newdirs_min = newdirs[i]; - } - - for (i = OLD; i <= INDEX; i++) - if (name[i]) - distance_from_minimum[i] = newdirs[i] - newdirs_min; - - i = best_name (name, distance_from_minimum); - } - } - } - - if (i == NONE) - inerrno = -1; - else - { - inname = name[i]; - name[i] = 0; - inerrno = stat_errno[i]; - invc = version_controlled[i]; - instat = st[i]; - } - - for (i = OLD; i <= INDEX; i++) - if (name[i]) - free (name[i]); - - return retval; -} - -/* Count the path name components in FILENAME's prefix. - If CHECKDIRS is nonzero, count only existing directories. */ -static int -prefix_components (char *filename, int checkdirs) -{ - int count = 0; - struct stat stat_buf; - int stat_result; - char *f = filename + FILESYSTEM_PREFIX_LEN (filename); - - if (*f) - while (*++f) - if (ISSLASH (f[0]) && ! ISSLASH (f[-1])) - { - if (checkdirs) - { - *f = '\0'; - stat_result = stat (filename, &stat_buf); - *f = '/'; - if (! (stat_result == 0 && S_ISDIR (stat_buf.st_mode))) - break; - } - - count++; - } - - return count; -} - -/* Return the index of the best of NAME[OLD], NAME[NEW], and NAME[INDEX]. - Ignore null names, and ignore NAME[i] if IGNORE[i] is nonzero. - Return NONE if all names are ignored. */ -static enum nametype -best_name (char *const *name, int const *ignore) -{ - enum nametype i; - int components[3]; - int components_min = INT_MAX; - size_t basename_len[3]; - size_t basename_len_min = SIZE_MAX; - size_t len[3]; - size_t len_min = SIZE_MAX; - - for (i = OLD; i <= INDEX; i++) - if (name[i] && !ignore[i]) - { - /* Take the names with the fewest prefix components. */ - components[i] = prefix_components (name[i], 0); - if (components_min < components[i]) - continue; - components_min = components[i]; - - /* Of those, take the names with the shortest basename. */ - basename_len[i] = strlen (base_name (name[i])); - if (basename_len_min < basename_len[i]) - continue; - basename_len_min = basename_len[i]; - - /* Of those, take the shortest names. */ - len[i] = strlen (name[i]); - if (len_min < len[i]) - continue; - len_min = len[i]; - } - - /* Of those, take the first name. */ - for (i = OLD; i <= INDEX; i++) - if (name[i] && !ignore[i] - && components[i] == components_min - && basename_len[i] == basename_len_min - && len[i] == len_min) - break; - - return i; -} - -/* Remember where this patch ends so we know where to start up again. */ - -static void -next_intuit_at (file_offset file_pos, LINENUM file_line) -{ - p_base = file_pos; - p_bline = file_line; -} - -/* Basically a verbose fseek() to the actual diff listing. */ - -static void -skip_to (file_offset file_pos, LINENUM file_line) -{ - register FILE *i = pfp; - register FILE *o = stdout; - register int c; - - assert(p_base <= file_pos); - if ((verbosity == VERBOSE || !inname) && p_base < file_pos) { - Fseek (i, p_base, SEEK_SET); - say ("The text leading up to this was:\n--------------------------\n"); - - while (file_tell (i) < file_pos) - { - putc ('|', o); - do - { - if ((c = getc (i)) == EOF) - read_fatal (); - putc (c, o); - } - while (c != '\n'); - } - - say ("--------------------------\n"); - } - else - Fseek (i, file_pos, SEEK_SET); - p_input_line = file_line - 1; -} - -/* Make this a function for better debugging. */ -static void -malformed (void) -{ - char numbuf[LINENUM_LENGTH_BOUND + 1]; - fatal ("malformed patch at line %s: %s", - format_linenum (numbuf, p_input_line), buf); - /* about as informative as "Syntax error" in C */ -} - -/* Parse a line number from a string. - Return the address of the first char after the number. */ -static char * -scan_linenum (char *s0, LINENUM *linenum) -{ - char *s; - LINENUM n = 0; - int overflow = 0; - char numbuf[LINENUM_LENGTH_BOUND + 1]; - - for (s = s0; ISDIGIT (*s); s++) - { - LINENUM new_n = 10 * n + (*s - '0'); - overflow |= new_n / 10 != n; - n = new_n; - } - - if (s == s0) - fatal ("missing line number at line %s: %s", - format_linenum (numbuf, p_input_line), buf); - - if (overflow) - fatal ("line number %.*s is too large at line %s: %s", - (int) (s - s0), s0, format_linenum (numbuf, p_input_line), buf); - - *linenum = n; - return s; -} - -/* 1 if there is more of the current diff listing to process; - 0 if not; -1 if ran out of memory. */ - -int -another_hunk (enum diff difftype, int rev) -{ - register char *s; - register LINENUM context = 0; - register size_t chars_read; - char numbuf0[LINENUM_LENGTH_BOUND + 1]; - char numbuf1[LINENUM_LENGTH_BOUND + 1]; - char numbuf2[LINENUM_LENGTH_BOUND + 1]; - char numbuf3[LINENUM_LENGTH_BOUND + 1]; - - while (p_end >= 0) { - if (p_end == p_efake) - p_end = p_bfake; /* don't free twice */ - else - free(p_line[p_end]); - p_end--; - } - assert(p_end == -1); - p_efake = -1; - - p_max = hunkmax; /* gets reduced when --- found */ - if (difftype == CONTEXT_DIFF || difftype == NEW_CONTEXT_DIFF) { - file_offset line_beginning = file_tell (pfp); - /* file pos of the current line */ - LINENUM repl_beginning = 0; /* index of --- line */ - register LINENUM fillcnt = 0; /* #lines of missing ptrn or repl */ - register LINENUM fillsrc; /* index of first line to copy */ - register LINENUM filldst; /* index of first missing line */ - bool ptrn_spaces_eaten = FALSE; /* ptrn was slightly misformed */ - bool some_context = FALSE; /* (perhaps internal) context seen */ - register bool repl_could_be_missing = TRUE; - bool repl_missing = FALSE; /* we are now backtracking */ - file_offset repl_backtrack_position = 0; - /* file pos of first repl line */ - LINENUM repl_patch_line; /* input line number for same */ - LINENUM repl_context; /* context for same */ - LINENUM ptrn_prefix_context = -1; /* lines in pattern prefix context */ - LINENUM ptrn_suffix_context = -1; /* lines in pattern suffix context */ - LINENUM repl_prefix_context = -1; /* lines in replac. prefix context */ - register LINENUM ptrn_copiable = 0; - /* # of copiable lines in ptrn */ - - /* Pacify `gcc -Wall'. */ - fillsrc = filldst = repl_patch_line = repl_context = 0; - - chars_read = get_line (); - if (chars_read == (size_t) -1 - || chars_read <= 8 - || strncmp (buf, "********", 8) != 0) { - next_intuit_at(line_beginning,p_input_line); - return chars_read == (size_t) -1 ? -1 : 0; - } - p_hunk_beg = p_input_line + 1; - while (p_end < p_max) { - chars_read = get_line (); - if (chars_read == (size_t) -1) - return -1; - if (!chars_read) { - if (repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - if (p_max - p_end < 4) { - strcpy (buf, " \n"); /* assume blank lines got chopped */ - chars_read = 3; - } else { - fatal ("unexpected end of file in patch"); - } - } - p_end++; - if (p_end == hunkmax) - fatal ("unterminated hunk starting at line %s; giving up at line %s: %s", - format_linenum (numbuf0, pch_hunk_beg ()), - format_linenum (numbuf1, p_input_line), buf); - assert(p_end < hunkmax); - p_Char[p_end] = *buf; - p_len[p_end] = 0; - p_line[p_end] = 0; - switch (*buf) { - case '*': - if (strnEQ(buf, "********", 8)) { - if (repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - else - fatal ("unexpected end of hunk at line %s", - format_linenum (numbuf0, p_input_line)); - } - if (p_end != 0) { - if (repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - fatal ("unexpected `***' at line %s: %s", - format_linenum (numbuf0, p_input_line), buf); - } - context = 0; - p_len[p_end] = strlen (buf); - if (! (p_line[p_end] = savestr (buf))) { - p_end--; - return -1; - } - for (s = buf; *s && !ISDIGIT (*s); s++) - continue; - if (strnEQ(s,"0,0",3)) - remove_prefix (s, 2); - s = scan_linenum (s, &p_first); - if (*s == ',') { - while (*s && !ISDIGIT (*s)) - s++; - scan_linenum (s, &p_ptrn_lines); - p_ptrn_lines += 1 - p_first; - } - else if (p_first) - p_ptrn_lines = 1; - else { - p_ptrn_lines = 0; - p_first = 1; - } - p_max = p_ptrn_lines + 6; /* we need this much at least */ - while (p_max >= hunkmax) - if (! grow_hunkmax ()) - return -1; - p_max = hunkmax; - break; - case '-': - if (buf[1] != '-') - goto change_line; - if (ptrn_prefix_context == -1) - ptrn_prefix_context = context; - ptrn_suffix_context = context; - if (repl_beginning - || (p_end - != p_ptrn_lines + 1 + (p_Char[p_end - 1] == '\n'))) - { - if (p_end == 1) - { - /* `Old' lines were omitted. Set up to fill - them in from `new' context lines. */ - p_end = p_ptrn_lines + 1; - ptrn_prefix_context = ptrn_suffix_context = -1; - fillsrc = p_end + 1; - filldst = 1; - fillcnt = p_ptrn_lines; - } - else if (! repl_beginning) - fatal ("%s `---' at line %s; check line numbers at line %s", - (p_end <= p_ptrn_lines - ? "Premature" - : "Overdue"), - format_linenum (numbuf0, p_input_line), - format_linenum (numbuf1, p_hunk_beg)); - else if (! repl_could_be_missing) - fatal ("duplicate `---' at line %s; check line numbers at line %s", - format_linenum (numbuf0, p_input_line), - format_linenum (numbuf1, - p_hunk_beg + repl_beginning)); - else - { - repl_missing = TRUE; - goto hunk_done; - } - } - repl_beginning = p_end; - repl_backtrack_position = file_tell (pfp); - repl_patch_line = p_input_line; - repl_context = context; - p_len[p_end] = strlen (buf); - if (! (p_line[p_end] = savestr (buf))) - { - p_end--; - return -1; - } - p_Char[p_end] = '='; - for (s = buf; *s && ! ISDIGIT (*s); s++) - continue; - s = scan_linenum (s, &p_newfirst); - if (*s == ',') - { - do - { - if (!*++s) - malformed (); - } - while (! ISDIGIT (*s)); - scan_linenum (s, &p_repl_lines); - p_repl_lines += 1 - p_newfirst; - } - else if (p_newfirst) - p_repl_lines = 1; - else - { - p_repl_lines = 0; - p_newfirst = 1; - } - p_max = p_repl_lines + p_end; - while (p_max >= hunkmax) - if (! grow_hunkmax ()) - return -1; - if (p_repl_lines != ptrn_copiable - && (p_prefix_context != 0 - || context != 0 - || p_repl_lines != 1)) - repl_could_be_missing = FALSE; - context = 0; - break; - case '+': case '!': - repl_could_be_missing = FALSE; - change_line: - s = buf + 1; - chars_read--; - if (*s == '\n' && canonicalize) { - strcpy (s, " \n"); - chars_read = 2; - } - if (*s == ' ' || *s == '\t') { - s++; - chars_read--; - } else if (repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - if (! repl_beginning) - { - if (ptrn_prefix_context == -1) - ptrn_prefix_context = context; - } - else - { - if (repl_prefix_context == -1) - repl_prefix_context = context; - } - chars_read -= - (1 < chars_read - && p_end == (repl_beginning ? p_max : p_ptrn_lines) - && incomplete_line ()); - p_len[p_end] = chars_read; - if (! (p_line[p_end] = savebuf (s, chars_read))) { - p_end--; - return -1; - } - context = 0; - break; - case '\t': case '\n': /* assume spaces got eaten */ - s = buf; - if (*buf == '\t') { - s++; - chars_read--; - } - if (repl_beginning && repl_could_be_missing && - (!ptrn_spaces_eaten || difftype == NEW_CONTEXT_DIFF) ) { - repl_missing = TRUE; - goto hunk_done; - } - chars_read -= - (1 < chars_read - && p_end == (repl_beginning ? p_max : p_ptrn_lines) - && incomplete_line ()); - p_len[p_end] = chars_read; - if (! (p_line[p_end] = savebuf (buf, chars_read))) { - p_end--; - return -1; - } - if (p_end != p_ptrn_lines + 1) { - ptrn_spaces_eaten |= (repl_beginning != 0); - some_context = TRUE; - context++; - if (!repl_beginning) - ptrn_copiable++; - p_Char[p_end] = ' '; - } - break; - case ' ': - s = buf + 1; - chars_read--; - if (*s == '\n' && canonicalize) { - strcpy (s, "\n"); - chars_read = 2; - } - if (*s == ' ' || *s == '\t') { - s++; - chars_read--; - } else if (repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - some_context = TRUE; - context++; - if (!repl_beginning) - ptrn_copiable++; - chars_read -= - (1 < chars_read - && p_end == (repl_beginning ? p_max : p_ptrn_lines) - && incomplete_line ()); - p_len[p_end] = chars_read; - if (! (p_line[p_end] = savebuf (buf + 2, chars_read))) { - p_end--; - return -1; - } - break; - default: - if (repl_beginning && repl_could_be_missing) { - repl_missing = TRUE; - goto hunk_done; - } - malformed (); - } - } - - hunk_done: - if (p_end >=0 && !repl_beginning) - fatal ("no `---' found in patch at line %s", - format_linenum (numbuf0, pch_hunk_beg ())); - - if (repl_missing) { - - /* reset state back to just after --- */ - p_input_line = repl_patch_line; - context = repl_context; - for (p_end--; p_end > repl_beginning; p_end--) - free(p_line[p_end]); - Fseek (pfp, repl_backtrack_position, SEEK_SET); - - /* redundant 'new' context lines were omitted - set */ - /* up to fill them in from the old file context */ - fillsrc = 1; - filldst = repl_beginning+1; - fillcnt = p_repl_lines; - p_end = p_max; - } - else if (!some_context && fillcnt == 1) { - /* the first hunk was a null hunk with no context */ - /* and we were expecting one line -- fix it up. */ - while (filldst < p_end) { - p_line[filldst] = p_line[filldst+1]; - p_Char[filldst] = p_Char[filldst+1]; - p_len[filldst] = p_len[filldst+1]; - filldst++; - } -#if 0 - repl_beginning--; /* this doesn't need to be fixed */ -#endif - p_end--; - p_first++; /* do append rather than insert */ - fillcnt = 0; - p_ptrn_lines = 0; - } - - p_prefix_context = ((repl_prefix_context == -1 - || (ptrn_prefix_context != -1 - && ptrn_prefix_context < repl_prefix_context)) - ? ptrn_prefix_context : repl_prefix_context); - p_suffix_context = ((ptrn_suffix_context != -1 - && ptrn_suffix_context < context) - ? ptrn_suffix_context : context); - assert (p_prefix_context != -1 && p_suffix_context != -1); - - if (difftype == CONTEXT_DIFF - && (fillcnt - || (p_first > 1 - && p_prefix_context + p_suffix_context < ptrn_copiable))) { - if (verbosity == VERBOSE) - say ("%s\n%s\n%s\n", -"(Fascinating -- this is really a new-style context diff but without", -"the telltale extra asterisks on the *** line that usually indicate", -"the new style...)"); - diff_type = difftype = NEW_CONTEXT_DIFF; - } - - /* if there were omitted context lines, fill them in now */ - if (fillcnt) { - p_bfake = filldst; /* remember where not to free() */ - p_efake = filldst + fillcnt - 1; - while (fillcnt-- > 0) { - while (fillsrc <= p_end && fillsrc != repl_beginning - && p_Char[fillsrc] != ' ') - fillsrc++; - if (p_end < fillsrc || fillsrc == repl_beginning) - { - fatal ("replacement text or line numbers mangled in hunk at line %s", - format_linenum (numbuf0, p_hunk_beg)); - } - p_line[filldst] = p_line[fillsrc]; - p_Char[filldst] = p_Char[fillsrc]; - p_len[filldst] = p_len[fillsrc]; - fillsrc++; filldst++; - } - while (fillsrc <= p_end && fillsrc != repl_beginning) - { - if (p_Char[fillsrc] == ' ') - fatal ("replacement text or line numbers mangled in hunk at line %s", - format_linenum (numbuf0, p_hunk_beg)); - fillsrc++; - } - if (debug & 64) - printf ("fillsrc %s, filldst %s, rb %s, e+1 %s\n", - format_linenum (numbuf0, fillsrc), - format_linenum (numbuf1, filldst), - format_linenum (numbuf2, repl_beginning), - format_linenum (numbuf3, p_end + 1)); - assert(fillsrc==p_end+1 || fillsrc==repl_beginning); - assert(filldst==p_end+1 || filldst==repl_beginning); - } - } - else if (difftype == UNI_DIFF) { - file_offset line_beginning = file_tell (pfp); - /* file pos of the current line */ - register LINENUM fillsrc; /* index of old lines */ - register LINENUM filldst; /* index of new lines */ - char ch = '\0'; - - chars_read = get_line (); - if (chars_read == (size_t) -1 - || chars_read <= 4 - || strncmp (buf, "@@ -", 4) != 0) { - next_intuit_at(line_beginning,p_input_line); - return chars_read == (size_t) -1 ? -1 : 0; - } - s = scan_linenum (buf + 4, &p_first); - if (*s == ',') - s = scan_linenum (s + 1, &p_ptrn_lines); - else - p_ptrn_lines = 1; - if (*s == ' ') s++; - if (*s != '+') - malformed (); - s = scan_linenum (s + 1, &p_newfirst); - if (*s == ',') - s = scan_linenum (s + 1, &p_repl_lines); - else - p_repl_lines = 1; - if (*s == ' ') s++; - if (*s != '@') - malformed (); - if (!p_ptrn_lines) - p_first++; /* do append rather than insert */ - if (!p_repl_lines) - p_newfirst++; - p_max = p_ptrn_lines + p_repl_lines + 1; - while (p_max >= hunkmax) - if (! grow_hunkmax ()) - return -1; - fillsrc = 1; - filldst = fillsrc + p_ptrn_lines; - p_end = filldst + p_repl_lines; - sprintf (buf, "*** %s,%s ****\n", - format_linenum (numbuf0, p_first), - format_linenum (numbuf1, p_first + p_ptrn_lines - 1)); - p_len[0] = strlen (buf); - if (! (p_line[0] = savestr (buf))) { - p_end = -1; - return -1; - } - p_Char[0] = '*'; - sprintf (buf, "--- %s,%s ----\n", - format_linenum (numbuf0, p_newfirst), - format_linenum (numbuf1, p_newfirst + p_repl_lines - 1)); - p_len[filldst] = strlen (buf); - if (! (p_line[filldst] = savestr (buf))) { - p_end = 0; - return -1; - } - p_Char[filldst++] = '='; - p_prefix_context = -1; - p_hunk_beg = p_input_line + 1; - while (fillsrc <= p_ptrn_lines || filldst <= p_end) { - chars_read = get_line (); - if (!chars_read) { - if (p_max - filldst < 3) { - strcpy (buf, " \n"); /* assume blank lines got chopped */ - chars_read = 2; - } else { - fatal ("unexpected end of file in patch"); - } - } - if (chars_read == (size_t) -1) - s = 0; - else if (*buf == '\t' || *buf == '\n') { - ch = ' '; /* assume the space got eaten */ - s = savebuf (buf, chars_read); - } - else { - ch = *buf; - s = savebuf (buf+1, --chars_read); - } - if (!s) { - while (--filldst > p_ptrn_lines) - free(p_line[filldst]); - p_end = fillsrc-1; - return -1; - } - switch (ch) { - case '-': - if (fillsrc > p_ptrn_lines) { - free(s); - p_end = filldst-1; - malformed (); - } - chars_read -= fillsrc == p_ptrn_lines && incomplete_line (); - p_Char[fillsrc] = ch; - p_line[fillsrc] = s; - p_len[fillsrc++] = chars_read; - break; - case '=': - ch = ' '; - /* FALL THROUGH */ - case ' ': - if (fillsrc > p_ptrn_lines) { - free(s); - while (--filldst > p_ptrn_lines) - free(p_line[filldst]); - p_end = fillsrc-1; - malformed (); - } - context++; - chars_read -= fillsrc == p_ptrn_lines && incomplete_line (); - p_Char[fillsrc] = ch; - p_line[fillsrc] = s; - p_len[fillsrc++] = chars_read; - s = savebuf (s, chars_read); - if (!s) { - while (--filldst > p_ptrn_lines) - free(p_line[filldst]); - p_end = fillsrc-1; - return -1; - } - /* FALL THROUGH */ - case '+': - if (filldst > p_end) { - free(s); - while (--filldst > p_ptrn_lines) - free(p_line[filldst]); - p_end = fillsrc-1; - malformed (); - } - chars_read -= filldst == p_end && incomplete_line (); - p_Char[filldst] = ch; - p_line[filldst] = s; - p_len[filldst++] = chars_read; - break; - default: - p_end = filldst; - malformed (); - } - if (ch != ' ') { - if (p_prefix_context == -1) - p_prefix_context = context; - context = 0; - } - }/* while */ - if (p_prefix_context == -1) - malformed (); - p_suffix_context = context; - } - else { /* normal diff--fake it up */ - char hunk_type; - register int i; - LINENUM min, max; - file_offset line_beginning = file_tell (pfp); - - p_prefix_context = p_suffix_context = 0; - chars_read = get_line (); - if (chars_read == (size_t) -1 || !chars_read || !ISDIGIT (*buf)) { - next_intuit_at(line_beginning,p_input_line); - return chars_read == (size_t) -1 ? -1 : 0; - } - s = scan_linenum (buf, &p_first); - if (*s == ',') { - s = scan_linenum (s + 1, &p_ptrn_lines); - p_ptrn_lines += 1 - p_first; - } - else - p_ptrn_lines = (*s != 'a'); - hunk_type = *s; - if (hunk_type == 'a') - p_first++; /* do append rather than insert */ - s = scan_linenum (s + 1, &min); - if (*s == ',') - scan_linenum (s + 1, &max); - else - max = min; - if (hunk_type == 'd') - min++; - p_end = p_ptrn_lines + 1 + max - min + 1; - while (p_end >= hunkmax) - if (! grow_hunkmax ()) - { - p_end = -1; - return -1; - } - p_newfirst = min; - p_repl_lines = max - min + 1; - sprintf (buf, "*** %s,%s\n", - format_linenum (numbuf0, p_first), - format_linenum (numbuf1, p_first + p_ptrn_lines - 1)); - p_len[0] = strlen (buf); - if (! (p_line[0] = savestr (buf))) { - p_end = -1; - return -1; - } - p_Char[0] = '*'; - for (i=1; i<=p_ptrn_lines; i++) { - chars_read = get_line (); - if (chars_read == (size_t) -1) - { - p_end = i - 1; - return -1; - } - if (!chars_read) - fatal ("unexpected end of file in patch at line %s", - format_linenum (numbuf0, p_input_line)); - if (buf[0] != '<' || (buf[1] != ' ' && buf[1] != '\t')) - fatal ("`<' expected at line %s of patch", - format_linenum (numbuf0, p_input_line)); - chars_read -= 2 + (i == p_ptrn_lines && incomplete_line ()); - p_len[i] = chars_read; - if (! (p_line[i] = savebuf (buf + 2, chars_read))) { - p_end = i-1; - return -1; - } - p_Char[i] = '-'; - } - if (hunk_type == 'c') { - chars_read = get_line (); - if (chars_read == (size_t) -1) - { - p_end = i - 1; - return -1; - } - if (! chars_read) - fatal ("unexpected end of file in patch at line %s", - format_linenum (numbuf0, p_input_line)); - if (*buf != '-') - fatal ("`---' expected at line %s of patch", - format_linenum (numbuf0, p_input_line)); - } - sprintf (buf, "--- %s,%s\n", - format_linenum (numbuf0, min), - format_linenum (numbuf1, max)); - p_len[i] = strlen (buf); - if (! (p_line[i] = savestr (buf))) { - p_end = i-1; - return -1; - } - p_Char[i] = '='; - for (i++; i<=p_end; i++) { - chars_read = get_line (); - if (chars_read == (size_t) -1) - { - p_end = i - 1; - return -1; - } - if (!chars_read) - fatal ("unexpected end of file in patch at line %s", - format_linenum (numbuf0, p_input_line)); - if (buf[0] != '>' || (buf[1] != ' ' && buf[1] != '\t')) - fatal ("`>' expected at line %s of patch", - format_linenum (numbuf0, p_input_line)); - chars_read -= 2 + (i == p_end && incomplete_line ()); - p_len[i] = chars_read; - if (! (p_line[i] = savebuf (buf + 2, chars_read))) { - p_end = i-1; - return -1; - } - p_Char[i] = '+'; - } - } - if (rev) /* backwards patch? */ - if (!pch_swap()) - say ("Not enough memory to swap next hunk!\n"); - if (debug & 2) { - LINENUM i; - char special; - - for (i=0; i <= p_end; i++) { - if (i == p_ptrn_lines) - special = '^'; - else - special = ' '; - fprintf (stderr, "%s %c %c ", format_linenum (numbuf0, i), - p_Char[i], special); - pch_write_line (i, stderr); - fflush (stderr); - } - } - if (p_end+1 < hunkmax) /* paranoia reigns supreme... */ - p_Char[p_end+1] = '^'; /* add a stopper for apply_hunk */ - return 1; -} - -static size_t -get_line (void) -{ - return pget_line (p_indent, p_rfc934_nesting, p_strip_trailing_cr); -} - -/* Input a line from the patch file, worrying about indentation. - Strip up to INDENT characters' worth of leading indentation. - Then remove up to RFC934_NESTING instances of leading "- ". - If STRIP_TRAILING_CR is nonzero, remove any trailing carriage-return. - Ignore any partial lines at end of input, but warn about them. - Succeed if a line was read; it is terminated by "\n\0" for convenience. - Return the number of characters read, including '\n' but not '\0'. - Return -1 if we ran out of memory. */ - -static size_t -pget_line (int indent, int rfc934_nesting, int strip_trailing_cr) -{ - register FILE *fp = pfp; - register int c; - register int i = 0; - register char *b; - register size_t s; - - for (;;) - { - c = getc (fp); - if (c == EOF) - { - if (ferror (fp)) - read_fatal (); - return 0; - } - if (indent <= i) - break; - if (c == ' ' || c == 'X') - i++; - else if (c == '\t') - i = (i + 8) & ~7; - else - break; - } - - i = 0; - b = buf; - - while (c == '-' && 0 <= --rfc934_nesting) - { - c = getc (fp); - if (c == EOF) - goto patch_ends_in_middle_of_line; - if (c != ' ') - { - i = 1; - b[0] = '-'; - break; - } - c = getc (fp); - if (c == EOF) - goto patch_ends_in_middle_of_line; - } - - s = bufsize; - - for (;;) - { - if (i == s - 1) - { - s *= 2; - b = realloc (b, s); - if (!b) - { - if (!using_plan_a) - memory_fatal (); - return (size_t) -1; - } - buf = b; - bufsize = s; - } - b[i++] = c; - if (c == '\n') - break; - c = getc (fp); - if (c == EOF) - goto patch_ends_in_middle_of_line; - } - - if (strip_trailing_cr && 2 <= i && b[i - 2] == '\r') - b[i-- - 2] = '\n'; - b[i] = '\0'; - p_input_line++; - return i; - - patch_ends_in_middle_of_line: - if (ferror (fp)) - read_fatal (); - say ("patch unexpectedly ends in middle of line\n"); - return 0; -} - -static bool -incomplete_line (void) -{ - register FILE *fp = pfp; - register int c; - register file_offset line_beginning = file_tell (fp); - - if (getc (fp) == '\\') - { - while ((c = getc (fp)) != '\n' && c != EOF) - continue; - return TRUE; - } - else - { - /* We don't trust ungetc. */ - Fseek (pfp, line_beginning, SEEK_SET); - return FALSE; - } -} - -/* Reverse the old and new portions of the current hunk. */ - -bool -pch_swap (void) -{ - char **tp_line; /* the text of the hunk */ - size_t *tp_len; /* length of each line */ - char *tp_char; /* +, -, and ! */ - register LINENUM i; - register LINENUM n; - bool blankline = FALSE; - register char *s; - - i = p_first; - p_first = p_newfirst; - p_newfirst = i; - - /* make a scratch copy */ - - tp_line = p_line; - tp_len = p_len; - tp_char = p_Char; - p_line = 0; /* force set_hunkmax to allocate again */ - p_len = 0; - p_Char = 0; - set_hunkmax(); - if (!p_line || !p_len || !p_Char) { - if (p_line) - free (p_line); - p_line = tp_line; - if (p_len) - free (p_len); - p_len = tp_len; - if (p_Char) - free (p_Char); - p_Char = tp_char; - return FALSE; /* not enough memory to swap hunk! */ - } - - /* now turn the new into the old */ - - i = p_ptrn_lines + 1; - if (tp_char[i] == '\n') { /* account for possible blank line */ - blankline = TRUE; - i++; - } - if (p_efake >= 0) { /* fix non-freeable ptr range */ - if (p_efake <= i) - n = p_end - i + 1; - else - n = -i; - p_efake += n; - p_bfake += n; - } - for (n=0; i <= p_end; i++,n++) { - p_line[n] = tp_line[i]; - p_Char[n] = tp_char[i]; - if (p_Char[n] == '+') - p_Char[n] = '-'; - p_len[n] = tp_len[i]; - } - if (blankline) { - i = p_ptrn_lines + 1; - p_line[n] = tp_line[i]; - p_Char[n] = tp_char[i]; - p_len[n] = tp_len[i]; - n++; - } - assert(p_Char[0] == '='); - p_Char[0] = '*'; - for (s=p_line[0]; *s; s++) - if (*s == '-') - *s = '*'; - - /* now turn the old into the new */ - - assert(tp_char[0] == '*'); - tp_char[0] = '='; - for (s=tp_line[0]; *s; s++) - if (*s == '*') - *s = '-'; - for (i=0; n <= p_end; i++,n++) { - p_line[n] = tp_line[i]; - p_Char[n] = tp_char[i]; - if (p_Char[n] == '-') - p_Char[n] = '+'; - p_len[n] = tp_len[i]; - } - assert(i == p_ptrn_lines + 1); - i = p_ptrn_lines; - p_ptrn_lines = p_repl_lines; - p_repl_lines = i; - if (tp_line) - free (tp_line); - if (tp_len) - free (tp_len); - if (tp_char) - free (tp_char); - return TRUE; -} - -/* Return whether file WHICH (0 = old, 1 = new) appears to nonexistent. - Return 1 for empty, 2 for nonexistent. */ - -bool -pch_says_nonexistent (int which) -{ - return p_says_nonexistent[which]; -} - -/* Return timestamp of patch header for file WHICH (0 = old, 1 = new), - or -1 if there was no timestamp or an error in the timestamp. */ - -time_t -pch_timestamp (int which) -{ - return p_timestamp[which]; -} - -/* Return the specified line position in the old file of the old context. */ - -LINENUM -pch_first (void) -{ - return p_first; -} - -/* Return the number of lines of old context. */ - -LINENUM -pch_ptrn_lines (void) -{ - return p_ptrn_lines; -} - -/* Return the probable line position in the new file of the first line. */ - -LINENUM -pch_newfirst (void) -{ - return p_newfirst; -} - -/* Return the number of lines in the replacement text including context. */ - -LINENUM -pch_repl_lines (void) -{ - return p_repl_lines; -} - -/* Return the number of lines in the whole hunk. */ - -LINENUM -pch_end (void) -{ - return p_end; -} - -/* Return the number of context lines before the first changed line. */ - -LINENUM -pch_prefix_context (void) -{ - return p_prefix_context; -} - -/* Return the number of context lines after the last changed line. */ - -LINENUM -pch_suffix_context (void) -{ - return p_suffix_context; -} - -/* Return the length of a particular patch line. */ - -size_t -pch_line_len (LINENUM line) -{ - return p_len[line]; -} - -/* Return the control character (+, -, *, !, etc) for a patch line. */ - -char -pch_char (LINENUM line) -{ - return p_Char[line]; -} - -/* Return a pointer to a particular patch line. */ - -char * -pfetch (LINENUM line) -{ - return p_line[line]; -} - -/* Output a patch line. */ - -bool -pch_write_line (LINENUM line, FILE *file) -{ - bool after_newline = p_line[line][p_len[line] - 1] == '\n'; - if (! fwrite (p_line[line], sizeof (*p_line[line]), p_len[line], file)) - write_fatal (); - return after_newline; -} - -/* Return where in the patch file this hunk began, for error messages. */ - -LINENUM -pch_hunk_beg (void) -{ - return p_hunk_beg; -} - -/* Apply an ed script by feeding ed itself. */ - -void -do_ed_script (FILE *ofp) -{ - static char const ed_program[] = ed_PROGRAM; - - register char *t; - register file_offset beginning_of_this_line; - register bool this_line_is_command = FALSE; - register FILE *pipefp = 0; - register size_t chars_read; - - if (!skip_rest_of_patch) { - int exclusive = TMPOUTNAME_needs_removal ? 0 : O_EXCL; - assert (! inerrno); - TMPOUTNAME_needs_removal = 1; - copy_file (inname, TMPOUTNAME, exclusive, instat.st_mode); - sprintf (buf, "%s %s%s", ed_program, verbosity == VERBOSE ? "" : "- ", - TMPOUTNAME); - fflush (stdout); - pipefp = popen(buf, binary_transput ? "wb" : "w"); - if (!pipefp) - pfatal ("Can't open pipe to %s", quotearg (buf)); - } - for (;;) { - beginning_of_this_line = file_tell (pfp); - chars_read = get_line (); - if (! chars_read) { - next_intuit_at(beginning_of_this_line,p_input_line); - break; - } - for (t = buf; ISDIGIT (*t) || *t == ','; t++) - continue; - this_line_is_command = (ISDIGIT (*buf) && - (*t == 'd' || *t == 'c' || *t == 'a' || *t == 'i' || *t == 's') ); - if (this_line_is_command) { - if (pipefp) - if (! fwrite (buf, sizeof *buf, chars_read, pipefp)) - write_fatal (); - if (*t != 'd' && *t != 's') { - while ((chars_read = get_line ()) != 0) { - if (pipefp) - if (! fwrite (buf, sizeof *buf, chars_read, pipefp)) - write_fatal (); - if (chars_read == 2 && strEQ (buf, ".\n")) - break; - } - } - } - else { - next_intuit_at(beginning_of_this_line,p_input_line); - break; - } - } - if (!pipefp) - return; - if (fwrite ("w\nq\n", sizeof (char), (size_t) 4, pipefp) == 0 - || fflush (pipefp) != 0) - write_fatal (); - if (pclose (pipefp) != 0) - fatal ("%s FAILED", ed_program); - - if (ofp) - { - FILE *ifp = fopen (TMPOUTNAME, binary_transput ? "rb" : "r"); - int c; - if (!ifp) - pfatal ("can't open `%s'", TMPOUTNAME); - while ((c = getc (ifp)) != EOF) - if (putc (c, ofp) == EOF) - write_fatal (); - if (ferror (ifp) || fclose (ifp) != 0) - read_fatal (); - } -} diff --git a/src/bin/patch/pch.h b/src/bin/patch/pch.h deleted file mode 100644 index 8581a9cf53..0000000000 --- a/src/bin/patch/pch.h +++ /dev/null @@ -1,25 +0,0 @@ -/* reading patches */ - -/* $Id: pch.h 8008 2004-06-16 21:22:10Z korli $ */ - -LINENUM pch_end PARAMS ((void)); -LINENUM pch_first PARAMS ((void)); -LINENUM pch_hunk_beg PARAMS ((void)); -LINENUM pch_newfirst PARAMS ((void)); -LINENUM pch_prefix_context PARAMS ((void)); -LINENUM pch_ptrn_lines PARAMS ((void)); -LINENUM pch_repl_lines PARAMS ((void)); -LINENUM pch_suffix_context PARAMS ((void)); -bool pch_swap PARAMS ((void)); -bool pch_write_line PARAMS ((LINENUM, FILE *)); -bool there_is_another_patch PARAMS ((void)); -char *pfetch PARAMS ((LINENUM)); -char pch_char PARAMS ((LINENUM)); -int another_hunk PARAMS ((enum diff, int)); -int pch_says_nonexistent PARAMS ((int)); -size_t pch_line_len PARAMS ((LINENUM)); -time_t pch_timestamp PARAMS ((int)); -void do_ed_script PARAMS ((FILE *)); -void open_patch_file PARAMS ((char const *)); -void re_patch PARAMS ((void)); -void set_hunkmax PARAMS ((void)); diff --git a/src/bin/patch/quotearg.c b/src/bin/patch/quotearg.c deleted file mode 100644 index 5ac903ca1b..0000000000 --- a/src/bin/patch/quotearg.c +++ /dev/null @@ -1,403 +0,0 @@ -/* quotearg.c - quote arguments for output - Copyright (C) 1998, 1999 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. */ - -/* Written by Paul Eggert */ - -/* FIXME: Multibyte characters are not supported yet. */ - -#if HAVE_CONFIG_H -# include -#endif - -#include -#include -#include - -#include -#if defined (STDC_HEADERS) || (!defined (isascii) && !defined (HAVE_ISASCII)) -# define ISASCII(c) 1 -#else -# define ISASCII(c) isascii (c) -#endif -#ifdef isgraph -# define ISGRAPH(c) (ISASCII (c) && isgraph (c)) -#else -# define ISGRAPH(c) (ISASCII (c) && isprint (c) && !isspace (c)) -#endif - -#if ENABLE_NLS -# include -# define _(text) gettext (text) -#else -# define _(text) text -#endif - -#if HAVE_LIMITS_H -# include -#endif -#ifndef CHAR_BIT -# define CHAR_BIT 8 -#endif -#ifndef UCHAR_MAX -# define UCHAR_MAX ((unsigned char) -1) -#endif - -#if HAVE_STDLIB_H -# include -#endif - -#if HAVE_STRING_H -# include -#endif - -#define INT_BITS (sizeof (int) * CHAR_BIT) - -struct quoting_options -{ - /* Basic quoting style. */ - enum quoting_style style; - - /* Quote the characters indicated by this bit vector even if the - quoting style would not normally require them to be quoted. */ - int quote_these_too[((UCHAR_MAX + 1) / INT_BITS - + ((UCHAR_MAX + 1) % INT_BITS != 0))]; -}; - -/* Names of quoting styles. */ -char const *const quoting_style_args[] = -{ - "literal", - "shell", - "shell-always", - "c", - "escape", - "locale", - 0 -}; - -/* Correspondences to quoting style names. */ -enum quoting_style const quoting_style_vals[] = -{ - literal_quoting_style, - shell_quoting_style, - shell_always_quoting_style, - c_quoting_style, - escape_quoting_style, - locale_quoting_style -}; - -/* The default quoting options. */ -static struct quoting_options default_quoting_options; - -/* Allocate a new set of quoting options, with contents initially identical - to O if O is not null, or to the default if O is null. - It is the caller's responsibility to free the result. */ -struct quoting_options * -clone_quoting_options (struct quoting_options *o) -{ - struct quoting_options *p - = (struct quoting_options *) xmalloc (sizeof (struct quoting_options)); - *p = *(o ? o : &default_quoting_options); - return p; -} - -/* Get the value of O's quoting style. If O is null, use the default. */ -enum quoting_style -get_quoting_style (struct quoting_options *o) -{ - return (o ? o : &default_quoting_options)->style; -} - -/* In O (or in the default if O is null), - set the value of the quoting style to S. */ -void -set_quoting_style (struct quoting_options *o, enum quoting_style s) -{ - (o ? o : &default_quoting_options)->style = s; -} - -/* In O (or in the default if O is null), - set the value of the quoting options for character C to I. - Return the old value. Currently, the only values defined for I are - 0 (the default) and 1 (which means to quote the character even if - it would not otherwise be quoted). */ -int -set_char_quoting (struct quoting_options *o, char c, int i) -{ - unsigned char uc = c; - int *p = (o ? o : &default_quoting_options)->quote_these_too + uc / INT_BITS; - int shift = uc % INT_BITS; - int r = (*p >> shift) & 1; - *p ^= ((i & 1) ^ r) << shift; - return r; -} - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using O to control quoting. - If O is null, use the default. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */ -size_t -quotearg_buffer (char *buffer, size_t buffersize, - char const *arg, size_t argsize, - struct quoting_options const *o) -{ - unsigned char c; - size_t i; - size_t len = 0; - char const *quote_string; - size_t quote_string_len; - struct quoting_options const *p = o ? o : &default_quoting_options; - enum quoting_style quoting_style = p->style; -#define STORE(c) \ - do \ - { \ - if (len < buffersize) \ - buffer[len] = (c); \ - len++; \ - } \ - while (0) - - switch (quoting_style) - { - case shell_quoting_style: - if (! (argsize == (size_t) -1 ? arg[0] == '\0' : argsize == 0)) - { - switch (arg[0]) - { - case '#': case '~': - break; - - default: - for (i = 0; ; i++) - { - if (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize) - goto done; - - c = arg[i]; - - switch (c) - { - case '\t': case '\n': case ' ': - case '!': /* special in csh */ - case '"': case '$': case '&': case '\'': - case '(': case ')': case '*': case ';': - case '<': case '>': case '?': case '[': case '\\': - case '^': /* special in old /bin/sh, e.g. SunOS 4.1.4 */ - case '`': case '|': - goto needs_quoting; - } - - if (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS))) - goto needs_quoting; - - STORE (c); - } - needs_quoting:; - - len = 0; - break; - } - } - /* Fall through. */ - - case shell_always_quoting_style: - STORE ('\''); - quote_string = "'"; - quote_string_len = 1; - break; - - case c_quoting_style: - STORE ('"'); - quote_string = "\""; - quote_string_len = 1; - break; - - case locale_quoting_style: - for (quote_string = _("`"); *quote_string; quote_string++) - STORE (*quote_string); - quote_string = _("'"); - quote_string_len = strlen (quote_string); - break; - - default: - quote_string = 0; - quote_string_len = 0; - break; - } - - for (i = 0; ! (argsize == (size_t) -1 ? arg[i] == '\0' : i == argsize); i++) - { - c = arg[i]; - - switch (quoting_style) - { - case literal_quoting_style: - break; - - case shell_quoting_style: - case shell_always_quoting_style: - if (c == '\'') - { - STORE ('\''); - STORE ('\\'); - STORE ('\''); - } - break; - - case c_quoting_style: - case escape_quoting_style: - case locale_quoting_style: - switch (c) - { - case '?': /* Do not generate trigraphs. */ - case '\\': goto store_escape; - /* Not all C compilers know what \a means. */ - case 7 : c = 'a'; goto store_escape; - case '\b': c = 'b'; goto store_escape; - case '\f': c = 'f'; goto store_escape; - case '\n': c = 'n'; goto store_escape; - case '\r': c = 'r'; goto store_escape; - case '\t': c = 't'; goto store_escape; - case '\v': c = 'v'; goto store_escape; - - case ' ': break; - - default: - if (quote_string_len - && strncmp (arg + i, quote_string, quote_string_len) == 0) - goto store_escape; - if (!ISGRAPH (c)) - { - STORE ('\\'); - STORE ('0' + (c >> 6)); - STORE ('0' + ((c >> 3) & 7)); - c = '0' + (c & 7); - goto store_c; - } - break; - } - - if (! (p->quote_these_too[c / INT_BITS] & (1 << (c % INT_BITS)))) - goto store_c; - - store_escape: - STORE ('\\'); - } - - store_c: - STORE (c); - } - - if (quote_string) - for (; *quote_string; quote_string++) - STORE (*quote_string); - - done: - if (len < buffersize) - buffer[len] = '\0'; - return len; -} - -/* Use storage slot N to return a quoted version of the string ARG. - OPTIONS specifies the quoting options. - The returned value points to static storage that can be - reused by the next call to this function with the same value of N. - N must be nonnegative. N is deliberately declared with type `int' - to allow for future extensions (using negative values). */ -static char * -quotearg_n_options (int n, char const *arg, - struct quoting_options const *options) -{ - static unsigned int nslots; - static struct slotvec - { - size_t size; - char *val; - } *slotvec; - - if (nslots <= n) - { - int n1 = n + 1; - size_t s = n1 * sizeof (struct slotvec); - if (! (0 < n1 && n1 == s / sizeof (struct slotvec))) - abort (); - slotvec = (struct slotvec *) xrealloc (slotvec, s); - memset (slotvec + nslots, 0, (n1 - nslots) * sizeof (struct slotvec)); - nslots = n; - } - - { - size_t size = slotvec[n].size; - char *val = slotvec[n].val; - size_t qsize = quotearg_buffer (val, size, arg, (size_t) -1, options); - - if (size <= qsize) - { - slotvec[n].size = size = qsize + 1; - slotvec[n].val = val = xrealloc (val, size); - quotearg_buffer (val, size, arg, (size_t) -1, options); - } - - return val; - } -} - -char * -quotearg_n (unsigned int n, char const *arg) -{ - return quotearg_n_options (n, arg, &default_quoting_options); -} - -char * -quotearg (char const *arg) -{ - return quotearg_n (0, arg); -} - -char * -quotearg_n_style (unsigned int n, enum quoting_style s, char const *arg) -{ - struct quoting_options o; - o.style = s; - memset (o.quote_these_too, 0, sizeof o.quote_these_too); - return quotearg_n_options (n, arg, &o); -} - -char * -quotearg_style (enum quoting_style s, char const *arg) -{ - return quotearg_n_style (0, s, arg); -} - -char * -quotearg_char (char const *arg, char ch) -{ - struct quoting_options options; - options = default_quoting_options; - set_char_quoting (&options, ch, 1); - return quotearg_n_options (0, arg, &options); -} - -char * -quotearg_colon (char const *arg) -{ - return quotearg_char (arg, ':'); -} diff --git a/src/bin/patch/quotearg.h b/src/bin/patch/quotearg.h deleted file mode 100644 index 2a600e7a67..0000000000 --- a/src/bin/patch/quotearg.h +++ /dev/null @@ -1,109 +0,0 @@ -/* quotearg.h - quote arguments for output - Copyright (C) 1998, 1999 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. */ - -/* Written by Paul Eggert */ - -/* Basic quoting styles. */ -enum quoting_style - { - literal_quoting_style, /* --quoting-style=literal */ - shell_quoting_style, /* --quoting-style=shell */ - shell_always_quoting_style, /* --quoting-style=shell-always */ - c_quoting_style, /* --quoting-style=c */ - escape_quoting_style, /* --quoting-style=escape */ - locale_quoting_style /* --quoting-style=locale */ - }; - -/* For now, --quoting-style=literal is the default, but this may change. */ -#ifndef DEFAULT_QUOTING_STYLE -# define DEFAULT_QUOTING_STYLE literal_quoting_style -#endif - -/* Names of quoting styles and their corresponding values. */ -extern char const *const quoting_style_args[]; -extern enum quoting_style const quoting_style_vals[]; - -struct quoting_options; - -#ifndef PARAMS -# if defined PROTOTYPES || defined __STDC__ -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -#endif - -/* The functions listed below set and use a hidden variable - that contains the default quoting style options. */ - -/* Allocate a new set of quoting options, with contents initially identical - to O if O is not null, or to the default if O is null. - It is the caller's responsibility to free the result. */ -struct quoting_options *clone_quoting_options - PARAMS ((struct quoting_options *o)); - -/* Get the value of O's quoting style. If O is null, use the default. */ -enum quoting_style get_quoting_style PARAMS ((struct quoting_options *o)); - -/* In O (or in the default if O is null), - set the value of the quoting style to S. */ -void set_quoting_style PARAMS ((struct quoting_options *o, - enum quoting_style s)); - -/* In O (or in the default if O is null), - set the value of the quoting options for character C to I. - Return the old value. Currently, the only values defined for I are - 0 (the default) and 1 (which means to quote the character even if - it would not otherwise be quoted). */ -int set_char_quoting PARAMS ((struct quoting_options *o, char c, int i)); - -/* Place into buffer BUFFER (of size BUFFERSIZE) a quoted version of - argument ARG (of size ARGSIZE), using O to control quoting. - If O is null, use the default. - Terminate the output with a null character, and return the written - size of the output, not counting the terminating null. - If BUFFERSIZE is too small to store the output string, return the - value that would have been returned had BUFFERSIZE been large enough. - If ARGSIZE is -1, use the string length of the argument for ARGSIZE. */ -size_t quotearg_buffer PARAMS ((char *buffer, size_t buffersize, - char const *arg, size_t argsize, - struct quoting_options const *o)); - -/* Use storage slot N to return a quoted version of the string ARG. - Use the default quoting options. - The returned value points to static storage that can be - reused by the next call to this function with the same value of N. - N must be nonnegative. */ -char *quotearg_n PARAMS ((unsigned int n, char const *arg)); - -/* Equivalent to quotearg_n (0, ARG). */ -char *quotearg PARAMS ((char const *arg)); - -/* Use style S and storage slot N to return a quoted version of the string ARG. - This is like quotearg_n (N, ARG), except that it uses S with no other - options to specify the quoting method. */ -char *quotearg_n_style PARAMS ((unsigned int n, enum quoting_style s, - char const *arg)); - -/* Equivalent to quotearg_n_style (0, S, ARG). */ -char *quotearg_style PARAMS ((enum quoting_style s, char const *arg)); - -/* Like quotearg (ARG), except also quote any instances of CH. */ -char *quotearg_char PARAMS ((char const *arg, char ch)); - -/* Equivalent to quotearg_char (ARG, ':'). */ -char *quotearg_colon PARAMS ((char const *arg)); diff --git a/src/bin/patch/quotesys.c b/src/bin/patch/quotesys.c deleted file mode 100644 index 528f382272..0000000000 --- a/src/bin/patch/quotesys.c +++ /dev/null @@ -1,125 +0,0 @@ -/* Shell command argument quoting. - Copyright (C) 1994, 1995, 1997 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -/* Written by Paul Eggert */ - -#if HAVE_CONFIG_H -# include -#endif - -#include -#include - -/* Place into QUOTED a quoted version of ARG suitable for `system'. - Return the length of the resulting string (which is not null-terminated). - If QUOTED is null, return the length without any side effects. */ - -size_t -quote_system_arg (quoted, arg) - char *quoted; - char const *arg; -{ - char const *a; - size_t len = 0; - - /* Scan ARG, copying it to QUOTED if QUOTED is not null, - looking for shell metacharacters. */ - - for (a = arg; ; a++) - { - char c = *a; - switch (c) - { - case 0: - /* ARG has no shell metacharacters. */ - return len; - - case '=': - if (*arg == '-') - break; - /* Fall through. */ - case '\t': case '\n': case ' ': - case '!': case '"': case '#': case '$': case '%': case '&': case '\'': - case '(': case ')': case '*': case ';': - case '<': case '>': case '?': case '[': case '\\': - case '^': case '`': case '|': case '~': - { - /* ARG has a shell metacharacter. - Start over, quoting it this time. */ - - len = 0; - c = *arg++; - - /* If ARG is an option, quote just its argument. - This is not necessary, but it looks nicer. */ - if (c == '-' && arg < a) - { - c = *arg++; - - if (quoted) - { - quoted[len] = '-'; - quoted[len + 1] = c; - } - len += 2; - - if (c == '-') - while (arg < a) - { - c = *arg++; - if (quoted) - quoted[len] = c; - len++; - if (c == '=') - break; - } - c = *arg++; - } - - if (quoted) - quoted[len] = '\''; - len++; - - for (; c; c = *arg++) - { - if (c == '\'') - { - if (quoted) - { - quoted[len] = '\''; - quoted[len + 1] = '\\'; - quoted[len + 2] = '\''; - } - len += 3; - } - if (quoted) - quoted[len] = c; - len++; - } - - if (quoted) - quoted[len] = '\''; - return len + 1; - } - } - - if (quoted) - quoted[len] = c; - len++; - } -} diff --git a/src/bin/patch/quotesys.h b/src/bin/patch/quotesys.h deleted file mode 100644 index 0d0d825709..0000000000 --- a/src/bin/patch/quotesys.h +++ /dev/null @@ -1,9 +0,0 @@ -/* quotesys.h -- declarations for quoting system arguments */ - -#if defined __STDC__ || __GNUC__ -# define __QUOTESYS_P(args) args -#else -# define __QUOTESYS_P(args) () -#endif - -size_t quote_system_arg __QUOTESYS_P ((char *, char const *)); diff --git a/src/bin/patch/util.c b/src/bin/patch/util.c deleted file mode 100644 index f9538de363..0000000000 --- a/src/bin/patch/util.c +++ /dev/null @@ -1,996 +0,0 @@ -/* utility functions for `patch' */ - -/* $Id: util.c 8008 2004-06-16 21:22:10Z korli $ */ - -/* Copyright 1986 Larry Wall - Copyright 1992, 1993, 1997-1998, 1999 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; see the file COPYING. - If not, write to the Free Software Foundation, - 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - -#define XTERN extern -#include -#include -#include -#include -#include -#include -#undef XTERN -#define XTERN -#include -#include - -#include -#include - -#include -#if !defined SIGCHLD && defined SIGCLD -#define SIGCHLD SIGCLD -#endif -#if ! HAVE_RAISE && ! defined raise -# define raise(sig) kill (getpid (), sig) -#endif - -#ifdef __STDC__ -# include -# define vararg_start va_start -#else -# define vararg_start(ap,p) va_start (ap) -# if HAVE_VARARGS_H -# include -# else - typedef char *va_list; -# define va_dcl int va_alist; -# define va_start(ap) ((ap) = (va_list) &va_alist) -# define va_arg(ap, t) (((t *) ((ap) += sizeof (t))) [-1]) -# define va_end(ap) -# endif -#endif - -static void makedirs PARAMS ((char *)); - -/* Move a file FROM (where *FROM_NEEDS_REMOVAL is nonzero if FROM - needs removal when cleaning up at the end of execution) - to TO, renaming it if possible and copying it if necessary. - If we must create TO, use MODE to create it. - If FROM is null, remove TO (ignoring FROMSTAT). - FROM_NEEDS_REMOVAL must be nonnull if FROM is nonnull. - Back up TO if BACKUP is nonzero. */ - -void -move_file (char const *from, int volatile *from_needs_removal, - char *to, mode_t mode, int backup) -{ - struct stat to_st; - int to_errno = ! backup ? -1 : stat (to, &to_st) == 0 ? 0 : errno; - - if (backup) - { - int try_makedirs_errno = 0; - char *bakname; - - if (origprae || origbase) - { - char const *p = origprae ? origprae : ""; - char const *b = origbase ? origbase : ""; - char const *o = base_name (to); - size_t plen = strlen (p); - size_t tlen = o - to; - size_t blen = strlen (b); - size_t osize = strlen (o) + 1; - bakname = xmalloc (plen + tlen + blen + osize); - memcpy (bakname, p, plen); - memcpy (bakname + plen, to, tlen); - memcpy (bakname + plen + tlen, b, blen); - memcpy (bakname + plen + tlen + blen, o, osize); - for (p += FILESYSTEM_PREFIX_LEN (p); *p; p++) - if (ISSLASH (*p)) - { - try_makedirs_errno = ENOENT; - break; - } - } - else - { - bakname = find_backup_file_name (to, backup_type); - if (!bakname) - memory_fatal (); - } - - if (to_errno) - { - int fd; - - if (debug & 4) - say ("Creating empty unreadable file %s\n", quotearg (bakname)); - - try_makedirs_errno = ENOENT; - unlink (bakname); - while ((fd = creat (bakname, 0)) < 0) - { - if (errno != try_makedirs_errno) - pfatal ("Can't create file %s", quotearg (bakname)); - makedirs (bakname); - try_makedirs_errno = 0; - } - if (close (fd) != 0) - pfatal ("Can't close file %s", quotearg (bakname)); - } - else - { - if (debug & 4) - say ("Renaming file %s to %s\n", - quotearg_n (0, to), quotearg_n (1, bakname)); - while (rename (to, bakname) != 0) - { - if (errno != try_makedirs_errno) - pfatal ("Can't rename file %s to %s", - quotearg_n (0, to), quotearg_n (1, bakname)); - makedirs (bakname); - try_makedirs_errno = 0; - } - } - - free (bakname); - } - - if (from) - { - if (debug & 4) - say ("Renaming file %s to %s\n", - quotearg_n (0, from), quotearg_n (1, to)); - - if (rename (from, to) == 0) - *from_needs_removal = 0; - else - { - int to_dir_known_to_exist = 0; - - if (errno == ENOENT - && (to_errno == -1 || to_errno == ENOENT)) - { - makedirs (to); - to_dir_known_to_exist = 1; - if (rename (from, to) == 0) - { - *from_needs_removal = 0; - return; - } - } - - if (errno == EXDEV) - { - if (! backup) - { - if (unlink (to) == 0) - to_dir_known_to_exist = 1; - else if (errno != ENOENT) - pfatal ("Can't remove file %s", quotearg (to)); - } - if (! to_dir_known_to_exist) - makedirs (to); - copy_file (from, to, 0, mode); - return; - } - - pfatal ("Can't rename file %s to %s", - quotearg_n (0, from), quotearg_n (1, to)); - } - } - else if (! backup) - { - if (debug & 4) - say ("Removing file %s\n", quotearg (to)); - if (unlink (to) != 0) - pfatal ("Can't remove file %s", quotearg (to)); - } -} - -/* Create FILE with OPEN_FLAGS, and with MODE adjusted so that - we can read and write the file and that the file is not executable. - Return the file descriptor. */ -int -create_file (char const *file, int open_flags, mode_t mode) -{ - int fd; - mode |= S_IRUSR | S_IWUSR; - mode &= ~ (S_IXUSR | S_IXGRP | S_IXOTH); - if (! (O_CREAT && O_TRUNC)) - close (creat (file, mode)); - fd = open (file, O_CREAT | O_TRUNC | open_flags, mode); - if (fd < 0) - pfatal ("Can't create file %s", quotearg (file)); - return fd; -} - -/* Copy a file. */ - -void -copy_file (char const *from, char const *to, int to_flags, mode_t mode) -{ - int tofd; - int fromfd; - size_t i; - - if ((fromfd = open (from, O_RDONLY | O_BINARY)) < 0) - pfatal ("Can't reopen file %s", quotearg (from)); - tofd = create_file (to, O_WRONLY | O_BINARY | to_flags, mode); - while ((i = read (fromfd, buf, bufsize)) != 0) - { - if (i == (size_t) -1) - read_fatal (); - if (write (tofd, buf, i) != i) - write_fatal (); - } - if (close (fromfd) != 0) - read_fatal (); - if (close (tofd) != 0) - write_fatal (); -} - -static char const DEV_NULL[] = NULL_DEVICE; - -static char const RCSSUFFIX[] = ",v"; -static char const CHECKOUT[] = "co %s"; -static char const CHECKOUT_LOCKED[] = "co -l %s"; -static char const RCSDIFF1[] = "rcsdiff %s"; - -static char const SCCSPREFIX[] = "s."; -static char const GET[] = "get "; -static char const GET_LOCKED[] = "get -e "; -static char const SCCSDIFF1[] = "get -p "; -static char const SCCSDIFF2[] = "|diff - %s"; - -static char const CLEARTOOL_CO[] = "cleartool co -unr -nc "; - -/* Return "RCS" if FILENAME is controlled by RCS, - "SCCS" if it is controlled by SCCS, - "ClearCase" if it is controlled by Clearcase, and 0 otherwise. - READONLY is nonzero if we desire only readonly access to FILENAME. - FILESTAT describes FILENAME's status or is 0 if FILENAME does not exist. - If successful and if GETBUF is nonzero, set *GETBUF to a command - that gets the file; similarly for DIFFBUF and a command to diff the file - (but set *DIFFBUF to 0 if the diff operation is meaningless). - *GETBUF and *DIFFBUF must be freed by the caller. */ -char const * -version_controller (char const *filename, int readonly, - struct stat const *filestat, char **getbuf, char **diffbuf) -{ - struct stat cstat; - char const *filebase = base_name (filename); - char const *dotslash = *filename == '-' ? "./" : ""; - size_t dir_len = filebase - filename; - size_t filenamelen = strlen (filename); - size_t maxfixlen = sizeof "SCCS/" - 1 + sizeof SCCSPREFIX - 1; - size_t maxtrysize = filenamelen + maxfixlen + 1; - size_t quotelen = quote_system_arg (0, filename); - size_t maxgetsize = sizeof CLEARTOOL_CO + quotelen + maxfixlen; - size_t maxdiffsize = - (sizeof SCCSDIFF1 + sizeof SCCSDIFF2 + sizeof DEV_NULL - 1 - + 2 * quotelen + maxfixlen); - char *trybuf = xmalloc (maxtrysize); - char const *r = 0; - - strcpy (trybuf, filename); - -#define try1(f,a1) (sprintf (trybuf + dir_len, f, a1), stat (trybuf, &cstat) == 0) -#define try2(f,a1,a2) (sprintf (trybuf + dir_len, f, a1,a2), stat (trybuf, &cstat) == 0) - - /* Check that RCS file is not working file. - Some hosts don't report file name length errors. */ - - if ((try2 ("RCS/%s%s", filebase, RCSSUFFIX) - || try1 ("RCS/%s", filebase) - || try2 ("%s%s", filebase, RCSSUFFIX)) - && ! (filestat - && filestat->st_dev == cstat.st_dev - && filestat->st_ino == cstat.st_ino)) - { - if (getbuf) - { - char *p = *getbuf = xmalloc (maxgetsize); - sprintf (p, readonly ? CHECKOUT : CHECKOUT_LOCKED, dotslash); - p += strlen (p); - p += quote_system_arg (p, filename); - *p = '\0'; - } - - if (diffbuf) - { - char *p = *diffbuf = xmalloc (maxdiffsize); - sprintf (p, RCSDIFF1, dotslash); - p += strlen (p); - p += quote_system_arg (p, filename); - *p++ = '>'; - strcpy (p, DEV_NULL); - } - - r = "RCS"; - } - else if (try2 ("SCCS/%s%s", SCCSPREFIX, filebase) - || try2 ("%s%s", SCCSPREFIX, filebase)) - { - if (getbuf) - { - char *p = *getbuf = xmalloc (maxgetsize); - sprintf (p, readonly ? GET : GET_LOCKED); - p += strlen (p); - p += quote_system_arg (p, trybuf); - *p = '\0'; - } - - if (diffbuf) - { - char *p = *diffbuf = xmalloc (maxdiffsize); - strcpy (p, SCCSDIFF1); - p += sizeof SCCSDIFF1 - 1; - p += quote_system_arg (p, trybuf); - sprintf (p, SCCSDIFF2, dotslash); - p += strlen (p); - p += quote_system_arg (p, filename); - *p++ = '>'; - strcpy (p, DEV_NULL); - } - - r = "SCCS"; - } - else if (!readonly && filestat - && try1 ("%s@@", filebase) && S_ISDIR (cstat.st_mode)) - { - if (getbuf) - { - char *p = *getbuf = xmalloc (maxgetsize); - strcpy (p, CLEARTOOL_CO); - p += sizeof CLEARTOOL_CO - 1; - p += quote_system_arg (p, filename); - *p = '\0'; - } - - if (diffbuf) - *diffbuf = 0; - - r = "ClearCase"; - } - - free (trybuf); - return r; -} - -/* Get FILENAME from version control system CS. The file already exists if - EXISTS is nonzero. Only readonly access is needed if READONLY is nonzero. - Use the command GETBUF to actually get the named file. - Store the resulting file status into *FILESTAT. - Return nonzero if successful. */ -int -version_get (char const *filename, char const *cs, int exists, int readonly, - char const *getbuf, struct stat *filestat) -{ - if (patch_get < 0) - { - ask ("Get file %s from %s%s? [y] ", - quotearg (filename), cs, readonly ? "" : " with lock"); - if (*buf == 'n') - return 0; - } - - if (dry_run) - { - if (! exists) - fatal ("can't do dry run on nonexistent version-controlled file %s; invoke `%s' and try again", - quotearg (filename), getbuf); - } - else - { - if (verbosity == VERBOSE) - say ("Getting file %s from %s%s...\n", quotearg (filename), - cs, readonly ? "" : " with lock"); - if (systemic (getbuf) != 0) - fatal ("Can't get file %s from %s", quotearg (filename), cs); - if (stat (filename, filestat) != 0) - pfatal ("%s", quotearg (filename)); - } - - return 1; -} - -/* Allocate a unique area for a string. */ - -char * -savebuf (register char const *s, register size_t size) -{ - register char *rv; - - assert (s && size); - rv = malloc (size); - - if (! rv) - { - if (! using_plan_a) - memory_fatal (); - } - else - memcpy (rv, s, size); - - return rv; -} - -char * -savestr (char const *s) -{ - return savebuf (s, strlen (s) + 1); -} - -void -remove_prefix (char *p, size_t prefixlen) -{ - char const *s = p + prefixlen; - while ((*p++ = *s++)) - continue; -} - -char * -format_linenum (char numbuf[LINENUM_LENGTH_BOUND + 1], LINENUM n) -{ - char *p = numbuf + LINENUM_LENGTH_BOUND; - *p = '\0'; - - if (n < 0) - { - do - *--p = '0' - (int) (n % 10); - while ((n /= 10) != 0); - - *--p = '-'; - } - else - { - do - *--p = '0' + (int) (n % 10); - while ((n /= 10) != 0); - } - - return p; -} - -#if !HAVE_VPRINTF -#define vfprintf my_vfprintf -static int -vfprintf (FILE *stream, char const *format, va_list args) -{ -#if !HAVE_DOPRNT && HAVE__DOPRINTF -# define _doprnt _doprintf -#endif -#if HAVE_DOPRNT || HAVE__DOPRINTF - _doprnt (format, args, stream); - return ferror (stream) ? -1 : 0; -#else - int *a = (int *) args; - return fprintf (stream, format, - a[0], a[1], a[2], a[3], a[4], a[5], a[6], a[7], a[8], a[9]); -#endif -} -#endif /* !HAVE_VPRINTF */ - -/* Terminal output, pun intended. */ - -void -fatal (char const *format, ...) -{ - va_list args; - fprintf (stderr, "%s: **** ", program_name); - vararg_start (args, format); - vfprintf (stderr, format, args); - va_end (args); - putc ('\n', stderr); - fflush (stderr); - fatal_exit (0); -} - -void -memory_fatal (void) -{ - fatal ("out of memory"); -} - -void -read_fatal (void) -{ - pfatal ("read error"); -} - -void -write_fatal (void) -{ - pfatal ("write error"); -} - -/* Say something from patch, something from the system, then silence . . . */ - -void -pfatal (char const *format, ...) -{ - int errnum = errno; - va_list args; - fprintf (stderr, "%s: **** ", program_name); - vararg_start (args, format); - vfprintf (stderr, format, args); - va_end (args); - fflush (stderr); /* perror bypasses stdio on some hosts. */ - errno = errnum; - perror (" "); - fflush (stderr); - fatal_exit (0); -} - -/* Tell the user something. */ - -void -say (char const *format, ...) -{ - va_list args; - vararg_start (args, format); - vfprintf (stdout, format, args); - va_end (args); - fflush (stdout); -} - -/* Get a response from the user, somehow or other. */ - -void -ask (char const *format, ...) -{ - static int ttyfd = -2; - int r; - va_list args; - - vararg_start (args, format); - vfprintf (stdout, format, args); - va_end (args); - fflush (stdout); - - if (ttyfd == -2) - { - /* If standard output is not a tty, don't bother opening /dev/tty, - since it's unlikely that stdout will be seen by the tty user. - The isatty test also works around a bug in GNU Emacs 19.34 under Linux - which makes a call-process `patch' hang when it reads from /dev/tty. - POSIX.2 requires that we read /dev/tty, though. */ - ttyfd = (posixly_correct || isatty (STDOUT_FILENO) - ? open (TTY_DEVICE, O_RDONLY) - : -1); - } - - if (ttyfd < 0) - { - /* No terminal at all -- default it. */ - printf ("\n"); - buf[0] = '\n'; - buf[1] = '\0'; - } - else - { - size_t s = 0; - while ((r = read (ttyfd, buf + s, bufsize - 1 - s)) == bufsize - 1 - s - && buf[bufsize - 2] != '\n') - { - s = bufsize - 1; - bufsize *= 2; - buf = realloc (buf, bufsize); - if (!buf) - memory_fatal (); - } - if (r == 0) - printf ("EOF\n"); - else if (r < 0) - { - perror ("tty read"); - fflush (stderr); - close (ttyfd); - ttyfd = -1; - r = 0; - } - buf[s + r] = '\0'; - } -} - -/* Return nonzero if it OK to reverse a patch. */ - -int -ok_to_reverse (char const *format, ...) -{ - int r = 0; - - if (noreverse || ! (force && verbosity == SILENT)) - { - va_list args; - vararg_start (args, format); - vfprintf (stdout, format, args); - va_end (args); - } - - if (noreverse) - { - printf (" Skipping patch.\n"); - skip_rest_of_patch = TRUE; - r = 0; - } - else if (force) - { - if (verbosity != SILENT) - printf (" Applying it anyway.\n"); - r = 0; - } - else if (batch) - { - say (reverse ? " Ignoring -R.\n" : " Assuming -R.\n"); - r = 1; - } - else - { - ask (reverse ? " Ignore -R? [n] " : " Assume -R? [n] "); - r = *buf == 'y'; - if (! r) - { - ask ("Apply anyway? [n] "); - if (*buf != 'y') - { - if (verbosity != SILENT) - say ("Skipping patch.\n"); - skip_rest_of_patch = TRUE; - } - } - } - - return r; -} - -/* How to handle certain events when not in a critical region. */ - -#define NUM_SIGS (sizeof (sigs) / sizeof (*sigs)) -static int const sigs[] = { -#ifdef SIGHUP - SIGHUP, -#endif -#ifdef SIGPIPE - SIGPIPE, -#endif -#ifdef SIGTERM - SIGTERM, -#endif -#ifdef SIGXCPU - SIGXCPU, -#endif -#ifdef SIGXFSZ - SIGXFSZ, -#endif - SIGINT -}; - -#if !HAVE_SIGPROCMASK -#define sigset_t int -#define sigemptyset(s) (*(s) = 0) -#ifndef sigmask -#define sigmask(sig) (1 << ((sig) - 1)) -#endif -#define sigaddset(s, sig) (*(s) |= sigmask (sig)) -#define sigismember(s, sig) ((*(s) & sigmask (sig)) != 0) -#ifndef SIG_BLOCK -#define SIG_BLOCK 0 -#endif -#ifndef SIG_UNBLOCK -#define SIG_UNBLOCK (SIG_BLOCK + 1) -#endif -#ifndef SIG_SETMASK -#define SIG_SETMASK (SIG_BLOCK + 2) -#endif -#define sigprocmask(how, n, o) \ - ((how) == SIG_BLOCK \ - ? ((o) ? *(o) = sigblock (*(n)) : sigblock (*(n))) \ - : (how) == SIG_UNBLOCK \ - ? sigsetmask (((o) ? *(o) = sigblock (0) : sigblock (0)) & ~*(n)) \ - : (o ? *(o) = sigsetmask (*(n)) : sigsetmask (*(n)))) -#if !HAVE_SIGSETMASK -#define sigblock(mask) 0 -#define sigsetmask(mask) 0 -#endif -#endif - -static sigset_t initial_signal_mask; -static sigset_t signals_to_block; - -#if ! HAVE_SIGACTION -static RETSIGTYPE fatal_exit_handler PARAMS ((int)) __attribute__ ((noreturn)); -static RETSIGTYPE -fatal_exit_handler (int sig) -{ - signal (sig, SIG_IGN); - fatal_exit (sig); -} -#endif - -void -set_signals (int reset) -{ - int i; -#if HAVE_SIGACTION - struct sigaction initial_act, fatal_act; - fatal_act.sa_handler = fatal_exit; - sigemptyset (&fatal_act.sa_mask); - fatal_act.sa_flags = 0; -#define setup_handler(sig) sigaction (sig, &fatal_act, (struct sigaction *) 0) -#else -#define setup_handler(sig) signal (sig, fatal_exit_handler) -#endif - - if (!reset) - { -#ifdef SIGCHLD - /* System V fork+wait does not work if SIGCHLD is ignored. */ - signal (SIGCHLD, SIG_DFL); -#endif - sigemptyset (&signals_to_block); - for (i = 0; i < NUM_SIGS; i++) - { - int ignoring_signal; -#if HAVE_SIGACTION - if (sigaction (sigs[i], (struct sigaction *) 0, &initial_act) != 0) - continue; - ignoring_signal = initial_act.sa_handler == SIG_IGN; -#else - ignoring_signal = signal (sigs[i], SIG_IGN) == SIG_IGN; -#endif - if (! ignoring_signal) - { - sigaddset (&signals_to_block, sigs[i]); - setup_handler (sigs[i]); - } - } - } - else - { - /* Undo the effect of ignore_signals. */ -#if HAVE_SIGPROCMASK || HAVE_SIGSETMASK - sigprocmask (SIG_SETMASK, &initial_signal_mask, (sigset_t *) 0); -#else - for (i = 0; i < NUM_SIGS; i++) - if (sigismember (&signals_to_block, sigs[i])) - setup_handler (sigs[i]); -#endif - } -} - -/* How to handle certain events when in a critical region. */ - -void -ignore_signals (void) -{ -#if HAVE_SIGPROCMASK || HAVE_SIGSETMASK - sigprocmask (SIG_BLOCK, &signals_to_block, &initial_signal_mask); -#else - int i; - for (i = 0; i < NUM_SIGS; i++) - if (sigismember (&signals_to_block, sigs[i])) - signal (sigs[i], SIG_IGN); -#endif -} - -void -exit_with_signal (int sig) -{ - sigset_t s; - signal (sig, SIG_DFL); - sigemptyset (&s); - sigaddset (&s, sig); - sigprocmask (SIG_UNBLOCK, &s, (sigset_t *) 0); - raise (sig); - exit (2); -} - -int -systemic (char const *command) -{ - if (debug & 8) - say ("+ %s\n", command); - fflush (stdout); - return system (command); -} - -/* Replace '/' with '\0' in FILENAME if it marks a place that - needs testing for the existence of directory. Return the address - of the last location replaced, or 0 if none were replaced. */ -static char * -replace_slashes (char *filename) -{ - char *f; - char *last_location_replaced = 0; - char const *component_start; - - for (f = filename + FILESYSTEM_PREFIX_LEN (filename); ISSLASH (*f); f++) - continue; - - component_start = f; - - for (; *f; f++) - if (ISSLASH (*f)) - { - char *slash = f; - - /* Treat multiple slashes as if they were one slash. */ - while (ISSLASH (f[1])) - f++; - - /* Ignore slashes at the end of the path. */ - if (! f[1]) - break; - - /* "." and ".." need not be tested. */ - if (! (slash - component_start <= 2 - && component_start[0] == '.' && slash[-1] == '.')) - { - *slash = '\0'; - last_location_replaced = slash; - } - - component_start = f + 1; - } - - return last_location_replaced; -} - -/* Make sure we'll have the directories to create a file. - Ignore the last element of `filename'. */ - -static void -makedirs (register char *filename) -{ - register char *f; - register char *flim = replace_slashes (filename); - - if (flim) - { - /* Create any missing directories, replacing NULs by '/'s. - Ignore errors. We may have to keep going even after an EEXIST, - since the path may contain ".."s; and when there is an EEXIST - failure the system may return some other error number. - Any problems will eventually be reported when we create the file. */ - for (f = filename; f <= flim; f++) - if (!*f) - { - mkdir (filename, - S_IRUSR|S_IWUSR|S_IXUSR - |S_IRGRP|S_IWGRP|S_IXGRP - |S_IROTH|S_IWOTH|S_IXOTH); - *f = '/'; - } - } -} - -/* Remove empty ancestor directories of FILENAME. - Ignore errors, since the path may contain ".."s, and when there - is an EEXIST failure the system may return some other error number. */ -void -removedirs (char *filename) -{ - size_t i; - - for (i = strlen (filename); i != 0; i--) - if (ISSLASH (filename[i]) - && ! (ISSLASH (filename[i - 1]) - || (filename[i - 1] == '.' - && (i == 1 - || ISSLASH (filename[i - 2]) - || (filename[i - 2] == '.' - && (i == 2 - || ISSLASH (filename[i - 3]))))))) - { - filename[i] = '\0'; - if (rmdir (filename) == 0 && verbosity == VERBOSE) - say ("Removed empty directory %s\n", quotearg (filename)); - filename[i] = '/'; - } -} - -static time_t initial_time; - -void -init_time (void) -{ - time (&initial_time); -} - -/* Make filenames more reasonable. */ - -char * -fetchname (char *at, int strip_leading, time_t *pstamp) -{ - char *name; - register char *t; - int sleading = strip_leading; - time_t stamp = (time_t) -1; - - while (ISSPACE ((unsigned char) *at)) - at++; - if (debug & 128) - say ("fetchname %s %d\n", at, strip_leading); - - name = at; - /* Strip up to `strip_leading' leading slashes and null terminate. - If `strip_leading' is negative, strip all leading slashes. */ - for (t = at; *t; t++) - { - if (ISSLASH (*t)) - { - while (ISSLASH (t[1])) - t++; - if (strip_leading < 0 || --sleading >= 0) - name = t+1; - } - else if (ISSPACE ((unsigned char) *t)) - { - char const *u = t; - - if (set_time | set_utc) - stamp = str2time (&u, initial_time, - set_utc ? 0L : TM_LOCAL_ZONE); - else - { - /* The head says the file is nonexistent if the timestamp - is the epoch; but the listed time is local time, not UTC, - and POSIX.1 allows local time offset anywhere in the range - -25:00 < offset < +26:00. Match any time in that - range by assuming local time is -25:00 and then matching - any ``local'' time T in the range 0 < T < 25+26 hours. */ - stamp = str2time (&u, initial_time, -25L * 60 * 60); - if (0 < stamp && stamp < (25 + 26) * 60L * 60) - stamp = 0; - } - - if (*u && ! ISSPACE ((unsigned char) *u)) - stamp = (time_t) -1; - - *t = '\0'; - break; - } - } - - if (!*name) - return 0; - - /* If the name is "/dev/null", ignore the name and mark the file - as being nonexistent. The name "/dev/null" appears in patches - regardless of how NULL_DEVICE is spelled. */ - if (strcmp (at, "/dev/null") == 0) - { - if (pstamp) - *pstamp = 0; - return 0; - } - - /* Ignore the name if it doesn't have enough slashes to strip off. */ - if (0 < sleading) - return 0; - - if (pstamp) - *pstamp = stamp; - - return savestr (name); -} - -void -Fseek (FILE *stream, file_offset offset, int ptrname) -{ - if (file_seek (stream, offset, ptrname) != 0) - pfatal ("fseek"); -} diff --git a/src/bin/patch/util.h b/src/bin/patch/util.h deleted file mode 100644 index 9215cd3854..0000000000 --- a/src/bin/patch/util.h +++ /dev/null @@ -1,39 +0,0 @@ -/* utility functions for `patch' */ - -/* $Id: util.h 8008 2004-06-16 21:22:10Z korli $ */ - -/* An upper bound on the print length of a signed decimal line number. - Add one for the sign. */ -#define LINENUM_LENGTH_BOUND (sizeof (LINENUM) * CHAR_BIT / 3 + 1) - -XTERN enum backup_type backup_type; - -int ok_to_reverse PARAMS ((char const *, ...)) __attribute__ ((format (printf, 1, 2))); -void ask PARAMS ((char const *, ...)) __attribute__ ((format (printf, 1, 2))); -void say PARAMS ((char const *, ...)) __attribute__ ((format (printf, 1, 2))); - -void fatal PARAMS ((char const *, ...)) - __attribute__ ((noreturn, format (printf, 1, 2))); -void pfatal PARAMS ((char const *, ...)) - __attribute__ ((noreturn, format (printf, 1, 2))); - -char *fetchname PARAMS ((char *, int, time_t *)); -char *savebuf PARAMS ((char const *, size_t)); -char *savestr PARAMS ((char const *)); -char const *version_controller PARAMS ((char const *, int, struct stat const *, char **, char **)); -int version_get PARAMS ((char const *, char const *, int, int, char const *, struct stat *)); -int create_file PARAMS ((char const *, int, mode_t)); -int systemic PARAMS ((char const *)); -char *format_linenum PARAMS ((char[LINENUM_LENGTH_BOUND + 1], LINENUM)); -void Fseek PARAMS ((FILE *, file_offset, int)); -void copy_file PARAMS ((char const *, char const *, int, mode_t)); -void exit_with_signal PARAMS ((int)) __attribute__ ((noreturn)); -void ignore_signals PARAMS ((void)); -void init_time PARAMS ((void)); -void memory_fatal PARAMS ((void)) __attribute__ ((noreturn)); -void move_file PARAMS ((char const *, int volatile *, char *, mode_t, int)); -void read_fatal PARAMS ((void)) __attribute__ ((noreturn)); -void remove_prefix PARAMS ((char *, size_t)); -void removedirs PARAMS ((char *)); -void set_signals PARAMS ((int)); -void write_fatal PARAMS ((void)) __attribute__ ((noreturn)); diff --git a/src/bin/patch/version.c b/src/bin/patch/version.c deleted file mode 100644 index 1cf6dda9d0..0000000000 --- a/src/bin/patch/version.c +++ /dev/null @@ -1,30 +0,0 @@ -/* Print the version number. */ - -/* $Id: version.c 8008 2004-06-16 21:22:10Z korli $ */ - -#define XTERN extern -#include -#undef XTERN -#define XTERN -#include -#include - -static char const copyright_string[] = "\ -Copyright 1984-1988 Larry Wall\n\ -Copyright 1989-1999 Free Software Foundation, Inc."; - -static char const free_software_msgid[] = "\ -This program comes with NO WARRANTY, to the extent permitted by law.\n\ -You may redistribute copies of this program\n\ -under the terms of the GNU General Public License.\n\ -For more information about these matters, see the file named COPYING."; - -static char const authorship_msgid[] = "\ -written by Larry Wall and Paul Eggert"; - -void -version (void) -{ - printf ("%s %s\n%s\n\n%s\n\n%s\n", program_name, PATCH_VERSION, - copyright_string, free_software_msgid, authorship_msgid); -} diff --git a/src/bin/patch/version.h b/src/bin/patch/version.h deleted file mode 100644 index 94d8d84307..0000000000 --- a/src/bin/patch/version.h +++ /dev/null @@ -1,5 +0,0 @@ -/* Print the version number. */ - -/* $Id: version.h 8008 2004-06-16 21:22:10Z korli $ */ - -void version PARAMS ((void)); diff --git a/src/bin/patch/xalloc.h b/src/bin/patch/xalloc.h deleted file mode 100644 index 2709ad866a..0000000000 --- a/src/bin/patch/xalloc.h +++ /dev/null @@ -1,52 +0,0 @@ -/* xalloc.h -- malloc with out-of-memory checking - Copyright (C) 1990-1998, 1999 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. */ - -#ifndef XALLOC_H_ -# define XALLOC_H_ - -# ifndef PARAMS -# if defined PROTOTYPES || (defined __STDC__ && __STDC__) -# define PARAMS(Args) Args -# else -# define PARAMS(Args) () -# endif -# endif - -/* Exit value when the requested amount of memory is not available. - It is initialized to EXIT_FAILURE, but the caller may set it to - some other value. */ -extern int xalloc_exit_failure; - -/* If this pointer is non-zero, run the specified function upon each - allocation failure. It is initialized to zero. */ -extern void (*xalloc_fail_func) (); - -/* If XALLOC_FAIL_FUNC is undefined or a function that returns, this - message must be non-NULL. It is translated via gettext. - The default value is "Memory exhausted". */ -extern char *const xalloc_msg_memory_exhausted; - -void *xmalloc PARAMS ((size_t n)); -void *xcalloc PARAMS ((size_t n, size_t s)); -void *xrealloc PARAMS ((void *p, size_t n)); - -# define XMALLOC(Type, N_bytes) ((Type *) xmalloc (sizeof (Type) * (N_bytes))) -# define XCALLOC(Type, N_bytes) ((Type *) xcalloc (sizeof (Type), (N_bytes))) -# define XREALLOC(Ptr, Type, N_bytes) \ - ((Type *) xrealloc ((void *) (Ptr), sizeof (Type) * (N_bytes))) - -#endif /* !XALLOC_H_ */ diff --git a/src/bin/patch/xmalloc.c b/src/bin/patch/xmalloc.c deleted file mode 100644 index 696cf3c9a2..0000000000 --- a/src/bin/patch/xmalloc.c +++ /dev/null @@ -1,113 +0,0 @@ -/* xmalloc.c -- malloc with out of memory checking - Copyright (C) 1990-1997, 98, 99 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 HAVE_CONFIG_H -# include -#endif - -#include - -#if STDC_HEADERS -# include -#else -void *calloc (); -void *malloc (); -void *realloc (); -void free (); -#endif - -#if ENABLE_NLS -# include -# define _(Text) gettext (Text) -#else -# define textdomain(Domain) -# define _(Text) Text -#endif -#define N_(Text) Text - -#include "error.h" -#include "xalloc.h" - -#ifndef EXIT_FAILURE -# define EXIT_FAILURE 1 -#endif - -#ifndef HAVE_DONE_WORKING_MALLOC_CHECK -you must run the autoconf test for a properly working malloc -- see malloc.m4 -#endif - -#ifndef HAVE_DONE_WORKING_REALLOC_CHECK -you must run the autoconf test for a properly working realloc -- see realloc.m4 -#endif - -/* Exit value when the requested amount of memory is not available. - The caller may set it to some other value. */ -int xalloc_exit_failure = EXIT_FAILURE; - -/* If non NULL, call this function when memory is exhausted. */ -void (*xalloc_fail_func) () = 0; - -/* If XALLOC_FAIL_FUNC is NULL, or does return, display this message - before exiting when memory is exhausted. Goes through gettext. */ -char *const xalloc_msg_memory_exhausted = N_("Memory exhausted"); - -static void -xalloc_fail (void) -{ - if (xalloc_fail_func) - (*xalloc_fail_func) (); - error (xalloc_exit_failure, 0, "%s", _(xalloc_msg_memory_exhausted)); -} - -/* Allocate N bytes of memory dynamically, with error checking. */ - -void * -xmalloc (size_t n) -{ - void *p; - - p = malloc (n); - if (p == 0) - xalloc_fail (); - return p; -} - -/* Change the size of an allocated block of memory P to N bytes, - with error checking. - If P is NULL, run xmalloc. */ - -void * -xrealloc (void *p, size_t n) -{ - p = realloc (p, n); - if (p == 0) - xalloc_fail (); - return p; -} - -/* Allocate memory for N elements of S bytes, with error checking. */ - -void * -xcalloc (size_t n, size_t s) -{ - void *p; - - p = calloc (n, s); - if (p == 0) - xalloc_fail (); - return p; -} diff --git a/src/data/package_infos/arm/haiku b/src/data/package_infos/arm/haiku index 40018cbd9f..ee3e79f163 100644 --- a/src/data/package_infos/arm/haiku +++ b/src/data/package_infos/arm/haiku @@ -41,7 +41,6 @@ provides { cmd:more cmd:netcat cmd:passwd - cmd:patch cmd:ping cmd:ping6 cmd:prio diff --git a/src/data/package_infos/m68k/haiku b/src/data/package_infos/m68k/haiku index fbf228f0bd..f4ba03c44c 100644 --- a/src/data/package_infos/m68k/haiku +++ b/src/data/package_infos/m68k/haiku @@ -41,7 +41,6 @@ provides { cmd:more cmd:netcat cmd:passwd - cmd:patch cmd:ping cmd:ping6 cmd:prio diff --git a/src/data/package_infos/ppc/haiku b/src/data/package_infos/ppc/haiku index 2f8dbaf79d..ceae41c755 100644 --- a/src/data/package_infos/ppc/haiku +++ b/src/data/package_infos/ppc/haiku @@ -41,7 +41,6 @@ provides { cmd:more cmd:netcat cmd:passwd - cmd:patch cmd:ping cmd:ping6 cmd:prio diff --git a/src/data/package_infos/x86/haiku b/src/data/package_infos/x86/haiku index fe1b5f58ff..1c792a0115 100644 --- a/src/data/package_infos/x86/haiku +++ b/src/data/package_infos/x86/haiku @@ -41,7 +41,6 @@ provides { cmd:more cmd:netcat cmd:passwd - cmd:patch cmd:ping cmd:ping6 cmd:prio diff --git a/src/data/package_infos/x86_64/haiku b/src/data/package_infos/x86_64/haiku index 6ccf76a666..7d987a13ab 100644 --- a/src/data/package_infos/x86_64/haiku +++ b/src/data/package_infos/x86_64/haiku @@ -40,7 +40,6 @@ provides { cmd:more cmd:netcat cmd:passwd - cmd:patch cmd:ping cmd:ping6 cmd:prio diff --git a/src/data/package_infos/x86_gcc2/haiku b/src/data/package_infos/x86_gcc2/haiku index ef663c4b27..2f9beee4e2 100644 --- a/src/data/package_infos/x86_gcc2/haiku +++ b/src/data/package_infos/x86_gcc2/haiku @@ -41,7 +41,6 @@ provides { cmd:more cmd:netcat cmd:passwd - cmd:patch cmd:ping cmd:ping6 cmd:prio