From c3f352d4ad515968c54d216a0e53252eff8ab3ef Mon Sep 17 00:00:00 2001 From: peter Date: Sat, 30 Dec 1995 19:02:48 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r13122, which included commits to RCS files with non-trunk default branches. --- gnu/usr.bin/diff3/COPYING | 339 --------- gnu/usr.bin/diff3/diff3.c | 1693 ------------------------------------------- gnu/usr.bin/diff3/getopt.c | 731 ------------------- gnu/usr.bin/diff3/getopt.h | 129 ---- gnu/usr.bin/diff3/getopt1.c | 176 ----- gnu/usr.bin/diff3/system.h | 159 ---- gnu/usr.bin/diff3/version.c | 3 - 7 files changed, 3230 deletions(-) delete mode 100644 gnu/usr.bin/diff3/COPYING delete mode 100644 gnu/usr.bin/diff3/diff3.c delete mode 100644 gnu/usr.bin/diff3/getopt.c delete mode 100644 gnu/usr.bin/diff3/getopt.h delete mode 100644 gnu/usr.bin/diff3/getopt1.c delete mode 100644 gnu/usr.bin/diff3/system.h delete mode 100644 gnu/usr.bin/diff3/version.c (limited to 'gnu/usr.bin/diff3') diff --git a/gnu/usr.bin/diff3/COPYING b/gnu/usr.bin/diff3/COPYING deleted file mode 100644 index a43ea21..0000000 --- a/gnu/usr.bin/diff3/COPYING +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, 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 - - Appendix: 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., 675 Mass Ave, Cambridge, MA 02139, 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/gnu/usr.bin/diff3/diff3.c b/gnu/usr.bin/diff3/diff3.c deleted file mode 100644 index b9952fc..0000000 --- a/gnu/usr.bin/diff3/diff3.c +++ /dev/null @@ -1,1693 +0,0 @@ -/* Three way file comparison program (diff3) for Project GNU. - Copyright (C) 1988, 1989, 1992 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., 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* Written by Randy Smith */ - -#if __STDC__ -#define VOID void -#else -#define VOID char -#endif - -#include -#include -#include "getopt.h" -#include "system.h" - -/* - * Internal data structures and macros for the diff3 program; includes - * data structures for both diff3 diffs and normal diffs. - */ - -/* Different files within a three way diff. */ -#define FILE0 0 -#define FILE1 1 -#define FILE2 2 - -/* - * A three way diff is built from two two-way diffs; the file which - * the two two-way diffs share is: - */ -#define FILEC FILE2 - -/* - * Different files within a two way diff. - * FC is the common file, FO the other file. - */ -#define FO 0 -#define FC 1 - -/* The ranges are indexed by */ -#define START 0 -#define END 1 - -enum diff_type { - ERROR, /* Should not be used */ - ADD, /* Two way diff add */ - CHANGE, /* Two way diff change */ - DELETE, /* Two way diff delete */ - DIFF_ALL, /* All three are different */ - DIFF_1ST, /* Only the first is different */ - DIFF_2ND, /* Only the second */ - DIFF_3RD /* Only the third */ -}; - -/* Two way diff */ -struct diff_block { - int ranges[2][2]; /* Ranges are inclusive */ - char **lines[2]; /* The actual lines (may contain nulls) */ - int *lengths[2]; /* Line lengths (including newlines, if any) */ - struct diff_block *next; -}; - -/* Three way diff */ - -struct diff3_block { - enum diff_type correspond; /* Type of diff */ - int ranges[3][2]; /* Ranges are inclusive */ - char **lines[3]; /* The actual lines (may contain nulls) */ - int *lengths[3]; /* Line lengths (including newlines, if any) */ - struct diff3_block *next; -}; - -/* - * Access the ranges on a diff block. - */ -#define D_LOWLINE(diff, filenum) \ - ((diff)->ranges[filenum][START]) -#define D_HIGHLINE(diff, filenum) \ - ((diff)->ranges[filenum][END]) -#define D_NUMLINES(diff, filenum) \ - (D_HIGHLINE (diff, filenum) - D_LOWLINE (diff, filenum) + 1) - -/* - * Access the line numbers in a file in a diff by relative line - * numbers (i.e. line number within the diff itself). Note that these - * are lvalues and can be used for assignment. - */ -#define D_RELNUM(diff, filenum, linenum) \ - ((diff)->lines[filenum][linenum]) -#define D_RELLEN(diff, filenum, linenum) \ - ((diff)->lengths[filenum][linenum]) - -/* - * And get at them directly, when that should be necessary. - */ -#define D_LINEARRAY(diff, filenum) \ - ((diff)->lines[filenum]) -#define D_LENARRAY(diff, filenum) \ - ((diff)->lengths[filenum]) - -/* - * Next block. - */ -#define D_NEXT(diff) ((diff)->next) - -/* - * Access the type of a diff3 block. - */ -#define D3_TYPE(diff) ((diff)->correspond) - -/* - * Line mappings based on diffs. The first maps off the top of the - * diff, the second off of the bottom. - */ -#define D_HIGH_MAPLINE(diff, fromfile, tofile, lineno) \ - ((lineno) \ - - D_HIGHLINE ((diff), (fromfile)) \ - + D_HIGHLINE ((diff), (tofile))) - -#define D_LOW_MAPLINE(diff, fromfile, tofile, lineno) \ - ((lineno) \ - - D_LOWLINE ((diff), (fromfile)) \ - + D_LOWLINE ((diff), (tofile))) - -/* - * General memory allocation function. - */ -#define ALLOCATE(number, type) \ - (type *) xmalloc ((number) * sizeof (type)) - -/* Options variables for flags set on command line. */ - -/* If nonzero, treat all files as text files, never as binary. */ -static int always_text; - -/* If nonzero, write out an ed script instead of the standard diff3 format. */ -static int edscript; - -/* If nonzero, in the case of overlapping diffs (type DIFF_ALL), - preserve the lines which would normally be deleted from - file 1 with a special flagging mechanism. */ -static int flagging; - -/* Number of lines to keep in identical prefix and suffix. */ -static int horizon_lines = 10; - -/* If nonzero, do not output information for overlapping diffs. */ -static int simple_only; - -/* If nonzero, do not output information for non-overlapping diffs. */ -static int overlap_only; - -/* If nonzero, show information for DIFF_2ND diffs. */ -static int show_2nd; - -/* If nonzero, include `:wq' at the end of the script - to write out the file being edited. */ -static int finalwrite; - -/* If nonzero, output a merged file. */ -static int merge; - -static char *argv0; - -/* - * Forward function declarations. - */ -static int myread (); -static void fatal (); -static void perror_with_exit (); -static struct diff_block *process_diff (); -static struct diff3_block *make_3way_diff (); -static void output_diff3 (); -static int output_diff3_edscript (); -static int output_diff3_merge (); -static void usage (); - -static struct diff3_block *using_to_diff3_block (); -static int copy_stringlist (); -static struct diff3_block *create_diff3_block (); -static int compare_line_list (); - -static char *read_diff (); -static enum diff_type process_diff_control (); -static char *scan_diff_line (); - -static struct diff3_block *reverse_diff3_blocklist (); - -VOID *xmalloc (); -static VOID *xrealloc (); - -static char diff_program[] = DIFF_PROGRAM; - -static struct option longopts[] = -{ - {"text", 0, NULL, 'a'}, - {"show-all", 0, NULL, 'A'}, - {"ed", 0, NULL, 'e'}, - {"show-overlap", 0, NULL, 'E'}, - {"label", 1, NULL, 'L'}, - {"merge", 0, NULL, 'm'}, - {"overlap-only", 0, NULL, 'x'}, - {"easy-only", 0, NULL, '3'}, - {"version", 0, NULL, 'v'}, - {0, 0, 0, 0} -}; - -/* - * Main program. Calls diff twice on two pairs of input files, - * combines the two diffs, and outputs them. - */ -int -main (argc, argv) - int argc; - char **argv; -{ - extern char *version_string; - int c, i; - int mapping[3]; - int rev_mapping[3]; - int incompat; - int conflicts_found; - struct diff_block *thread0, *thread1, *last_block; - struct diff3_block *diff3; - int tag_count = 0; - char *tag_strings[3]; - extern char *optarg; - char *commonname; - char **file; - struct stat statb; - - incompat = 0; - - argv0 = argv[0]; - - while ((c = getopt_long (argc, argv, "aeimvx3AEXL:", longopts, (int *) 0)) - != EOF) - { - switch (c) - { - case 'a': - always_text = 1; - break; - case 'A': - show_2nd = 1; - flagging = 1; - incompat++; - break; - case 'x': - overlap_only = 1; - incompat++; - break; - case '3': - simple_only = 1; - incompat++; - break; - case 'i': - finalwrite = 1; - break; - case 'm': - merge = 1; - break; - case 'X': - overlap_only = 1; - /* Falls through */ - case 'E': - flagging = 1; - /* Falls through */ - case 'e': - incompat++; - break; - case 'v': - fprintf (stderr, "GNU diff3 version %s\n", version_string); - break; - case 'L': - /* Handle up to three -L options. */ - if (tag_count < 3) - { - tag_strings[tag_count++] = optarg; - break; - } - /* Falls through */ - default: - usage (); - /* NOTREACHED */ - } - } - - edscript = incompat & ~merge; /* -AeExX3 without -m implies ed script. */ - show_2nd |= ~incompat & merge; /* -m without -AeExX3 implies -A. */ - flagging |= ~incompat & merge; - - if (incompat > 1 /* Ensure at most one of -AeExX3. */ - || finalwrite & merge /* -i -m would rewrite input file. */ - || (tag_count && ! flagging) /* -L requires one of -AEX. */ - || argc - optind != 3) - usage (); - - file = &argv[optind]; - - for (i = tag_count; i < 3; i++) - tag_strings[i] = file[i]; - - /* Always compare file1 to file2, even if file2 is "-". - This is needed for -mAeExX3. Using the file0 as - the common file would produce wrong results, because if the - file0-file1 diffs didn't line up with the file0-file2 diffs - (which is entirely possible since we don't use diff's -n option), - diff3 might report phantom changes from file1 to file2. */ - - if (strcmp (file[2], "-") == 0) - { - /* Sigh. We've got standard input as the last arg. We can't - call diff twice on stdin. Use the middle arg as the common - file instead. */ - if (strcmp (file[0], "-") == 0 || strcmp (file[1], "-") == 0) - fatal ("`-' specified for more than one input file"); - mapping[0] = 0; - mapping[1] = 2; - mapping[2] = 1; - } - else - { - /* Normal, what you'd expect */ - mapping[0] = 0; - mapping[1] = 1; - mapping[2] = 2; - } - - for (i = 0; i < 3; i++) - rev_mapping[mapping[i]] = i; - - for (i = 0; i < 3; i++) - if (strcmp (file[i], "-") != 0) - if (stat (file[i], &statb) < 0) - perror_with_exit (file[i]); - else if (S_ISDIR(statb.st_mode)) - { - fprintf (stderr, "%s: %s: Is a directory\n", argv0, file[i]); - exit (2); - } - - - commonname = file[rev_mapping[FILEC]]; - thread1 = process_diff (file[rev_mapping[FILE1]], commonname, &last_block); - if (thread1) - for (i = 0; i < 2; i++) - { - horizon_lines = max (horizon_lines, D_NUMLINES (thread1, i)); - horizon_lines = max (horizon_lines, D_NUMLINES (last_block, i)); - } - thread0 = process_diff (file[rev_mapping[FILE0]], commonname, &last_block); - diff3 = make_3way_diff (thread0, thread1); - if (edscript) - conflicts_found - = output_diff3_edscript (stdout, diff3, mapping, rev_mapping, - tag_strings[0], tag_strings[1], tag_strings[2]); - else if (merge) - { - if (! freopen (file[rev_mapping[FILE0]], "r", stdin)) - perror_with_exit (file[rev_mapping[FILE0]]); - conflicts_found - = output_diff3_merge (stdin, stdout, diff3, mapping, rev_mapping, - tag_strings[0], tag_strings[1], tag_strings[2]); - if (ferror (stdin)) - fatal ("read error"); - } - else - { - output_diff3 (stdout, diff3, mapping, rev_mapping); - conflicts_found = 0; - } - - if (ferror (stdout) || fclose (stdout) != 0) - fatal ("write error"); - exit (conflicts_found); - return conflicts_found; -} - -/* - * Explain, patiently and kindly, how to use this program. Then exit. - */ -static void -usage () -{ - fprintf (stderr, "\ -Usage: %s [options] my-file older-file your-file\n\ -Options:\n\ - [-exAEX3v] [-i|-m] [-L label1 [-L label2 [-L label3]]] [--text] [--ed]\n\ - [--merge] [--show-all] [--show-overlap] [--overlap-only] [--easy-only]\n\ - [--label=label1 [--label=label2 [--label=label3]]] [--version]\n\ - Only one of [exAEX3] is allowed\n", argv0); - exit (2); -} - -/* - * Routines that combine the two diffs together into one. The - * algorithm used follows: - * - * File2 is shared in common between the two diffs. - * Diff02 is the diff between 0 and 2. - * Diff12 is the diff between 1 and 2. - * - * 1) Find the range for the first block in File2. - * a) Take the lowest of the two ranges (in File2) in the two - * current blocks (one from each diff) as being the low - * water mark. Assign the upper end of this block as - * being the high water mark and move the current block up - * one. Mark the block just moved over as to be used. - * b) Check the next block in the diff that the high water - * mark is *not* from. - * - * *If* the high water mark is above - * the low end of the range in that block, - * - * mark that block as to be used and move the current - * block up. Set the high water mark to the max of - * the high end of this block and the current. Repeat b. - * - * 2) Find the corresponding ranges in File0 (from the blocks - * in diff02; line per line outside of diffs) and in File1. - * Create a diff3_block, reserving space as indicated by the ranges. - * - * 3) Copy all of the pointers for file2 in. At least for now, - * do bcmp's between corresponding strings in the two diffs. - * - * 4) Copy all of the pointers for file0 and 1 in. Get what you - * need from file2 (when there isn't a diff block, it's - * identical to file2 within the range between diff blocks). - * - * 5) If the diff blocks you used came from only one of the two - * strings of diffs, then that file (i.e. the one other than - * the common file in that diff) is the odd person out. If you used - * diff blocks from both sets, check to see if files 0 and 1 match: - * - * Same number of lines? If so, do a set of bcmp's (if a - * bcmp matches; copy the pointer over; it'll be easier later - * if you have to do any compares). If they match, 0 & 1 are - * the same. If not, all three different. - * - * Then you do it again, until you run out of blocks. - * - */ - -/* - * This routine makes a three way diff (chain of diff3_block's) from two - * two way diffs (chains of diff_block's). It is assumed that each of - * the two diffs passed are onto the same file (i.e. that each of the - * diffs were made "to" the same file). The three way diff pointer - * returned will have numbering FILE0--the other file in diff02, - * FILE1--the other file in diff12, and FILEC--the common file. - */ -static struct diff3_block * -make_3way_diff (thread0, thread1) - struct diff_block *thread0, *thread1; -{ -/* - * This routine works on the two diffs passed to it as threads. - * Thread number 0 is diff02, thread number 1 is diff12. The USING - * array is set to the base of the list of blocks to be used to - * construct each block of the three way diff; if no blocks from a - * particular thread are to be used, that element of the using array - * is set to 0. The elements LAST_USING array are set to the last - * elements on each of the using lists. - * - * The HIGH_WATER_MARK is set to the highest line number in the common file - * described in any of the diffs in either of the USING lists. The - * HIGH_WATER_THREAD names the thread. Similarly the BASE_WATER_MARK - * and BASE_WATER_THREAD describe the lowest line number in the common file - * described in any of the diffs in either of the USING lists. The - * HIGH_WATER_DIFF is the diff from which the HIGH_WATER_MARK was - * taken. - * - * The HIGH_WATER_DIFF should always be equal to LAST_USING - * [HIGH_WATER_THREAD]. The OTHER_DIFF is the next diff to check for - * higher water, and should always be equal to - * CURRENT[HIGH_WATER_THREAD ^ 0x1]. The OTHER_THREAD is the thread - * in which the OTHER_DIFF is, and hence should always be equal to - * HIGH_WATER_THREAD ^ 0x1. - * - * The variable LAST_DIFF is kept set to the last diff block produced - * by this routine, for line correspondence purposes between that diff - * and the one currently being worked on. It is initialized to - * ZERO_DIFF before any blocks have been created. - */ - - struct diff_block - *using[2], - *last_using[2], - *current[2]; - - int - high_water_mark; - - int - high_water_thread, - base_water_thread, - other_thread; - - struct diff_block - *high_water_diff, - *other_diff; - - struct diff3_block - *result, - *tmpblock, - **result_end, - *last_diff3; - - static struct diff3_block zero_diff3 = { - ERROR, - { {0, 0}, {0, 0}, {0, 0} }, - { (char **) 0, (char **) 0, (char **) 0 }, - { (int *) 0, (int *) 0, (int *) 0 }, - (struct diff3_block *) 0 - }; - - /* Initialization */ - result = 0; - result_end = &result; - current[0] = thread0; current[1] = thread1; - last_diff3 = &zero_diff3; - - /* Sniff up the threads until we reach the end */ - - while (current[0] || current[1]) - { - using[0] = using[1] = last_using[0] = last_using[1] = - (struct diff_block *) 0; - - /* Setup low and high water threads, diffs, and marks. */ - if (!current[0]) - base_water_thread = 1; - else if (!current[1]) - base_water_thread = 0; - else - base_water_thread = - (D_LOWLINE (current[0], FC) > D_LOWLINE (current[1], FC)); - - high_water_thread = base_water_thread; - - high_water_diff = current[high_water_thread]; - -#if 0 - /* low and high waters start off same diff */ - base_water_mark = D_LOWLINE (high_water_diff, FC); -#endif - - high_water_mark = D_HIGHLINE (high_water_diff, FC); - - /* Make the diff you just got info from into the using class */ - using[high_water_thread] - = last_using[high_water_thread] - = high_water_diff; - current[high_water_thread] = high_water_diff->next; - last_using[high_water_thread]->next - = (struct diff_block *) 0; - - /* And mark the other diff */ - other_thread = high_water_thread ^ 0x1; - other_diff = current[other_thread]; - - /* Shuffle up the ladder, checking the other diff to see if it - needs to be incorporated. */ - while (other_diff - && D_LOWLINE (other_diff, FC) <= high_water_mark + 1) - { - - /* Incorporate this diff into the using list. Note that - this doesn't take it off the current list */ - if (using[other_thread]) - last_using[other_thread]->next = other_diff; - else - using[other_thread] = other_diff; - last_using[other_thread] = other_diff; - - /* Take it off the current list. Note that this following - code assumes that other_diff enters it equal to - current[high_water_thread ^ 0x1] */ - current[other_thread] - = current[other_thread]->next; - other_diff->next - = (struct diff_block *) 0; - - /* Set the high_water stuff - If this comparison is equal, then this is the last pass - through this loop; since diff blocks within a given - thread cannot overlap, the high_water_mark will be - *below* the range_start of either of the next diffs. */ - - if (high_water_mark < D_HIGHLINE (other_diff, FC)) - { - high_water_thread ^= 1; - high_water_diff = other_diff; - high_water_mark = D_HIGHLINE (other_diff, FC); - } - - /* Set the other diff */ - other_thread = high_water_thread ^ 0x1; - other_diff = current[other_thread]; - } - - /* The using lists contain a list of all of the blocks to be - included in this diff3_block. Create it. */ - - tmpblock = using_to_diff3_block (using, last_using, - base_water_thread, high_water_thread, - last_diff3); - - if (!tmpblock) - fatal ("internal error: screwup in format of diff blocks"); - - /* Put it on the list. */ - *result_end = tmpblock; - result_end = &tmpblock->next; - - /* Set up corresponding lines correctly. */ - last_diff3 = tmpblock; - } - return result; -} - -/* - * using_to_diff3_block: - * This routine takes two lists of blocks (from two separate diff - * threads) and puts them together into one diff3 block. - * It then returns a pointer to this diff3 block or 0 for failure. - * - * All arguments besides using are for the convenience of the routine; - * they could be derived from the using array. - * LAST_USING is a pair of pointers to the last blocks in the using - * structure. - * LOW_THREAD and HIGH_THREAD tell which threads contain the lowest - * and highest line numbers for File0. - * last_diff3 contains the last diff produced in the calling routine. - * This is used for lines mappings which would still be identical to - * the state that diff ended in. - * - * A distinction should be made in this routine between the two diffs - * that are part of a normal two diff block, and the three diffs that - * are part of a diff3_block. - */ -static struct diff3_block * -using_to_diff3_block (using, last_using, low_thread, high_thread, last_diff3) - struct diff_block - *using[2], - *last_using[2]; - int low_thread, high_thread; - struct diff3_block *last_diff3; -{ - int low[2], high[2]; - struct diff3_block *result; - struct diff_block *ptr; - int d, i; - - /* Find the range in the common file. */ - int lowc = D_LOWLINE (using[low_thread], FC); - int highc = D_HIGHLINE (last_using[high_thread], FC); - - /* Find the ranges in the other files. - If using[d] is null, that means that the file to which that diff - refers is equivalent to the common file over this range. */ - - for (d = 0; d < 2; d++) - if (using[d]) - { - low[d] = D_LOW_MAPLINE (using[d], FC, FO, lowc); - high[d] = D_HIGH_MAPLINE (last_using[d], FC, FO, highc); - } - else - { - low[d] = D_HIGH_MAPLINE (last_diff3, FILEC, FILE0 + d, lowc); - high[d] = D_HIGH_MAPLINE (last_diff3, FILEC, FILE0 + d, highc); - } - - /* Create a block with the appropriate sizes */ - result = create_diff3_block (low[0], high[0], low[1], high[1], lowc, highc); - - /* Copy information for the common file. - Return with a zero if any of the compares failed. */ - - for (d = 0; d < 2; d++) - for (ptr = using[d]; ptr; ptr = D_NEXT (ptr)) - { - int result_offset = D_LOWLINE (ptr, FC) - lowc; - - if (!copy_stringlist (D_LINEARRAY (ptr, FC), - D_LENARRAY (ptr, FC), - D_LINEARRAY (result, FILEC) + result_offset, - D_LENARRAY (result, FILEC) + result_offset, - D_NUMLINES (ptr, FC))) - return 0; - } - - /* Copy information for file d. First deal with anything that might be - before the first diff. */ - - for (d = 0; d < 2; d++) - { - struct diff_block *u = using[d]; - int lo = low[d], hi = high[d]; - - for (i = 0; - i + lo < (u ? D_LOWLINE (u, FO) : hi + 1); - i++) - { - D_RELNUM (result, FILE0 + d, i) = D_RELNUM (result, FILEC, i); - D_RELLEN (result, FILE0 + d, i) = D_RELLEN (result, FILEC, i); - } - - for (ptr = u; ptr; ptr = D_NEXT (ptr)) - { - int result_offset = D_LOWLINE (ptr, FO) - lo; - int linec; - - if (!copy_stringlist (D_LINEARRAY (ptr, FO), - D_LENARRAY (ptr, FO), - D_LINEARRAY (result, FILE0 + d) + result_offset, - D_LENARRAY (result, FILE0 + d) + result_offset, - D_NUMLINES (ptr, FO))) - return 0; - - /* Catch the lines between here and the next diff */ - linec = D_HIGHLINE (ptr, FC) + 1 - lowc; - for (i = D_HIGHLINE (ptr, FO) + 1 - lo; - i < (D_NEXT (ptr) ? D_LOWLINE (D_NEXT (ptr), FO) : hi + 1) - lo; - i++) - { - D_RELNUM (result, FILE0 + d, i) = D_RELNUM (result, FILEC, linec); - D_RELLEN (result, FILE0 + d, i) = D_RELLEN (result, FILEC, linec); - linec++; - } - } - } - - /* Set correspond */ - if (!using[0]) - D3_TYPE (result) = DIFF_2ND; - else if (!using[1]) - D3_TYPE (result) = DIFF_1ST; - else - { - int nl0 = D_NUMLINES (result, FILE0); - int nl1 = D_NUMLINES (result, FILE1); - - if (nl0 != nl1 - || !compare_line_list (D_LINEARRAY (result, FILE0), - D_LENARRAY (result, FILE0), - D_LINEARRAY (result, FILE1), - D_LENARRAY (result, FILE1), - nl0)) - D3_TYPE (result) = DIFF_ALL; - else - D3_TYPE (result) = DIFF_3RD; - } - - return result; -} - -/* - * This routine copies pointers from a list of strings to a different list - * of strings. If a spot in the second list is already filled, it - * makes sure that it is filled with the same string; if not it - * returns 0, the copy incomplete. - * Upon successful completion of the copy, it returns 1. - */ -static int -copy_stringlist (fromptrs, fromlengths, toptrs, tolengths, copynum) - char *fromptrs[], *toptrs[]; - int *fromlengths, *tolengths; - int copynum; -{ - register char - **f = fromptrs, - **t = toptrs; - register int - *fl = fromlengths, - *tl = tolengths; - - while (copynum--) - { - if (*t) - { if (*fl != *tl || bcmp (*f, *t, *fl)) return 0; } - else - { *t = *f ; *tl = *fl; } - - t++; f++; tl++; fl++; - } - return 1; -} - -/* - * Create a diff3_block, with ranges as specified in the arguments. - * Allocate the arrays for the various pointers (and zero them) based - * on the arguments passed. Return the block as a result. - */ -static struct diff3_block * -create_diff3_block (low0, high0, low1, high1, low2, high2) - register int low0, high0, low1, high1, low2, high2; -{ - struct diff3_block *result = ALLOCATE (1, struct diff3_block); - int numlines; - - D3_TYPE (result) = ERROR; - D_NEXT (result) = 0; - - /* Assign ranges */ - D_LOWLINE (result, FILE0) = low0; - D_HIGHLINE (result, FILE0) = high0; - D_LOWLINE (result, FILE1) = low1; - D_HIGHLINE (result, FILE1) = high1; - D_LOWLINE (result, FILE2) = low2; - D_HIGHLINE (result, FILE2) = high2; - - /* Allocate and zero space */ - numlines = D_NUMLINES (result, FILE0); - if (numlines) - { - D_LINEARRAY (result, FILE0) = ALLOCATE (numlines, char *); - D_LENARRAY (result, FILE0) = ALLOCATE (numlines, int); - bzero (D_LINEARRAY (result, FILE0), (numlines * sizeof (char *))); - bzero (D_LENARRAY (result, FILE0), (numlines * sizeof (int))); - } - else - { - D_LINEARRAY (result, FILE0) = (char **) 0; - D_LENARRAY (result, FILE0) = (int *) 0; - } - - numlines = D_NUMLINES (result, FILE1); - if (numlines) - { - D_LINEARRAY (result, FILE1) = ALLOCATE (numlines, char *); - D_LENARRAY (result, FILE1) = ALLOCATE (numlines, int); - bzero (D_LINEARRAY (result, FILE1), (numlines * sizeof (char *))); - bzero (D_LENARRAY (result, FILE1), (numlines * sizeof (int))); - } - else - { - D_LINEARRAY (result, FILE1) = (char **) 0; - D_LENARRAY (result, FILE1) = (int *) 0; - } - - numlines = D_NUMLINES (result, FILE2); - if (numlines) - { - D_LINEARRAY (result, FILE2) = ALLOCATE (numlines, char *); - D_LENARRAY (result, FILE2) = ALLOCATE (numlines, int); - bzero (D_LINEARRAY (result, FILE2), (numlines * sizeof (char *))); - bzero (D_LENARRAY (result, FILE2), (numlines * sizeof (int))); - } - else - { - D_LINEARRAY (result, FILE2) = (char **) 0; - D_LENARRAY (result, FILE2) = (int *) 0; - } - - /* Return */ - return result; -} - -/* - * Compare two lists of lines of text. - * Return 1 if they are equivalent, 0 if not. - */ -static int -compare_line_list (list1, lengths1, list2, lengths2, nl) - char *list1[], *list2[]; - int *lengths1, *lengths2; - int nl; -{ - char - **l1 = list1, - **l2 = list2; - int - *lgths1 = lengths1, - *lgths2 = lengths2; - - while (nl--) - if (!*l1 || !*l2 || *lgths1 != *lgths2++ - || bcmp (*l1++, *l2++, *lgths1++)) - return 0; - return 1; -} - -/* - * Routines to input and parse two way diffs. - */ - -extern char **environ; - -#define DIFF_CHUNK_SIZE 10000 - -static struct diff_block * -process_diff (filea, fileb, last_block) - char *filea, *fileb; - struct diff_block **last_block; -{ - char *diff_contents; - char *diff_limit; - char *scan_diff; - enum diff_type dt; - int i; - struct diff_block *block_list, **block_list_end, *bptr; - - diff_limit = read_diff (filea, fileb, &diff_contents); - scan_diff = diff_contents; - block_list_end = &block_list; - - while (scan_diff < diff_limit) - { - bptr = ALLOCATE (1, struct diff_block); - bptr->lines[0] = bptr->lines[1] = (char **) 0; - bptr->lengths[0] = bptr->lengths[1] = (int *) 0; - - dt = process_diff_control (&scan_diff, bptr); - if (dt == ERROR || *scan_diff != '\n') - { - fprintf (stderr, "%s: diff error: ", argv0); - do - { - putc (*scan_diff, stderr); - } - while (*scan_diff++ != '\n'); - exit (2); - } - scan_diff++; - - /* Force appropriate ranges to be null, if necessary */ - switch (dt) - { - case ADD: - bptr->ranges[0][0]++; - break; - case DELETE: - bptr->ranges[1][0]++; - break; - case CHANGE: - break; - default: - fatal ("internal error: invalid diff type in process_diff"); - break; - } - - /* Allocate space for the pointers for the lines from filea, and - parcel them out among these pointers */ - if (dt != ADD) - { - int numlines = D_NUMLINES (bptr, 0); - bptr->lines[0] = ALLOCATE (numlines, char *); - bptr->lengths[0] = ALLOCATE (numlines, int); - for (i = 0; i < numlines; i++) - scan_diff = scan_diff_line (scan_diff, - &(bptr->lines[0][i]), - &(bptr->lengths[0][i]), - diff_limit, - '<'); - } - - /* Get past the separator for changes */ - if (dt == CHANGE) - { - if (strncmp (scan_diff, "---\n", 4)) - fatal ("invalid diff format; invalid change separator"); - scan_diff += 4; - } - - /* Allocate space for the pointers for the lines from fileb, and - parcel them out among these pointers */ - if (dt != DELETE) - { - int numlines = D_NUMLINES (bptr, 1); - bptr->lines[1] = ALLOCATE (numlines, char *); - bptr->lengths[1] = ALLOCATE (numlines, int); - for (i = 0; i < numlines; i++) - scan_diff = scan_diff_line (scan_diff, - &(bptr->lines[1][i]), - &(bptr->lengths[1][i]), - diff_limit, - '>'); - } - - /* Place this block on the blocklist. */ - *block_list_end = bptr; - block_list_end = &bptr->next; - } - - *block_list_end = 0; - *last_block = bptr; - return block_list; -} - -/* - * This routine will parse a normal format diff control string. It - * returns the type of the diff (ERROR if the format is bad). All of - * the other important information is filled into to the structure - * pointed to by db, and the string pointer (whose location is passed - * to this routine) is updated to point beyond the end of the string - * parsed. Note that only the ranges in the diff_block will be set by - * this routine. - * - * If some specific pair of numbers has been reduced to a single - * number, then both corresponding numbers in the diff block are set - * to that number. In general these numbers are interpetted as ranges - * inclusive, unless being used by the ADD or DELETE commands. It is - * assumed that these will be special cased in a superior routine. - */ - -static enum diff_type -process_diff_control (string, db) - char **string; - struct diff_block *db; -{ - char *s = *string; - int holdnum; - enum diff_type type; - -/* These macros are defined here because they can use variables - defined in this function. Don't try this at home kids, we're - trained professionals! - - Also note that SKIPWHITE only recognizes tabs and spaces, and - that READNUM can only read positive, integral numbers */ - -#define SKIPWHITE(s) { while (*s == ' ' || *s == '\t') s++; } -#define READNUM(s, num) \ - { if (!isdigit (*s)) return ERROR; holdnum = 0; \ - do { holdnum = (*s++ - '0' + holdnum * 10); } \ - while (isdigit (*s)); (num) = holdnum; } - - /* Read first set of digits */ - SKIPWHITE (s); - READNUM (s, db->ranges[0][START]); - - /* Was that the only digit? */ - SKIPWHITE (s); - if (*s == ',') - { - /* Get the next digit */ - s++; - READNUM (s, db->ranges[0][END]); - } - else - db->ranges[0][END] = db->ranges[0][START]; - - /* Get the letter */ - SKIPWHITE (s); - switch (*s) - { - case 'a': - type = ADD; - break; - case 'c': - type = CHANGE; - break; - case 'd': - type = DELETE; - break; - default: - return ERROR; /* Bad format */ - } - s++; /* Past letter */ - - /* Read second set of digits */ - SKIPWHITE (s); - READNUM (s, db->ranges[1][START]); - - /* Was that the only digit? */ - SKIPWHITE (s); - if (*s == ',') - { - /* Get the next digit */ - s++; - READNUM (s, db->ranges[1][END]); - SKIPWHITE (s); /* To move to end */ - } - else - db->ranges[1][END] = db->ranges[1][START]; - - *string = s; - return type; -} - -static char * -read_diff (filea, fileb, output_placement) - char *filea, *fileb; - char **output_placement; -{ - char *argv[7]; - char horizon_arg[256]; - char **ap; - int fds[2]; - char *diff_result; - int current_chunk_size; - int bytes; - int total; - int pid, w; - int wstatus; - - ap = argv; - *ap++ = diff_program; - if (always_text) - *ap++ = "-a"; - sprintf (horizon_arg, "--horizon-lines=%d", horizon_lines); - *ap++ = horizon_arg; - *ap++ = "--"; - *ap++ = filea; - *ap++ = fileb; - *ap = (char *) 0; - - if (pipe (fds) < 0) - perror_with_exit ("pipe failed"); - - pid = vfork (); - if (pid == 0) - { - /* Child */ - close (fds[0]); - if (fds[1] != fileno (stdout)) - { - dup2 (fds[1], fileno (stdout)); - close (fds[1]); - } - execve (diff_program, argv, environ); - /* Avoid stdio, because the parent process's buffers are inherited. */ - write (fileno (stderr), diff_program, strlen (diff_program)); - write (fileno (stderr), ": not found\n", 12); - _exit (2); - } - - if (pid == -1) - perror_with_exit ("fork failed"); - - close (fds[1]); /* Prevent erroneous lack of EOF */ - current_chunk_size = DIFF_CHUNK_SIZE; - diff_result = (char *) xmalloc (current_chunk_size); - total = 0; - do { - bytes = myread (fds[0], - diff_result + total, - current_chunk_size - total); - total += bytes; - if (total == current_chunk_size) - diff_result = (char *) xrealloc (diff_result, (current_chunk_size *= 2)); - } while (bytes); - - if (total != 0 && diff_result[total-1] != '\n') - fatal ("invalid diff format; incomplete last line"); - - *output_placement = diff_result; - - do - if ((w = wait (&wstatus)) == -1) - perror_with_exit ("wait failed"); - while (w != pid); - - if (! (WIFEXITED (wstatus) && WEXITSTATUS (wstatus) < 2)) - fatal ("subsidiary diff failed"); - - return diff_result + total; -} - - -/* - * Scan a regular diff line (consisting of > or <, followed by a - * space, followed by text (including nulls) up to a newline. - * - * This next routine began life as a macro and many parameters in it - * are used as call-by-reference values. - */ -static char * -scan_diff_line (scan_ptr, set_start, set_length, limit, firstchar) - char *scan_ptr, **set_start; - int *set_length; - char *limit; - char firstchar; -{ - char *line_ptr; - - if (!(scan_ptr[0] == (firstchar) - && scan_ptr[1] == ' ')) - fatal ("invalid diff format; incorrect leading line chars"); - - *set_start = line_ptr = scan_ptr + 2; - while (*line_ptr++ != '\n') - ; - - /* Include newline if the original line ended in a newline, - or if an edit script is being generated. - Copy any missing newline message to stderr if an edit script is being - generated, because edit scripts cannot handle missing newlines. - Return the beginning of the next line. */ - *set_length = line_ptr - *set_start; - if (line_ptr < limit && *line_ptr == '\\') - { - if (edscript) - fprintf (stderr, "%s:", argv0); - else - --*set_length; - line_ptr++; - do - { - if (edscript) - putc (*line_ptr, stderr); - } - while (*line_ptr++ != '\n'); - } - - return line_ptr; -} - -/* - * This routine outputs a three way diff passed as a list of - * diff3_block's. - * The argument MAPPING is indexed by external file number (in the - * argument list) and contains the internal file number (from the - * diff passed). This is important because the user expects his - * outputs in terms of the argument list number, and the diff passed - * may have been done slightly differently (if the last argument - * was "-", for example). - * REV_MAPPING is the inverse of MAPPING. - */ -static void -output_diff3 (outputfile, diff, mapping, rev_mapping) - FILE *outputfile; - struct diff3_block *diff; - int mapping[3], rev_mapping[3]; -{ - int i; - int oddoneout; - char *cp; - struct diff3_block *ptr; - int line; - int length; - int dontprint; - static int skew_increment[3] = { 2, 3, 1 }; /* 0==>2==>1==>3 */ - - for (ptr = diff; ptr; ptr = D_NEXT (ptr)) - { - char x[2]; - - switch (ptr->correspond) - { - case DIFF_ALL: - x[0] = '\0'; - dontprint = 3; /* Print them all */ - oddoneout = 3; /* Nobody's odder than anyone else */ - break; - case DIFF_1ST: - case DIFF_2ND: - case DIFF_3RD: - oddoneout = rev_mapping[(int) ptr->correspond - (int) DIFF_1ST]; - - x[0] = oddoneout + '1'; - x[1] = '\0'; - dontprint = oddoneout==0; - break; - default: - fatal ("internal error: invalid diff type passed to output"); - } - fprintf (outputfile, "====%s\n", x); - - /* Go 0, 2, 1 if the first and third outputs are equivalent. */ - for (i = 0; i < 3; - i = (oddoneout == 1 ? skew_increment[i] : i + 1)) - { - int realfile = mapping[i]; - int - lowt = D_LOWLINE (ptr, realfile), - hight = D_HIGHLINE (ptr, realfile); - - fprintf (outputfile, "%d:", i + 1); - switch (lowt - hight) - { - case 1: - fprintf (outputfile, "%da\n", lowt - 1); - break; - case 0: - fprintf (outputfile, "%dc\n", lowt); - break; - default: - fprintf (outputfile, "%d,%dc\n", lowt, hight); - break; - } - - if (i == dontprint) continue; - - for (line = 0; line < hight - lowt + 1; line++) - { - fprintf (outputfile, " "); - cp = D_RELNUM (ptr, realfile, line); - length = D_RELLEN (ptr, realfile, line); - fwrite (cp, sizeof (char), length, outputfile); - } - if (line != 0 && cp[length - 1] != '\n') - fprintf (outputfile, "\n\\ No newline at end of file\n"); - } - } -} - - -/* - * Output to OUTPUTFILE the lines of B taken from FILENUM. - * Double any initial '.'s; yield nonzero if any initial '.'s were doubled. - */ -static int -dotlines (outputfile, b, filenum) - FILE *outputfile; - struct diff3_block *b; - int filenum; -{ - int i; - int leading_dot = 0; - - for (i = 0; - i < D_NUMLINES (b, filenum); - i++) - { - char *line = D_RELNUM (b, filenum, i); - if (line[0] == '.') - { - leading_dot = 1; - fprintf (outputfile, "."); - } - fwrite (line, sizeof (char), - D_RELLEN (b, filenum, i), outputfile); - } - - return leading_dot; -} - -/* - * Output to OUTPUTFILE a '.' line. If LEADING_DOT is nonzero, - * also output a command that removes initial '.'s - * starting with line START and continuing for NUM lines. - */ -static void -undotlines (outputfile, leading_dot, start, num) - FILE *outputfile; - int leading_dot, start, num; -{ - fprintf (outputfile, ".\n"); - if (leading_dot) - if (num == 1) - fprintf (outputfile, "%ds/^\\.//\n", start); - else - fprintf (outputfile, "%d,%ds/^\\.//\n", start, start + num - 1); -} - -/* - * This routine outputs a diff3 set of blocks as an ed script. This - * script applies the changes between file's 2 & 3 to file 1. It - * takes the precise format of the ed script to be output from global - * variables set during options processing. Note that it does - * destructive things to the set of diff3 blocks it is passed; it - * reverses their order (this gets around the problems involved with - * changing line numbers in an ed script). - * - * Note that this routine has the same problem of mapping as the last - * one did; the variable MAPPING maps from file number according to - * the argument list to file number according to the diff passed. All - * files listed below are in terms of the argument list. - * REV_MAPPING is the inverse of MAPPING. - * - * The arguments FILE0, FILE1 and FILE2 are the strings to print - * as the names of the three files. These may be the actual names, - * or may be the arguments specified with -L. - * - * Returns 1 if conflicts were found. - */ - -static int -output_diff3_edscript (outputfile, diff, mapping, rev_mapping, - file0, file1, file2) - FILE *outputfile; - struct diff3_block *diff; - int mapping[3], rev_mapping[3]; - char *file0, *file1, *file2; -{ - int leading_dot; - int conflicts_found = 0, conflict; - struct diff3_block *b; - - for (b = reverse_diff3_blocklist (diff); b; b = b->next) - { - /* Must do mapping correctly. */ - enum diff_type type - = ((b->correspond == DIFF_ALL) ? - DIFF_ALL : - ((enum diff_type) - (((int) DIFF_1ST) - + rev_mapping[(int) b->correspond - (int) DIFF_1ST]))); - - /* If we aren't supposed to do this output block, skip it. */ - switch (type) - { - default: continue; - case DIFF_2ND: if (!show_2nd) continue; conflict = 1; break; - case DIFF_3RD: if (overlap_only) continue; conflict = 0; break; - case DIFF_ALL: if (simple_only) continue; conflict = flagging; break; - } - - if (conflict) - { - conflicts_found = 1; - - - /* Mark end of conflict. */ - - fprintf (outputfile, "%da\n", D_HIGHLINE (b, mapping[FILE0])); - leading_dot = 0; - if (type == DIFF_ALL) - { - if (show_2nd) - { - /* Append lines from FILE1. */ - fprintf (outputfile, "||||||| %s\n", file1); - leading_dot = dotlines (outputfile, b, mapping[FILE1]); - } - /* Append lines from FILE2. */ - fprintf (outputfile, "=======\n"); - leading_dot |= dotlines (outputfile, b, mapping[FILE2]); - } - fprintf (outputfile, ">>>>>>> %s\n", file2); - undotlines (outputfile, leading_dot, - D_HIGHLINE (b, mapping[FILE0]) + 2, - (D_NUMLINES (b, mapping[FILE1]) - + D_NUMLINES (b, mapping[FILE2]) + 1)); - - - /* Mark start of conflict. */ - - fprintf (outputfile, "%da\n<<<<<<< %s\n", - D_LOWLINE (b, mapping[FILE0]) - 1, - type == DIFF_ALL ? file0 : file1); - leading_dot = 0; - if (type == DIFF_2ND) - { - /* Prepend lines from FILE1. */ - leading_dot = dotlines (outputfile, b, mapping[FILE1]); - fprintf (outputfile, "=======\n"); - } - undotlines (outputfile, leading_dot, - D_LOWLINE (b, mapping[FILE0]) + 1, - D_NUMLINES (b, mapping[FILE1])); - } - else if (D_NUMLINES (b, mapping[FILE2]) == 0) - /* Write out a delete */ - { - if (D_NUMLINES (b, mapping[FILE0]) == 1) - fprintf (outputfile, "%dd\n", - D_LOWLINE (b, mapping[FILE0])); - else - fprintf (outputfile, "%d,%dd\n", - D_LOWLINE (b, mapping[FILE0]), - D_HIGHLINE (b, mapping[FILE0])); - } - else - /* Write out an add or change */ - { - switch (D_NUMLINES (b, mapping[FILE0])) - { - case 0: - fprintf (outputfile, "%da\n", - D_HIGHLINE (b, mapping[FILE0])); - break; - case 1: - fprintf (outputfile, "%dc\n", - D_HIGHLINE (b, mapping[FILE0])); - break; - default: - fprintf (outputfile, "%d,%dc\n", - D_LOWLINE (b, mapping[FILE0]), - D_HIGHLINE (b, mapping[FILE0])); - break; - } - - undotlines (outputfile, dotlines (outputfile, b, mapping[FILE2]), - D_LOWLINE (b, mapping[FILE0]), - D_NUMLINES (b, mapping[FILE2])); - } - } - if (finalwrite) fprintf (outputfile, "w\nq\n"); - return conflicts_found; -} - -/* - * Read from INFILE and output to OUTPUTFILE a set of diff3_ blocks DIFF - * as a merged file. This acts like 'ed file0 <[output_diff3_edscript]', - * except that it works even for binary data or incomplete lines. - * - * As before, MAPPING maps from arg list file number to diff file number, - * REV_MAPPING is its inverse, - * and FILE0, FILE1, and FILE2 are the names of the files. - * - * Returns 1 if conflicts were found. - */ - -static int -output_diff3_merge (infile, outputfile, diff, mapping, rev_mapping, - file0, file1, file2) - FILE *infile, *outputfile; - struct diff3_block *diff; - int mapping[3], rev_mapping[3]; - char *file0, *file1, *file2; -{ - int c, i; - int conflicts_found = 0, conflict; - struct diff3_block *b; - int linesread = 0; - - for (b = diff; b; b = b->next) - { - /* Must do mapping correctly. */ - enum diff_type type - = ((b->correspond == DIFF_ALL) ? - DIFF_ALL : - ((enum diff_type) - (((int) DIFF_1ST) - + rev_mapping[(int) b->correspond - (int) DIFF_1ST]))); - char *format_2nd = "<<<<<<< %s\n"; - - /* If we aren't supposed to do this output block, skip it. */ - switch (type) - { - default: continue; - case DIFF_2ND: if (!show_2nd) continue; conflict = 1; break; - case DIFF_3RD: if (overlap_only) continue; conflict = 0; break; - case DIFF_ALL: if (simple_only) continue; conflict = flagging; - format_2nd = "||||||| %s\n"; - break; - } - - /* Copy I lines from file 0. */ - i = D_LOWLINE (b, FILE0) - linesread - 1; - linesread += i; - while (0 <= --i) - do - { - c = getc (infile); - if (c == EOF) - if (ferror (infile)) - perror_with_exit ("input file"); - else if (feof (infile)) - fatal ("input file shrank"); - putc (c, outputfile); - } - while (c != '\n'); - - if (conflict) - { - conflicts_found = 1; - - if (type == DIFF_ALL) - { - /* Put in lines from FILE0 with bracket. */ - fprintf (outputfile, "<<<<<<< %s\n", file0); - for (i = 0; - i < D_NUMLINES (b, mapping[FILE0]); - i++) - fwrite (D_RELNUM (b, mapping[FILE0], i), sizeof (char), - D_RELLEN (b, mapping[FILE0], i), outputfile); - } - - if (show_2nd) - { - /* Put in lines from FILE1 with bracket. */ - fprintf (outputfile, format_2nd, file1); - for (i = 0; - i < D_NUMLINES (b, mapping[FILE1]); - i++) - fwrite (D_RELNUM (b, mapping[FILE1], i), sizeof (char), - D_RELLEN (b, mapping[FILE1], i), outputfile); - } - - fprintf (outputfile, "=======\n"); - } - - /* Put in lines from FILE2. */ - for (i = 0; - i < D_NUMLINES (b, mapping[FILE2]); - i++) - fwrite (D_RELNUM (b, mapping[FILE2], i), sizeof (char), - D_RELLEN (b, mapping[FILE2], i), outputfile); - - if (conflict) - fprintf (outputfile, ">>>>>>> %s\n", file2); - - /* Skip I lines in file 0. */ - i = D_NUMLINES (b, FILE0); - linesread += i; - while (0 <= --i) - while ((c = getc (infile)) != '\n') - if (c == EOF) - if (ferror (infile)) - perror_with_exit ("input file"); - else if (feof (infile)) - { - if (i || b->next) - fatal ("input file shrank"); - return conflicts_found; - } - } - /* Copy rest of common file. */ - while ((c = getc (infile)) != EOF || !(ferror (infile) | feof (infile))) - putc (c, outputfile); - return conflicts_found; -} - -/* - * Reverse the order of the list of diff3 blocks. - */ -static struct diff3_block * -reverse_diff3_blocklist (diff) - struct diff3_block *diff; -{ - register struct diff3_block *tmp, *next, *prev; - - for (tmp = diff, prev = (struct diff3_block *) 0; - tmp; tmp = next) - { - next = tmp->next; - tmp->next = prev; - prev = tmp; - } - - return prev; -} - -static int -myread (fd, ptr, size) - int fd, size; - char *ptr; -{ - int result = read (fd, ptr, size); - if (result < 0) - perror_with_exit ("read failed"); - return result; -} - -VOID * -xmalloc (size) - unsigned size; -{ - VOID *result = (VOID *) malloc (size ? size : 1); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -static VOID * -xrealloc (ptr, size) - VOID *ptr; - unsigned size; -{ - VOID *result = (VOID *) realloc (ptr, size ? size : 1); - if (!result) - fatal ("virtual memory exhausted"); - return result; -} - -static void -fatal (string) - char *string; -{ - fprintf (stderr, "%s: %s\n", argv0, string); - exit (2); -} - -static void -perror_with_exit (string) - char *string; -{ - int e = errno; - fprintf (stderr, "%s: ", argv0); - errno = e; - perror (string); - exit (2); -} diff --git a/gnu/usr.bin/diff3/getopt.c b/gnu/usr.bin/diff3/getopt.c deleted file mode 100644 index a59a013..0000000 --- a/gnu/usr.bin/diff3/getopt.c +++ /dev/null @@ -1,731 +0,0 @@ -/* Getopt for GNU. - NOTE: getopt is now part of the C library, so if you don't know what - "Keep this file name-space clean" means, talk to roland@gnu.ai.mit.edu - before changing it! - - Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 - 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -/* NOTE!!! AIX requires this to be the first thing in the file. - Do not put ANYTHING before it! */ -#if !defined (__GNUC__) && defined (_AIX) - #pragma alloca -#endif - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#ifdef __GNUC__ -#define alloca __builtin_alloca -#else /* not __GNUC__ */ -#if defined (HAVE_ALLOCA_H) || (defined(sparc) && (defined(sun) || (!defined(USG) && !defined(SVR4) && !defined(__svr4__)))) -#include -#else -#ifndef _AIX -char *alloca (); -#endif -#endif /* alloca.h */ -#endif /* not __GNUC__ */ - -#if !__STDC__ && !defined(const) && IN_GCC -#define const -#endif - -/* This tells Alpha OSF/1 not to define a getopt prototype in . */ -#ifndef _NO_PROTO -#define _NO_PROTO -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#undef alloca -/* Don't include stdlib.h for non-GNU C libraries because some of them - contain conflicting prototypes for getopt. */ -#include -#else /* Not GNU C library. */ -#define __alloca alloca -#endif /* GNU C library. */ - -/* If GETOPT_COMPAT is defined, `+' as well as `--' can introduce a - long-named option. Because this is not POSIX.2 compliant, it is - being phased out. */ -/* #define GETOPT_COMPAT */ - -/* This version of `getopt' appears to the caller like standard Unix `getopt' - but it behaves differently for the user, since it allows the user - to intersperse the options with the other arguments. - - As `getopt' works, it permutes the elements of ARGV so that, - when it is done, all the options precede everything else. Thus - all application programs are extended to handle flexible argument order. - - Setting the environment variable POSIXLY_CORRECT disables permutation. - Then the behavior is completely standard. - - GNU application programs can use a third alternative mode in which - they can distinguish the relative order of options and other arguments. */ - -#include "getopt.h" - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -char *optarg = 0; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -/* XXX 1003.2 says this must be 1 before any call. */ -int optind = 0; - -/* The next char to be scanned in the option-element - in which the last option character we returned was found. - This allows us to pick up the scan where we left off. - - If this is zero, or a null string, it means resume the scan - by advancing to the next ARGV-element. */ - -static char *nextchar; - -/* Callers store zero here to inhibit the error message - for unrecognized options. */ - -int opterr = 1; - -/* Set to an option character which was unrecognized. - This must be initialized on some systems to avoid linking in the - system's own getopt implementation. */ - -int optopt = '?'; - -/* Describe how to deal with options that follow non-option ARGV-elements. - - If the caller did not specify anything, - the default is REQUIRE_ORDER if the environment variable - POSIXLY_CORRECT is defined, PERMUTE otherwise. - - REQUIRE_ORDER means don't recognize them as options; - stop option processing when the first non-option is seen. - This is what Unix does. - This mode of operation is selected by either setting the environment - variable POSIXLY_CORRECT, or using `+' as the first character - of the list of option characters. - - PERMUTE is the default. We permute the contents of ARGV as we scan, - so that eventually all the non-options are at the end. This allows options - to be given in any order, even with programs that were not written to - expect this. - - RETURN_IN_ORDER is an option available to programs that were written - to expect options and other ARGV-elements in any order and that care about - the ordering of the two. We describe each non-option ARGV-element - as if it were the argument of an option with character code 1. - Using `-' as the first character of the list of option characters - selects this mode of operation. - - The special argument `--' forces an end of option-scanning regardless - of the value of `ordering'. In the case of RETURN_IN_ORDER, only - `--' can cause `getopt' to return EOF with `optind' != ARGC. */ - -static enum -{ - REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER -} ordering; - -#ifdef __GNU_LIBRARY__ -/* We want to avoid inclusion of string.h with non-GNU libraries - because there are many ways it can cause trouble. - On some systems, it contains special magic macros that don't work - in GCC. */ -#include -#define my_index strchr -#define my_bcopy(src, dst, n) memcpy ((dst), (src), (n)) -#else - -/* Avoid depending on library functions or files - whose names are inconsistent. */ - -char *getenv (); - -static char * -my_index (str, chr) - const char *str; - int chr; -{ - while (*str) - { - if (*str == chr) - return (char *) str; - str++; - } - return 0; -} - -static void -my_bcopy (from, to, size) - const char *from; - char *to; - int size; -{ - int i; - for (i = 0; i < size; i++) - to[i] = from[i]; -} -#endif /* GNU C library. */ - -/* Handle permutation of arguments. */ - -/* Describe the part of ARGV that contains non-options that have - been skipped. `first_nonopt' is the index in ARGV of the first of them; - `last_nonopt' is the index after the last of them. */ - -static int first_nonopt; -static int last_nonopt; - -/* Exchange two adjacent subsequences of ARGV. - One subsequence is elements [first_nonopt,last_nonopt) - which contains all the non-options that have been skipped so far. - The other is elements [last_nonopt,optind), which contains all - the options processed since those non-options were skipped. - - `first_nonopt' and `last_nonopt' are relocated so that they describe - the new indices of the non-options in ARGV after they are moved. */ - -static void -exchange (argv) - char **argv; -{ - int nonopts_size = (last_nonopt - first_nonopt) * sizeof (char *); - char **temp = (char **) __alloca (nonopts_size); - - /* Interchange the two blocks of data in ARGV. */ - - my_bcopy ((char *) &argv[first_nonopt], (char *) temp, nonopts_size); - my_bcopy ((char *) &argv[last_nonopt], (char *) &argv[first_nonopt], - (optind - last_nonopt) * sizeof (char *)); - my_bcopy ((char *) temp, - (char *) &argv[first_nonopt + optind - last_nonopt], - nonopts_size); - - /* Update records for the slots the non-options now occupy. */ - - first_nonopt += (optind - last_nonopt); - last_nonopt = optind; -} - -/* Scan elements of ARGV (whose length is ARGC) for option characters - given in OPTSTRING. - - If an element of ARGV starts with '-', and is not exactly "-" or "--", - then it is an option element. The characters of this element - (aside from the initial '-') are option characters. If `getopt' - is called repeatedly, it returns successively each of the option characters - from each of the option elements. - - If `getopt' finds another option character, it returns that character, - updating `optind' and `nextchar' so that the next call to `getopt' can - resume the scan with the following option character or ARGV-element. - - If there are no more option characters, `getopt' returns `EOF'. - Then `optind' is the index in ARGV of the first ARGV-element - that is not an option. (The ARGV-elements have been permuted - so that those that are not options now come last.) - - OPTSTRING is a string containing the legitimate option characters. - If an option character is seen that is not listed in OPTSTRING, - return '?' after printing an error message. If you set `opterr' to - zero, the error message is suppressed but we still return '?'. - - If a char in OPTSTRING is followed by a colon, that means it wants an arg, - so the following text in the same ARGV-element, or the text of the following - ARGV-element, is returned in `optarg'. Two colons mean an option that - wants an optional arg; if there is text in the current ARGV-element, - it is returned in `optarg', otherwise `optarg' is set to zero. - - If OPTSTRING starts with `-' or `+', it requests different methods of - handling the non-option ARGV-elements. - See the comments about RETURN_IN_ORDER and REQUIRE_ORDER, above. - - Long-named options begin with `--' instead of `-'. - Their names may be abbreviated as long as the abbreviation is unique - or is an exact match for some defined option. If they have an - argument, it follows the option name in the same ARGV-element, separated - from the option name by a `=', or else the in next ARGV-element. - When `getopt' finds a long-named option, it returns 0 if that option's - `flag' field is nonzero, the value of the option's `val' field - if the `flag' field is zero. - - The elements of ARGV aren't really const, because we permute them. - But we pretend they're const in the prototype to be compatible - with other systems. - - LONGOPTS is a vector of `struct option' terminated by an - element containing a name which is zero. - - LONGIND returns the index in LONGOPT of the long-named option found. - It is only valid when a long-named option has been found by the most - recent call. - - If LONG_ONLY is nonzero, '-' as well as '--' can introduce - long-named options. */ - -int -_getopt_internal (argc, argv, optstring, longopts, longind, long_only) - int argc; - char *const *argv; - const char *optstring; - const struct option *longopts; - int *longind; - int long_only; -{ - int option_index; - - optarg = 0; - - /* Initialize the internal data when the first call is made. - Start processing options with ARGV-element 1 (since ARGV-element 0 - is the program name); the sequence of previously skipped - non-option ARGV-elements is empty. */ - - if (optind == 0) - { - first_nonopt = last_nonopt = optind = 1; - - nextchar = NULL; - - /* Determine how to handle the ordering of options and nonoptions. */ - - if (optstring[0] == '-') - { - ordering = RETURN_IN_ORDER; - ++optstring; - } - else if (optstring[0] == '+') - { - ordering = REQUIRE_ORDER; - ++optstring; - } - else if (getenv ("POSIXLY_CORRECT") != NULL) - ordering = REQUIRE_ORDER; - else - ordering = PERMUTE; - } - - if (nextchar == NULL || *nextchar == '\0') - { - if (ordering == PERMUTE) - { - /* If we have just processed some options following some non-options, - exchange them so that the options come first. */ - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (last_nonopt != optind) - first_nonopt = optind; - - /* Now skip any additional non-options - and extend the range of non-options previously skipped. */ - - while (optind < argc - && (argv[optind][0] != '-' || argv[optind][1] == '\0') -#ifdef GETOPT_COMPAT - && (longopts == NULL - || argv[optind][0] != '+' || argv[optind][1] == '\0') -#endif /* GETOPT_COMPAT */ - ) - optind++; - last_nonopt = optind; - } - - /* Special ARGV-element `--' means premature end of options. - Skip it like a null option, - then exchange with previous non-options as if it were an option, - then skip everything else like a non-option. */ - - if (optind != argc && !strcmp (argv[optind], "--")) - { - optind++; - - if (first_nonopt != last_nonopt && last_nonopt != optind) - exchange ((char **) argv); - else if (first_nonopt == last_nonopt) - first_nonopt = optind; - last_nonopt = argc; - - optind = argc; - } - - /* If we have done all the ARGV-elements, stop the scan - and back over any non-options that we skipped and permuted. */ - - if (optind == argc) - { - /* Set the next-arg-index to point at the non-options - that we previously skipped, so the caller will digest them. */ - if (first_nonopt != last_nonopt) - optind = first_nonopt; - return EOF; - } - - /* If we have come to a non-option and did not permute it, - either stop the scan or describe it to the caller and pass it by. */ - - if ((argv[optind][0] != '-' || argv[optind][1] == '\0') -#ifdef GETOPT_COMPAT - && (longopts == NULL - || argv[optind][0] != '+' || argv[optind][1] == '\0') -#endif /* GETOPT_COMPAT */ - ) - { - if (ordering == REQUIRE_ORDER) - return EOF; - optarg = argv[optind++]; - return 1; - } - - /* We have found another option-ARGV-element. - Start decoding its characters. */ - - nextchar = (argv[optind] + 1 - + (longopts != NULL && argv[optind][1] == '-')); - } - - if (longopts != NULL - && ((argv[optind][0] == '-' - && (argv[optind][1] == '-' || long_only)) -#ifdef GETOPT_COMPAT - || argv[optind][0] == '+' -#endif /* GETOPT_COMPAT */ - )) - { - const struct option *p; - char *s = nextchar; - int exact = 0; - int ambig = 0; - const struct option *pfound = NULL; - int indfound; - - while (*s && *s != '=') - s++; - - /* Test all options for either exact match or abbreviated matches. */ - for (p = longopts, option_index = 0; p->name; - p++, option_index++) - if (!strncmp (p->name, nextchar, s - nextchar)) - { - if (s - nextchar == strlen (p->name)) - { - /* Exact match found. */ - pfound = p; - indfound = option_index; - exact = 1; - break; - } - else if (pfound == NULL) - { - /* First nonexact match found. */ - pfound = p; - indfound = option_index; - } - else - /* Second nonexact match found. */ - ambig = 1; - } - - if (ambig && !exact) - { - if (opterr) - fprintf (stderr, "%s: option `%s' is ambiguous\n", - argv[0], argv[optind]); - nextchar += strlen (nextchar); - optind++; - return '?'; - } - - if (pfound != NULL) - { - option_index = indfound; - optind++; - if (*s) - { - /* Don't test has_arg with >, because some C compilers don't - allow it to be used on enums. */ - if (pfound->has_arg) - optarg = s + 1; - else - { - if (opterr) - { - if (argv[optind - 1][1] == '-') - /* --option */ - fprintf (stderr, - "%s: option `--%s' doesn't allow an argument\n", - argv[0], pfound->name); - else - /* +option or -option */ - fprintf (stderr, - "%s: option `%c%s' doesn't allow an argument\n", - argv[0], argv[optind - 1][0], pfound->name); - } - nextchar += strlen (nextchar); - return '?'; - } - } - else if (pfound->has_arg == 1) - { - if (optind < argc) - optarg = argv[optind++]; - else - { - if (opterr) - fprintf (stderr, "%s: option `%s' requires an argument\n", - argv[0], argv[optind - 1]); - nextchar += strlen (nextchar); - return optstring[0] == ':' ? ':' : '?'; - } - } - nextchar += strlen (nextchar); - if (longind != NULL) - *longind = option_index; - if (pfound->flag) - { - *(pfound->flag) = pfound->val; - return 0; - } - return pfound->val; - } - /* Can't find it as a long option. If this is not getopt_long_only, - or the option starts with '--' or is not a valid short - option, then it's an error. - Otherwise interpret it as a short option. */ - if (!long_only || argv[optind][1] == '-' -#ifdef GETOPT_COMPAT - || argv[optind][0] == '+' -#endif /* GETOPT_COMPAT */ - || my_index (optstring, *nextchar) == NULL) - { - if (opterr) - { - if (argv[optind][1] == '-') - /* --option */ - fprintf (stderr, "%s: unrecognized option `--%s'\n", - argv[0], nextchar); - else - /* +option or -option */ - fprintf (stderr, "%s: unrecognized option `%c%s'\n", - argv[0], argv[optind][0], nextchar); - } - nextchar = (char *) ""; - optind++; - return '?'; - } - } - - /* Look at and handle the next option-character. */ - - { - char c = *nextchar++; - char *temp = my_index (optstring, c); - - /* Increment `optind' when we start to process its last character. */ - if (*nextchar == '\0') - ++optind; - - if (temp == NULL || c == ':') - { - if (opterr) - { -#if 0 - if (c < 040 || c >= 0177) - fprintf (stderr, "%s: unrecognized option, character code 0%o\n", - argv[0], c); - else - fprintf (stderr, "%s: unrecognized option `-%c'\n", argv[0], c); -#else - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: illegal option -- %c\n", argv[0], c); -#endif - } - optopt = c; - return '?'; - } - if (temp[1] == ':') - { - if (temp[2] == ':') - { - /* This is an option that accepts an argument optionally. */ - if (*nextchar != '\0') - { - optarg = nextchar; - optind++; - } - else - optarg = 0; - nextchar = NULL; - } - else - { - /* This is an option that requires an argument. */ - if (*nextchar != '\0') - { - optarg = nextchar; - /* If we end this ARGV-element by taking the rest as an arg, - we must advance to the next element now. */ - optind++; - } - else if (optind == argc) - { - if (opterr) - { -#if 0 - fprintf (stderr, "%s: option `-%c' requires an argument\n", - argv[0], c); -#else - /* 1003.2 specifies the format of this message. */ - fprintf (stderr, "%s: option requires an argument -- %c\n", - argv[0], c); -#endif - } - optopt = c; - if (optstring[0] == ':') - c = ':'; - else - c = '?'; - } - else - /* We already incremented `optind' once; - increment it again when taking next ARGV-elt as argument. */ - optarg = argv[optind++]; - nextchar = NULL; - } - } - return c; - } -} - -int -getopt (argc, argv, optstring) - int argc; - char *const *argv; - const char *optstring; -{ - return _getopt_internal (argc, argv, optstring, - (const struct option *) 0, - (int *) 0, - 0); -} - -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef TEST - -/* Compile with -DTEST to make an executable for use in testing - the above definition of `getopt'. */ - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - - c = getopt (argc, argv, "abc:d:0123456789"); - if (c == EOF) - break; - - switch (c) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/gnu/usr.bin/diff3/getopt.h b/gnu/usr.bin/diff3/getopt.h deleted file mode 100644 index 45541f5..0000000 --- a/gnu/usr.bin/diff3/getopt.h +++ /dev/null @@ -1,129 +0,0 @@ -/* Declarations for getopt. - Copyright (C) 1989, 1990, 1991, 1992, 1993 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifndef _GETOPT_H -#define _GETOPT_H 1 - -#ifdef __cplusplus -extern "C" { -#endif - -/* For communication from `getopt' to the caller. - When `getopt' finds an option that takes an argument, - the argument value is returned here. - Also, when `ordering' is RETURN_IN_ORDER, - each non-option ARGV-element is returned here. */ - -extern char *optarg; - -/* Index in ARGV of the next element to be scanned. - This is used for communication to and from the caller - and for communication between successive calls to `getopt'. - - On entry to `getopt', zero means this is the first call; initialize. - - When `getopt' returns EOF, this is the index of the first of the - non-option elements that the caller should itself scan. - - Otherwise, `optind' communicates from one call to the next - how much of ARGV has been scanned so far. */ - -extern int optind; - -/* Callers store zero here to inhibit the error message `getopt' prints - for unrecognized options. */ - -extern int opterr; - -/* Set to an option character which was unrecognized. */ - -extern int optopt; - -/* Describe the long-named options requested by the application. - The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector - of `struct option' terminated by an element containing a name which is - zero. - - The field `has_arg' is: - no_argument (or 0) if the option does not take an argument, - required_argument (or 1) if the option requires an argument, - optional_argument (or 2) if the option takes an optional argument. - - If the field `flag' is not NULL, it points to a variable that is set - to the value given in the field `val' when the option is found, but - left unchanged if the option is not found. - - To have a long-named option do something other than set an `int' to - a compiled-in constant, such as set a value from `optarg', set the - option's `flag' field to zero and its `val' field to a nonzero - value (the equivalent single-letter option character, if there is - one). For long options that have a zero `flag' field, `getopt' - returns the contents of the `val' field. */ - -struct option -{ -#if __STDC__ - const char *name; -#else - char *name; -#endif - /* has_arg can't be an enum because some compilers complain about - type mismatches in all the code that assumes it is an int. */ - int has_arg; - int *flag; - int val; -}; - -/* Names for the values of the `has_arg' field of `struct option'. */ - -#define no_argument 0 -#define required_argument 1 -#define optional_argument 2 - -#if __STDC__ -#if defined(__GNU_LIBRARY__) -/* Many other libraries have conflicting prototypes for getopt, with - differences in the consts, in stdlib.h. To avoid compilation - errors, only prototype getopt for the GNU C library. */ -extern int getopt (int argc, char *const *argv, const char *shortopts); -#else /* not __GNU_LIBRARY__ */ -extern int getopt (); -#endif /* not __GNU_LIBRARY__ */ -extern int getopt_long (int argc, char *const *argv, const char *shortopts, - const struct option *longopts, int *longind); -extern int getopt_long_only (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind); - -/* Internal only. Users should not call this directly. */ -extern int _getopt_internal (int argc, char *const *argv, - const char *shortopts, - const struct option *longopts, int *longind, - int long_only); -#else /* not __STDC__ */ -extern int getopt (); -extern int getopt_long (); -extern int getopt_long_only (); - -extern int _getopt_internal (); -#endif /* not __STDC__ */ - -#ifdef __cplusplus -} -#endif - -#endif /* _GETOPT_H */ diff --git a/gnu/usr.bin/diff3/getopt1.c b/gnu/usr.bin/diff3/getopt1.c deleted file mode 100644 index a32615c..0000000 --- a/gnu/usr.bin/diff3/getopt1.c +++ /dev/null @@ -1,176 +0,0 @@ -/* getopt_long and getopt_long_only entry points for GNU getopt. - Copyright (C) 1987, 88, 89, 90, 91, 92, 1993 - 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, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#ifdef HAVE_CONFIG_H -#include "config.h" -#endif - -#include "getopt.h" - -#if !__STDC__ && !defined(const) && IN_GCC -#define const -#endif - -#include - -/* Comment out all this code if we are using the GNU C Library, and are not - actually compiling the library itself. This code is part of the GNU C - Library, but also included in many other GNU distributions. Compiling - and linking in this code is a waste when using the GNU C library - (especially if it is a shared library). Rather than having every GNU - program understand `configure --with-gnu-libc' and omit the object files, - it is simpler to just do this in the source for each such file. */ - -#if defined (_LIBC) || !defined (__GNU_LIBRARY__) - - -/* This needs to come after some library #include - to get __GNU_LIBRARY__ defined. */ -#ifdef __GNU_LIBRARY__ -#include -#else -char *getenv (); -#endif - -#ifndef NULL -#define NULL 0 -#endif - -int -getopt_long (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 0); -} - -/* Like getopt_long, but '-' as well as '--' can indicate a long option. - If an option that starts with '-' (not '--') doesn't match a long option, - but does match a short option, it is parsed as a short option - instead. */ - -int -getopt_long_only (argc, argv, options, long_options, opt_index) - int argc; - char *const *argv; - const char *options; - const struct option *long_options; - int *opt_index; -{ - return _getopt_internal (argc, argv, options, long_options, opt_index, 1); -} - - -#endif /* _LIBC or not __GNU_LIBRARY__. */ - -#ifdef TEST - -#include - -int -main (argc, argv) - int argc; - char **argv; -{ - int c; - int digit_optind = 0; - - while (1) - { - int this_option_optind = optind ? optind : 1; - int option_index = 0; - static struct option long_options[] = - { - {"add", 1, 0, 0}, - {"append", 0, 0, 0}, - {"delete", 1, 0, 0}, - {"verbose", 0, 0, 0}, - {"create", 0, 0, 0}, - {"file", 1, 0, 0}, - {0, 0, 0, 0} - }; - - c = getopt_long (argc, argv, "abc:d:0123456789", - long_options, &option_index); - if (c == EOF) - break; - - switch (c) - { - case 0: - printf ("option %s", long_options[option_index].name); - if (optarg) - printf (" with arg %s", optarg); - printf ("\n"); - break; - - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - if (digit_optind != 0 && digit_optind != this_option_optind) - printf ("digits occur in two different argv-elements.\n"); - digit_optind = this_option_optind; - printf ("option %c\n", c); - break; - - case 'a': - printf ("option a\n"); - break; - - case 'b': - printf ("option b\n"); - break; - - case 'c': - printf ("option c with value `%s'\n", optarg); - break; - - case 'd': - printf ("option d with value `%s'\n", optarg); - break; - - case '?': - break; - - default: - printf ("?? getopt returned character code 0%o ??\n", c); - } - } - - if (optind < argc) - { - printf ("non-option ARGV-elements: "); - while (optind < argc) - printf ("%s ", argv[optind++]); - printf ("\n"); - } - - exit (0); -} - -#endif /* TEST */ diff --git a/gnu/usr.bin/diff3/system.h b/gnu/usr.bin/diff3/system.h deleted file mode 100644 index b17d39a..0000000 --- a/gnu/usr.bin/diff3/system.h +++ /dev/null @@ -1,159 +0,0 @@ -/* System dependent declarations. - Copyright (C) 1988, 1989, 1992, 1993 Free Software Foundation, Inc. - -This file is part of GNU DIFF. - -GNU DIFF 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. - -GNU DIFF 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 GNU DIFF; see the file COPYING. If not, write to -the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ - -#include -#include - -#ifndef S_ISDIR -#define S_ISDIR(mode) (((mode) & S_IFMT) == S_IFDIR) -#endif -#ifndef S_ISREG -#define S_ISREG(mode) (((mode) & S_IFMT) == S_IFREG) -#endif - -#if HAVE_UNISTD_H -#include -#endif - -#if HAVE_TIME_H -#include -#else -#include -#endif - -#if HAVE_FCNTL_H -#include -#else -#include -#endif - -#if !HAVE_DUP2 -#define dup2(f,t) (close (t), fcntl (f,F_DUPFD,t)) -#endif - -#ifndef O_RDONLY -#define O_RDONLY 0 -#endif - -#if HAVE_SYS_WAIT_H -#ifndef _POSIX_VERSION -/* Prevent the NeXT prototype using union wait from causing problems. */ -#define wait system_wait -#endif -#include -#ifndef _POSIX_VERSION -#undef wait -#endif -#endif /* HAVE_SYS_WAIT_H */ - -#ifndef WEXITSTATUS -#define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8) -#undef WIFEXITED /* Avoid 4.3BSD incompatibility with Posix. */ -#endif -#ifndef WIFEXITED -#define WIFEXITED(stat_val) (((stat_val) & 255) == 0) -#endif - -#if HAVE_ST_BLKSIZE -#define STAT_BLOCKSIZE(s) (s).st_blksize -#else -#define STAT_BLOCKSIZE(s) (S_ISREG ((s).st_mode) ? 8192 : 4096) -#endif - -#if DIRENT || defined (_POSIX_VERSION) -#include -#ifdef direct -#undef direct -#endif -#define direct dirent -#else /* ! (DIRENT || defined (_POSIX_VERSION)) */ -#if SYSNDIR -#include -#else -#if SYSDIR -#include -#else -#include -#endif -#endif -#endif /* ! (DIRENT || defined (_POSIX_VERSION)) */ - -#if HAVE_VFORK_H -#include -#endif - -#if HAVE_STRING_H || STDC_HEADERS -#include -#ifndef index -#define index strchr -#endif -#ifndef rindex -#define rindex strrchr -#endif -#ifndef bcopy -#define bcopy(s,d,n) memcpy (d,s,n) -#endif -#ifndef bcmp -#define bcmp(s1,s2,n) memcmp (s1,s2,n) -#endif -#ifndef bzero -#define bzero(s,n) memset (s,0,n) -#endif -#else -#include -#endif -#if !HAVE_MEMCHR && !STDC_HEADERS -char *memchr (); -#endif - -#if STDC_HEADERS -#include -#include -#else -char *getenv (); -char *malloc (); -char *realloc (); -#if __STDC__ || __GNUC__ -#include "limits.h" -#else -#define INT_MAX 2147483647 -#define CHAR_BIT 8 -#endif -#endif - -#include -#if !STDC_HEADERS -extern int errno; -#endif - -#ifdef TRUE -#undef TRUE -#endif -#ifdef FALSE -#undef FALSE -#endif -#define TRUE 1 -#define FALSE 0 - -#if !__STDC__ -#define volatile -#endif - -#define min(a,b) ((a) <= (b) ? (a) : (b)) -#define max(a,b) ((a) >= (b) ? (a) : (b)) diff --git a/gnu/usr.bin/diff3/version.c b/gnu/usr.bin/diff3/version.c deleted file mode 100644 index cb9d3b9..0000000 --- a/gnu/usr.bin/diff3/version.c +++ /dev/null @@ -1,3 +0,0 @@ -/* Version number of GNU diff. */ - -char *version_string = "2.3"; -- cgit v1.1